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