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 #include "SundanceExodusWriter.hpp"
00043 #include "PlayaExceptions.hpp"
00044 #include "SundanceOut.hpp"
00045 #include "SundanceMaximalCellFilter.hpp"
00046 #include "SundanceCellFilter.hpp"
00047 #include "SundanceVertexSort.hpp"
00048 #include "PlayaTabs.hpp"
00049 #include "Teuchos_XMLObject.hpp"
00050
00051 #ifdef HAVE_SUNDANCE_EXODUS
00052 #include "exodusII.h"
00053 #endif
00054
00055
00056 using namespace Sundance;
00057 using namespace Teuchos;
00058 using namespace std;
00059
00060
00061 void ExodusWriter::write() const
00062 {
00063
00064 std::string exoFile = filename();
00065 std::string parFile = filename();
00066 if (nProc() > 1)
00067 {
00068 exoFile = exoFile + "-" + Teuchos::toString(nProc()) + "-" + Teuchos::toString(myRank());
00069 parFile = parFile + "-" + Teuchos::toString(nProc()) + "-" + Teuchos::toString(myRank());
00070 }
00071 exoFile = exoFile + ".exo";
00072 parFile = parFile + ".pxo";
00073
00074 if (nProc() > 1) writeParallelInfo(parFile);
00075 #ifdef HAVE_SUNDANCE_EXODUS
00076 int ws = 8;
00077 int exoid = ex_create(exoFile.c_str(), EX_CLOBBER, &ws, &ws);
00078
00079 TEUCHOS_TEST_FOR_EXCEPTION(exoid < 0, std::runtime_error, "failure to create file "
00080 << filename());
00081
00082
00083 Array<CellFilter> nsFilters;
00084 Array<int> omniNodalFuncs;
00085 Array<RCP<Array<int> > > funcsForNodeset;
00086 Array<RCP<Array<int> > > nodesForNodeset;
00087 Array<int> nsID;
00088 Array<int> nsNodesPerSet;
00089 Array<int> nsNodePtr;
00090 RCP<Array<int> > allNodes=rcp(new Array<int>());
00091
00092 Array<CellFilter> blockFilters;
00093 Array<int> omniElemFuncs;
00094 Array<RCP<Array<int> > > funcsForBlock;
00095 Array<RCP<Array<int> > > elemsForBlock;
00096 Array<int> blockID;
00097 Array<int> nElemsPerBlock;
00098 Array<int> blockElemPtr;
00099 RCP<Array<int> > allElems=rcp(new Array<int>());
00100
00101
00102 findNodeSets(nsFilters, omniNodalFuncs, funcsForNodeset,
00103 nodesForNodeset, nsID, nsNodesPerSet, nsNodePtr, allNodes);
00104
00105 findBlocks(blockFilters, omniElemFuncs, funcsForBlock,
00106 elemsForBlock, blockID, nElemsPerBlock, blockElemPtr, allElems);
00107
00108
00109
00110 writeMesh(exoid, nsFilters, nsID, nsNodesPerSet, nsNodePtr, allNodes );
00111
00112 writeFields(exoid, nsFilters, omniNodalFuncs, omniElemFuncs,
00113 funcsForNodeset,
00114 nodesForNodeset, nsID);
00115
00116
00117 ex_close(exoid);
00118 #else
00119 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Exodus not enabled");
00120 #endif
00121 }
00122
00123
00124 void ExodusWriter::offset(Array<int>& x) const
00125 {
00126 for (int i=0; i<x.size(); i++) x[i]++;
00127 }
00128
00129
00130 void ExodusWriter::writeMesh(int exoid,
00131 const Array<CellFilter>& nodesetFilters,
00132 const Array<int>& nsID,
00133 const Array<int>& nNodesPerSet,
00134 const Array<int>& nsNodePtr,
00135 const RCP<Array<int> >& allNodes) const
00136 {
00137 #ifdef HAVE_SUNDANCE_EXODUS
00138
00139 int ierr = 0;
00140
00141 int dim = mesh().spatialDim();
00142 int nElems = mesh().numCells(dim);
00143
00144 Array<int> ssLabels = mesh().getAllLabelsForDimension(dim-1).elements();
00145 int numSS = 0;
00146
00147 for (int ss=0; ss<ssLabels.size(); ss++)
00148 {
00149 if (ssLabels[ss] != 0) numSS++;
00150 }
00151
00152 int numNS = nsID.size();
00153
00154
00155
00156 int nElemBlocks = mesh().numLabels(dim);
00157
00158 ierr = ex_put_init(
00159 exoid,
00160 filename().c_str(),
00161 dim,
00162 mesh().numCells(0),
00163 nElems,
00164 nElemBlocks,
00165 numNS,
00166 numSS
00167 );
00168 TEUCHOS_TEST_FOR_EXCEPT(ierr<0);
00169
00170
00171
00172 int nPts = mesh().numCells(0);
00173
00174 Array<double> x(nPts);
00175 Array<double> y(nPts);
00176 Array<double> z(nPts * (dim > 2));
00177
00178 for (int n=0; n<nPts; n++)
00179 {
00180 const Point& P = mesh().nodePosition(n);
00181 x[n] = P[0];
00182 y[n] = P[1];
00183 if (dim==3) z[n] = P[2];
00184 }
00185
00186 if (dim==2)
00187 {
00188 ierr = ex_put_coord(exoid, &(x[0]), &(y[0]), (void*) 0);
00189 }
00190 else
00191 {
00192 ierr = ex_put_coord(exoid, &(x[0]), &(y[0]), &(z[0]));
00193 }
00194
00195 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00196
00197 if (dim==2)
00198 {
00199 Array<std::string> cn;
00200 cn.append("x");
00201 cn.append("y");
00202 Array<const char*> pp;
00203 getCharpp(cn, pp);
00204 ierr = ex_put_coord_names(exoid,(char**) &(pp[0]));
00205 }
00206 else
00207 {
00208 Array<std::string> cn;
00209 cn.append("x");
00210 cn.append("y");
00211 cn.append("z");
00212 Array<const char*> pp;
00213 getCharpp(cn, pp);
00214 ierr = ex_put_coord_names(exoid, (char**)&(pp[0]));
00215 }
00216
00217 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00218
00219
00220
00221 Array<int> blockLabels = mesh().getAllLabelsForDimension(dim).elements();
00222 int nodesPerElem = dim+1;
00223 std::string eType = elemType(mesh().cellType(dim));
00224
00225 bool minBlockIsZero = false;
00226 for (int b=0; b<blockLabels.size(); b++)
00227 {
00228 if (blockLabels[b] < 1) {minBlockIsZero = true; break;}
00229 }
00230
00231
00232 for (int b=0; b<blockLabels.size(); b++)
00233 {
00234
00235 int numBlockAttr = 0;
00236 Array<int> blockElemLIDs;
00237 Array<int> nodeLIDs;
00238 Array<int> orient;
00239 mesh().getLIDsForLabel(dim, blockLabels[b], blockElemLIDs);
00240 int numElemsThisBlock = blockElemLIDs.size();
00241
00242
00243 mesh().getFacetLIDs(dim, blockElemLIDs, 0, nodeLIDs, orient);
00244 offset(nodeLIDs);
00245 ierr = ex_put_elem_block(
00246 exoid, blockLabels[b]+minBlockIsZero, eType.c_str(),
00247 numElemsThisBlock, nodesPerElem, numBlockAttr
00248 );
00249
00250 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00251
00252 ierr = ex_put_elem_conn(exoid, blockLabels[b]+minBlockIsZero,
00253 &(nodeLIDs[0]));
00254 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00255 }
00256
00257
00258 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00259
00260
00261
00262
00263 for (int ss=0; ss<ssLabels.size(); ss++)
00264 {
00265
00266 if (ssLabels[ss]==0) continue;
00267 Array<int> sideLIDs;
00268 RCP<Array<int> > elemLIDs = rcp(new Array<int>());
00269 RCP<Array<int> > facets = rcp(new Array<int>());
00270 MaximalCofacetBatch maxCofacetBatch;
00271
00272
00273 mesh().getLIDsForLabel(dim-1, ssLabels[ss], sideLIDs);
00274 sort(&(sideLIDs[0]), &(sideLIDs[sideLIDs.size()-1]));
00275
00276
00277 mesh().getMaxCofacetLIDs(sideLIDs, maxCofacetBatch);
00278
00279 maxCofacetBatch.getSpecifiedCofacets(0, elemLIDs, facets);
00280
00281 int numSides = sideLIDs.size();
00282 int numDists = 0;
00283
00284 for (int i=0; i<elemLIDs->size(); i++)
00285 {
00286 (*facets)[i] = ufcFacetIndexToExFacetIndex(dim, (*facets)[i]);
00287 }
00288
00289 offset(sideLIDs);
00290 offset(*elemLIDs);
00291 offset(*facets);
00292
00293
00294 ierr = ex_put_side_set_param(exoid, ssLabels[ss], numSides, numDists);
00295 ierr = ex_put_side_set(exoid, ssLabels[ss], &((*elemLIDs)[0]), &((*facets)[0]));
00296 }
00297
00298
00299 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00300
00301
00302
00303 if (nsID.size() > 0)
00304 {
00305
00306
00307 Array<int> nsDistPerSet(nsID.size(), 0);
00308 Array<int> nsDistPtr(nsID.size(), 0);
00309 Array<int> emptyDist(1, 0);
00310
00311 offset(*allNodes);
00312
00313 ierr = ex_put_concat_node_sets( exoid,
00314 (int*) &(nsID[0]),
00315 (int*) &(nNodesPerSet[0]),
00316 &(nsDistPerSet[0]),
00317 (int*) &(nsNodePtr[0]),
00318 &(nsDistPtr[0]),
00319 &((*allNodes)[0]),
00320 &(emptyDist[0]));
00321
00322 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00323 }
00324
00325 #else
00326 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Exodus not enabled");
00327 #endif
00328 }
00329
00330
00331 void ExodusWriter::writeFields(int exoid,
00332 const Array<CellFilter>& nodesetFilters,
00333 const Array<int>& omnipresentNodalFuncs,
00334 const Array<int>& omnipresentElemFuncs,
00335 const Array<RCP<Array<int> > >& funcsForNodeset,
00336 const Array<RCP<Array<int> > >& nodesForNodeset,
00337 const Array<int>& nsID) const
00338 {
00339
00340 #ifdef HAVE_SUNDANCE_EXODUS
00341 Tabs tab0(0);
00342 Tabs tab1;
00343 int verb=3;
00344
00345
00346 int nNodalFuncs = omnipresentNodalFuncs().size();
00347 int nElemFuncs = omnipresentElemFuncs().size();
00348
00349 int nNodesetFuncs = pointScalarFields().size() - nNodalFuncs;
00350
00351 int nNodesets = funcsForNodeset.size();
00352
00353 PLAYA_ROOT_MSG1(verb, tab0 << "ExodusWriter::writeFields()");
00354 PLAYA_ROOT_MSG2(verb, tab1 << "nNodalFuncs = " << nNodalFuncs);
00355 PLAYA_ROOT_MSG2(verb, tab1 << "nElemFuncs = " << nElemFuncs);
00356 PLAYA_ROOT_MSG2(verb, tab1 << "nNodesetFuncs = " << nNodesetFuncs);
00357 PLAYA_ROOT_MSG2(verb, tab1 << "nNodesets = " << nNodesets);
00358
00359
00360 Set<int> nsFuncSet;
00361 Map<int, Array<int> > funcToNSMap;
00362
00363 for (int i=0; i<nNodesets; i++)
00364 {
00365 const Array<int>& f = *(funcsForNodeset[i]);
00366 for (int j=0; j<f.size(); j++)
00367 {
00368 nsFuncSet.put(f[j]);
00369 if (funcToNSMap.containsKey(f[j]))
00370 {
00371 funcToNSMap[f[j]].append(i);
00372 }
00373 else
00374 {
00375 funcToNSMap.put(f[j], ::Teuchos::tuple(i));
00376 }
00377 }
00378 }
00379 Array<int> nsFuncs = nsFuncSet.elements();
00380 TEUCHOS_TEST_FOR_EXCEPT(nsFuncs.size() != nNodesetFuncs);
00381
00382 Map<int, int > funcIDToNSFuncIndex;
00383 for (int i=0; i<nNodesetFuncs; i++) funcIDToNSFuncIndex.put(nsFuncs[i],i);
00384
00385 Array<Array<int> > nsFuncNodesets(nsFuncs.size());
00386 for (int i=0; i<nNodesetFuncs; i++)
00387 {
00388 nsFuncNodesets[i] = funcToNSMap.get(nsFuncs[i]);
00389 }
00390
00391 Array<int> nodesetFuncTruthTable(nNodesetFuncs * nNodesets, 0);
00392 for (int i=0; i<nNodesetFuncs; i++)
00393 {
00394 for (int j=0; j<nsFuncNodesets[i].size(); j++)
00395 {
00396 int ns = nsFuncNodesets[i][j];
00397 nodesetFuncTruthTable[ns*nNodesetFuncs + i] = 1;
00398 }
00399
00400 nsFuncNodesets[i] = funcToNSMap.get(nsFuncs[i]);
00401 }
00402
00403
00404
00405 int ierr;
00406
00407 if (nNodalFuncs > 0)
00408 {
00409 ierr = ex_put_var_param(exoid, "N", nNodalFuncs);
00410 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00411 }
00412
00413 if (nElemFuncs > 0)
00414 {
00415 ierr = ex_put_var_param(exoid, "E", nElemFuncs);
00416 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00417 }
00418
00419
00420 if (nNodesets > 0)
00421 {
00422 ierr = ex_put_var_param(exoid, "M", nNodesetFuncs);
00423 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00424
00425 ierr = ex_put_nset_var_tab(exoid, nNodesets,
00426 nNodesetFuncs, &(nodesetFuncTruthTable[0]));
00427 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00428
00429 Array<std::string> nsFuncNames(nNodesetFuncs);
00430 Array<const char*> nsNameP;
00431
00432 for (int i=0; i<nNodesetFuncs; i++)
00433 {
00434 nsFuncNames[i] = pointScalarNames()[nsFuncs[i]];
00435 }
00436 getCharpp(nsFuncNames, nsNameP);
00437
00438 ierr = ex_put_var_names(exoid, "M", nNodesetFuncs, (char**)&(nsNameP[0]));
00439 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00440 }
00441
00442
00443 Array<std::string> nodalFuncNames(nNodalFuncs);
00444 Array<std::string> elemFuncNames(nElemFuncs);
00445 Array<const char*> nNameP;
00446 Array<const char*> eNameP;
00447
00448 for (int i=0; i<nNodalFuncs; i++)
00449 {
00450 nodalFuncNames[i] = pointScalarNames()[omnipresentNodalFuncs[i]];
00451 }
00452 getCharpp(nodalFuncNames, nNameP);
00453
00454 for (int i=0; i<nElemFuncs; i++)
00455 {
00456 elemFuncNames[i] = cellScalarNames()[omnipresentElemFuncs[i]];
00457 }
00458 getCharpp(elemFuncNames, eNameP);
00459
00460 if (nNodalFuncs > 0)
00461 {
00462 ierr = ex_put_var_names(exoid, "N", nNodalFuncs, (char**)&(nNameP[0]));
00463 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00464
00465 Array<double> funcVals;
00466 Array<int> nodeID(mesh().numCells(0));
00467 for (int i=0; i<mesh().numCells(0); i++) nodeID[i]=i;
00468
00469 for (int i=0; i<nNodalFuncs; i++)
00470 {
00471 int f = omnipresentNodalFuncs[i];
00472 pointScalarFields()[f]->getDataBatch(0, nodeID, ::Teuchos::tuple(f), funcVals);
00473 int t = 1;
00474 int numNodes = funcVals.size();
00475 ierr = ex_put_nodal_var(exoid, t, i+1, numNodes, &(funcVals[0]));
00476 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00477 }
00478
00479 for (int i=0; i<nNodesetFuncs; i++)
00480 {
00481 const Array<int>& ns = nsFuncNodesets[i];
00482 int fid = nsFuncs[i];
00483
00484 for (int s=0; s<ns.size(); s++)
00485 {
00486 const Array<int>& nodes = *(nodesForNodeset[ns[s]]);
00487 pointScalarFields()[fid]->getDataBatch(0, nodes, ::Teuchos::tuple(fid), funcVals);
00488 int t = 1;
00489 int numNodes = funcVals.size();
00490 int id = nsID[ns[s]];
00491 ierr = ex_put_nset_var(exoid, t, i+1, id, numNodes, &(funcVals[0]));
00492 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00493 }
00494 }
00495 }
00496
00497 if (nElemFuncs > 0)
00498 {
00499 ierr = ex_put_var_names(exoid, "E", nElemFuncs, (char**)&(eNameP[0]));
00500 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00501
00502 Array<double> funcVals;
00503 int dim = mesh().spatialDim();
00504 Array<int> elemID(mesh().numCells(dim));
00505 for (int i=0; i<mesh().numCells(dim); i++) elemID[i]=i;
00506
00507 for (int i=0; i<nElemFuncs; i++)
00508 {
00509 int f = omnipresentElemFuncs[i];
00510 cellScalarFields()[f]->getDataBatch(dim, elemID, ::Teuchos::tuple(f), funcVals);
00511 int t = 1;
00512 int numElems = funcVals.size();
00513 ierr = ex_put_elem_var(exoid, t, i+1, 1, numElems, &(funcVals[0]));
00514 TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00515 }
00516 }
00517
00518
00519 #else
00520 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Exodus not enabled");
00521 #endif
00522
00523 }
00524
00525
00526
00527 std::string ExodusWriter::elemType(const CellType& type) const
00528 {
00529 switch(type)
00530 {
00531 case TriangleCell:
00532 return "TRIANGLE";
00533 case TetCell:
00534 return "TETRA";
00535 default:
00536 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "cell type=" << type << " cannot be used as a "
00537 "maximal-dimension cell in exodus");
00538 }
00539 return "NULL";
00540 }
00541
00542
00543
00544 void ExodusWriter::writeParallelInfo(const std::string& parfile) const
00545 {
00546 std::ofstream os(parfile.c_str());
00547
00548 int dim = mesh().spatialDim();
00549 int nCells = mesh().numCells(dim);
00550 int nPts = mesh().numCells(0);
00551
00552 os << myRank() << " " << nProc() << std::endl;
00553
00554 os << nPts << std::endl;
00555 for (int i=0; i<nPts; i++)
00556 {
00557 os << i << " " << mesh().mapLIDToGID(0,i)
00558 << " " << mesh().ownerProcID(0,i) << std::endl;
00559 }
00560
00561 os << nCells << std::endl;
00562 for (int c=0; c<nCells; c++)
00563 {
00564 os << c << " " << mesh().mapLIDToGID(dim,c)
00565 << " " << mesh().ownerProcID(dim,c) << std::endl;
00566 }
00567
00568 for (int i=0; i<comments().length(); i++)
00569 {
00570 os << "# " << comments()[i] << std::endl;
00571 }
00572 }
00573
00574
00575
00576
00577
00578 void ExodusWriter::findNodeSets(
00579 Array<CellFilter>& nodesetFilters,
00580 Array<int>& omnipresentFuncs,
00581 Array<RCP<Array<int> > >& funcsForNodeset,
00582 Array<RCP<Array<int> > >& nodesForNodeset,
00583 Array<int>& nsID,
00584 Array<int>& nNodesPerSet,
00585 Array<int>& nsNodePtr,
00586 RCP<Array<int> > allNodes
00587 ) const
00588 {
00589
00590 int verb = 2;
00591
00592 const Array<RCP<FieldBase> >& f = pointScalarFields();
00593 CellFilter maximal = new MaximalCellFilter();
00594
00595 nNodesPerSet.resize(0);
00596 nsNodePtr.resize(0);
00597 nsID.resize(0);
00598
00599 Map<CellFilter, RCP<Array<int> > > tmp;
00600
00601 for (int i=0; i<f.size(); i++)
00602 {
00603 const CellFilter& cf = f[i]->domain();
00604 if (cf==maximal)
00605 {
00606 SUNDANCE_MSG2(verb, "function #" << i << " is defined on all nodes");
00607 omnipresentFuncs.append(i);
00608 continue;
00609 }
00610 if (!tmp.containsKey(cf))
00611 {
00612 RCP<Array<int> > a = rcp(new Array<int>());
00613 tmp.put(cf, a);
00614 }
00615 SUNDANCE_MSG2(verb, "function #" << i << " is defined on CF " << cf);
00616 tmp[cf]->append(i);
00617 }
00618
00619 int nodesetID=1;
00620 int nodePtr=0;
00621 nodesetFilters.resize(0);
00622 funcsForNodeset.resize(0);
00623 nodesForNodeset.resize(0);
00624
00625 for (Map<CellFilter, RCP<Array<int> > >::const_iterator
00626 i=tmp.begin(); i!=tmp.end(); i++)
00627 {
00628 const CellFilter& cf = i->first;
00629 nodesetFilters.append(cf);
00630 funcsForNodeset.append(i->second);
00631 RCP<Array<int> > cells
00632 = cellSetToLIDArray(connectedNodeSet(cf, mesh()));
00633 nodesForNodeset.append(cells);
00634 int nn = cells->size();
00635 nNodesPerSet.append(nn);
00636 nsID.append(nodesetID++);
00637 nsNodePtr.append(nodePtr);
00638 nodePtr += nn;
00639 }
00640
00641 SUNDANCE_MSG2(verb, "node set IDs = " << nsID);
00642 SUNDANCE_MSG2(verb, "num nodes = " << nNodesPerSet);
00643 SUNDANCE_MSG2(verb, "node set pointers = " << nsNodePtr);
00644
00645
00646 int numNodes = nodePtr;
00647 allNodes->resize(numNodes);
00648
00649 int k=0;
00650 for (int i=0; i<nsID.size(); i++)
00651 {
00652 SUNDANCE_MSG4(verb, "node set " << i << " funcs = "
00653 << *funcsForNodeset[i]);
00654 SUNDANCE_MSG4(verb, "node set " << i
00655 << " nodes = " << *nodesForNodeset[i]);
00656 const Array<int>& myCells = *(nodesForNodeset[i]);
00657 for (int c=0; c<myCells.size(); c++)
00658 {
00659 (*allNodes)[k++] = myCells[c];
00660 }
00661 }
00662
00663 SUNDANCE_MSG4(verb, "all nodes = " << *allNodes);
00664 }
00665
00666
00667
00668 void ExodusWriter::findBlocks(
00669 Array<CellFilter>& blockFilters,
00670 Array<int>& omnipresentFuncs,
00671 Array<RCP<Array<int> > >& funcsForBlock,
00672 Array<RCP<Array<int> > >& elemsForBlock,
00673 Array<int>& blockIDs,
00674 Array<int>& nElemsPerBlock,
00675 Array<int>& elemBlockPtr,
00676 RCP<Array<int> > allElems
00677 ) const
00678 {
00679
00680 int verb=0;
00681 const Array<RCP<FieldBase> >& f = cellScalarFields();
00682 CellFilter maximal = new MaximalCellFilter();
00683
00684 nElemsPerBlock.resize(0);
00685 elemBlockPtr.resize(0);
00686 blockIDs.resize(0);
00687
00688 Map<CellFilter, RCP<Array<int> > > tmp;
00689
00690 for (int i=0; i<f.size(); i++)
00691 {
00692 const CellFilter& cf = f[i]->domain();
00693 if (cf==maximal)
00694 {
00695 SUNDANCE_MSG2(verb, "function #" << i << " is defined on all nodes");
00696 omnipresentFuncs.append(i);
00697 continue;
00698 }
00699 if (!tmp.containsKey(cf))
00700 {
00701 RCP<Array<int> > a = rcp(new Array<int>());
00702 tmp.put(cf, a);
00703 }
00704 SUNDANCE_MSG2(verb, "function #" << i << " is defined on CF " << cf);
00705 tmp[cf]->append(i);
00706 }
00707
00708 int blockID=1;
00709 int blockPtr=0;
00710 blockFilters.resize(0);
00711 funcsForBlock.resize(0);
00712 elemsForBlock.resize(0);
00713
00714 for (Map<CellFilter, RCP<Array<int> > >::const_iterator
00715 i=tmp.begin(); i!=tmp.end(); i++)
00716 {
00717 const CellFilter& cf = i->first;
00718 blockFilters.append(cf);
00719 funcsForBlock.append(i->second);
00720 RCP<Array<int> > cells
00721 = cellSetToLIDArray(cf.getCells(mesh()));
00722 elemsForBlock.append(cells);
00723 int nn = cells->size();
00724 nElemsPerBlock.append(nn);
00725 blockIDs.append(blockID++);
00726 elemBlockPtr.append(blockPtr);
00727 blockPtr += nn;
00728 }
00729
00730 SUNDANCE_MSG2(verb, "block IDs = " << blockIDs);
00731 SUNDANCE_MSG2(verb, "num elems = " << nElemsPerBlock);
00732 SUNDANCE_MSG2(verb, "block pointers = " << elemBlockPtr);
00733
00734
00735 int numElems = blockPtr;
00736 allElems->resize(numElems);
00737
00738 int k=0;
00739 for (int i=0; i<blockIDs.size(); i++)
00740 {
00741 SUNDANCE_MSG2(verb, "block " << i << " funcs = "
00742 << *funcsForBlock[i]);
00743 SUNDANCE_MSG2(verb, "block " << i
00744 << " elems = " << *elemsForBlock[i]);
00745 const Array<int>& myCells = *(elemsForBlock[i]);
00746 for (int c=0; c<myCells.size(); c++)
00747 {
00748 (*allElems)[k++] = myCells[c];
00749 }
00750 }
00751
00752 SUNDANCE_MSG2(verb, "all elems = " << *allElems);
00753 }
00754
00755 void ExodusWriter::getCharpp(const Array<std::string>& s, Array<const char*>& p) const
00756 {
00757 p.resize(s.size());
00758 for (int i=0; i<p.size(); i++) p[i] = s[i].c_str();
00759 }
00760
00761