Actual source code: meshdolfin.c
1: #include <petscmesh_formats.hh> /*I "petscmesh.h" I*/
3: #ifdef PETSC_HAVE_LIBXML2
5: namespace ALE {
6: namespace Dolfin {
7: void XMLObject::error(std::string msg, ...) {
8: static char buffer[2048];
9: va_list aptr;
11: va_start(aptr, msg);
12: vsnprintf(buffer, 2048, msg.c_str(), aptr);
13: va_end(aptr);
14: std::cerr << buffer << std::endl;
15: }
16: int XMLObject::parseInt(const xmlChar* name, const xmlChar** attrs, const char* attribute) {
17: // Check that we got the data
18: if (!attrs) error("Missing attribute \"%s\" for <%s> in XML file.", attribute, name);
19: // Parse data
20: for (uint i = 0; attrs[i]; i++) {
21: // Check for attribute
22: if (xmlStrcasecmp(attrs[i], (xmlChar *) attribute) == 0) {
23: if (!attrs[i+1]) error("Value for attribute \"%s\" of <%s> missing in XML file.", attribute, name);
24: return atoi((const char *) (attrs[i+1]));
25: }
26: }
27: // Didn't get the value
28: error("Missing attribute \"%s\" for <%s> in XML file.", attribute, name);
29: return 0;
30: };
31: unsigned int XMLObject::parseUnsignedInt(const xmlChar* name, const xmlChar** attrs, const char* attribute) {
32: // Check that we got the data
33: if (!attrs) error("Missing attribute \"%s\" for <%s> in XML file.", attribute, name);
34: // Parse data
35: for (uint i = 0; attrs[i]; i++) {
36: // Check for attribute
37: if (xmlStrcasecmp(attrs[i], (xmlChar *) attribute) == 0) {
38: if (!attrs[i+1]) error("Value for attribute \"%s\" of <%s> missing in XML file.", attribute, name);
39: int value = atoi((const char *) (attrs[i+1]));
41: if (value < 0) error("Value for attribute \"%s\" of <%s> is negative.", attribute, name);
42: return static_cast<uint>(value);
43: }
44: }
45: // Didn't get the value
46: error("Missing attribute \"%s\" for <%s> in XML file.", attribute, name);
47: return 0;
48: };
49: double XMLObject::parseReal(const xmlChar* name, const xmlChar** attrs, const char* attribute) {
50: // Check that we got the data
51: if (!attrs) error("Missing attribute \"%s\" for <%s> in XML file.", attribute, name);
52: // Parse data
53: for (uint i = 0; attrs[i]; i++) {
54: // Check for attribute
55: if (xmlStrcasecmp(attrs[i], (xmlChar *) attribute) == 0) {
56: if (!attrs[i+1]) error("Value for attribute \"%s\" of <%s> missing in XML file.", attribute, name);
57: return atof((const char *) (attrs[i+1]));
58: }
59: }
60: // Didn't get the value
61: error("Missing attribute \"%s\" for <%s> in XML file.", attribute, name);
62: return 0.0;
63: };
64: std::string XMLObject::parseString(const xmlChar* name, const xmlChar** attrs, const char* attribute) {
65: // Check that we got the data
66: if (!attrs) error("Missing attribute \"%s\" for <%s> in XML file.", attribute, name);
67: // Parse data
68: for (uint i = 0; attrs[i]; i++) {
69: // Check for attribute
70: if (xmlStrcasecmp(attrs[i], (xmlChar *) attribute) == 0) {
71: if (!attrs[i+1]) error("Value for attribute \"%s\" of <%s> missing in XML file.", attribute, name);
72: return (const char *) (attrs[i+1]);
73: }
74: }
75: // Didn't get the value
76: error("Missing attribute \"%s\" for <%s> in XML file.", attribute, name);
77: return "";
78: };
79: bool XMLObject::parseBool(const xmlChar* name, const xmlChar** attrs, const char* attribute) {
80: // Check that we got the data
81: if (!attrs) error("Missing attribute \"%s\" for <%s> in XML file.", attribute, name);
82: // Parse data
83: for (uint i = 0; attrs[i]; i++) {
84: // Check for attribute
85: if (xmlStrcasecmp(attrs[i], (xmlChar *) attribute) == 0) {
86: if (!attrs[i+1]) error("Value for attribute \"%s\" of <%s> missing in XML file.", attribute, name);
87: std::string value = (const char *) (attrs[i+1]);
88: if (strcmp(value.c_str(), "true") == 0 or strcmp(value.c_str(), "1") == 0)
89: return true;
90: if (strcmp(value.c_str(), "false") == 0 or strcmp(value.c_str(), "0") == 0)
91: return false;
92: error("Cannot convert \"%s\" for attribute \"%s\" in <%s> to bool.", value.c_str(), attribute, name);
93: return false;
94: }
95: }
96: // Didn't get the value
97: error("Missing attribute \"%s\" for <%s> in XML file.", attribute, name);
98: return false;
99: };
101: void XMLMesh::startElement(const xmlChar *name, const xmlChar **attrs) {
102: switch (state) {
103: case OUTSIDE:
104: if (xmlStrcasecmp(name, (xmlChar *) "mesh") == 0) {
105: readMesh(name, attrs);
106: state = INSIDE_MESH;
107: }
108: break;
109: case INSIDE_MESH:
110: if (xmlStrcasecmp(name, (xmlChar *) "vertices") == 0) {
111: readVertices(name, attrs);
112: state = INSIDE_VERTICES;
113: }
114: else if (xmlStrcasecmp(name, (xmlChar *) "cells") == 0) {
115: readCells(name, attrs);
116: state = INSIDE_CELLS;
117: }
118: break;
119: case INSIDE_VERTICES:
120: if (xmlStrcasecmp(name, (xmlChar *) "vertex") == 0)
121: readVertex(name, attrs);
122: break;
123: case INSIDE_CELLS:
124: if (xmlStrcasecmp(name, (xmlChar *) "interval") == 0) {
125: readInterval(name, attrs);
126: } else if (xmlStrcasecmp(name, (xmlChar *) "triangle") == 0) {
127: readTriangle(name, attrs);
128: } else if (xmlStrcasecmp(name, (xmlChar *) "tetrahedron") == 0) {
129: readTetrahedron(name, attrs);
130: }
131: break;
132: default:
133: break;
134: }
135: };
136: void XMLMesh::endElement(const xmlChar *name) {
137: switch (state) {
138: case INSIDE_MESH:
139: if (xmlStrcasecmp(name, (xmlChar *) "mesh") == 0) {
140: closeMesh();
141: state = DONE;
142: }
143: break;
144: case INSIDE_VERTICES:
145: if (xmlStrcasecmp(name, (xmlChar *) "vertices") == 0)
146: state = INSIDE_MESH;
147: break;
148: case INSIDE_CELLS:
149: if (xmlStrcasecmp(name, (xmlChar *) "cells") == 0)
150: state = INSIDE_MESH;
151: break;
152: default:
153: break;
154: }
155: };
156: void XMLMesh::readMesh(const xmlChar *name, const xmlChar **attrs) {
157: // Parse values
158: std::string type = parseString(name, attrs, "celltype");
159: this->embedDim = parseUnsignedInt(name, attrs, "dim");
160: int tdim = 0;
162: if (type == "interval") {
163: tdim = 1;
164: } else if (type == "triangle") {
165: tdim = 2;
166: } else if (type == "tetrahedron") {
167: tdim = 3;
168: }
169: mesh->setDimension(tdim);
170: };
171: void XMLMesh::readVertices(const xmlChar *name, const xmlChar **attrs) {
172: // Parse values
173: unsigned int num_vertices = parseUnsignedInt(name, attrs, "size");
174: // Set number of vertices
175: this->coords = new double[num_vertices*this->embedDim];
176: };
177: void XMLMesh::readCells(const xmlChar *name, const xmlChar **attrs) {
178: // Parse values
179: this->numCells = parseUnsignedInt(name, attrs, "size");
180: };
181: void XMLMesh::readVertex(const xmlChar *name, const xmlChar **attrs) {
182: // Read index
183: uint v = parseUnsignedInt(name, attrs, "index");
185: switch (this->embedDim) {
186: case 3:
187: this->coords[v*this->embedDim+2] = parseReal(name, attrs, "z");
188: case 2:
189: this->coords[v*this->embedDim+1] = parseReal(name, attrs, "y");
190: case 1:
191: this->coords[v*this->embedDim+0] = parseReal(name, attrs, "x");
192: break;
193: default:
194: error("Dimension of mesh must be 1, 2 or 3.");
195: }
196: };
197: void XMLMesh::readInterval(const xmlChar *name, const xmlChar **attrs) {
198: // Check dimension
199: if (mesh->getDimension() != 1)
200: error("Mesh entity (interval) does not match dimension of mesh (%d).", mesh->getDimension());
201: // Parse values
202: unsigned int c = parseUnsignedInt(name, attrs, "index");
203: unsigned int v0 = parseUnsignedInt(name, attrs, "v0") + this->numCells;
204: unsigned int v1 = parseUnsignedInt(name, attrs, "v1") + this->numCells;
205: // Add cell
206: mesh->getSieve()->addArrow(v0, c, 0);
207: mesh->getSieve()->addArrow(v1, c, 1);
208: };
209: void XMLMesh::readTriangle(const xmlChar *name, const xmlChar **attrs) {
210: // Check dimension
211: if (mesh->getDimension() != 2)
212: error("Mesh entity (triangle) does not match dimension of mesh (%d).", mesh->getDimension());
213: // Parse values
214: unsigned int c = parseUnsignedInt(name, attrs, "index");
215: unsigned int v0 = parseUnsignedInt(name, attrs, "v0") + this->numCells;
216: unsigned int v1 = parseUnsignedInt(name, attrs, "v1") + this->numCells;
217: unsigned int v2 = parseUnsignedInt(name, attrs, "v2") + this->numCells;
218: // Add cell
219: mesh->getSieve()->addArrow(v0, c, 0);
220: mesh->getSieve()->addArrow(v1, c, 1);
221: mesh->getSieve()->addArrow(v2, c, 2);
222: };
223: void XMLMesh::readTetrahedron(const xmlChar *name, const xmlChar **attrs) {
224: // Check dimension
225: if (mesh->getDimension() != 3)
226: error("Mesh entity (tetrahedron) does not match dimension of mesh (%d).", mesh->getDimension());
227: // Parse values
228: unsigned int c = parseUnsignedInt(name, attrs, "index");
229: unsigned int v0 = parseUnsignedInt(name, attrs, "v0") + this->numCells;
230: unsigned int v1 = parseUnsignedInt(name, attrs, "v1") + this->numCells;
231: unsigned int v2 = parseUnsignedInt(name, attrs, "v2") + this->numCells;
232: unsigned int v3 = parseUnsignedInt(name, attrs, "v3") + this->numCells;
233: // Add cell
234: mesh->getSieve()->addArrow(v0, c, 0);
235: mesh->getSieve()->addArrow(v1, c, 1);
236: mesh->getSieve()->addArrow(v2, c, 2);
237: mesh->getSieve()->addArrow(v3, c, 3);
238: };
239: void XMLMesh::closeMesh() {
240: mesh->stratify();
241: ALE::SieveBuilder<PETSC_MESH_TYPE>::buildCoordinates(mesh, this->embedDim, this->coords);
242: delete [] this->coords;
243: };
244: }
245: }
247: #endif // PETSC_HAVE_LIBXML2