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 #include "multiDirRefinement.H"
00027 #include <OpenFOAM/polyMesh.H>
00028 #include <dynamicMesh/polyTopoChanger.H>
00029 #include <OpenFOAM/Time.H>
00030 #include <dynamicMesh/undoableMeshCutter.H>
00031 #include <dynamicMesh/hexCellLooper.H>
00032 #include <dynamicMesh/geomCellLooper.H>
00033 #include <meshTools/topoSet.H>
00034 #include <dynamicMesh/directions.H>
00035 #include <dynamicMesh/hexRef8.H>
00036 #include <OpenFOAM/mapPolyMesh.H>
00037 #include <dynamicMesh/polyTopoChange.H>
00038 #include <OpenFOAM/ListOps.H>
00039 #include <OpenFOAM/cellModeller.H>
00040
00041
00042
00043 namespace Foam
00044 {
00045 defineTypeNameAndDebug(multiDirRefinement, 0);
00046 }
00047
00048
00049
00050
00051
00052
00053 void Foam::multiDirRefinement::addCells
00054 (
00055 const Map<label>& splitMap,
00056 List<refineCell>& refCells
00057 )
00058 {
00059 label newRefI = refCells.size();
00060
00061 label oldSize = refCells.size();
00062
00063 refCells.setSize(newRefI + splitMap.size());
00064
00065 for (label refI = 0; refI < oldSize; refI++)
00066 {
00067 const refineCell& refCell = refCells[refI];
00068
00069 Map<label>::const_iterator iter = splitMap.find(refCell.cellNo());
00070
00071 if (iter == splitMap.end())
00072 {
00073 FatalErrorIn
00074 (
00075 "multiDirRefinement::addCells(const Map<label>&"
00076 ", List<refineCell>&)"
00077 ) << "Problem : cannot find added cell for cell "
00078 << refCell.cellNo() << abort(FatalError);
00079 }
00080
00081 refCells[newRefI++] = refineCell(iter(), refCell.direction());
00082 }
00083 }
00084
00085
00086
00087
00088 void Foam::multiDirRefinement::update
00089 (
00090 const Map<label>& splitMap,
00091 vectorField& field
00092 )
00093 {
00094 field.setSize(field.size() + splitMap.size());
00095
00096 for
00097 (
00098 Map<label>::const_iterator iter = splitMap.begin();
00099 iter != splitMap.end();
00100 ++iter
00101 )
00102 {
00103 field[iter()] = field[iter.key()];
00104 }
00105 }
00106
00107
00108
00109 void Foam::multiDirRefinement::addCells
00110 (
00111 const Map<label>& splitMap,
00112 labelList& labels
00113 )
00114 {
00115 label newCellI = labels.size();
00116
00117 labels.setSize(labels.size() + splitMap.size());
00118
00119 for
00120 (
00121 Map<label>::const_iterator iter = splitMap.begin();
00122 iter != splitMap.end();
00123 ++iter
00124 )
00125 {
00126 labels[newCellI++] = iter();
00127 }
00128 }
00129
00130
00131
00132
00133 void Foam::multiDirRefinement::addCells
00134 (
00135 const primitiveMesh& mesh,
00136 const Map<label>& splitMap
00137 )
00138 {
00139
00140 labelList origCell(mesh.nCells(), -1);
00141
00142 forAll(addedCells_, cellI)
00143 {
00144 const labelList& added = addedCells_[cellI];
00145
00146 forAll(added, i)
00147 {
00148 label slave = added[i];
00149
00150 if (origCell[slave] == -1)
00151 {
00152 origCell[slave] = cellI;
00153 }
00154 else if (origCell[slave] != cellI)
00155 {
00156 FatalErrorIn
00157 (
00158 "multiDirRefinement::addCells(const primitiveMesh&"
00159 ", const Map<label>&"
00160 ) << "Added cell " << slave << " has two different masters:"
00161 << origCell[slave] << " , " << cellI
00162 << abort(FatalError);
00163 }
00164 }
00165 }
00166
00167
00168 for
00169 (
00170 Map<label>::const_iterator iter = splitMap.begin();
00171 iter != splitMap.end();
00172 ++iter
00173 )
00174 {
00175 label masterI = iter.key();
00176 label newCellI = iter();
00177
00178 while (origCell[masterI] != -1 && origCell[masterI] != masterI)
00179 {
00180 masterI = origCell[masterI];
00181 }
00182
00183 if (masterI >= addedCells_.size())
00184 {
00185 FatalErrorIn
00186 (
00187 "multiDirRefinement::addCells(const primitiveMesh&"
00188 ", const Map<label>&"
00189 ) << "Map of added cells contains master cell " << masterI
00190 << " which is not a valid cell number" << endl
00191 << "This means that the mesh is not consistent with the"
00192 << " done refinement" << endl
00193 << "newCell:" << newCellI << abort(FatalError);
00194 }
00195
00196 labelList& added = addedCells_[masterI];
00197
00198 if (added.empty())
00199 {
00200 added.setSize(2);
00201 added[0] = masterI;
00202 added[1] = newCellI;
00203 }
00204 else if (findIndex(added, newCellI) == -1)
00205 {
00206 label sz = added.size();
00207 added.setSize(sz + 1);
00208 added[sz] = newCellI;
00209 }
00210 }
00211 }
00212
00213
00214 Foam::labelList Foam::multiDirRefinement::splitOffHex(const primitiveMesh& mesh)
00215 {
00216 const cellModel& hex = *(cellModeller::lookup("hex"));
00217
00218 const cellShapeList& cellShapes = mesh.cellShapes();
00219
00220
00221
00222 labelList nonHexLabels(cellLabels_.size());
00223 label nonHexI = 0;
00224
00225 labelList hexLabels(cellLabels_.size());
00226 label hexI = 0;
00227
00228 forAll(cellLabels_, i)
00229 {
00230 label cellI = cellLabels_[i];
00231
00232 if (cellShapes[cellI].model() == hex)
00233 {
00234 hexLabels[hexI++] = cellI;
00235 }
00236 else
00237 {
00238 nonHexLabels[nonHexI++] = cellI;
00239 }
00240 }
00241
00242 nonHexLabels.setSize(nonHexI);
00243
00244 cellLabels_.transfer(nonHexLabels);
00245
00246 hexLabels.setSize(hexI);
00247
00248 return hexLabels;
00249 }
00250
00251
00252 void Foam::multiDirRefinement::refineHex8
00253 (
00254 polyMesh& mesh,
00255 const labelList& hexCells,
00256 const bool writeMesh
00257 )
00258 {
00259 if (debug)
00260 {
00261 Pout<< "multiDirRefinement : Refining hexes " << hexCells.size()
00262 << endl;
00263 }
00264
00265 hexRef8 hexRefiner
00266 (
00267 mesh,
00268 labelList(mesh.nCells(), 0),
00269 labelList(mesh.nPoints(), 0),
00270 refinementHistory
00271 (
00272 IOobject
00273 (
00274 "refinementHistory",
00275 mesh.facesInstance(),
00276 polyMesh::meshSubDir,
00277 mesh,
00278 IOobject::NO_READ,
00279 IOobject::NO_WRITE,
00280 false
00281 ),
00282 List<refinementHistory::splitCell8>(0),
00283 labelList(0)
00284 )
00285 );
00286
00287 polyTopoChange meshMod(mesh);
00288
00289 labelList consistentCells
00290 (
00291 hexRefiner.consistentRefinement
00292 (
00293 hexCells,
00294 true
00295 )
00296 );
00297
00298
00299 {
00300
00301 Map<label> hexCellSet(2*hexCells.size());
00302 forAll(hexCells, i)
00303 {
00304 hexCellSet.insert(hexCells[i], 1);
00305 }
00306
00307
00308 forAll(consistentCells, i)
00309 {
00310 label cellI = consistentCells[i];
00311
00312 Map<label>::iterator iter = hexCellSet.find(cellI);
00313
00314 if (iter == hexCellSet.end())
00315 {
00316 FatalErrorIn
00317 (
00318 "multiDirRefinement::refineHex8"
00319 "(polyMesh&, const labelList&, const bool)"
00320 ) << "Resulting mesh would not satisfy 2:1 ratio"
00321 << " when refining cell " << cellI << abort(FatalError);
00322 }
00323 else
00324 {
00325 iter() = 2;
00326 }
00327 }
00328
00329
00330
00331 forAllConstIter(Map<label>, hexCellSet, iter)
00332 {
00333 if (iter() != 2)
00334 {
00335 FatalErrorIn
00336 (
00337 "multiDirRefinement::refineHex8"
00338 "(polyMesh&, const labelList&, const bool)"
00339 ) << "Resulting mesh would not satisfy 2:1 ratio"
00340 << " when refining cell " << iter.key()
00341 << abort(FatalError);
00342 }
00343 }
00344 }
00345
00346
00347 hexRefiner.setRefinement(consistentCells, meshMod);
00348
00349
00350 autoPtr<mapPolyMesh> morphMapPtr = meshMod.changeMesh(mesh, false, true);
00351 const mapPolyMesh& morphMap = morphMapPtr();
00352
00353 if (morphMap.hasMotionPoints())
00354 {
00355 mesh.movePoints(morphMap.preMotionPoints());
00356 }
00357
00358 if (writeMesh)
00359 {
00360 mesh.write();
00361 }
00362
00363 if (debug)
00364 {
00365 Pout<< "multiDirRefinement : updated mesh at time "
00366 << mesh.time().timeName() << endl;
00367 }
00368
00369 hexRefiner.updateMesh(morphMap);
00370
00371
00372
00373 forAll(consistentCells, i)
00374 {
00375 addedCells_[consistentCells[i]].setSize(8);
00376 }
00377 labelList nAddedCells(addedCells_.size(), 0);
00378
00379 const labelList& cellMap = morphMap.cellMap();
00380
00381 forAll(cellMap, cellI)
00382 {
00383 label oldCellI = cellMap[cellI];
00384
00385 if (addedCells_[oldCellI].size())
00386 {
00387 addedCells_[oldCellI][nAddedCells[oldCellI]++] = cellI;
00388 }
00389 }
00390 }
00391
00392
00393 void Foam::multiDirRefinement::refineAllDirs
00394 (
00395 polyMesh& mesh,
00396 List<vectorField>& cellDirections,
00397 const cellLooper& cellWalker,
00398 undoableMeshCutter& cutter,
00399 const bool writeMesh
00400 )
00401 {
00402
00403 refinementIterator refiner(mesh, cutter, cellWalker, writeMesh);
00404
00405 forAll(cellDirections, dirI)
00406 {
00407 if (debug)
00408 {
00409 Pout<< "multiDirRefinement : Refining " << cellLabels_.size()
00410 << " cells in direction " << dirI << endl
00411 << endl;
00412 }
00413
00414 const vectorField& dirField = cellDirections[dirI];
00415
00416
00417
00418
00419 List<refineCell> refCells(cellLabels_.size());
00420
00421 if (dirField.size() == 1)
00422 {
00423
00424 if (debug)
00425 {
00426 Pout<< "multiDirRefinement : Uniform refinement:"
00427 << dirField[0] << endl;
00428 }
00429
00430 forAll(refCells, refI)
00431 {
00432 label cellI = cellLabels_[refI];
00433
00434 refCells[refI] = refineCell(cellI, dirField[0]);
00435 }
00436 }
00437 else
00438 {
00439
00440 forAll(refCells, refI)
00441 {
00442 label cellI = cellLabels_[refI];
00443
00444 refCells[refI] = refineCell(cellI, dirField[cellI]);
00445 }
00446 }
00447
00448
00449 Map<label> splitMap = refiner.setRefinement(refCells);
00450
00451
00452 addCells(mesh, splitMap);
00453
00454
00455 addCells(splitMap, cellLabels_);
00456
00457
00458 if (dirField.size() != 1)
00459 {
00460 forAll(cellDirections, i)
00461 {
00462 update(splitMap, cellDirections[i]);
00463 }
00464 }
00465
00466 if (debug)
00467 {
00468 Pout<< "multiDirRefinement : Done refining direction " << dirI
00469 << " resulting in " << cellLabels_.size() << " cells" << nl
00470 << endl;
00471 }
00472 }
00473 }
00474
00475
00476 void Foam::multiDirRefinement::refineFromDict
00477 (
00478 polyMesh& mesh,
00479 List<vectorField>& cellDirections,
00480 const dictionary& dict,
00481 const bool writeMesh
00482 )
00483 {
00484
00485 Switch pureGeomCut(dict.lookup("geometricCut"));
00486
00487 autoPtr<cellLooper> cellWalker(NULL);
00488 if (pureGeomCut)
00489 {
00490 cellWalker.reset(new geomCellLooper(mesh));
00491 }
00492 else
00493 {
00494 cellWalker.reset(new hexCellLooper(mesh));
00495 }
00496
00497
00498
00499
00500
00501 undoableMeshCutter cutter(mesh, false);
00502
00503 refineAllDirs(mesh, cellDirections, cellWalker(), cutter, writeMesh);
00504 }
00505
00506
00507
00508
00509
00510
00511 Foam::multiDirRefinement::multiDirRefinement
00512 (
00513 polyMesh& mesh,
00514 const labelList& cellLabels,
00515 const dictionary& dict
00516 )
00517 :
00518 cellLabels_(cellLabels),
00519 addedCells_(mesh.nCells())
00520 {
00521 Switch useHex(dict.lookup("useHexTopology"));
00522
00523 Switch writeMesh(dict.lookup("writeMesh"));
00524
00525 wordList dirNames(dict.lookup("directions"));
00526
00527 if (useHex && dirNames.size() == 3)
00528 {
00529
00530 labelList hexCells(splitOffHex(mesh));
00531
00532 refineHex8(mesh, hexCells, writeMesh);
00533 }
00534
00535 label nRemainingCells = cellLabels_.size();
00536
00537 reduce(nRemainingCells, sumOp<label>());
00538
00539 if (nRemainingCells > 0)
00540 {
00541
00542
00543
00544
00545 directions cellDirections(mesh, dict);
00546
00547 refineFromDict(mesh, cellDirections, dict, writeMesh);
00548 }
00549 }
00550
00551
00552
00553 Foam::multiDirRefinement::multiDirRefinement
00554 (
00555 polyMesh& mesh,
00556 const labelList& cellLabels,
00557 const List<vectorField>& cellDirs,
00558 const dictionary& dict
00559 )
00560 :
00561 cellLabels_(cellLabels),
00562 addedCells_(mesh.nCells())
00563 {
00564 Switch useHex(dict.lookup("useHexTopology"));
00565
00566 Switch writeMesh(dict.lookup("writeMesh"));
00567
00568 wordList dirNames(dict.lookup("directions"));
00569
00570 if (useHex && dirNames.size() == 3)
00571 {
00572
00573 labelList hexCells(splitOffHex(mesh));
00574
00575 refineHex8(mesh, hexCells, writeMesh);
00576 }
00577
00578 label nRemainingCells = cellLabels_.size();
00579
00580 reduce(nRemainingCells, sumOp<label>());
00581
00582 if (nRemainingCells > 0)
00583 {
00584
00585
00586
00587 List<vectorField> cellDirections(cellDirs);
00588
00589 refineFromDict(mesh, cellDirections, dict, writeMesh);
00590 }
00591 }
00592
00593
00594
00595 Foam::multiDirRefinement::multiDirRefinement
00596 (
00597 polyMesh& mesh,
00598 undoableMeshCutter& cutter,
00599 const cellLooper& cellWalker,
00600
00601 const labelList& cellLabels,
00602 const List<vectorField>& cellDirs,
00603 const bool writeMesh
00604 )
00605 :
00606 cellLabels_(cellLabels),
00607 addedCells_(mesh.nCells())
00608 {
00609
00610 List<vectorField> cellDirections(cellDirs);
00611
00612 refineAllDirs(mesh, cellDirections, cellWalker, cutter, writeMesh);
00613 }
00614
00615
00616