SundanceExodusWriter.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
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 //  Out::os() << "in ExodusWriter::write()" << endl;
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 //  Out::os() << "in ExodusWriter::writeMesh()" << endl;
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   /* initialize the output file */
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   /* write the vertices */
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   /* write the element blocks */
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 //    Out::os() << "writing element block" << b << endl;
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 //    Out::os() << "writing block #" << blockLabels[b] << " with " << numElemsThisBlock << " elems"  
00242 //              << endl;
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 //    Out::os() << "block: " << blockLabels[b]+minBlockIsZero << endl;
00252     ierr = ex_put_elem_conn(exoid, blockLabels[b]+minBlockIsZero, 
00253       &(nodeLIDs[0]));
00254     TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00255   }
00256 //  Out::os() << "done all element blocks" << endl;
00257 
00258   TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00259   
00260   /* write the side sets */
00261   
00262 //  Out::os() << "writing side sets "<< endl;  
00263   for (int ss=0; ss<ssLabels.size(); ss++)
00264   {
00265 //    Out::os() << "writing side set=" << ss << " of " << ssLabels.size() << endl;
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 //    Out::os() << "getting LIDs "<< endl;  
00273     mesh().getLIDsForLabel(dim-1, ssLabels[ss], sideLIDs);
00274     sort(&(sideLIDs[0]), &(sideLIDs[sideLIDs.size()-1]));
00275 //    Out::os() << "LIDs= "<< sideLIDs << endl;  
00276 //    Out::os() << "getting cofacets "<< endl;  
00277     mesh().getMaxCofacetLIDs(sideLIDs, maxCofacetBatch);
00278     //Out::os() << "getting specified cofacets "<< endl;  
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 //  Out::os() << "done all side sets" << endl;
00298   
00299   TEUCHOS_TEST_FOR_EXCEPT(ierr < 0);
00300 
00301 
00302 //  Out::os() << "writing node sets "<< endl;  
00303   if (nsID.size() > 0)
00304   {
00305     /* write the node sets */
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 //  Out::os() << "done all node sets" << endl;
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"; //-Wall
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 //  Out::os() << "in ExodusWriter::findNodeSets()" << endl;
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 //  Out::os() << "in ExodusWriter::findBlocks()" << endl;
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 

Site Contact