SundanceRivaraDriver.cpp
Go to the documentation of this file.
00001 #include "SundanceRivaraDriver.hpp"
00002 #include "SundanceMesh.hpp"
00003 #include "SundanceRivaraMesh.hpp"
00004 #include "SundanceExprFieldWrapper.hpp"
00005 
00006 using namespace Sundance;
00007 using namespace Sundance;
00008 using namespace Teuchos;
00009 using namespace Sundance::Rivara;
00010 using Sundance::ExprFieldWrapper;
00011 
00012 
00013 static Time& refTimer() 
00014 {
00015   static RCP<Time> rtn 
00016     = TimeMonitor::getNewTimer("mesh refinement"); 
00017   return *rtn;
00018 }
00019 
00020 static Time& m2rTimer() 
00021 {
00022   static RCP<Time> rtn 
00023     = TimeMonitor::getNewTimer("mesh to rivara copy"); 
00024   return *rtn;
00025 }
00026 
00027 static Time& r2mTimer() 
00028 {
00029   static RCP<Time> rtn 
00030     = TimeMonitor::getNewTimer("rivara to mesh copy"); 
00031   return *rtn;
00032 }
00033 
00034 static Time& volSetTimer() 
00035 {
00036   static RCP<Time> rtn 
00037     = TimeMonitor::getNewTimer("refinement stack building"); 
00038   return *rtn;
00039 }
00040 
00041 
00042 Mesh RefinementTransformation::apply(const Mesh& inputMesh) const 
00043 {
00044   TimeMonitor timer(refTimer());
00045 
00046   int dim = inputMesh.spatialDim();
00047   MPIComm comm = inputMesh.comm();
00048   int numElems = inputMesh.numCells(dim);
00049 
00050   RCP<RivaraMesh> rivMesh = rcp(new RivaraMesh(dim, comm));
00051 
00052   Array<int> lidMap;
00053 
00054   meshToRivara(inputMesh, lidMap,rivMesh);
00055   
00056   ExprFieldWrapper expr(errExpr_);
00057   TEST_FOR_EXCEPTION(expr.isPointData(), RuntimeError,
00058     "Expected cell-based discrete function for area specification");
00059 
00060   {
00061     TimeMonitor timer(volSetTimer());
00062     numRefined_ = 0;
00063     for (int c=0; c<numElems; c++)
00064     {
00065       double err = expr.getData(dim,c,0);
00066       int rivLID = lidMap[c];
00067       Element* e = rivMesh->element(rivLID).get();
00068       double vol = e->volume();
00069       double newVol = vol * std::pow(reqErr_/(err+1.0e-12), 0.5*dim);
00070 ///      Out::os() << "c=" << c << " refine by " << newVol/vol << std::endl;
00071       if (newVol >= vol) continue;
00072       rivMesh->refinementSet().push(e);
00073       rivMesh->refinementAreas().push(newVol);
00074       numRefined_ ++;
00075     }
00076   }
00077   Out::os() << "refining n=" << numRefined_ << " cells" << std::endl;
00078   rivMesh->refine();
00079 
00080 
00081   Mesh outputMesh = rivaraToMesh(rivMesh, comm);
00082 
00083   return outputMesh;
00084 }
00085 
00086 
00087 void RefinementTransformation::meshToRivara(
00088   const Mesh& mesh, 
00089   Array<int>& lidMap,
00090   RCP<RivaraMesh>& rivMesh) const 
00091 {
00092   TimeMonitor timer(m2rTimer());
00093   int dim = mesh.spatialDim();
00094   int numNodes = mesh.numCells(0);
00095   int numElems = mesh.numCells(dim);
00096 
00097   for (int n=0; n<numNodes; n++)
00098   {
00099     int gid = n;
00100     int label = mesh.label(0,n);
00101     int ownerProcID = mesh.ownerProcID(0,n);
00102     Point x = mesh.nodePosition(n);
00103     rivMesh->addVertex(gid, x, ownerProcID, label);
00104   }
00105 
00106   lidMap.resize(numElems);
00107   for (int e=0; e<numElems; e++)
00108   {
00109     int gid = e;
00110     int label = mesh.label(dim,e);
00111     int ownerProcID = mesh.ownerProcID(dim,e);
00112     Array<int> verts;
00113     Array<int> fo;
00114     mesh.getFacetArray(dim, e, 0, verts, fo);
00115     int elemLID = rivMesh->addElement(gid, verts, ownerProcID, label);
00116     lidMap[e] = elemLID;
00117     /* label edges or faces */
00118     if (dim==2)
00119     {
00120       Array<int> edgeLIDs;
00121       mesh.getFacetArray(dim, e, 1, edgeLIDs, fo);
00122       for (int f=0; f<3; f++)
00123       {
00124         int edgeLabel = mesh.label(1,edgeLIDs[f]);
00125         rivMesh->element(elemLID)->edge(f)->setLabel(edgeLabel);
00126       }
00127     }
00128     else if (dim==3)
00129     {
00130       Array<int> faceLIDs;
00131       mesh.getFacetArray(dim, e, 2, faceLIDs, fo);
00132       for (int f=0; f<4; f++)
00133       {
00134         int faceLabel = mesh.label(2,faceLIDs[f]);
00135         rivMesh->element(elemLID)->face(f)->setLabel(faceLabel);
00136       }
00137     }
00138   }
00139 }
00140 
00141 
00142 Mesh RefinementTransformation::rivaraToMesh(const RCP<RivaraMesh>& rivMesh,
00143   const MPIComm& comm) const 
00144 {
00145   TimeMonitor timer(r2mTimer());
00146   int dim = rivMesh->spatialDim();
00147   int numNodes = rivMesh->numNodes();
00148 
00149   Mesh mesh = meshType_.createEmptyMesh(dim, comm);
00150 
00151   for (int n=0; n<numNodes; n++)
00152   {
00153     const RCP<Node>& node = rivMesh->node(n);
00154     const Point& x = node->pt();
00155     int gid = node->globalIndex();
00156     int ownerProcID = node->ownerProc();
00157     int label = node->label();
00158     mesh.addVertex(gid, x, ownerProcID, label);
00159   }
00160 
00161 
00162   ElementIterator iter(rivMesh.get());
00163 
00164   int gid=0;
00165 
00166   Array<int> verts(dim+1);
00167   Array<int> fo;
00168   Array<int> edgeLIDs;
00169   Array<int> faceLIDs;
00170       
00171   while (iter.hasMoreElements())
00172   {
00173     const Element* e = iter.getNextElement();
00174     int ownerProcID = e->ownerProc();
00175     int label = e->label();
00176     const Array<RCP<Node> >& nodes = e->nodes();
00177 
00178     for (int i=0; i<nodes.size(); i++)
00179     {
00180       verts[i] = nodes[i]->globalIndex();
00181     }
00182     int lid = mesh.addElement(gid, verts, ownerProcID, label);
00183     gid++;
00184     /* label edges or faces */
00185     if (dim==2)
00186     {
00187       if (e->hasNoEdgeLabels()) continue;
00188       mesh.getFacetArray(dim, lid, 1, edgeLIDs, fo);
00189       for (int f=0; f<3; f++)
00190       {
00191         int edgeLabel = e->edge(f)->label();
00192         mesh.setLabel(1, edgeLIDs[f], edgeLabel);
00193       }
00194     }
00195     else if (dim==3)
00196     {
00197       if (e->hasNoFaceLabels()) continue;
00198       mesh.getFacetArray(dim, lid, 2, faceLIDs, fo);
00199       for (int f=0; f<4; f++)
00200       {
00201         int faceLabel = e->face(f)->label();
00202         mesh.setLabel(2, faceLIDs[f], faceLabel);
00203       }
00204     }
00205   }
00206 
00207   return mesh;
00208   
00209 }
00210 
00211   

Site Contact