SundanceRivaraDriver.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 
00043 #include "SundanceRivaraDriver.hpp"
00044 #include "SundanceMesh.hpp"
00045 #include "SundanceRivaraMesh.hpp"
00046 #include "SundanceExprFieldWrapper.hpp"
00047 
00048 using namespace Sundance;
00049 using namespace Sundance;
00050 using namespace Teuchos;
00051 using namespace Sundance::Rivara;
00052 using Sundance::ExprFieldWrapper;
00053 using std::endl;
00054 
00055 void sort(const Array<int>& in, Array<int>& rtn)
00056 {
00057   rtn.resize(in.size());
00058   const int* pIn = &(in[0]);
00059   int* pRtn = &(rtn[0]);
00060   for (int i=0; i<in.size(); i++) pRtn[i] = pIn[i];
00061   
00062   for (int j=1; j<in.size(); j++)
00063   {
00064     int key = pRtn[j];
00065     int i=j-1;
00066     while (i>=0 && pRtn[i]>key)
00067     {
00068       pRtn[i+1]=pRtn[i];
00069       i--;
00070     }
00071     pRtn[i+1]=key;
00072   }
00073   //std::sort(rtn.begin(), rtn.end());
00074 }
00075 
00076 static Time& refTimer() 
00077 {
00078   static RCP<Time> rtn 
00079     = TimeMonitor::getNewTimer("mesh refinement"); 
00080   return *rtn;
00081 }
00082 
00083 static Time& m2rTimer() 
00084 {
00085   static RCP<Time> rtn 
00086     = TimeMonitor::getNewTimer("mesh to rivara copy"); 
00087   return *rtn;
00088 }
00089 
00090 static Time& r2mTimer() 
00091 {
00092   static RCP<Time> rtn 
00093     = TimeMonitor::getNewTimer("rivara to mesh copy"); 
00094   return *rtn;
00095 }
00096 
00097 static Time& volSetTimer() 
00098 {
00099   static RCP<Time> rtn 
00100     = TimeMonitor::getNewTimer("refinement stack building"); 
00101   return *rtn;
00102 }
00103 
00104 
00105 Mesh RefinementTransformation::apply(const Mesh& inputMesh) const 
00106 {
00107   TimeMonitor timer(refTimer());
00108 
00109   int dim = inputMesh.spatialDim();
00110   MPIComm comm = inputMesh.comm();
00111   int numElems = inputMesh.numCells(dim);
00112 
00113   RCP<RivaraMesh> rivMesh = rcp(new RivaraMesh(dim, comm));
00114 
00115   Array<int> lidMap;
00116 
00117   meshToRivara(inputMesh, lidMap,rivMesh);
00118   
00119   ExprFieldWrapper expr(errExpr_);
00120   TEUCHOS_TEST_FOR_EXCEPTION(expr.isPointData(), std::runtime_error,
00121     "Expected cell-based discrete function for area specification");
00122 
00123   {
00124     TimeMonitor timer(volSetTimer());
00125     numRefined_ = 0;
00126     for (int c=0; c<numElems; c++)
00127     {
00128       double err = expr.getData(dim,c,0);
00129       int rivLID = lidMap[c];
00130       Element* e = rivMesh->element(rivLID).get();
00131       double vol = e->volume();
00132       double newVol = vol * std::pow(reqErr_/(err+1.0e-12), 0.5*dim);
00133 ///      Out::os() << "c=" << c << " refine by " << newVol/vol << std::endl;
00134       if (newVol >= vol) continue;
00135       rivMesh->refinementSet().push(e);
00136       rivMesh->refinementAreas().push(newVol);
00137       numRefined_ ++;
00138     }
00139   }
00140   Out::os() << "refining n=" << numRefined_ << " cells" << std::endl;
00141   rivMesh->refine();
00142 
00143 
00144   Mesh outputMesh = rivaraToMesh(rivMesh, comm);
00145 
00146   return outputMesh;
00147 }
00148 
00149 
00150 void RefinementTransformation::meshToRivara(
00151   const Mesh& mesh, 
00152   Array<int>& lidMap,
00153   RCP<RivaraMesh>& rivMesh) const 
00154 {
00155   TimeMonitor timer(m2rTimer());
00156   int dim = mesh.spatialDim();
00157   int numNodes = mesh.numCells(0);
00158   int numElems = mesh.numCells(dim);
00159 
00160   for (int n=0; n<numNodes; n++)
00161   {
00162     int gid = n;
00163     int label = mesh.label(0,n);
00164     int ownerProcID = mesh.ownerProcID(0,n);
00165     Point x = mesh.nodePosition(n);
00166     rivMesh->addVertex(gid, x, ownerProcID, label);
00167   }
00168 
00169   lidMap.resize(numElems);
00170   for (int e=0; e<numElems; e++)
00171   {
00172     int gid = e;
00173     int label = mesh.label(dim,e);
00174     int ownerProcID = mesh.ownerProcID(dim,e);
00175     Array<int> verts;
00176     Array<int> fo;
00177     mesh.getFacetArray(dim, e, 0, verts, fo);
00178     int elemLID = rivMesh->addElement(gid, verts, ownerProcID, label);
00179     lidMap[e] = elemLID;
00180     /* label edges or faces */
00181     if (dim==2)
00182     {
00183       Array<int> edgeLIDs;
00184       mesh.getFacetArray(dim, e, 1, edgeLIDs, fo);
00185       for (int f=0; f<3; f++)
00186       {
00187         int edgeLabel = mesh.label(1,edgeLIDs[f]);
00188         rivMesh->element(elemLID)->edge(f)->setLabel(edgeLabel);
00189       }
00190     }
00191     else if (dim==3)
00192     {
00193       Array<int> faceLIDs;
00194       mesh.getFacetArray(dim, e, 2, faceLIDs, fo);
00195       for (int f=0; f<4; f++)
00196       {
00197         int faceLabel = mesh.label(2,faceLIDs[f]);
00198         rivMesh->element(elemLID)->face(f)->setLabel(faceLabel);
00199       }
00200     }
00201   }
00202 }
00203 
00204 
00205 Mesh RefinementTransformation::rivaraToMesh(const RCP<RivaraMesh>& rivMesh,
00206   const MPIComm& comm) const 
00207 {
00208   TimeMonitor timer(r2mTimer());
00209   int dim = rivMesh->spatialDim();
00210   int numNodes = rivMesh->numNodes();
00211 
00212   Mesh mesh = meshType_.createEmptyMesh(dim, comm);
00213 
00214   for (int n=0; n<numNodes; n++)
00215   {
00216     const RCP<Node>& node = rivMesh->node(n);
00217     const Point& x = node->pt();
00218     int gid = node->globalIndex();
00219     int ownerProcID = node->ownerProc();
00220     int label = node->label();
00221     mesh.addVertex(gid, x, ownerProcID, label);
00222   }
00223 
00224 
00225   ElementIterator iter(rivMesh.get());
00226 
00227   int gid=0;
00228 
00229   Array<int> verts(dim+1);
00230   Array<int> fo;
00231   Array<int> edgeLIDs;
00232   Array<int> faceLIDs;
00233       
00234   while (iter.hasMoreElements())
00235   {
00236     Tabs tab;
00237     const Element* e = iter.getNextElement();
00238     int ownerProcID = e->ownerProc();
00239     int label = e->label();
00240     const Array<RCP<Node> >& nodes = e->nodes();
00241 
00242     for (int i=0; i<nodes.size(); i++)
00243     {
00244       verts[i] = nodes[i]->globalIndex();
00245     }
00246     int lid = mesh.addElement(gid, verts, ownerProcID, label);
00247     gid++;
00248 
00249     Array<int> sortedVerts(verts.size());
00250     sort(verts, sortedVerts);
00251 
00252     Out::os() << tab << "elem LID=" << lid << " verts=" << sortedVerts << endl; 
00253     /* label edges or faces */
00254     if (dim==2)
00255     {
00256       if (e->hasNoEdgeLabels()) continue;
00257       mesh.getFacetArray(dim, lid, 1, edgeLIDs, fo);
00258       for (int f=0; f<3; f++)
00259       {
00260         int edgeLabel = e->edge(f)->label();
00261         if (edgeLabel < 0) continue;
00262         mesh.setLabel(1, edgeLIDs[f], edgeLabel);
00263       }
00264     }
00265     else if (dim==3)
00266     {
00267       Tabs tab1;
00268       if (e->hasNoFaceLabels()) continue;
00269       mesh.getFacetArray(dim, lid, 2, faceLIDs, fo);
00270       for (int f=0; f<4; f++)
00271       {
00272         /* the faces have been renumbered by the mesh */
00273         int faceLabel = e->face(f)->label();
00274         if (faceLabel <= 0) continue;
00275         const FaceNodes& nodes = e->face(f)->nodes();
00276         Array<int> nodeLIDs = nodes.nodes().elements();
00277         Out::os() << tab1 << "face nodes = " << nodeLIDs << endl;
00278         int faceNum = -1;
00279         if (nodeLIDs[0]==sortedVerts[0] && nodeLIDs[1]==sortedVerts[1]
00280           && nodeLIDs[2]==sortedVerts[2])
00281         {
00282           faceNum = 3;
00283         }
00284         else if (nodeLIDs[0]==sortedVerts[0] && nodeLIDs[1]==sortedVerts[1]
00285           && nodeLIDs[2]==sortedVerts[3])
00286         {
00287           faceNum = 2;
00288         }
00289         else if (nodeLIDs[0]==sortedVerts[0] && nodeLIDs[1]==sortedVerts[2]
00290           && nodeLIDs[2]==sortedVerts[3])
00291         {
00292           faceNum = 1;
00293         }
00294         else if (nodeLIDs[0]==sortedVerts[1] && nodeLIDs[1]==sortedVerts[2]
00295           && nodeLIDs[2]==sortedVerts[3])
00296         {
00297           faceNum = 0;
00298         }
00299         else
00300         {
00301           TEUCHOS_TEST_FOR_EXCEPT(true);
00302         }
00303         Out::os() << tab1 << "faceLID=" << faceLIDs[faceNum] << " UFC face num=" 
00304                   << faceNum 
00305                   << " label = " << faceLabel 
00306                   << " parent = " << lid << std::endl;
00307         mesh.setLabel(2, faceLIDs[faceNum], faceLabel);
00308       }
00309     }
00310   }
00311 
00312   return mesh;
00313   
00314 }
00315 
00316   

Site Contact