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 #include "autoLayerDriver.H"
00030 #include <finiteVolume/fvMesh.H>
00031 #include <OpenFOAM/Time.H>
00032 #include <OpenFOAM/pointFields.H>
00033 #include <dynamicMesh/motionSmoother.H>
00034 #include <autoMesh/pointData.H>
00035 #include <meshTools/PointEdgeWave.H>
00036
00037
00038
00039
00040 void Foam::autoLayerDriver::sumWeights
00041 (
00042 const PackedBoolList& isMasterEdge,
00043 const labelList& meshEdges,
00044 const labelList& meshPoints,
00045 const edgeList& edges,
00046 scalarField& invSumWeight
00047 ) const
00048 {
00049 invSumWeight = 0;
00050
00051 forAll(edges, edgeI)
00052 {
00053 if (isMasterEdge.get(meshEdges[edgeI]) == 1)
00054 {
00055 const edge& e = edges[edgeI];
00056
00057 scalar eWeight = 1.0;
00058
00059 invSumWeight[e[0]] += eWeight;
00060 invSumWeight[e[1]] += eWeight;
00061 }
00062 }
00063
00064 syncTools::syncPointList
00065 (
00066 meshRefiner_.mesh(),
00067 meshPoints,
00068 invSumWeight,
00069 plusEqOp<scalar>(),
00070 scalar(0.0),
00071 false
00072 );
00073
00074 forAll(invSumWeight, pointI)
00075 {
00076 scalar w = invSumWeight[pointI];
00077
00078 if (w > 0.0)
00079 {
00080 invSumWeight[pointI] = 1.0/w;
00081 }
00082 }
00083 }
00084
00085
00086
00087 void Foam::autoLayerDriver::smoothField
00088 (
00089 const motionSmoother& meshMover,
00090 const PackedBoolList& isMasterEdge,
00091 const labelList& meshEdges,
00092 const scalarField& fieldMin,
00093 const label nSmoothDisp,
00094 scalarField& field
00095 ) const
00096 {
00097 const indirectPrimitivePatch& pp = meshMover.patch();
00098 const edgeList& edges = pp.edges();
00099 const labelList& meshPoints = pp.meshPoints();
00100
00101 scalarField invSumWeight(pp.nPoints());
00102 sumWeights
00103 (
00104 isMasterEdge,
00105 meshEdges,
00106 meshPoints,
00107 edges,
00108 invSumWeight
00109 );
00110
00111
00112 Info<< "shrinkMeshDistance : Smoothing field ..." << endl;
00113
00114 for (label iter = 0; iter < nSmoothDisp; iter++)
00115 {
00116 scalarField average(pp.nPoints());
00117 averageNeighbours
00118 (
00119 meshMover.mesh(),
00120 isMasterEdge,
00121 meshEdges,
00122 meshPoints,
00123 pp.edges(),
00124 invSumWeight,
00125 field,
00126 average
00127 );
00128
00129
00130 forAll(field, pointI)
00131 {
00132
00133 average[pointI] = 0.5*(field[pointI]+average[pointI]);
00134
00135
00136 if
00137 (
00138 average[pointI] < field[pointI]
00139 && average[pointI] >= fieldMin[pointI]
00140 )
00141 {
00142 field[pointI] = average[pointI];
00143 }
00144 }
00145
00146
00147 if ((iter % 10) == 0)
00148 {
00149 Info<< " Iteration " << iter << " residual "
00150 << gSum(mag(field-average))
00151 /returnReduce(average.size(), sumOp<label>())
00152 << endl;
00153 }
00154 }
00155 }
00156
00157
00158
00159 void Foam::autoLayerDriver::smoothPatchNormals
00160 (
00161 const motionSmoother& meshMover,
00162 const PackedBoolList& isMasterEdge,
00163 const labelList& meshEdges,
00164 const label nSmoothDisp,
00165 pointField& normals
00166 ) const
00167 {
00168 const indirectPrimitivePatch& pp = meshMover.patch();
00169 const edgeList& edges = pp.edges();
00170 const labelList& meshPoints = pp.meshPoints();
00171
00172
00173
00174 scalarField invSumWeight(pp.nPoints());
00175 sumWeights
00176 (
00177 isMasterEdge,
00178 meshEdges,
00179 meshPoints,
00180 edges,
00181 invSumWeight
00182 );
00183
00184
00185 Info<< "shrinkMeshDistance : Smoothing normals ..." << endl;
00186
00187 for (label iter = 0; iter < nSmoothDisp; iter++)
00188 {
00189 vectorField average(pp.nPoints());
00190 averageNeighbours
00191 (
00192 meshMover.mesh(),
00193 isMasterEdge,
00194 meshEdges,
00195 meshPoints,
00196 pp.edges(),
00197 invSumWeight,
00198 normals,
00199 average
00200 );
00201
00202
00203 if ((iter % 10) == 0)
00204 {
00205 Info<< " Iteration " << iter << " residual "
00206 << gSum(mag(normals-average))
00207 /returnReduce(average.size(), sumOp<label>())
00208 << endl;
00209 }
00210
00211
00212 forAll(average, pointI)
00213 {
00214
00215 average[pointI] = 0.5*(normals[pointI]+average[pointI]);
00216 normals[pointI] = average[pointI];
00217 normals[pointI] /= mag(normals[pointI]) + VSMALL;
00218 }
00219 }
00220 }
00221
00222
00223
00224 void Foam::autoLayerDriver::smoothNormals
00225 (
00226 const label nSmoothDisp,
00227 const PackedBoolList& isMasterEdge,
00228 const labelList& fixedPoints,
00229 pointVectorField& normals
00230 ) const
00231 {
00232
00233 Info<< "shrinkMeshDistance : Smoothing normals ..." << endl;
00234
00235 const fvMesh& mesh = meshRefiner_.mesh();
00236 const edgeList& edges = mesh.edges();
00237
00238
00239 PackedBoolList isFixedPoint(mesh.nPoints());
00240
00241
00242 forAll(fixedPoints, i)
00243 {
00244 label meshPointI = fixedPoints[i];
00245 isFixedPoint.set(meshPointI, 1);
00246 }
00247
00248
00249 const labelList meshEdges(identity(mesh.nEdges()));
00250 const labelList meshPoints(identity(mesh.nPoints()));
00251
00252
00253
00254 scalarField invSumWeight(mesh.nPoints(), 0);
00255 sumWeights
00256 (
00257 isMasterEdge,
00258 meshEdges,
00259 meshPoints,
00260 edges,
00261 invSumWeight
00262 );
00263
00264 Info<< "shrinkMeshDistance : Smoothing normals in interior ..." << endl;
00265
00266 for (label iter = 0; iter < nSmoothDisp; iter++)
00267 {
00268 vectorField average(mesh.nPoints());
00269 averageNeighbours
00270 (
00271 mesh,
00272 isMasterEdge,
00273 meshEdges,
00274 meshPoints,
00275 edges,
00276 invSumWeight,
00277 normals,
00278 average
00279 );
00280
00281
00282 if ((iter % 10) == 0)
00283 {
00284 Info<< " Iteration " << iter << " residual "
00285 << gSum(mag(normals-average))
00286 /returnReduce(average.size(), sumOp<label>())
00287 << endl;
00288 }
00289
00290
00291
00292 forAll(average, pointI)
00293 {
00294 if (isFixedPoint.get(pointI) == 0)
00295 {
00296
00297 average[pointI] = 0.5*(normals[pointI]+average[pointI]);
00298 normals[pointI] = average[pointI];
00299 normals[pointI] /= mag(normals[pointI]) + VSMALL;
00300 }
00301 }
00302 }
00303 }
00304
00305
00306
00307
00308 bool Foam::autoLayerDriver::isMaxEdge
00309 (
00310 const List<pointData>& pointWallDist,
00311 const label edgeI,
00312 const scalar minCos
00313 ) const
00314 {
00315 const fvMesh& mesh = meshRefiner_.mesh();
00316 const pointField& points = mesh.points();
00317
00318
00319
00320 const edge& e = mesh.edges()[edgeI];
00321
00322 vector v0(points[e[0]] - pointWallDist[e[0]].origin());
00323 scalar magV0(mag(v0));
00324
00325 if (magV0 < SMALL)
00326 {
00327 return false;
00328 }
00329
00330 vector v1(points[e[1]] - pointWallDist[e[1]].origin());
00331 scalar magV1(mag(v1));
00332
00333 if (magV1 < SMALL)
00334 {
00335 return false;
00336 }
00337
00338 v0 /= magV0;
00339 v1 /= magV1;
00340
00341
00342 if ((v0 & v1) < minCos)
00343 {
00344 return true;
00345 }
00346 else
00347 {
00348 return false;
00349 }
00350 }
00351
00352
00353
00354
00355 void Foam::autoLayerDriver::handleFeatureAngleLayerTerminations
00356 (
00357 const indirectPrimitivePatch& pp,
00358 const scalar minCos,
00359 List<extrudeMode>& extrudeStatus,
00360 pointField& patchDisp,
00361 labelList& patchNLayers,
00362 label& nPointCounter
00363 ) const
00364 {
00365
00366
00367
00368 boolList extrudedFaces(pp.size(), true);
00369
00370 forAll(pp.localFaces(), faceI)
00371 {
00372 const face& f = pp.localFaces()[faceI];
00373
00374 forAll(f, fp)
00375 {
00376 if (extrudeStatus[f[fp]] == NOEXTRUDE)
00377 {
00378 extrudedFaces[faceI] = false;
00379 break;
00380 }
00381 }
00382 }
00383
00384
00385
00386
00387
00388
00389 forAll(pp.edgeFaces(), edgeI)
00390 {
00391 const labelList& eFaces = pp.edgeFaces()[edgeI];
00392
00393 if (eFaces.size() == 2)
00394 {
00395 const edge& e = pp.edges()[edgeI];
00396 label v0 = e[0];
00397 label v1 = e[1];
00398
00399 if
00400 (
00401 extrudeStatus[v0] != NOEXTRUDE
00402 || extrudeStatus[v1] != NOEXTRUDE
00403 )
00404 {
00405 if (!extrudedFaces[eFaces[0]] || !extrudedFaces[eFaces[1]])
00406 {
00407 const vector& n0 = pp.faceNormals()[eFaces[0]];
00408 const vector& n1 = pp.faceNormals()[eFaces[1]];
00409
00410 if ((n0 & n1) < minCos)
00411 {
00412 if
00413 (
00414 unmarkExtrusion
00415 (
00416 v0,
00417 patchDisp,
00418 patchNLayers,
00419 extrudeStatus
00420 )
00421 )
00422 {
00423 nPointCounter++;
00424 }
00425 if
00426 (
00427 unmarkExtrusion
00428 (
00429 v1,
00430 patchDisp,
00431 patchNLayers,
00432 extrudeStatus
00433 )
00434 )
00435 {
00436 nPointCounter++;
00437 }
00438 }
00439 }
00440 }
00441 }
00442 }
00443 }
00444
00445
00446
00447
00448 void Foam::autoLayerDriver::findIsolatedRegions
00449 (
00450 const indirectPrimitivePatch& pp,
00451 const PackedBoolList& isMasterEdge,
00452 const labelList& meshEdges,
00453 const scalar minCosLayerTermination,
00454 scalarField& field,
00455 List<extrudeMode>& extrudeStatus,
00456 pointField& patchDisp,
00457 labelList& patchNLayers
00458 ) const
00459 {
00460 const fvMesh& mesh = meshRefiner_.mesh();
00461
00462 Info<< "shrinkMeshDistance : Removing isolated regions ..." << endl;
00463
00464
00465 label nPointCounter = 0;
00466
00467 while (true)
00468 {
00469
00470
00471 handleFeatureAngleLayerTerminations
00472 (
00473 pp,
00474 minCosLayerTermination,
00475
00476 extrudeStatus,
00477 patchDisp,
00478 patchNLayers,
00479 nPointCounter
00480 );
00481
00482
00483
00484
00485
00486 boolList extrudedFaces(pp.size(), true);
00487 forAll(pp.localFaces(), faceI)
00488 {
00489 const face& f = pp.localFaces()[faceI];
00490 forAll(f, fp)
00491 {
00492 if (extrudeStatus[f[fp]] == NOEXTRUDE)
00493 {
00494 extrudedFaces[faceI] = false;
00495 break;
00496 }
00497 }
00498 }
00499
00500 const labelListList& pointFaces = pp.pointFaces();
00501
00502 boolList keptPoints(pp.nPoints(), false);
00503 forAll(keptPoints, patchPointI)
00504 {
00505 const labelList& pFaces = pointFaces[patchPointI];
00506
00507 forAll(pFaces, i)
00508 {
00509 label faceI = pFaces[i];
00510 if (extrudedFaces[faceI])
00511 {
00512 keptPoints[patchPointI] = true;
00513 break;
00514 }
00515 }
00516 }
00517
00518 syncTools::syncPointList
00519 (
00520 mesh,
00521 pp.meshPoints(),
00522 keptPoints,
00523 orEqOp<bool>(),
00524 false,
00525 false
00526 );
00527
00528 label nChanged = 0;
00529
00530 forAll(keptPoints, patchPointI)
00531 {
00532 if (!keptPoints[patchPointI])
00533 {
00534 if
00535 (
00536 unmarkExtrusion
00537 (
00538 patchPointI,
00539 patchDisp,
00540 patchNLayers,
00541 extrudeStatus
00542 )
00543 )
00544 {
00545 nPointCounter++;
00546 nChanged++;
00547 }
00548 }
00549 }
00550
00551
00552 if (returnReduce(nChanged, sumOp<label>()) == 0)
00553 {
00554 break;
00555 }
00556 }
00557
00558 const edgeList& edges = pp.edges();
00559
00560
00561
00562
00563
00564 labelList isolatedPoint(pp.nPoints(),0);
00565
00566 forAll(edges, edgeI)
00567 {
00568 if (isMasterEdge.get(meshEdges[edgeI]) == 1)
00569 {
00570 const edge& e = edges[edgeI];
00571
00572 label v0 = e[0];
00573 label v1 = e[1];
00574
00575 if (extrudeStatus[v1] != NOEXTRUDE)
00576 {
00577 isolatedPoint[v0] += 1;
00578 }
00579 if (extrudeStatus[v0] != NOEXTRUDE)
00580 {
00581 isolatedPoint[v1] += 1;
00582 }
00583 }
00584 }
00585
00586 syncTools::syncPointList
00587 (
00588 mesh,
00589 pp.meshPoints(),
00590 isolatedPoint,
00591 plusEqOp<label>(),
00592 0,
00593 false
00594 );
00595
00596
00597
00598 forAll(pp, faceI)
00599 {
00600 const face& f = pp.localFaces()[faceI];
00601 bool failed = false;
00602 forAll(f, fp)
00603 {
00604 if (isolatedPoint[f[fp]] > 2)
00605 {
00606 failed = true;
00607 break;
00608 }
00609 }
00610 bool allPointsExtruded = true;
00611 if (!failed)
00612 {
00613 forAll(f, fp)
00614 {
00615 if (extrudeStatus[f[fp]] == NOEXTRUDE)
00616 {
00617 allPointsExtruded = false;
00618 break;
00619 }
00620 }
00621
00622 if (allPointsExtruded)
00623 {
00624 forAll(f, fp)
00625 {
00626 if
00627 (
00628 unmarkExtrusion
00629 (
00630 f[fp],
00631 patchDisp,
00632 patchNLayers,
00633 extrudeStatus
00634 )
00635 )
00636 {
00637 field[f[fp]] = 0.0;
00638 nPointCounter++;
00639 }
00640 }
00641 }
00642 }
00643 }
00644
00645 reduce(nPointCounter, sumOp<label>());
00646 Info<< "Number isolated points extrusion stopped : "<< nPointCounter<< endl;
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656 void Foam::autoLayerDriver::medialAxisSmoothingInfo
00657 (
00658 const motionSmoother& meshMover,
00659 const label nSmoothNormals,
00660 const label nSmoothSurfaceNormals,
00661 const scalar minMedianAxisAngleCos,
00662
00663 pointVectorField& dispVec,
00664 pointScalarField& medialRatio,
00665 pointScalarField& medialDist
00666 ) const
00667 {
00668
00669 Info<< "medialAxisSmoothingInfo :"
00670 << " Calculate distance to Medial Axis ..." << endl;
00671
00672 const polyMesh& mesh = meshMover.mesh();
00673 const pointField& points = mesh.points();
00674
00675 const indirectPrimitivePatch& pp = meshMover.patch();
00676 const vectorField& faceNormals = pp.faceNormals();
00677 const labelList& meshPoints = pp.meshPoints();
00678
00679
00680
00681
00682
00683 PackedBoolList isMasterEdge(syncTools::getMasterEdges(mesh));
00684
00685 labelList meshEdges(pp.nEdges());
00686
00687 forAll(meshEdges, patchEdgeI)
00688 {
00689 const edge& e = pp.edges()[patchEdgeI];
00690
00691 label v0 = pp.meshPoints()[e[0]];
00692 label v1 = pp.meshPoints()[e[1]];
00693 meshEdges[patchEdgeI] = meshTools::findEdge
00694 (
00695 mesh.edges(),
00696 mesh.pointEdges()[v0],
00697 v0,
00698 v1
00699 );
00700 }
00701
00702
00703
00704
00705
00706 pointField pointNormals(pp.nPoints(), vector::zero);
00707 {
00708 labelList nPointFaces(pp.nPoints(), 0);
00709
00710 forAll(faceNormals, faceI)
00711 {
00712 const face& f = pp.localFaces()[faceI];
00713
00714 forAll(f, fp)
00715 {
00716 pointNormals[f[fp]] += faceNormals[faceI];
00717 nPointFaces[f[fp]] ++;
00718 }
00719 }
00720
00721 syncTools::syncPointList
00722 (
00723 mesh,
00724 meshPoints,
00725 pointNormals,
00726 plusEqOp<vector>(),
00727 vector::zero,
00728 false
00729 );
00730
00731 syncTools::syncPointList
00732 (
00733 mesh,
00734 meshPoints,
00735 nPointFaces,
00736 plusEqOp<label>(),
00737 0,
00738 false
00739 );
00740
00741 forAll(pointNormals, i)
00742 {
00743 pointNormals[i] /= nPointFaces[i];
00744 }
00745 }
00746
00747
00748 smoothPatchNormals
00749 (
00750 meshMover,
00751 isMasterEdge,
00752 meshEdges,
00753 nSmoothSurfaceNormals,
00754 pointNormals
00755 );
00756
00757
00758
00759
00760
00761
00762 List<pointData> pointWallDist(mesh.nPoints());
00763
00764
00765
00766 {
00767
00768 List<pointData> wallInfo(meshPoints.size());
00769
00770 forAll(meshPoints, patchPointI)
00771 {
00772 label pointI = meshPoints[patchPointI];
00773 wallInfo[patchPointI] = pointData
00774 (
00775 points[pointI],
00776 0.0,
00777 pointI,
00778 pointNormals[patchPointI]
00779 );
00780 }
00781
00782
00783 List<pointData> edgeWallDist(mesh.nEdges());
00784 PointEdgeWave<pointData> wallDistCalc
00785 (
00786 mesh,
00787 meshPoints,
00788 wallInfo,
00789 pointWallDist,
00790 edgeWallDist,
00791 mesh.globalData().nTotalPoints()
00792 );
00793 }
00794
00795
00796
00797 {
00798 List<pointData> pointMedialDist(mesh.nPoints());
00799 List<pointData> edgeMedialDist(mesh.nEdges());
00800
00801
00802 DynamicList<pointData> maxInfo(meshPoints.size());
00803 DynamicList<label> maxPoints(meshPoints.size());
00804
00805
00806
00807 const edgeList& edges = mesh.edges();
00808
00809 forAll(edges, edgeI)
00810 {
00811 if (isMaxEdge(pointWallDist, edgeI, minMedianAxisAngleCos))
00812 {
00813
00814
00815 const edge& e = edges[edgeI];
00816
00817 forAll(e, ep)
00818 {
00819 label pointI = e[ep];
00820
00821 if (!pointMedialDist[pointI].valid())
00822 {
00823 maxPoints.append(pointI);
00824 maxInfo.append
00825 (
00826 pointData
00827 (
00828 points[pointI],
00829 0.0,
00830 pointI,
00831 vector::zero
00832 )
00833 );
00834 pointMedialDist[pointI] = maxInfo[maxInfo.size()-1];
00835 }
00836 }
00837 }
00838 }
00839
00840
00841
00842 const polyBoundaryMesh& patches = mesh.boundaryMesh();
00843
00844 labelHashSet adaptPatches(meshMover.adaptPatchIDs());
00845
00846 forAll(patches, patchI)
00847 {
00848 const polyPatch& pp = patches[patchI];
00849
00850 if
00851 (
00852 !pp.coupled()
00853 && !isA<emptyPolyPatch>(pp)
00854 && !adaptPatches.found(patchI)
00855 )
00856 {
00857 Info<< "Inserting points on patch " << pp.name() << endl;
00858
00859 const labelList& meshPoints = pp.meshPoints();
00860
00861 forAll(meshPoints, i)
00862 {
00863 label pointI = meshPoints[i];
00864
00865 if (!pointMedialDist[pointI].valid())
00866 {
00867 maxPoints.append(pointI);
00868 maxInfo.append
00869 (
00870 pointData
00871 (
00872 points[pointI],
00873 0.0,
00874 pointI,
00875 vector::zero
00876 )
00877 );
00878 pointMedialDist[pointI] = maxInfo[maxInfo.size()-1];
00879 }
00880 }
00881 }
00882 }
00883
00884 maxInfo.shrink();
00885 maxPoints.shrink();
00886
00887
00888 PointEdgeWave<pointData> medialDistCalc
00889 (
00890 mesh,
00891 maxPoints,
00892 maxInfo,
00893
00894 pointMedialDist,
00895 edgeMedialDist,
00896 mesh.globalData().nTotalPoints()
00897 );
00898
00899
00900 forAll(pointMedialDist, pointI)
00901 {
00902 medialDist[pointI] = Foam::sqrt(pointMedialDist[pointI].distSqr());
00903 }
00904 }
00905
00906
00907 forAll(dispVec, i)
00908 {
00909 dispVec[i] = pointWallDist[i].v();
00910 }
00911
00912
00913 smoothNormals(nSmoothNormals, isMasterEdge, meshPoints, dispVec);
00914
00915
00916 forAll(medialRatio, pointI)
00917 {
00918 scalar wDist2 = pointWallDist[pointI].distSqr();
00919 scalar mDist = medialDist[pointI];
00920
00921 if (wDist2 < sqr(SMALL) && mDist < SMALL)
00922 {
00923 medialRatio[pointI] = 0.0;
00924 }
00925 else
00926 {
00927 medialRatio[pointI] = mDist / (Foam::sqrt(wDist2) + mDist);
00928 }
00929 }
00930
00931 if (debug)
00932 {
00933 Info<< "medialAxisSmoothingInfo :"
00934 << " Writing:" << nl
00935 << " " << dispVec.name()
00936 << " : normalised direction of nearest displacement" << nl
00937 << " " << medialDist.name()
00938 << " : distance to medial axis" << nl
00939 << " " << medialRatio.name()
00940 << " : ratio of medial distance to wall distance" << nl
00941 << endl;
00942 dispVec.write();
00943 medialDist.write();
00944 medialRatio.write();
00945 }
00946 }
00947
00948
00949 void Foam::autoLayerDriver::shrinkMeshMedialDistance
00950 (
00951 motionSmoother& meshMover,
00952 const dictionary& meshQualityDict,
00953 const label nSmoothThickness,
00954 const scalar maxThicknessToMedialRatio,
00955 const label nAllowableErrors,
00956 const label nSnap,
00957 const scalar minCosLayerTermination,
00958
00959 const scalarField& layerThickness,
00960 const scalarField& minThickness,
00961
00962 const pointVectorField& dispVec,
00963 const pointScalarField& medialRatio,
00964 const pointScalarField& medialDist,
00965
00966 List<extrudeMode>& extrudeStatus,
00967 pointField& patchDisp,
00968 labelList& patchNLayers
00969 ) const
00970 {
00971 Info<< "shrinkMeshMedialDistance : Smoothing using Medial Axis ..." << endl;
00972
00973 const polyMesh& mesh = meshMover.mesh();
00974
00975 const indirectPrimitivePatch& pp = meshMover.patch();
00976 const labelList& meshPoints = pp.meshPoints();
00977
00978
00979 PackedBoolList isMasterEdge(syncTools::getMasterEdges(mesh));
00980
00981 labelList meshEdges(pp.nEdges());
00982
00983 forAll(meshEdges, patchEdgeI)
00984 {
00985 const edge& e = pp.edges()[patchEdgeI];
00986
00987 label v0 = pp.meshPoints()[e[0]];
00988 label v1 = pp.meshPoints()[e[1]];
00989 meshEdges[patchEdgeI] = meshTools::findEdge
00990 (
00991 mesh.edges(),
00992 mesh.pointEdges()[v0],
00993 v0,
00994 v1
00995 );
00996 }
00997
00998
00999 scalarField thickness(layerThickness.size());
01000
01001 thickness = mag(patchDisp);
01002
01003 forAll(thickness, patchPointI)
01004 {
01005 if (extrudeStatus[patchPointI] == NOEXTRUDE)
01006 {
01007 thickness[patchPointI] = 0.0;
01008 }
01009 }
01010
01011 label numThicknessRatioExclude = 0;
01012
01013
01014 forAll(meshPoints, patchPointI)
01015 {
01016 if (extrudeStatus[patchPointI] != NOEXTRUDE)
01017 {
01018 label pointI = meshPoints[patchPointI];
01019
01020 scalar mDist = medialDist[pointI];
01021
01022 scalar thicknessRatio = thickness[patchPointI]/(mDist+VSMALL);
01023
01024 if (thicknessRatio > maxThicknessToMedialRatio)
01025 {
01026
01027 thickness[patchPointI] =
01028 0.5*(minThickness[patchPointI]+thickness[patchPointI]);
01029
01030 patchDisp[patchPointI] =
01031 thickness[patchPointI]
01032 * patchDisp[patchPointI]
01033 / (mag(patchDisp[patchPointI]) + VSMALL);
01034 numThicknessRatioExclude++;
01035 }
01036 }
01037 }
01038
01039 reduce(numThicknessRatioExclude, sumOp<label>());
01040 Info<< "shrinkMeshMedialDistance : Reduce layer thickness at "
01041 << numThicknessRatioExclude
01042 << " nodes where thickness to medial axis distance is large " << endl;
01043
01044
01045
01046 findIsolatedRegions
01047 (
01048 pp,
01049 isMasterEdge,
01050 meshEdges,
01051 minCosLayerTermination,
01052 thickness,
01053 extrudeStatus,
01054 patchDisp,
01055 patchNLayers
01056 );
01057
01058
01059 smoothField
01060 (
01061 meshMover,
01062 isMasterEdge,
01063 meshEdges,
01064 minThickness,
01065 nSmoothThickness,
01066 thickness
01067 );
01068
01069 List<pointData> pointWallDist(mesh.nPoints());
01070
01071 const pointField& points = mesh.points();
01072
01073
01074 {
01075
01076 List<pointData> edgeWallDist(mesh.nEdges());
01077 labelList wallPoints(meshPoints.size());
01078
01079
01080 List<pointData> wallInfo(meshPoints.size());
01081
01082 forAll(meshPoints, patchPointI)
01083 {
01084 label pointI = meshPoints[patchPointI];
01085 wallPoints[patchPointI] = pointI;
01086 wallInfo[patchPointI] = pointData
01087 (
01088 points[pointI],
01089 0.0,
01090 thickness[patchPointI],
01091 vector::zero
01092 );
01093 }
01094
01095
01096 PointEdgeWave<pointData> wallDistCalc
01097 (
01098 mesh,
01099 wallPoints,
01100 wallInfo,
01101 pointWallDist,
01102 edgeWallDist,
01103 mesh.globalData().nTotalPoints()
01104 );
01105 }
01106
01107
01108 pointVectorField& displacement = meshMover.displacement();
01109
01110 forAll(displacement, pointI)
01111 {
01112
01113
01114
01115
01116
01117 displacement[pointI] =
01118 -medialRatio[pointI]
01119 *pointWallDist[pointI].s()
01120 *dispVec[pointI];
01121 }
01122
01123
01124 labelList checkFaces(identity(mesh.nFaces()));
01125
01126 Info<< "shrinkMeshMedialDistance : Moving mesh ..." << endl;
01127 scalar oldErrorReduction = -1;
01128
01129 for (label iter = 0; iter < 2*nSnap ; iter++)
01130 {
01131 Info<< "Iteration " << iter << endl;
01132 if (iter == nSnap)
01133 {
01134 Info<< "Displacement scaling for error reduction set to 0." << endl;
01135 oldErrorReduction = meshMover.setErrorReduction(0.0);
01136 }
01137
01138 if
01139 (
01140 meshMover.scaleMesh
01141 (
01142 checkFaces,
01143 List<labelPair>(0),
01144 meshMover.paramDict(),
01145 meshQualityDict,
01146 true,
01147 nAllowableErrors
01148 )
01149 )
01150 {
01151 Info<< "shrinkMeshMedialDistance : Successfully moved mesh" << endl;
01152 break;
01153 }
01154 }
01155
01156 if (oldErrorReduction >= 0)
01157 {
01158 meshMover.setErrorReduction(oldErrorReduction);
01159 }
01160
01161 Info<< "shrinkMeshMedialDistance : Finished moving mesh ..." << endl;
01162 }
01163
01164
01165