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

Site Contact