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