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