00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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
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
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
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;
00182
00183
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
00193 oldToNewElemMap_.value(c, p) = newElemLID;
00194 newToOldElemMap_[newElemLID] = c;
00195
00196
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])
00206 {
00207
00208
00209
00210 TEUCHOS_TEST_FOR_EXCEPT(interiorEdgeCount >= 3);
00211 interiorEdges_.value(c, interiorEdgeCount++) = newEdge;
00212
00213
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
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
00391
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 }