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