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 "motionSmoother.H"
00027 #include <meshTools/twoDPointCorrector.H>
00028 #include <meshTools/faceSet.H>
00029 #include <meshTools/pointSet.H>
00030 #include <OpenFOAM/fixedValuePointPatchFields.H>
00031 #include <OpenFOAM/pointConstraint.H>
00032 #include <OpenFOAM/syncTools.H>
00033 #include <meshTools/meshTools.H>
00034 #include <OpenFOAM/OFstream.H>
00035
00036 namespace Foam
00037 {
00038
00039
00040
00041 defineTypeNameAndDebug(motionSmoother, 0);
00042
00043 }
00044
00045
00046
00047
00048
00049 void Foam::motionSmoother::makePatchPatchAddressing()
00050 {
00051 if (debug)
00052 {
00053 Pout<< "motionSmoother::makePatchPatchAddressing() : "
00054 << "constructing boundary addressing"
00055 << endl;
00056 }
00057
00058 const polyBoundaryMesh& bm = mesh_.boundaryMesh();
00059 const pointBoundaryMesh& pbm = pMesh_.boundary();
00060
00061
00062
00063 label nPatchPatchPoints = 0;
00064
00065 forAll(bm, patchi)
00066 {
00067 if(!isA<emptyPolyPatch>(bm[patchi]))
00068 {
00069 nPatchPatchPoints += bm[patchi].boundaryPoints().size();
00070 }
00071 }
00072
00073
00074
00075 Map<label> patchPatchPointSet(2*nPatchPatchPoints);
00076
00077 labelList patchPatchPoints(nPatchPatchPoints);
00078
00079 List<pointConstraint> patchPatchPointConstraints(nPatchPatchPoints);
00080
00081 label pppi = 0;
00082
00083 forAll(bm, patchi)
00084 {
00085 if(!isA<emptyPolyPatch>(bm[patchi]))
00086 {
00087 const labelList& bp = bm[patchi].boundaryPoints();
00088 const labelList& meshPoints = bm[patchi].meshPoints();
00089
00090 forAll(bp, pointi)
00091 {
00092 label ppp = meshPoints[bp[pointi]];
00093
00094 Map<label>::iterator iter = patchPatchPointSet.find(ppp);
00095
00096 if (iter == patchPatchPointSet.end())
00097 {
00098 patchPatchPointSet.insert(ppp, pppi);
00099 patchPatchPoints[pppi] = ppp;
00100 pbm[patchi].applyConstraint
00101 (
00102 bp[pointi],
00103 patchPatchPointConstraints[pppi]
00104 );
00105 pppi++;
00106 }
00107 else
00108 {
00109 pbm[patchi].applyConstraint
00110 (
00111 bp[pointi],
00112 patchPatchPointConstraints[iter()]
00113 );
00114 }
00115 }
00116 }
00117 }
00118
00119 nPatchPatchPoints = pppi;
00120 patchPatchPoints.setSize(nPatchPatchPoints);
00121 patchPatchPointConstraints.setSize(nPatchPatchPoints);
00122
00123 patchPatchPointConstraintPoints_.setSize(nPatchPatchPoints);
00124 patchPatchPointConstraintTensors_.setSize(nPatchPatchPoints);
00125
00126 label nConstraints = 0;
00127
00128 forAll(patchPatchPointConstraints, i)
00129 {
00130 if (patchPatchPointConstraints[i].first() != 0)
00131 {
00132 patchPatchPointConstraintPoints_[nConstraints] =
00133 patchPatchPoints[i];
00134
00135 patchPatchPointConstraintTensors_[nConstraints] =
00136 patchPatchPointConstraints[i].constraintTransformation();
00137
00138 nConstraints++;
00139 }
00140 }
00141
00142 patchPatchPointConstraintPoints_.setSize(nConstraints);
00143 patchPatchPointConstraintTensors_.setSize(nConstraints);
00144
00145
00146 if (debug)
00147 {
00148 OFstream str(mesh_.db().path()/"constraintPoints.obj");
00149
00150 Pout<< "Dumping " << patchPatchPointConstraintPoints_.size()
00151 << " constraintPoints to " << str.name() << endl;
00152 forAll(patchPatchPointConstraintPoints_, i)
00153 {
00154 label pointI = patchPatchPointConstraintPoints_[i];
00155
00156 meshTools::writeOBJ(str, mesh_.points()[pointI]);
00157 }
00158
00159 Pout<< "motionSmoother::makePatchPatchAddressing() : "
00160 << "finished constructing boundary addressing"
00161 << endl;
00162 }
00163 }
00164
00165
00166 void Foam::motionSmoother::checkFld(const pointScalarField& fld)
00167 {
00168 forAll(fld, pointI)
00169 {
00170 const scalar val = fld[pointI];
00171
00172 if ((val > -GREAT) && (val < GREAT))
00173 {}
00174 else
00175 {
00176 FatalErrorIn("motionSmoother::checkFld")
00177 << "Problem : point:" << pointI << " value:" << val
00178 << abort(FatalError);
00179 }
00180 }
00181 }
00182
00183
00184 Foam::labelHashSet Foam::motionSmoother::getPoints
00185 (
00186 const labelHashSet& faceLabels
00187 ) const
00188 {
00189 labelHashSet usedPoints(mesh_.nPoints()/100);
00190
00191 forAllConstIter(labelHashSet, faceLabels, iter)
00192 {
00193 const face& f = mesh_.faces()[iter.key()];
00194
00195 forAll(f, fp)
00196 {
00197 usedPoints.insert(f[fp]);
00198 }
00199 }
00200
00201 return usedPoints;
00202 }
00203
00204
00205
00206 void Foam::motionSmoother::minSmooth
00207 (
00208 const PackedBoolList& isAffectedPoint,
00209 const labelList& meshPoints,
00210 const pointScalarField& fld,
00211 pointScalarField& newFld
00212 ) const
00213 {
00214 tmp<pointScalarField> tavgFld = avg
00215 (
00216 fld,
00217 scalarField(mesh_.nEdges(), 1.0),
00218 false
00219 );
00220 const pointScalarField& avgFld = tavgFld();
00221
00222 forAll(meshPoints, i)
00223 {
00224 label pointI = meshPoints[i];
00225 if (isAffectedPoint.get(pointI) == 1)
00226 {
00227 newFld[pointI] = min
00228 (
00229 fld[pointI],
00230 0.5*fld[pointI] + 0.5*avgFld[pointI]
00231 );
00232 }
00233 }
00234
00235 newFld.correctBoundaryConditions();
00236 applyCornerConstraints(newFld);
00237 }
00238
00239
00240
00241 void Foam::motionSmoother::minSmooth
00242 (
00243 const PackedBoolList& isAffectedPoint,
00244 const pointScalarField& fld,
00245 pointScalarField& newFld
00246 ) const
00247 {
00248 tmp<pointScalarField> tavgFld = avg
00249 (
00250 fld,
00251 scalarField(mesh_.nEdges(), 1.0),
00252 false
00253 );
00254 const pointScalarField& avgFld = tavgFld();
00255
00256 forAll(fld, pointI)
00257 {
00258 if (isAffectedPoint.get(pointI) == 1 && isInternalPoint(pointI))
00259 {
00260 newFld[pointI] = min
00261 (
00262 fld[pointI],
00263 0.5*fld[pointI] + 0.5*avgFld[pointI]
00264 );
00265 }
00266 }
00267
00268 newFld.correctBoundaryConditions();
00269 applyCornerConstraints(newFld);
00270 }
00271
00272
00273
00274 void Foam::motionSmoother::scaleField
00275 (
00276 const labelHashSet& pointLabels,
00277 const scalar scale,
00278 pointScalarField& fld
00279 ) const
00280 {
00281 forAllConstIter(labelHashSet, pointLabels, iter)
00282 {
00283 if (isInternalPoint(iter.key()))
00284 {
00285 fld[iter.key()] *= scale;
00286 }
00287 }
00288 fld.correctBoundaryConditions();
00289 applyCornerConstraints(fld);
00290 }
00291
00292
00293
00294 void Foam::motionSmoother::scaleField
00295 (
00296 const labelList& meshPoints,
00297 const labelHashSet& pointLabels,
00298 const scalar scale,
00299 pointScalarField& fld
00300 ) const
00301 {
00302 forAll(meshPoints, i)
00303 {
00304 label pointI = meshPoints[i];
00305
00306 if (pointLabels.found(pointI))
00307 {
00308 fld[pointI] *= scale;
00309 }
00310 }
00311 }
00312
00313
00314 bool Foam::motionSmoother::isInternalPoint(const label pointI) const
00315 {
00316 return isInternalPoint_.get(pointI) == 1;
00317 }
00318
00319
00320 void Foam::motionSmoother::getAffectedFacesAndPoints
00321 (
00322 const label nPointIter,
00323 const faceSet& wrongFaces,
00324
00325 labelList& affectedFaces,
00326 PackedBoolList& isAffectedPoint
00327 ) const
00328 {
00329 isAffectedPoint.setSize(mesh_.nPoints());
00330 isAffectedPoint = 0;
00331
00332 faceSet nbrFaces(mesh_, "checkFaces", wrongFaces);
00333
00334
00335
00336
00337
00338
00339 for (label i = 0; i < nPointIter; i++)
00340 {
00341 pointSet nbrPoints(mesh_, "grownPoints", getPoints(nbrFaces.toc()));
00342
00343 forAllConstIter(pointSet, nbrPoints, iter)
00344 {
00345 const labelList& pCells = mesh_.pointCells(iter.key());
00346
00347 forAll(pCells, pCellI)
00348 {
00349 const cell& cFaces = mesh_.cells()[pCells[pCellI]];
00350
00351 forAll(cFaces, cFaceI)
00352 {
00353 nbrFaces.insert(cFaces[cFaceI]);
00354 }
00355 }
00356 }
00357 nbrFaces.sync(mesh_);
00358
00359 if (i == nPointIter - 2)
00360 {
00361 forAllConstIter(faceSet, nbrFaces, iter)
00362 {
00363 const face& f = mesh_.faces()[iter.key()];
00364 forAll(f, fp)
00365 {
00366 isAffectedPoint.set(f[fp], 1);
00367 }
00368 }
00369 }
00370 }
00371
00372 affectedFaces = nbrFaces.toc();
00373 }
00374
00375
00376
00377
00378 Foam::motionSmoother::motionSmoother
00379 (
00380 polyMesh& mesh,
00381 pointMesh& pMesh,
00382 indirectPrimitivePatch& pp,
00383 const labelList& adaptPatchIDs,
00384 const dictionary& paramDict
00385 )
00386 :
00387 mesh_(mesh),
00388 pMesh_(pMesh),
00389 pp_(pp),
00390 adaptPatchIDs_(adaptPatchIDs),
00391 paramDict_(paramDict),
00392 displacement_
00393 (
00394 IOobject
00395 (
00396 "displacement",
00397 mesh_.time().timeName(),
00398 mesh_,
00399 IOobject::MUST_READ,
00400 IOobject::AUTO_WRITE
00401 ),
00402 pMesh_
00403 ),
00404 scale_
00405 (
00406 IOobject
00407 (
00408 "scale",
00409 mesh_.time().timeName(),
00410 mesh_,
00411 IOobject::NO_READ,
00412 IOobject::AUTO_WRITE
00413 ),
00414 pMesh_,
00415 dimensionedScalar("scale", dimless, 1.0)
00416 ),
00417 oldPoints_(mesh_.points()),
00418 isInternalPoint_(mesh_.nPoints(), 1),
00419 twoDCorrector_(mesh_)
00420 {
00421 updateMesh();
00422 }
00423
00424
00425 Foam::motionSmoother::motionSmoother
00426 (
00427 polyMesh& mesh,
00428 indirectPrimitivePatch& pp,
00429 const labelList& adaptPatchIDs,
00430 const pointVectorField& displacement,
00431 const dictionary& paramDict
00432 )
00433 :
00434 mesh_(mesh),
00435 pMesh_(const_cast<pointMesh&>(displacement.mesh())),
00436 pp_(pp),
00437 adaptPatchIDs_(adaptPatchIDs),
00438 paramDict_(paramDict),
00439 displacement_
00440 (
00441 IOobject
00442 (
00443 "displacement",
00444 mesh_.time().timeName(),
00445 mesh_,
00446 IOobject::NO_READ,
00447 IOobject::AUTO_WRITE
00448 ),
00449 displacement
00450 ),
00451 scale_
00452 (
00453 IOobject
00454 (
00455 "scale",
00456 mesh_.time().timeName(),
00457 mesh_,
00458 IOobject::NO_READ,
00459 IOobject::AUTO_WRITE
00460 ),
00461 pMesh_,
00462 dimensionedScalar("scale", dimless, 1.0)
00463 ),
00464 oldPoints_(mesh_.points()),
00465 isInternalPoint_(mesh_.nPoints(), 1),
00466 twoDCorrector_(mesh_)
00467 {
00468 updateMesh();
00469 }
00470
00471
00472
00473
00474 Foam::motionSmoother::~motionSmoother()
00475 {}
00476
00477
00478
00479
00480 const Foam::polyMesh& Foam::motionSmoother::mesh() const
00481 {
00482 return mesh_;
00483 }
00484
00485
00486 const Foam::pointMesh& Foam::motionSmoother::pMesh() const
00487 {
00488 return pMesh_;
00489 }
00490
00491
00492 const Foam::indirectPrimitivePatch& Foam::motionSmoother::patch() const
00493 {
00494 return pp_;
00495 }
00496
00497
00498 const Foam::labelList& Foam::motionSmoother::adaptPatchIDs() const
00499 {
00500 return adaptPatchIDs_;
00501 }
00502
00503
00504 const Foam::dictionary& Foam::motionSmoother::paramDict() const
00505 {
00506 return paramDict_;
00507 }
00508
00509
00510 Foam::pointVectorField& Foam::motionSmoother::displacement()
00511 {
00512 return displacement_;
00513 }
00514
00515
00516 const Foam::pointVectorField& Foam::motionSmoother::displacement() const
00517 {
00518 return displacement_;
00519 }
00520
00521
00522 const Foam::pointScalarField& Foam::motionSmoother::scale() const
00523 {
00524 return scale_;
00525 }
00526
00527
00528 const Foam::pointField& Foam::motionSmoother::oldPoints() const
00529 {
00530 return oldPoints_;
00531 }
00532
00533
00534 void Foam::motionSmoother::correct()
00535 {
00536 oldPoints_ = mesh_.points();
00537
00538 scale_ = 1.0;
00539
00540
00541
00542
00543 }
00544
00545
00546 void Foam::motionSmoother::setDisplacement(pointField& patchDisp)
00547 {
00548
00549 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
00550
00551 forAll(patches, patchI)
00552 {
00553 const polyPatch& pp = patches[patchI];
00554
00555 if (pp.coupled())
00556 {
00557 const labelList& meshPoints = pp.meshPoints();
00558
00559 forAll(meshPoints, i)
00560 {
00561 displacement_[meshPoints[i]] = vector::zero;
00562 }
00563 }
00564 }
00565
00566 const labelList& ppMeshPoints = pp_.meshPoints();
00567
00568
00569 forAll(ppMeshPoints, patchPointI)
00570 {
00571 displacement_[ppMeshPoints[patchPointI]] = patchDisp[patchPointI];
00572 }
00573
00574
00575
00576 forAll(adaptPatchIDs_, i)
00577 {
00578 label patchI = adaptPatchIDs_[i];
00579
00580 displacement_.boundaryField()[patchI] ==
00581 displacement_.boundaryField()[patchI].patchInternalField();
00582 }
00583
00584
00585
00586
00587
00588 labelHashSet adaptPatchSet(adaptPatchIDs_);
00589
00590 const lduSchedule& patchSchedule = mesh_.globalData().patchSchedule();
00591
00592 forAll(patchSchedule, patchEvalI)
00593 {
00594 label patchI = patchSchedule[patchEvalI].patch;
00595
00596 if (!adaptPatchSet.found(patchI))
00597 {
00598 if (patchSchedule[patchEvalI].init)
00599 {
00600 displacement_.boundaryField()[patchI]
00601 .initEvaluate(Pstream::scheduled);
00602 }
00603 else
00604 {
00605 displacement_.boundaryField()[patchI]
00606 .evaluate(Pstream::scheduled);
00607 }
00608 }
00609 }
00610
00611
00612 applyCornerConstraints(displacement_);
00613
00614
00615 syncTools::syncPointList
00616 (
00617 mesh_,
00618 displacement_,
00619 maxMagEqOp(),
00620 vector::zero,
00621 false
00622 );
00623
00624
00625
00626
00627 forAll(adaptPatchIDs_, i)
00628 {
00629 label patchI = adaptPatchIDs_[i];
00630
00631 displacement_.boundaryField()[patchI] ==
00632 displacement_.boundaryField()[patchI].patchInternalField();
00633 }
00634
00635 if (debug)
00636 {
00637 OFstream str(mesh_.db().path()/"changedPoints.obj");
00638 label nVerts = 0;
00639 forAll(ppMeshPoints, patchPointI)
00640 {
00641 const vector& newDisp = displacement_[ppMeshPoints[patchPointI]];
00642
00643 if (mag(newDisp-patchDisp[patchPointI]) > SMALL)
00644 {
00645 const point& pt = mesh_.points()[ppMeshPoints[patchPointI]];
00646
00647 meshTools::writeOBJ(str, pt);
00648 nVerts++;
00649
00650
00651
00652 }
00653 }
00654 Pout<< "Written " << nVerts << " points that are changed to file "
00655 << str.name() << endl;
00656 }
00657
00658
00659 forAll(ppMeshPoints, patchPointI)
00660 {
00661 patchDisp[patchPointI] = displacement_[ppMeshPoints[patchPointI]];
00662 }
00663 }
00664
00665
00666
00667 void Foam::motionSmoother::correctBoundaryConditions
00668 (
00669 pointVectorField& displacement
00670 ) const
00671 {
00672 labelHashSet adaptPatchSet(adaptPatchIDs_);
00673
00674 const lduSchedule& patchSchedule = mesh_.globalData().patchSchedule();
00675
00676
00677 forAll(patchSchedule, patchEvalI)
00678 {
00679 label patchI = patchSchedule[patchEvalI].patch;
00680
00681 if (adaptPatchSet.found(patchI))
00682 {
00683 if (patchSchedule[patchEvalI].init)
00684 {
00685 displacement.boundaryField()[patchI]
00686 .initEvaluate(Pstream::blocking);
00687 }
00688 else
00689 {
00690 displacement.boundaryField()[patchI]
00691 .evaluate(Pstream::blocking);
00692 }
00693 }
00694 }
00695
00696
00697
00698 forAll(patchSchedule, patchEvalI)
00699 {
00700 label patchI = patchSchedule[patchEvalI].patch;
00701
00702 if (!adaptPatchSet.found(patchI))
00703 {
00704 if (patchSchedule[patchEvalI].init)
00705 {
00706 displacement.boundaryField()[patchI]
00707 .initEvaluate(Pstream::blocking);
00708 }
00709 else
00710 {
00711 displacement.boundaryField()[patchI]
00712 .evaluate(Pstream::blocking);
00713 }
00714 }
00715 }
00716
00717
00718 applyCornerConstraints(displacement);
00719
00720
00721 syncTools::syncPointList
00722 (
00723 mesh_,
00724 displacement,
00725 maxMagEqOp(),
00726 vector::zero,
00727 false
00728 );
00729 }
00730
00731
00732 Foam::tmp<Foam::scalarField> Foam::motionSmoother::movePoints
00733 (
00734 pointField& newPoints
00735 )
00736 {
00737
00738 if (twoDCorrector_.required())
00739 {
00740 Info<< "Correct-ing 2-D mesh motion";
00741
00742 if (mesh_.globalData().parallel())
00743 {
00744 WarningIn("motionSmoother::movePoints(pointField& newPoints)")
00745 << "2D mesh-motion probably not correct in parallel" << endl;
00746 }
00747
00748
00749 const pointField& oldPoints = mesh_.points();
00750 const edgeList& edges = mesh_.edges();
00751
00752 const labelList& neIndices = twoDCorrector().normalEdgeIndices();
00753 const vector& pn = twoDCorrector().planeNormal();
00754
00755 forAll(neIndices, i)
00756 {
00757 const edge& e = edges[neIndices[i]];
00758
00759 point& pStart = newPoints[e.start()];
00760
00761 pStart += pn*(pn & (oldPoints[e.start()] - pStart));
00762
00763 point& pEnd = newPoints[e.end()];
00764
00765 pEnd += pn*(pn & (oldPoints[e.end()] - pEnd));
00766 }
00767
00768
00769 twoDCorrector_.correctPoints(newPoints);
00770 Info<< " ...done" << endl;
00771 }
00772
00773 if (debug)
00774 {
00775 Pout<< "motionSmoother::movePoints : testing sync of newPoints."
00776 << endl;
00777 testSyncField
00778 (
00779 newPoints,
00780 minEqOp<point>(),
00781 vector(GREAT,GREAT,GREAT),
00782 true,
00783 1E-6*mesh_.bounds().mag()
00784 );
00785 }
00786
00787 tmp<scalarField> tsweptVol = mesh_.movePoints(newPoints);
00788
00789 pp_.movePoints(mesh_.points());
00790
00791 return tsweptVol;
00792 }
00793
00794
00795 Foam::scalar Foam::motionSmoother::setErrorReduction
00796 (
00797 const scalar errorReduction
00798 )
00799 {
00800 scalar oldErrorReduction = readScalar(paramDict_.lookup("errorReduction"));
00801
00802 paramDict_.remove("errorReduction");
00803 paramDict_.add("errorReduction", errorReduction);
00804
00805 return oldErrorReduction;
00806 }
00807
00808
00809 bool Foam::motionSmoother::scaleMesh
00810 (
00811 labelList& checkFaces,
00812 const bool smoothMesh,
00813 const label nAllowableErrors
00814 )
00815 {
00816 List<labelPair> emptyBaffles;
00817 return scaleMesh
00818 (
00819 checkFaces,
00820 emptyBaffles,
00821 smoothMesh,
00822 nAllowableErrors
00823 );
00824 }
00825
00826
00827 bool Foam::motionSmoother::scaleMesh
00828 (
00829 labelList& checkFaces,
00830 const List<labelPair>& baffles,
00831 const bool smoothMesh,
00832 const label nAllowableErrors
00833 )
00834 {
00835 return scaleMesh
00836 (
00837 checkFaces,
00838 baffles,
00839 paramDict_,
00840 paramDict_,
00841 smoothMesh,
00842 nAllowableErrors
00843 );
00844 }
00845
00846
00847 bool Foam::motionSmoother::scaleMesh
00848 (
00849 labelList& checkFaces,
00850 const List<labelPair>& baffles,
00851 const dictionary& paramDict,
00852 const dictionary& meshQualityDict,
00853 const bool smoothMesh,
00854 const label nAllowableErrors
00855 )
00856 {
00857 if (!smoothMesh && adaptPatchIDs_.empty())
00858 {
00859 FatalErrorIn("motionSmoother::scaleMesh(const bool")
00860 << "You specified both no movement on the internal mesh points"
00861 << " (smoothMesh = false)" << nl
00862 << "and no movement on the patch (adaptPatchIDs is empty)" << nl
00863 << "Hence nothing to adapt."
00864 << exit(FatalError);
00865 }
00866
00867 if (debug)
00868 {
00869
00870 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
00871
00872 Pout<< "Entering scaleMesh : coupled patches:" << endl;
00873 forAll(patches, patchI)
00874 {
00875 if (patches[patchI].coupled())
00876 {
00877 const coupledPolyPatch& pp =
00878 refCast<const coupledPolyPatch>(patches[patchI]);
00879
00880 Pout<< '\t' << patchI << '\t' << pp.name()
00881 << " parallel:" << pp.parallel()
00882 << " separated:" << pp.separated()
00883 << " forwardT:" << pp.forwardT().size()
00884 << endl;
00885 }
00886 }
00887 }
00888
00889 const scalar errorReduction =
00890 readScalar(paramDict.lookup("errorReduction"));
00891 const label nSmoothScale =
00892 readLabel(paramDict.lookup("nSmoothScale"));
00893
00894
00895
00896
00897 syncTools::syncPointList
00898 (
00899 mesh_,
00900 displacement_,
00901 maxMagEqOp(),
00902 vector::zero,
00903 false
00904 );
00905
00906
00907 pointField newPoints;
00908 {
00909
00910 pointVectorField totalDisplacement
00911 (
00912 IOobject
00913 (
00914 "totalDisplacement",
00915 mesh_.time().timeName(),
00916 mesh_,
00917 IOobject::NO_READ,
00918 IOobject::NO_WRITE,
00919 false
00920 ),
00921 scale_*displacement_,
00922 displacement_.boundaryField().types()
00923 );
00924 correctBoundaryConditions(totalDisplacement);
00925
00926 if (debug)
00927 {
00928 Pout<< "scaleMesh : testing sync of totalDisplacement" << endl;
00929 testSyncField
00930 (
00931 totalDisplacement,
00932 maxMagEqOp(),
00933 vector::zero,
00934 false,
00935 1E-6*mesh_.bounds().mag()
00936 );
00937 }
00938
00939 newPoints = oldPoints_ + totalDisplacement.internalField();
00940 }
00941
00942 Info<< "Moving mesh using diplacement scaling :"
00943 << " min:" << gMin(scale_.internalField())
00944 << " max:" << gMax(scale_.internalField())
00945 << endl;
00946
00947
00948
00949 movePoints(newPoints);
00950
00951
00952 faceSet wrongFaces(mesh_, "wrongFaces", mesh_.nFaces()/100+100);
00953 checkMesh(false, mesh_, meshQualityDict, checkFaces, baffles, wrongFaces);
00954
00955 if (returnReduce(wrongFaces.size(), sumOp<label>()) <= nAllowableErrors)
00956 {
00957 return true;
00958 }
00959 else
00960 {
00961
00962 wrongFaces.sync(mesh_);
00963
00964
00965
00966
00967
00968 if (mag(errorReduction) < SMALL)
00969 {
00970 labelHashSet newWrongFaces(wrongFaces);
00971 forAllConstIter(labelHashSet, wrongFaces, iter)
00972 {
00973 label own = mesh_.faceOwner()[iter.key()];
00974 const cell& ownFaces = mesh_.cells()[own];
00975
00976 forAll(ownFaces, cfI)
00977 {
00978 newWrongFaces.insert(ownFaces[cfI]);
00979 }
00980
00981 if (iter.key() < mesh_.nInternalFaces())
00982 {
00983 label nei = mesh_.faceNeighbour()[iter.key()];
00984 const cell& neiFaces = mesh_.cells()[nei];
00985
00986 forAll(neiFaces, cfI)
00987 {
00988 newWrongFaces.insert(neiFaces[cfI]);
00989 }
00990 }
00991 }
00992 wrongFaces.transfer(newWrongFaces);
00993 wrongFaces.sync(mesh_);
00994 }
00995
00996
00997
00998
00999
01000 pointSet usedPoints(mesh_, "usedPoints", getPoints(wrongFaces));
01001 usedPoints.sync(mesh_);
01002
01003
01004
01005
01006
01007
01008 PackedBoolList isAffectedPoint(mesh_.nPoints());
01009 getAffectedFacesAndPoints
01010 (
01011 nSmoothScale,
01012 wrongFaces,
01013 checkFaces,
01014 isAffectedPoint
01015 );
01016
01017 if (debug)
01018 {
01019 Pout<< "Faces in error:" << wrongFaces.size()
01020 << " with points:" << usedPoints.size()
01021 << endl;
01022 }
01023
01024 if (adaptPatchIDs_.size())
01025 {
01026
01027 scaleField(pp_.meshPoints(), usedPoints, errorReduction, scale_);
01028 }
01029 if (smoothMesh)
01030 {
01031
01032 scaleField(usedPoints, errorReduction, scale_);
01033 }
01034
01035 for (label i = 0; i < nSmoothScale; i++)
01036 {
01037 if (adaptPatchIDs_.size())
01038 {
01039
01040 pointScalarField oldScale(scale_);
01041 minSmooth
01042 (
01043 isAffectedPoint,
01044 pp_.meshPoints(),
01045 oldScale,
01046 scale_
01047 );
01048 checkFld(scale_);
01049 }
01050 if (smoothMesh)
01051 {
01052
01053 pointScalarField oldScale(scale_);
01054 minSmooth(isAffectedPoint, oldScale, scale_);
01055 checkFld(scale_);
01056 }
01057 }
01058
01059 syncTools::syncPointList
01060 (
01061 mesh_,
01062 scale_,
01063 maxEqOp<scalar>(),
01064 -GREAT,
01065 false
01066 );
01067
01068
01069 if (debug)
01070 {
01071 Pout<< "scale_ after smoothing :"
01072 << " min:" << Foam::gMin(scale_)
01073 << " max:" << Foam::gMax(scale_)
01074 << endl;
01075 }
01076
01077 return false;
01078 }
01079 }
01080
01081
01082 void Foam::motionSmoother::updateMesh()
01083 {
01084 const pointBoundaryMesh& patches = pMesh_.boundary();
01085
01086
01087 forAll(adaptPatchIDs_, i)
01088 {
01089 label patchI = adaptPatchIDs_[i];
01090
01091 if
01092 (
01093 !isA<fixedValuePointPatchVectorField>
01094 (
01095 displacement_.boundaryField()[patchI]
01096 )
01097 )
01098 {
01099 FatalErrorIn
01100 (
01101 "motionSmoother::motionSmoother"
01102 ) << "Patch " << patches[patchI].name()
01103 << " has wrong boundary condition "
01104 << displacement_.boundaryField()[patchI].type()
01105 << " on field " << displacement_.name() << nl
01106 << "Only type allowed is "
01107 << fixedValuePointPatchVectorField::typeName
01108 << exit(FatalError);
01109 }
01110 }
01111
01112
01113
01114
01115
01116 twoDCorrector_.updateMesh();
01117
01118 const labelList& meshPoints = pp_.meshPoints();
01119
01120 forAll(meshPoints, i)
01121 {
01122 isInternalPoint_.set(meshPoints[i], 0);
01123 }
01124
01125
01126 isMasterEdge_ = syncTools::getMasterEdges(mesh_);
01127
01128 makePatchPatchAddressing();
01129 }
01130
01131
01132
01133
01134 template<>
01135 void Foam::motionSmoother::applyCornerConstraints<Foam::scalar>
01136 (
01137 GeometricField<scalar, pointPatchField, pointMesh>& pf
01138 ) const
01139 {}
01140
01141
01142