Date: 2013-07-02T14:45:31+00:00

Actual source code: meshdolfin.c
petsc-3.4.2 2013-07-02

      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