SundanceExodusNetCDFMeshReader.cpp
Go to the documentation of this file.
00001 #include "SundanceExodusNetCDFMeshReader.hpp"
00002 #include "SundanceOut.hpp"
00003 #include "SundanceExceptions.hpp"
00004 
00005 using namespace Sundance;
00006 using namespace Sundance;
00007 
00008 using namespace Teuchos;
00009 using namespace Sundance;
00010 
00011 
00012 ExodusNetCDFMeshReader::ExodusNetCDFMeshReader(const std::string& fname,
00013                                                const MeshType& meshType,
00014                                                const MPIComm& comm)
00015   : MeshReaderBase(fname, meshType, comm)
00016 {
00017   TEST_FOR_EXCEPTION(nProc() > 1, RuntimeError,
00018                      "ExodusNetCDFMeshReader not useable with parallel meshes");
00019 }
00020 
00021 ExodusNetCDFMeshReader::ExodusNetCDFMeshReader(const ParameterList& params)
00022   : MeshReaderBase(params)
00023 {
00024   TEST_FOR_EXCEPTION(nProc() > 1, RuntimeError,
00025                      "ExodusNetCDFMeshReader not useable with parallel meshes");
00026 }
00027 
00028 
00029 
00030 
00031 Mesh ExodusNetCDFMeshReader::fillMesh() const 
00032 {
00033   Mesh mesh;
00034 
00035   RCP<std::ifstream> is = openFile(filename(), "NetCDF");
00036 
00037   std::string line;
00038   Array<string> tokens;
00039 
00040   /* read the header line */
00041   getNextLine(*is, line, tokens, '#');
00042 
00043   TEST_FOR_EXCEPTION(tokens[0] != "netcdf", RuntimeError,
00044                      "ExodusNetCDF reader expected to find [netcdf] as first "
00045                      "token, found " << tokens[0]);
00046 
00047   /* read the list of dimensions */
00048   getNextLine(*is, line, tokens, '#');
00049 
00050 
00051   TEST_FOR_EXCEPTION(tokens[0] != "dimensions:", RuntimeError,
00052                      "ExodusNetCDF reader expected to find [dimension:] as first "
00053                      "token, found " << tokens[0]);
00054   
00055   int nElem = 0;
00056   int nNodes = 0;
00057   int nElemBlocks = 0;
00058   int nSideSets = 0;
00059   int nNodeSets = 0;
00060   int dimension = 0 ;
00061   Array<int> blockSizes;
00062   Array<int> sideSetSizes;
00063   Array<int> nodeSetSizes;
00064   Array<int> nodesPerElem;
00065   while (true)
00066     {
00067       getNextLine(*is, line, tokens, '#');
00068 
00069       if (tokens[0] == "variables:") break;
00070       std::string keyword = tokens[0];
00071       std::string equals = tokens[1];
00072       TEST_FOR_EXCEPTION(equals!="=", RuntimeError, "ExodusNetCDF reader "
00073                          "expected [=] as second token, found "
00074                          << equals);
00075 
00076       TEST_FOR_EXCEPTION(tokens.size() < 4, RuntimeError,
00077                          "ExodusNetCDF reader found a dimension line with "
00078                          "fewer than 4 tokens");
00079 
00080       int val = atoi(tokens[2]);
00081       if (keyword=="num_dim")
00082         {
00083           dimension = val;
00084         }
00085       else if (keyword=="num_nodes")
00086         {
00087           nNodes = val;
00088         }
00089       else if (keyword=="num_elem")
00090         {
00091           nElem = val;
00092         } 
00093       else if (keyword=="num_el_blk")
00094         {
00095           nElemBlocks = val;
00096           blockSizes.resize(nElemBlocks);
00097           nodesPerElem.resize(nElemBlocks);
00098         }
00099       else if (keyword=="num_side_sets")
00100         {
00101           nSideSets = val;
00102           sideSetSizes.resize(nSideSets);
00103           std::cerr << "num side sets = " << nSideSets << std::endl;
00104         }
00105       else if (keyword=="num_node_sets")
00106         {
00107           nNodeSets = val;
00108           nodeSetSizes.resize(nNodeSets);
00109           std::cerr << "num node sets = " << nNodeSets << std::endl;
00110         }
00111       else
00112         {
00113           for (int i=0; i<nElemBlocks; i++)
00114             {
00115               if (keyword=="num_el_in_blk" + Teuchos::toString(i+1))
00116                 {
00117                   blockSizes[i] = val;
00118                   break;
00119                 }
00120               if (keyword=="num_nod_per_el" + Teuchos::toString(i+1))
00121                 {
00122                   nodesPerElem[i] = val;
00123                   break;
00124                 }
00125             }
00126           for (int i=0; i<nSideSets; i++)
00127             {
00128               if (keyword=="num_side_ss" + Teuchos::toString(i+1))
00129                 {
00130                   sideSetSizes[i] = val;
00131                   break;
00132                 }
00133             }
00134           for (int i=0; i<nNodeSets; i++)
00135             {
00136               if (keyword=="num_nod_ns" + Teuchos::toString(i+1))
00137                 {
00138                   nodeSetSizes[i] = val;
00139                   break;
00140                 }
00141             }
00142         }
00143     }
00144 
00145   
00146 
00147   /* skip until we find [data:] */
00148   while (true)
00149     {
00150       getNextLine(*is, line, tokens, '#');
00151 
00152       if (tokens[0] == "data:") break;
00153     }
00154 
00155   /* read the data */
00156   
00157 
00158   Array<double> coords;
00159   coords.reserve(nNodes*dimension);
00160   Array<Array<int> > connect(nElemBlocks);
00161   Array<Array<int> > sideSetElems(nSideSets);
00162   Array<Array<int> > sideSetFacets(nSideSets);
00163   Array<Array<int> > nodeSetNodes(nNodeSets);
00164 
00165   bool doneWithData = false;
00166   while(!doneWithData)
00167     {
00168       if (!getNextLine(*is, line, tokens, '#')) 
00169         {
00170           doneWithData = true;
00171           break;
00172         }
00173 
00174       if (tokens.size()==0) 
00175         {
00176 
00177           doneWithData=true;
00178           break;
00179         }
00180       
00181       if (tokens[0]=="coord")
00182         {
00183           bool done = false;
00184           for (int i=1; i<tokens.size(); i++)
00185             {
00186               if (tokens[i] == "=") continue;
00187               if (tokens[i] == ";") 
00188                 {
00189                   done = true;
00190                   break;
00191                 }
00192               coords.append(atof(StrUtils::before(tokens[i], ",")));
00193             }
00194           while (!done)
00195             {
00196               if (!getNextLine(*is, line, tokens, '#'))
00197                 {
00198                   doneWithData = true;
00199                   break;
00200                 }
00201 
00202               for (int i=0; i<tokens.size(); i++)
00203                 {
00204                   if (tokens[i] == "=") continue;
00205                   if (tokens[i] == ";") 
00206                     {
00207                       done = true;
00208                       break;
00209                     }
00210                   coords.append(atof(StrUtils::before(tokens[i], ",")));
00211                 }
00212             }
00213           continue;
00214         }
00215       /* see if the line lists connectivity data for a block */
00216       for (int b=0; b<nElemBlocks; b++)
00217         {
00218           if (tokens[0] == "connect" + Teuchos::toString(b+1))
00219             {
00220               connect[b].reserve(blockSizes[b]);
00221               bool done = false;
00222               for (int i=1; i<tokens.size(); i++)
00223                 {
00224                   if (tokens[i] == "=") continue;
00225                   if (tokens[i] == ";") 
00226                     {
00227                       done = true;
00228                       break;
00229                     }
00230                   connect[b].append(atoi(StrUtils::before(tokens[i], ",")));
00231                 }
00232               while (!done)
00233                 {
00234                   if (!getNextLine(*is, line, tokens, '#'))
00235                     {
00236                       doneWithData = true;
00237                       break;
00238                     }
00239 
00240                   for (int i=0; i<tokens.size(); i++)
00241                     {
00242                       if (tokens[i] == "=") continue;
00243                       if (tokens[i] == ";") 
00244                         {
00245                           done = true;
00246                           break;
00247                         }
00248                       connect[b].append(atoi(StrUtils::before(tokens[i], ",")));
00249                     }
00250                 }
00251               continue;
00252             }
00253         }
00254 
00255       /* see if the line lists side set element numbers */
00256       for (int s=0; s<nSideSets; s++)
00257         {
00258           if (tokens[0] == "elem_ss" + Teuchos::toString(s+1))
00259             {
00260               sideSetElems[s].reserve(sideSetSizes[s]);
00261               bool done = false;
00262               for (int i=1; i<tokens.size(); i++)
00263                 {
00264                   if (tokens[i] == "=") continue;
00265                   if (tokens[i] == ";") 
00266                     {
00267                       done = true;
00268                       break;
00269                     }
00270                   sideSetElems[s].append(atoi(StrUtils::before(tokens[i], ",")));
00271                 }
00272               while (!done)
00273                 {
00274                   if (!getNextLine(*is, line, tokens, '#'))
00275                     {
00276                       doneWithData = true;
00277                       break;
00278                     }
00279 
00280                   for (int i=0; i<tokens.size(); i++)
00281                     {
00282                       if (tokens[i] == "=") continue;
00283                       if (tokens[i] == ";") 
00284                         {
00285                           done = true;
00286                           break;
00287                         }
00288                       sideSetElems[s].append(atoi(StrUtils::before(tokens[i], ",")));
00289                     }
00290                 }
00291               continue;
00292             }
00293         }
00294 
00295       /* see if the line lists side set facet numbers */
00296       for (int s=0; s<nSideSets; s++)
00297         {
00298           if (tokens[0] == "side_ss" + Teuchos::toString(s+1))
00299             {
00300               sideSetFacets[s].reserve(sideSetSizes[s]);
00301               bool done = false;
00302               for (int i=1; i<tokens.size(); i++)
00303                 {
00304                   if (tokens[i] == "=") continue;
00305                   if (tokens[i] == ";") 
00306                     {
00307                       done = true;
00308                       break;
00309                     }
00310                   sideSetFacets[s].append(atoi(StrUtils::before(tokens[i], ",")));
00311                 }
00312               while (!done)
00313                 {
00314                   if (!getNextLine(*is, line, tokens, '#'))
00315                     {
00316                       doneWithData = true;
00317                       break;
00318                     }
00319                   for (int i=0; i<tokens.size(); i++)
00320                     {
00321                       if (tokens[i] == "=") continue;
00322                       if (tokens[i] == ";") 
00323                         {
00324                           done = true;
00325                           break;
00326                         }
00327                       sideSetFacets[s].append(atoi(StrUtils::before(tokens[i], ",")));
00328                     }
00329                 }
00330               continue;
00331             }
00332         }
00333 
00334       /* see if the line lists node set node numbers */
00335       for (int s=0; s<nNodeSets; s++)
00336         {
00337           if (tokens[0] == "node_ns" + Teuchos::toString(s+1))
00338             {
00339               nodeSetNodes[s].reserve(nodeSetSizes[s]);
00340               bool done = false;
00341               for (int i=1; i<tokens.size(); i++)
00342                 {
00343                   if (tokens[i] == "=") continue;
00344                   if (tokens[i] == ";") 
00345                     {
00346                       done = true;
00347                       break;
00348                     }
00349                   nodeSetNodes[s].append(atoi(StrUtils::before(tokens[i], ",")));
00350                 }
00351               while (!done)
00352                 {
00353                   if (!getNextLine(*is, line, tokens, '#'))
00354                     {
00355                       doneWithData = true;
00356                       break;
00357                     }
00358                   for (int i=0; i<tokens.size(); i++)
00359                     {
00360                       if (tokens[i] == "=") continue;
00361                       if (tokens[i] == ";") 
00362                         {
00363                           done = true;
00364                           break;
00365                         }
00366                       nodeSetNodes[s].append(atoi(StrUtils::before(tokens[i], ",")));
00367                     }
00368                 }
00369               continue;
00370             }
00371         }
00372     }
00373 
00374 
00375 
00376   /* now we can build the mesh */
00377   mesh = createMesh(dimension);
00378 
00379   /* do some consistency checks */
00380   TEST_FOR_EXCEPTION(dimension * nNodes != coords.size(), RuntimeError,
00381                      "bad coordinate array in exodus reader");
00382 
00383   for (int b=0; b<nElemBlocks; b++)
00384     {
00385       TEST_FOR_EXCEPTION(blockSizes[b]*nodesPerElem[b] != connect[b].size(), RuntimeError,
00386                          "bad connectivity array for block " << b << " in exodus reader");
00387     }
00388 
00389   for (int s=0; s<nSideSets; s++)
00390     {
00391       TEST_FOR_EXCEPTION(sideSetElems[s].size() != sideSetFacets[s].size(), RuntimeError,
00392                          "inconsistent side set specification for ss=" << s 
00393                          << " in exodus reader ");
00394     }
00395 
00396   /* add the points to the mesh */
00397   for (int n=0; n<nNodes; n++)
00398     {
00399       Point x;
00400       if (dimension==2)
00401         {
00402           x = Point(coords[n], coords[nNodes+n]);
00403         }
00404       else
00405         {
00406           x = Point(coords[n], coords[nNodes+n], coords[2*nNodes+n]);
00407         }
00408       mesh.addVertex(n, x, 0, 0);
00409     }
00410 
00411 
00412   /* add the elements */
00413   int lid=0;
00414   for (int b=0; b<nElemBlocks; b++)
00415     {
00416       int n = 0;
00417       for (int e=0; e<blockSizes[b]; e++, n+=nodesPerElem[b], lid++)
00418         {
00419           if (dimension==2)
00420             {
00421               mesh.addElement(lid, tuple(connect[b][n]-1, connect[b][n+1]-1, connect[b][n+2]-1), 0, b+1);
00422             }
00423           else
00424             {
00425               mesh.addElement(lid, 
00426                               tuple(connect[b][n]-1, connect[b][n+1]-1, connect[b][n+2]-1, connect[b][n+3]-1),
00427                               0, b+1);
00428             }
00429         }
00430     }
00431   
00432   /* label the side sets */
00433 
00434   for (int s=0; s<nSideSets; s++)
00435     {
00436       for (int n=0; n<sideSetSizes[s]; n++)
00437         {
00438           int elemID = sideSetElems[s][n];
00439           int facetNum = sideSetFacets[s][n];
00440           int fsign;
00441           int sideLID = mesh.facetLID(dimension, elemID-1, dimension-1, facetNum-1,fsign);
00442           mesh.setLabel(dimension-1, sideLID, s+1);
00443         }
00444     }
00445 
00446   /* label the node sets */
00447   for (int s=0; s<nNodeSets; s++)
00448     {
00449       for (int n=0; n<nodeSetSizes[s]; n++)
00450         {
00451           int nodeNum = nodeSetNodes[s][n]-1;
00452           mesh.setLabel(0, nodeNum, s+1);
00453         }
00454     }
00455 
00456   return mesh;
00457 }
00458 

Site Contact