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