SundanceUniformRefinementPair.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 "SundanceUniformRefinementPair.hpp"
00044 #include "SundanceGeomUtils.hpp"
00045 using std::cout;
00046 using std::endl;
00047 using std::setw;
00048 
00049 namespace Sundance
00050 {
00051 using namespace Teuchos;
00052 
00053 
00054 UniformRefinementPair::UniformRefinementPair() {}
00055 
00056 UniformRefinementPair::UniformRefinementPair(const MeshType& meshType,
00057   const Mesh& coarse)
00058   : meshType_(meshType),
00059     coarse_(coarse),
00060     fine_()
00061 {
00062   if (coarse.spatialDim() == 2)
00063   {
00064     refineTriMesh();
00065   }
00066   TEUCHOS_TEST_FOR_EXCEPT(coarse.spatialDim() != 2);
00067 }
00068 
00069 void UniformRefinementPair::refineTriMesh()
00070 {
00071   const MPIComm& comm = coarse_.comm();
00072   fine_ = meshType_.createEmptyMesh(2, comm);
00073 
00074   TEUCHOS_TEST_FOR_EXCEPT(fine_.spatialDim() != 2);
00075   TEUCHOS_TEST_FOR_EXCEPT(comm.getNProc() > 1);
00076 
00077   int numVerts = coarse_.numCells(0);
00078   int numEdges = coarse_.numCells(1);
00079   int numElems = coarse_.numCells(2);
00080 
00081   int numNewVerts = numVerts + numEdges;
00082   int numNewEdges = 2*numEdges + 3*numElems;
00083   int numNewElems = 4*numElems;
00084 
00085   Array<int> vertDone(numVerts, 0);
00086   Array<int> oldEdgeDone(numEdges, 0);
00087   Array<int> newEdgeDone(numNewEdges, 0);
00088 
00089   oldToNewVertMap_ = Array<int>(numVerts, -1);
00090   newVertToOldLIDMap_ = Array<int>(numVerts+numEdges, -1);
00091   newVertIsOnEdge_ = Array<int>(numNewVerts, 0);
00092   oldEdgeToNewVertMap_ = Array<int>(numEdges, -1);
00093     
00094   ArrayOfTuples<int> elemVerts(numElems, 6);
00095   oldToNewElemMap_ = ArrayOfTuples<int>(numElems, 4);
00096   newToOldElemMap_ = Array<int>(numNewElems, -1);
00097   oldEdgeChildren_ = Array<Array<int> >(numEdges);
00098   oldEdgeParallels_ = Array<Array<int> >(numEdges);
00099   newEdgeParents_ = Array<int>(numNewEdges, -1);
00100   newEdgeParallels_ = Array<int>(numNewEdges, -1);
00101   
00102   interiorEdges_ = ArrayOfTuples<int>(numElems, 3);
00103 
00104   int newVertLID = 0;
00105 
00106   for (int c=0; c<numElems; c++)
00107   {
00108     /* add the old vertices to the new mesh */
00109     const int* verts = coarse_.elemZeroFacetView(c);
00110     for (int i=0; i<3; i++)
00111     {
00112       int v = verts[i];
00113       if (!vertDone[v])
00114       {
00115         int vertOwner = coarse_.ownerProcID(0, v);
00116         int vertLabel = coarse_.label(0, v);
00117         fine_.addVertex(newVertLID, coarse_.nodePosition(v), vertOwner, vertLabel);
00118 
00119         oldToNewVertMap_[v] = newVertLID;
00120         newVertToOldLIDMap_[newVertLID] = v;
00121         elemVerts.value(c, i) = newVertLID;
00122         newVertLID++;
00123         vertDone[v]=true;
00124       }
00125       else
00126       {
00127         elemVerts.value(c, i) = oldToNewVertMap_[v];
00128       }
00129     }
00130   
00131     /* put new vertices at the centroids of the old edges */
00132     for (int i=0; i<3; i++)
00133     {
00134       int ori;
00135       int e = coarse_.facetLID(2, c, 1, i, ori);
00136       if (!oldEdgeDone[e])
00137       {
00138         int edgeOwner = coarse_.ownerProcID(1, e);
00139         Point centroid = coarse_.centroid(1, e);
00140         fine_.addVertex(newVertLID, centroid, edgeOwner, 0);
00141         elemVerts.value(c, 3+i) = newVertLID;
00142         oldEdgeToNewVertMap_[e] = newVertLID;
00143         newVertIsOnEdge_[newVertLID] = true;
00144         newVertToOldLIDMap_[newVertLID] = e;
00145         oldEdgeDone[e] = true;
00146         newVertLID++;
00147       }
00148       else
00149       {
00150         elemVerts.value(c, 3+i) = oldEdgeToNewVertMap_[e];
00151       }
00152     }
00153   }
00154 
00155   Array<Array<int> > pairs
00156     = tuple<Array<int> >(
00157       tuple(0,1),
00158       tuple(1,2),
00159       tuple(2,0)
00160       );
00161 
00162   Array<Array<int> > vertPtrs 
00163     = tuple<Array<int> >(
00164       tuple(0,4,5),
00165       tuple(1,3,5),
00166       tuple(3,4,5),
00167       tuple(2,3,4)
00168       );
00169   
00170   int newElemLID=0;      
00171   for (int c=0; c<numElems; c++)
00172   {
00173     /* find the coarse edges */
00174     Array<int> edgeLIDs(3);
00175     for (int s=0; s<3; s++)
00176     {
00177       int ori = 0;
00178       edgeLIDs[s] = coarse_.facetLID(2, c, 1, s, ori);
00179     }
00180 
00181     int interiorEdgeCount = 0; // initialize to zero
00182 
00183     /* make the new elements */
00184     int elemOwner = coarse_.ownerProcID(2, c);
00185     int elemLabel = coarse_.label(2, c);
00186     for (int p=0; p<vertPtrs.size(); p++)
00187     {
00188       Array<int> verts = tuple(elemVerts.value(c, vertPtrs[p][0]),
00189         elemVerts.value(c, vertPtrs[p][1]),
00190         elemVerts.value(c, vertPtrs[p][2]));
00191       fine_.addElement(newElemLID, verts, elemOwner, elemLabel);
00192       /* put the new elements in the map */
00193       oldToNewElemMap_.value(c, p) = newElemLID;
00194       newToOldElemMap_[newElemLID] = c;
00195 
00196       /* Find the relations between old and new edges */
00197       for (int side=0; side<3; side++)
00198       {
00199         int v1 = verts[pairs[side][0]];
00200         int v2 = verts[pairs[side][1]];
00201         int newEdge = lookupEdge(fine_, v1, v2);
00202         if (newEdgeDone[newEdge]) continue;
00203         
00204         
00205         if (newVertIsOnEdge_[v1] && newVertIsOnEdge_[v2]) // edge is interior
00206         {
00207           /* Add to the list of interior edges for this element. This
00208            * will only happen once per edge thanks to the newEdgeDone check
00209            * above. */
00210           TEUCHOS_TEST_FOR_EXCEPT(interiorEdgeCount >= 3);
00211           interiorEdges_.value(c, interiorEdgeCount++) = newEdge;
00212           
00213           /* find the coarse edge parallel to the new interior edge */
00214           int parEdge = -1;
00215           for (int i=0; i<3; i++)
00216           {
00217             int ev = oldEdgeToNewVertMap_[edgeLIDs[i]];
00218             if (ev==v1 || ev==v2) continue;
00219             parEdge = edgeLIDs[i];
00220             break;
00221           }
00222           TEUCHOS_TEST_FOR_EXCEPT(parEdge==-1);
00223           oldEdgeParallels_[parEdge].append(newEdge);
00224           newEdgeParallels_[newEdge] = parEdge;
00225         }
00226         else // edge is a child
00227         {
00228           for (int n=0; n<2; n++)
00229           {
00230             int v = verts[pairs[side][n]];
00231             if (newVertIsOnEdge_[v]) 
00232             {
00233               int oldEdge = newVertToOldLIDMap_[v];
00234               oldEdgeChildren_[oldEdge].append(newEdge);
00235               newEdgeParents_[newEdge] = oldEdge;
00236             }
00237           }
00238         }
00239         newEdgeDone[newEdge] = true;
00240       }
00241       newElemLID++;
00242     }
00243   }
00244 
00245   TEUCHOS_TEST_FOR_EXCEPT(newElemLID != 4*numElems);
00246 
00247 
00248 }
00249 
00250 int UniformRefinementPair::lookupEdge(const Mesh& mesh,
00251   int v1, int v2) const
00252 {
00253   return lookupEdgeLIDFromVerts(mesh, v1, v2);
00254 }
00255 
00256 
00257 int UniformRefinementPair::check() const 
00258 {
00259   int bad = 0;
00260   double tol = 1.0e-12;
00261   cout << "old vertex to new vertex map" << endl;
00262   cout << "----------------------------------------" << endl;
00263   for (int v=0; v<coarse_.numCells(0); v++)
00264   {
00265     int vNew = oldToNewVertMap()[v];
00266     double d = coarse_.centroid(0, v).distance(fine_.centroid(0, vNew));
00267     string state = "GOOD";
00268     if (d > tol) {state="BAD"; bad++;}
00269     if (fine_.label(0,vNew) != coarse_.label(0,v)) {state="BAD"; bad++;}
00270     cout << setw(4) << v 
00271          << setw(16) << coarse_.centroid(0, v) 
00272          << setw(4) << coarse_.label(0,v)
00273          << setw(4) << vNew 
00274          << setw(16) << fine_.centroid(0, vNew) 
00275          << setw(4) << fine_.label(0,vNew)
00276          << setw(6) << state << endl;
00277   }
00278 
00279   cout << endl << endl;
00280 
00281   cout << "old edge to new vertex map" << endl;
00282   cout << "----------------------------------------" << endl;
00283   for (int e=0; e<coarse_.numCells(1); e++)
00284   {
00285     int vNew = oldEdgeToNewVertMap()[e];
00286     double d = coarse_.centroid(1, e).distance(fine_.centroid(0, vNew));
00287     string state = "GOOD";
00288     if (d > tol) {state="BAD"; bad++;}
00289     cout << setw(4) << e << setw(16) 
00290          << coarse_.centroid(1, e) << "\t" << setw(10)
00291          << vNew << setw(16)
00292          << fine_.centroid(0, vNew) << setw(6) << state  << endl;
00293   }
00294 
00295   cout << endl << endl;
00296   cout << "old vertex to new vertex map inversion" << endl;
00297   cout << "----------------------------------------" << endl;
00298   for (int v=0; v<coarse_.numCells(0); v++)
00299   {
00300     int vNew = oldToNewVertMap()[v];
00301     int vOld = newVertToOldLIDMap()[vNew];
00302       
00303     string state = "GOOD";
00304     if (vOld != v) {state="BAD"; bad++;}
00305     cout << setw(4) << v << setw(4) << vNew << setw(4) << vOld
00306          << setw(6) << state << endl;
00307   }
00308 
00309   cout << endl << endl;
00310   cout << "old edge to new vertex map inversion" << endl;
00311   cout << "----------------------------------------" << endl;
00312   for (int e=0; e<coarse_.numCells(1); e++)
00313   {
00314     int vNew = oldEdgeToNewVertMap()[e];
00315     int eOld = newVertToOldLIDMap()[vNew];
00316       
00317     string state = "GOOD";
00318     if (eOld != e) {state="BAD"; bad++;}
00319     cout << setw(4) << e << setw(4) << vNew << setw(4) << eOld
00320          << setw(6) << state << endl;
00321   }
00322 
00323 
00324 
00325 
00326   cout << endl << endl;
00327   cout << "old to new elem map" << endl;
00328   cout << "----------------------------------------" << endl;
00329   for (int c=0; c<coarse_.numCells(2); c++)
00330   {
00331     cout << setw(6) << c;
00332     for (int e=0; e<4; e++) 
00333     {
00334       int eNew = oldToNewElemMap().value(c, e);
00335       int eOld = newToOldElemMap()[eNew];
00336       cout << setw(4) << eNew ;
00337       string state = "OK";
00338       if (eOld != c) {state="BAD"; bad++;}
00339       cout << setw(4) << state;
00340     }
00341     cout << endl;
00342       
00343   }
00344 
00345   cout << endl << endl;
00346   cout << "old edge children and parallels" << endl;
00347   cout << "----------------------------------------" << endl;
00348   for (int e=0; e<coarse_.numCells(1); e++)
00349   {
00350     string state = "GOOD";
00351     const Array<int>& children = oldEdgeChildren()[e];
00352     const Array<int>& parallels = oldEdgeParallels()[e];
00353     Array<int> parents(children.size());
00354     Array<int> coarsePar(parallels.size());
00355     for (int i=0; i<children.size(); i++) 
00356     {
00357       parents[i] = newEdgeParents()[children[i]];
00358       if (parents[i] != e) {state="BAD"; bad++;}
00359     }
00360     for (int i=0; i<parallels.size(); i++) 
00361     {
00362       coarsePar[i] = newEdgeParallels()[parallels[i]];
00363       if (coarsePar[i] != e) {state="BAD"; bad++;}
00364     }
00365       
00366     cout << setw(4) << e << setw(12) << children 
00367          << setw(12) << parents 
00368          << setw(12) << parallels
00369          << setw(12) << coarsePar 
00370          << setw(6) << state << endl;
00371   }
00372 
00373   cout << endl << endl;
00374   cout << "interior edges" << endl;
00375   cout << "----------------------------------------" << endl;
00376   for (int c=0; c<coarse_.numCells(2); c++)
00377   {
00378     string state = "GOOD";
00379     Array<int> edges(3);
00380     for (int i=0; i<3; i++) 
00381     {
00382       edges[i] = interiorEdges_.value(c,i);
00383       int ori;
00384       int v1 = fine_.facetLID(1, edges[i], 0, 0, ori);
00385       if (!newVertIsOnEdge_[v1]) 
00386       {bad++; state="BAD";}
00387       int v2 = fine_.facetLID(1, edges[i], 0, 1, ori);
00388       if (!newVertIsOnEdge_[v2]) 
00389       {bad++; state="BAD";}
00390       /* check that the cofacets of this edge are both refinements of
00391        * the current coarse cell */
00392       Array<int> cofs;
00393       fine_.getCofacets(1, edges[i], 2, cofs);
00394       if (cofs.size() != 2) {bad++; state="BAD";}
00395       for (int cf=0; cf<cofs.size(); cf++)
00396       {
00397         if (newToOldElemMap_[cofs[cf]] != c)
00398         {bad++; state="BAD";}
00399       }
00400     }
00401       
00402     cout << setw(4) << c << setw(20) << edges
00403          << setw(6) << state << endl;
00404   }
00405 
00406   return bad;
00407 }
00408 
00409 }

Site Contact