diff --git a/applications/solvers/combustion/dieselEngineFoam/createSpray.H b/applications/solvers/combustion/dieselEngineFoam/createSpray.H index b86b3684c29816f5009edddcf7cc6612e11ebe30..ac473957e5d1e86395509f79c2175c4f8039bc4d 100644 --- a/applications/solvers/combustion/dieselEngineFoam/createSpray.H +++ b/applications/solvers/combustion/dieselEngineFoam/createSpray.H @@ -32,7 +32,5 @@ if (dieselSpray.twoD()) gasMass0 *= 2.0*mathematicalConstant::pi/dieselSpray.angleOfWedge(); } -reduce(gasMass0, sumOp<scalar>()); - gasMass0 -= dieselSpray.injectedMass(runTime.value()) - dieselSpray.liquidMass(); diff --git a/applications/solvers/combustion/dieselEngineFoam/spraySummary.H b/applications/solvers/combustion/dieselEngineFoam/spraySummary.H index 907784b4388791a2c167f149384c1872914a9308..5b251e22902437f4b4bf964ee25c3d9c3169e90e 100644 --- a/applications/solvers/combustion/dieselEngineFoam/spraySummary.H +++ b/applications/solvers/combustion/dieselEngineFoam/spraySummary.H @@ -23,8 +23,6 @@ gasMass *= 2.0*mathematicalConstant::pi/dieselSpray.angleOfWedge(); } - reduce(gasMass, sumOp<scalar>()); - scalar addedMass = gasMass - gasMass0; Info<< "Added gas mass................. | " << 1e6*addedMass << " mg" diff --git a/applications/solvers/heatTransfer/buoyantPisoFoam/Make/options b/applications/solvers/heatTransfer/buoyantPisoFoam/Make/options index 9ac482d92edf3dcf8e65f39015dbb1ce96a127ca..f26563fc0fbdcff74dec668f5489bf159778d9ab 100644 --- a/applications/solvers/heatTransfer/buoyantPisoFoam/Make/options +++ b/applications/solvers/heatTransfer/buoyantPisoFoam/Make/options @@ -1,7 +1,6 @@ EXE_INC = \ -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ -I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \ - -I../XiFoam \ -I$(LIB_SRC)/finiteVolume/lnInclude EXE_LIBS = \ diff --git a/applications/solvers/heatTransfer/buoyantPisoFoam/buoyantPisoFoam.C b/applications/solvers/heatTransfer/buoyantPisoFoam/buoyantPisoFoam.C index 18dadabf8baaf398d16e0be06cb69eb726fd7fae..83527f8215130271882402bac0f6d5769ba4f860 100644 --- a/applications/solvers/heatTransfer/buoyantPisoFoam/buoyantPisoFoam.C +++ b/applications/solvers/heatTransfer/buoyantPisoFoam/buoyantPisoFoam.C @@ -70,11 +70,12 @@ int main(int argc, char *argv[]) #include "UEqn.H" + #include "hEqn.H" + // --- PISO loop for (int corr=0; corr<nCorr; corr++) { - #include "hEqn.H" #include "pEqn.H" } diff --git a/applications/solvers/heatTransfer/buoyantPisoFoam/createFields.H b/applications/solvers/heatTransfer/buoyantPisoFoam/createFields.H index a647f0a3ef2a0831cd06f96ab973c58286a0ba9b..103b3ea3bb531684ed48fc5fe74ac8ec588f4d99 100644 --- a/applications/solvers/heatTransfer/buoyantPisoFoam/createFields.H +++ b/applications/solvers/heatTransfer/buoyantPisoFoam/createFields.H @@ -53,12 +53,15 @@ ); Info<< "Creating field DpDt\n" << endl; - volScalarField DpDt = - fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p); + volScalarField DpDt + ( + "DpDt", + fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p) + ); Info<< "Calculating field g.h\n" << endl; volScalarField gh("gh", g & mesh.C()); - surfaceScalarField ghf("gh", g & mesh.Cf()); + surfaceScalarField ghf("ghf", g & mesh.Cf()); dimensionedScalar pRef("pRef", p.dimensions(), thermo->lookup("pRef")); diff --git a/applications/solvers/heatTransfer/buoyantPisoFoam/pEqn.H b/applications/solvers/heatTransfer/buoyantPisoFoam/pEqn.H index 91e190b4cdfa4eeab0151de9126ecab5f5173036..53f6688a6a8438f11c91816941e5d78b5bd47c14 100644 --- a/applications/solvers/heatTransfer/buoyantPisoFoam/pEqn.H +++ b/applications/solvers/heatTransfer/buoyantPisoFoam/pEqn.H @@ -12,8 +12,8 @@ ( fvc::interpolate(rho) *( - (fvc::interpolate(U) & mesh.Sf()) - + fvc::ddtPhiCorr(rUA, rho, U, phi) + (fvc::interpolate(U) & mesh.Sf()) + + fvc::ddtPhiCorr(rUA, rho, U, phi) ) ); diff --git a/applications/solvers/heatTransfer/buoyantSimpleFoam/createFields.H b/applications/solvers/heatTransfer/buoyantSimpleFoam/createFields.H index d26da5cb325560d17f59e3f9a1aed4d3f08acdc5..879ee722b98ec4c6ab21ca66518c22fc31a9105c 100644 --- a/applications/solvers/heatTransfer/buoyantSimpleFoam/createFields.H +++ b/applications/solvers/heatTransfer/buoyantSimpleFoam/createFields.H @@ -53,7 +53,7 @@ Info<< "Calculating field g.h\n" << endl; volScalarField gh("gh", g & mesh.C()); - surfaceScalarField ghf("gh", g & mesh.Cf()); + surfaceScalarField ghf("ghf", g & mesh.Cf()); dimensionedScalar pRef("pRef", p.dimensions(), thermo->lookup("pRef")); diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H index 5a78299a7a7967d47417f9f214ec3d8fd77427d9..34c32b1abf4204864d1cc7268ecf3e5874a25d36 100644 --- a/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H +++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H @@ -103,8 +103,8 @@ public: const dictionary& ); - //- Construct by mapping given solidWallMixedTemperatureCoupledFvPatchScalarField - // onto a new patch + //- Construct by mapping given + // solidWallMixedTemperatureCoupledFvPatchScalarField onto a new patch solidWallMixedTemperatureCoupledFvPatchScalarField ( const solidWallMixedTemperatureCoupledFvPatchScalarField&, diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H index bc4590a4286e71d0db721d6f5db9dde70345f810..35a64418a8c6cbd1d488970f1d665420a2f752b6 100644 --- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H +++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H @@ -4,7 +4,7 @@ volScalarField& rho = rhoFluid[i]; volScalarField& K = KFluid[i]; volVectorField& U = UFluid[i]; - surfaceScalarField phi = phiFluid[i]; + surfaceScalarField& phi = phiFluid[i]; compressible::turbulenceModel& turb = turbulence[i]; volScalarField& DpDt = DpDtFluid[i]; const volScalarField& gh = ghFluid[i]; diff --git a/applications/solvers/multiphase/interFoam/createFields.H b/applications/solvers/multiphase/interFoam/createFields.H index af349d79174e164e50dca3d8d48b49b0f8c1349a..53dd01672a274de04ea0c4d5979fb3aaa97a7a7f 100644 --- a/applications/solvers/multiphase/interFoam/createFields.H +++ b/applications/solvers/multiphase/interFoam/createFields.H @@ -85,7 +85,7 @@ Info<< "Calculating field g.h\n" << endl; volScalarField gh("gh", g & mesh.C()); - surfaceScalarField ghf("gh", g & mesh.Cf()); + surfaceScalarField ghf("ghf", g & mesh.Cf()); volScalarField p diff --git a/applications/solvers/multiphase/multiphaseInterFoam/createFields.H b/applications/solvers/multiphase/multiphaseInterFoam/createFields.H index aa62d0f2a177af49e20ed3cb49ce9ba605029037..9119631d0cc34e4bd366c7f00c43379490a7d71c 100644 --- a/applications/solvers/multiphase/multiphaseInterFoam/createFields.H +++ b/applications/solvers/multiphase/multiphaseInterFoam/createFields.H @@ -47,7 +47,7 @@ Info<< "Calculating field g.h\n" << endl; volScalarField gh("gh", g & mesh.C()); - surfaceScalarField ghf("gh", g & mesh.Cf()); + surfaceScalarField ghf("ghf", g & mesh.Cf()); volScalarField p diff --git a/applications/solvers/multiphase/settlingFoam/createFields.H b/applications/solvers/multiphase/settlingFoam/createFields.H index 400f89c43bce66ce29f3d9cfe79e4a9cc84be9b3..b13649c3124ddaf5ba06c5e13e3b090b746798ec 100644 --- a/applications/solvers/multiphase/settlingFoam/createFields.H +++ b/applications/solvers/multiphase/settlingFoam/createFields.H @@ -339,4 +339,4 @@ ); Info<< "Calculating field (g.h)f\n" << endl; - surfaceScalarField ghf = surfaceScalarField("gh", g & mesh.Cf()); + surfaceScalarField ghf = surfaceScalarField("ghf", g & mesh.Cf()); diff --git a/applications/test/List/ListTest.C b/applications/test/List/ListTest.C index bc8901b03beacc65c399053ab5c5d49532009edf..d4834cb1db2b02bc79f4d6e8508e9f3b3361c695 100644 --- a/applications/test/List/ListTest.C +++ b/applications/test/List/ListTest.C @@ -43,31 +43,33 @@ using namespace Foam; int main(int argc, char *argv[]) { - List<vector> list(IStringStream("1 ((0 1 2))")()); - Info<< list << endl; + List<vector> list1(IStringStream("1 ((0 1 2))")()); + Info<< "list1: " << list1 << endl; List<vector> list2(IStringStream("((0 1 2) (3 4 5) (6 7 8))")()); - Info<< list2 << endl; + Info<< "list2: " << list2 << endl; + + list1.append(list2); + Info<< "list1.append(list2): " << list1 << endl; Info<< findIndex(list2, vector(3, 4, 5)) << endl; list2.setSize(10, vector(1, 2, 3)); - Info<< list2 << endl; + Info<< "list2: " << list2 << endl; List<vector> list3(list2.xfer()); Info<< "Transferred via the xfer() method" << endl; - Info<< list2 << nl - << list3 << endl; + Info<< "list2: " << list2 << nl + << "list3: " << list3 << endl; // Subset const labelList map(IStringStream("2 (0 2)")()); List<vector> subList3(list3, map); Info<< "Elements " << map << " out of " << list3 - << " : " << subList3 << endl; + << " => " << subList3 << endl; return 0; } - // ************************************************************************* // diff --git a/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C b/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C index 364aed2e16c4196938e76e0bd9839f67899f470f..c18e0af978a147ca1b9b2dc522f6d8773f85b947 100644 --- a/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C +++ b/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C @@ -182,6 +182,7 @@ int main(int argc, char *argv[]) if (overwrite) { mesh.setInstance(oldInstance); + meshCutter.setInstance(oldInstance); } Info<< "Writing mesh to " << runTime.timeName() << endl; diff --git a/applications/utilities/mesh/conversion/writeMeshObj/writeMeshObj.C b/applications/utilities/mesh/conversion/writeMeshObj/writeMeshObj.C index d8042fdaa8a2b522f332592793817d67e50b4e1e..9eaaf2c199ffb24ce064ab888d5739b8ec63160e 100644 --- a/applications/utilities/mesh/conversion/writeMeshObj/writeMeshObj.C +++ b/applications/utilities/mesh/conversion/writeMeshObj/writeMeshObj.C @@ -344,6 +344,7 @@ int main(int argc, char *argv[]) argList::validOptions.insert("point", "pointI"); argList::validOptions.insert("cellSet", "setName"); argList::validOptions.insert("faceSet", "setName"); +# include "addRegionOption.H" # include "setRootCase.H" # include "createTime.H" @@ -364,7 +365,7 @@ int main(int argc, char *argv[]) instantList timeDirs = timeSelector::select0(runTime, args); -# include "createPolyMesh.H" +# include "createNamedPolyMesh.H" forAll(timeDirs, timeI) { diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeMesh.C b/applications/utilities/mesh/generation/extrudeMesh/extrudeMesh.C index 0bb37f6727d2be3001f3fc05265ed45d263e9cec..37860e27b25d217c4ddef3a765058fa6f7b1d8fb 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeMesh.C +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeMesh.C @@ -52,19 +52,18 @@ using namespace Foam; int main(int argc, char *argv[]) { -# include "setRoots.H" -# include "createTimeExtruded.H" + #include "setRoots.H" + #include "createTimeExtruded.H" - - if (args.options().found("sourceRoot") == args.options().found("surface")) + if (args.options().found("sourceCase") == args.options().found("surface")) { FatalErrorIn(args.executable()) - << "Need to specify either -sourceRoot/Case/Patch or -surface" - << " option to specify the source of the patch to extrude" + << "Specify either -sourceCase and -sourcePatch" + " or -surface options\n" + " to specify the source of the patch to extrude" << exit(FatalError); } - autoPtr<extrudedMesh> meshPtr(NULL); autoPtr<extrudeModel> model @@ -84,23 +83,24 @@ int main(int argc, char *argv[]) ) ); - if (args.options().found("sourceRoot")) + if (args.options().found("sourceCase")) { - fileName rootDirSource(args.options()["sourceRoot"]); - fileName caseDirSource(args.options()["sourceCase"]); - fileName patchName(args.options()["sourcePatch"]); + fileName sourceCasePath(args.options()["sourceCase"]); + fileName sourceRootDir = sourceCasePath.path(); + fileName sourceCaseDir = sourceCasePath.name(); + word patchName(args.options()["sourcePatch"]); Info<< "Extruding patch " << patchName - << " on mesh " << rootDirSource << ' ' << caseDirSource << nl + << " on mesh " << sourceCasePath << nl << endl; Time runTime ( Time::controlDictName, - rootDirSource, - caseDirSource + sourceRootDir, + sourceCaseDir ); -# include "createPolyMesh.H" + #include "createPolyMesh.H" label patchID = mesh.boundaryMesh().findPatchID(patchName); @@ -171,7 +171,7 @@ int main(int argc, char *argv[]) fMesh, model() ) - ); + ); } extrudedMesh& mesh = meshPtr(); @@ -180,7 +180,7 @@ int main(int argc, char *argv[]) const vector span = bb.span(); const scalar mergeDim = 1E-4 * bb.minDim(); - Pout<< "Mesh bounding box:" << bb << nl + Info<< "Mesh bounding box:" << bb << nl << " with span:" << span << nl << "Merge distance :" << mergeDim << nl << endl; @@ -201,7 +201,7 @@ int main(int argc, char *argv[]) // ~~~~~~~~~~~~~~ { - Pout<< "Collapsing edges < " << mergeDim << " ..." << nl << endl; + Info<< "Collapsing edges < " << mergeDim << " ..." << nl << endl; // Edge collapsing engine edgeCollapser collapser(mesh); @@ -217,7 +217,7 @@ int main(int argc, char *argv[]) if (d < mergeDim) { - Pout<< "Merging edge " << e << " since length " << d + Info<< "Merging edge " << e << " since length " << d << " << " << mergeDim << nl; // Collapse edge to e[0] @@ -252,8 +252,8 @@ int main(int argc, char *argv[]) if (args.options().found("mergeFaces")) { - Pout<< "Assuming full 360 degree axisymmetric case;" - << " stitching faces on patches " + Info<< "Assuming full 360 degree axisymmetric case;" + << " stitching faces on patches " << patches[origPatchID].name() << " and " << patches[otherPatchID].name() << " together ..." << nl << endl; diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.C b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.C index 27dec921b720873f35b0e7a6b7a068c7776e7cc4..6da971a1bf0e2d048976c808abbaa0dea944908c 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.C +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.C @@ -48,7 +48,7 @@ wedge::wedge(const dictionary& dict) : extrudeModel(typeName, dict), axisPt_(coeffDict_.lookup("axisPt")), - axisNormal_(coeffDict_.lookup("axisNormal")), + axis_(coeffDict_.lookup("axis")), angle_ ( readScalar(coeffDict_.lookup("angle")) @@ -96,7 +96,7 @@ point wedge::operator() // of surface point and surface normal. point d = surfacePoint - axisPt_; - d -= (axisNormal_ & d)*axisNormal_; + d -= (axis_ & d)*axis_; scalar dMag = mag(d); @@ -107,7 +107,7 @@ point wedge::operator() if (dMag > VSMALL) { - vector n = (d/dMag) ^ axisNormal_; + vector n = (d/dMag) ^ axis_; rotatedPoint += + cos(sliceAngle)*d @@ -124,4 +124,3 @@ point wedge::operator() } // End namespace Foam // ************************************************************************* // - diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.H b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.H index 38b862630d5c804e1d01691baf0ae89fb70cba39..39c4b4a2d3073ade350e8c5db80f6faea29b5d5b 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.H +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.H @@ -60,13 +60,13 @@ class wedge { // Private data - //- point on axis + //- Point on axis const point axisPt_; - //- normalized direction of axis - const vector axisNormal_; + //- Normalized direction of axis + const vector axis_; - //- overall angle (radians) + //- Overall angle (radians) const scalar angle_; @@ -80,6 +80,7 @@ public: //- Construct from components wedge(const dictionary& dict); + //- Destrcuctor ~wedge(); diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeProperties b/applications/utilities/mesh/generation/extrudeMesh/extrudeProperties index c9b7977508b29c2e0f6fa454dca2af26c7fe3874..ecbe160a150ab5f1b16ecad4e5fd423a64edc278 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeProperties +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeProperties @@ -24,7 +24,7 @@ nLayers 1; wedgeCoeffs { axisPt (0 0 0); - axisNormal (0 -1 0); + axis (0 -1 0); angle 2.0; } @@ -47,4 +47,3 @@ sigmaRadialCoeffs // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - diff --git a/applications/utilities/mesh/generation/extrudeMesh/setRoots.H b/applications/utilities/mesh/generation/extrudeMesh/setRoots.H index 255949426bae2e399cd8d03f50c812b5145ed9ca..9c13db28d19f93ec3fc4bb9b7be943bc721eed33 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/setRoots.H +++ b/applications/utilities/mesh/generation/extrudeMesh/setRoots.H @@ -1,7 +1,6 @@ argList::validArgs.clear(); argList::noParallel(); - argList::validOptions.insert("sourceRoot", "source root"); argList::validOptions.insert("sourceCase", "source case"); argList::validOptions.insert("sourcePatch", "source patch"); @@ -15,4 +14,3 @@ { FatalError.exit(); } - diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict index cc975eb9708ac93b1a478343b34363b0ef3a0587..205c767600bede32ffba05d4a2bd0873598b7511 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict @@ -274,6 +274,14 @@ addLayersControls // Create buffer region for new layer terminations nBufferCellsNoExtrude 0; + + + // Overall max number of layer addition iterations + nLayerIter 50; + + // Max number of iterations after which relaxed meshQuality controls + // get used. + nRelaxedIter 20; } @@ -335,6 +343,16 @@ meshQualityControls nSmoothScale 4; //- amount to scale back displacement at error points errorReduction 0.75; + + + + // Optional : some meshing phases allow usage of relaxed rules. + // See e.g. addLayersControls::nRelaxedIter. + relaxed + { + //- Maximum non-orthogonality allowed. Set to 180 to disable. + maxNonOrtho 75; + } } diff --git a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C index 582a6ca9bf6b2bb9da89ca9397576fb5c1bce45e..e71a5f11c0b2ff259f3d3f6b0f997df0efd29f88 100644 --- a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C +++ b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C @@ -57,6 +57,7 @@ Description #include "EdgeMap.H" #include "syncTools.H" #include "ReadFields.H" +#include "directMappedWallPolyPatch.H" using namespace Foam; @@ -1022,13 +1023,13 @@ EdgeMap<label> addRegionPatches ( mesh, regionNames[e[0]] + "_to_" + regionNames[e[1]], - polyPatch::typeName + directMappedWallPolyPatch::typeName ); addPatch ( mesh, regionNames[e[1]] + "_to_" + regionNames[e[0]], - polyPatch::typeName + directMappedWallPolyPatch::typeName ); Info<< "For interface between region " << e[0] @@ -1100,7 +1101,6 @@ EdgeMap<label> addRegionPatches //} -//XXXXXXXXX // Find region that covers most of cell zone label findCorrespondingRegion ( @@ -1152,7 +1152,6 @@ label findCorrespondingRegion return regionI; } -//XXXXXXXXX //// Checks if cellZone has corresponding cellRegion. diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C index 5edafcf561611abb7cab29944b824ccd6bf21cc7..26ee3e062a4b1ae9087b6a37b73aa4bb2bd60c76 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C +++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C @@ -83,6 +83,7 @@ Usage int main(int argc, char *argv[]) { argList::noParallel(); +# include "addRegionOption.H" argList::validOptions.insert("cellDist", ""); argList::validOptions.insert("copyUniform", ""); argList::validOptions.insert("fields", ""); @@ -92,6 +93,17 @@ int main(int argc, char *argv[]) # include "setRootCase.H" + word regionName = fvMesh::defaultRegion; + word regionDir = word::null; + + if (args.options().found("region")) + { + regionName = args.options()["region"]; + regionDir = regionName; + Info<< "Decomposing mesh " << regionName << nl << endl; + } + + bool writeCellDist(args.options().found("cellDist")); bool copyUniform(args.options().found("copyUniform")); bool decomposeFieldsOnly(args.options().found("fields")); @@ -105,7 +117,17 @@ int main(int argc, char *argv[]) // determine the existing processor count directly label nProcs = 0; - while (isDir(runTime.path()/(word("processor") + name(nProcs)))) + while + ( + isDir + ( + runTime.path() + /(word("processor") + name(nProcs)) + /runTime.constant() + /regionDir + /polyMesh::meshSubDir + ) + ) { ++nProcs; } @@ -119,6 +141,7 @@ int main(int argc, char *argv[]) ( "decomposeParDict", runTime.time().system(), + regionDir, // use region if non-standard runTime, IOobject::MUST_READ, IOobject::NO_WRITE, @@ -196,7 +219,7 @@ int main(int argc, char *argv[]) ( IOobject ( - domainDecomposition::defaultRegion, + regionName, runTime.timeName(), runTime ) @@ -219,7 +242,7 @@ int main(int argc, char *argv[]) ( runTime.path() / mesh.facesInstance() - / polyMesh::defaultRegion + / regionName / "cellDecomposition" ); @@ -383,7 +406,12 @@ int main(int argc, char *argv[]) label i = 0; - forAllIter(Cloud<indexedParticle>, lagrangianPositions[cloudI], iter) + forAllIter + ( + Cloud<indexedParticle>, + lagrangianPositions[cloudI], + iter + ) { iter().index() = i++; @@ -405,7 +433,8 @@ int main(int argc, char *argv[]) if (!cellParticles[cloudI][celli]) { - cellParticles[cloudI][celli] = new SLList<indexedParticle*>(); + cellParticles[cloudI][celli] = new SLList<indexedParticle*> + (); } cellParticles[cloudI][celli]->append(&iter()); @@ -513,7 +542,7 @@ int main(int argc, char *argv[]) ( IOobject ( - fvMesh::defaultRegion, + regionName, processorDb.timeName(), processorDb ) diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposeParDict b/applications/utilities/parallelProcessing/decomposePar/decomposeParDict index 288797ed1e444b4e1d76b9bd9c053bd7bdbc6873..98ec9b7087f53d7a33edffabac31de7f0b2b7e5e 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposeParDict +++ b/applications/utilities/parallelProcessing/decomposePar/decomposeParDict @@ -19,7 +19,7 @@ FoamFile numberOfSubdomains 4; -// preservePatches (inlet); +//- Keep owner and neighbour on same processor for faces in zones: // preserveFaceZones (heater solid1 solid3); method simple; diff --git a/applications/utilities/parallelProcessing/decomposePar/distributeCells.C b/applications/utilities/parallelProcessing/decomposePar/distributeCells.C index ad78b2a9142c0f1dfa0352b89bc786555d469b46..af47af244ff4848db0587e9db02a44f21cde5574 100644 --- a/applications/utilities/parallelProcessing/decomposePar/distributeCells.C +++ b/applications/utilities/parallelProcessing/decomposePar/distributeCells.C @@ -45,35 +45,6 @@ void domainDecomposition::distributeCells() labelHashSet sameProcFaces; - if (decompositionDict_.found("preservePatches")) - { - wordList pNames(decompositionDict_.lookup("preservePatches")); - - Info<< "Keeping owner and neighbour of faces in patches " << pNames - << " on same processor" << endl; - - const polyBoundaryMesh& patches = boundaryMesh(); - - forAll(pNames, i) - { - label patchI = patches.findPatchID(pNames[i]); - - if (patchI == -1) - { - FatalErrorIn("domainDecomposition::distributeCells()") - << "Unknown preservePatch " << pNames[i] - << endl << "Valid patches are " << patches.names() - << exit(FatalError); - } - - const polyPatch& pp = patches[patchI]; - - forAll(pp, i) - { - sameProcFaces.insert(pp.start() + i); - } - } - } if (decompositionDict_.found("preserveFaceZones")) { wordList zNames(decompositionDict_.lookup("preserveFaceZones")); @@ -104,14 +75,6 @@ void domainDecomposition::distributeCells() } } - if (sameProcFaces.size()) - { - Info<< "Selected " << sameProcFaces.size() - << " faces whose owner and neighbour cell should be kept on the" - << " same processor" << endl; - } - - // Construct decomposition method and either do decomposition on // cell centres or on agglomeration @@ -129,6 +92,10 @@ void domainDecomposition::distributeCells() } else { + Info<< "Selected " << sameProcFaces.size() + << " faces whose owner and neighbour cell should be kept on the" + << " same processor" << endl; + // Faces where owner and neighbour are not 'connected' (= all except // sameProcFaces) boolList blockedFace(nFaces(), true); diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C index 989d384e40325e47deda38efa26df2221a4c4d70..2940577d163722f8dcabbd761ef70215f252d77b 100644 --- a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C +++ b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C @@ -268,7 +268,7 @@ bool domainDecomposition::writeDecomposition() ( IOobject ( - polyMesh::defaultRegion, + this->polyMesh::name(), // region name of undecomposed mesh "constant", processorDb ), diff --git a/applications/utilities/surface/surfaceCheck/surfaceCheck.C b/applications/utilities/surface/surfaceCheck/surfaceCheck.C index e7b789007475cfd40617116532e1e0a98a0cc3d8..d714c19ec36e5bc5be435b9ac3a02349274954f2 100644 --- a/applications/utilities/surface/surfaceCheck/surfaceCheck.C +++ b/applications/utilities/surface/surfaceCheck/surfaceCheck.C @@ -32,6 +32,7 @@ License #include "OFstream.H" #include "surfaceIntersection.H" #include "SortableList.H" +#include "PatchTools.H" using namespace Foam; @@ -171,11 +172,11 @@ int main(int argc, char *argv[]) argList::validArgs.clear(); argList::validArgs.append("surface file"); - argList::validOptions.insert("noSelfIntersection", ""); + argList::validOptions.insert("checkSelfIntersection", ""); argList::validOptions.insert("verbose", ""); argList args(argc, argv); - bool checkSelfIntersection = !args.options().found("noSelfIntersection"); + bool checkSelfIntersection = args.options().found("checkSelfIntersection"); bool verbose = args.options().found("verbose"); fileName surfFileName(args.additionalArgs()[0]); @@ -596,13 +597,14 @@ int main(int argc, char *argv[]) // Check orientation // ~~~~~~~~~~~~~~~~~ - boolList borderEdge(surf.checkOrientation(false)); + labelHashSet borderEdge(surf.size()/1000); + PatchTools::checkOrientation(surf, false, &borderEdge); // // Colour all faces into zones using borderEdge // labelList normalZone; - label numNormalZones = surf.markZones(borderEdge, normalZone); + label numNormalZones = PatchTools::markZones(surf, borderEdge, normalZone); Pout<< endl << "Number of zones (connected area with consistent normal) : " diff --git a/applications/utilities/surface/surfaceConvert/surfaceConvert.C b/applications/utilities/surface/surfaceConvert/surfaceConvert.C index 311dab28f66f01986d584df1bf96aaa237e8a645..fd7b223827334261083e944fb9d559be218c4106 100644 --- a/applications/utilities/surface/surfaceConvert/surfaceConvert.C +++ b/applications/utilities/surface/surfaceConvert/surfaceConvert.C @@ -115,15 +115,13 @@ int main(int argc, char *argv[]) } Info<< "writing " << exportName; - if (scaleFactor <= 0) + if (scaleFactor > 0) { - Info<< " without scaling" << endl; - } - else - { - Info<< " with scaling " << scaleFactor << endl; + Info<< " with scaling " << scaleFactor; surf.scalePoints(scaleFactor); } + Info<< endl; + surf.write(exportName, sortByRegion); Info<< "\nEnd\n" << endl; diff --git a/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C b/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C index 3a48a5deda74c71e13ace6dea886cb5b3fa03c35..4f607e89fb15b477ddc6238805068db482c5d80a 100644 --- a/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C +++ b/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C @@ -73,7 +73,7 @@ int main(int argc, char *argv[]) argList::noParallel(); argList::validArgs.append("inputFile"); argList::validArgs.append("outputFile"); - argList::validOptions.insert("clean", "scale"); + argList::validOptions.insert("clean", ""); argList::validOptions.insert("scaleIn", "scale"); argList::validOptions.insert("scaleOut", "scale"); argList::validOptions.insert("dict", "coordinateSystemsDict"); diff --git a/applications/utilities/surface/surfaceMeshExport/surfaceMeshExport.C b/applications/utilities/surface/surfaceMeshExport/surfaceMeshExport.C index 41c8a43d6dcea882f0d6e4c3c3703d6d11509996..34d93c93ebecb6e0f51f905366c33342b365fde4 100644 --- a/applications/utilities/surface/surfaceMeshExport/surfaceMeshExport.C +++ b/applications/utilities/surface/surfaceMeshExport/surfaceMeshExport.C @@ -76,7 +76,7 @@ int main(int argc, char *argv[]) argList::noParallel(); argList::validArgs.append("outputFile"); argList::validOptions.insert("name", "name"); - argList::validOptions.insert("clean", "scale"); + argList::validOptions.insert("clean", ""); argList::validOptions.insert("scaleIn", "scale"); argList::validOptions.insert("scaleOut", "scale"); argList::validOptions.insert("dict", "coordinateSystemsDict"); diff --git a/applications/utilities/surface/surfaceMeshImport/surfaceMeshImport.C b/applications/utilities/surface/surfaceMeshImport/surfaceMeshImport.C index 01ef15d74e60c8bd81b08b9c8842c2aed9c75d77..0cb131e4ebefded7fb56483c137ed23f55b3fc86 100644 --- a/applications/utilities/surface/surfaceMeshImport/surfaceMeshImport.C +++ b/applications/utilities/surface/surfaceMeshImport/surfaceMeshImport.C @@ -76,7 +76,7 @@ int main(int argc, char *argv[]) argList::noParallel(); argList::validArgs.append("inputFile"); argList::validOptions.insert("name", "name"); - argList::validOptions.insert("clean", "scale"); + argList::validOptions.insert("clean", ""); argList::validOptions.insert("scaleIn", "scale"); argList::validOptions.insert("scaleOut", "scale"); argList::validOptions.insert("dict", "coordinateSystemsDict"); diff --git a/etc/controlDict b/etc/controlDict index 5cbe331fe591645ef53c22cab6b50f499a53427a..65058af1a6c6a324f826be3d8b22ec9425195b96 100644 --- a/etc/controlDict +++ b/etc/controlDict @@ -360,7 +360,7 @@ DebugSwitches diagonal 0; dictionary 0; dimensionSet 1; - directMapped 0; + directMappedBase 0; directMappedPatch 0; directMappedVelocityFlux 0; directionMixed 0; diff --git a/src/OpenFOAM/containers/Lists/List/List.C b/src/OpenFOAM/containers/Lists/List/List.C index 6d20e2b3b72af3b5ec441d8c88668f2c9158b83c..429c91f820675d4ead0d17b1827dcca15fd9fbae 100644 --- a/src/OpenFOAM/containers/Lists/List/List.C +++ b/src/OpenFOAM/containers/Lists/List/List.C @@ -404,6 +404,61 @@ void Foam::List<T>::clear() } +template<class T> +void Foam::List<T>::append(const UList<T>& lst) +{ + if (this == &lst) + { + FatalErrorIn + ( + "List<T>::append(const UList<T>&)" + ) << "attempted appending to self" << abort(FatalError); + } + + label nextFree = this->size_; + setSize(nextFree + lst.size()); + + forAll(lst, elemI) + { + this->operator[](nextFree++) = lst[elemI]; + } +} + + +template<class T> +void Foam::List<T>::append(const UIndirectList<T>& lst) +{ + label nextFree = this->size_; + setSize(nextFree + lst.size()); + + forAll(lst, elemI) + { + this->operator[](nextFree++) = lst[elemI]; + } +} + + +template<class T> +void Foam::List<T>::append(const SLList<T>& lst) +{ + if (lst.size()) + { + label nextFree = this->size_; + setSize(nextFree + lst.size()); + + for + ( + typename SLList<T>::const_iterator iter = lst.begin(); + iter != lst.end(); + ++iter + ) + { + this->operator[](nextFree++) = iter(); + } + } +} + + // Transfer the contents of the argument List into this List // and anull the argument list template<class T> @@ -559,12 +614,9 @@ void Foam::List<T>::operator=(const IndirectList<T>& lst) if (this->size_) this->v_ = new T[this->size_]; } - if (this->size_) + forAll(*this, i) { - forAll(*this, i) - { - this->operator[](i) = lst[i]; - } + this->operator[](i) = lst[i]; } } @@ -581,12 +633,9 @@ void Foam::List<T>::operator=(const UIndirectList<T>& lst) if (this->size_) this->v_ = new T[this->size_]; } - if (this->size_) + forAll(*this, i) { - forAll(*this, i) - { - this->operator[](i) = lst[i]; - } + this->operator[](i) = lst[i]; } } @@ -603,12 +652,9 @@ void Foam::List<T>::operator=(const BiIndirectList<T>& lst) if (this->size_) this->v_ = new T[this->size_]; } - if (this->size_) + forAll(*this, i) { - forAll(*this, i) - { - this->operator[](i) = lst[i]; - } + this->operator[](i) = lst[i]; } } diff --git a/src/OpenFOAM/containers/Lists/List/List.H b/src/OpenFOAM/containers/Lists/List/List.H index 86876cff713e4bbba54302df8a51bb127370a9d0..5961ff174793741a484f7955872108c471791d7b 100644 --- a/src/OpenFOAM/containers/Lists/List/List.H +++ b/src/OpenFOAM/containers/Lists/List/List.H @@ -109,7 +109,7 @@ public: List(const List<T>&); //- Construct by transferring the parameter contents - List(const Xfer<List<T> >&); + List(const Xfer< List<T> >&); //- Construct as copy or re-use as specified. List(List<T>&, bool reUse); @@ -181,6 +181,15 @@ public: //- Clear the list, i.e. set size to zero. void clear(); + //- Append a List at the end of this list + void append(const UList<T>&); + + //- Append a UIndirectList at the end of this list + void append(const UIndirectList<T>&); + + //- Append a SLList at the end of this list + void append(const SLList<T>&); + //- Transfer the contents of the argument List into this List // and annull the argument list. void transfer(List<T>&); @@ -195,7 +204,7 @@ public: void transfer(SortableList<T>&); //- Transfer contents to the Xfer container - inline Xfer<List<T> > xfer(); + inline Xfer< List<T> > xfer(); //- Return subscript-checked element of UList. inline T& newElmt(const label); diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H index af0f5cb5e03940d22f44d0f791650f954430e69e..1e6070e8368ad3a93d765fa112f0febe4ecb9452 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H @@ -26,7 +26,7 @@ Class Foam::PackedList Description - A Dynamically allocatable list of packed unsigned ints. + A dynamically allocatable list of packed unsigned integers. The list resizing is similar to DynamicList, thus the methods clear() and setSize() behave like their DynamicList counterparts and the methods @@ -38,7 +38,7 @@ Note In a const context, the '[]' operator simply returns the stored value, with out-of-range elements returned as zero. In a non-const context, the '[]' operator returns an iteratorBase, which - may not have a valid reference for out-of-range elements. + might not have a valid reference for out-of-range elements. The iteratorBase class handles the assignment of new values. Using the iteratorBase as a proxy allows assignment of values @@ -50,11 +50,11 @@ Note @endcode Using get() or the '[]' operator are similarly fast. Looping and reading - with an iterator is approx. 15% slower, but can be more flexible. + via an iterator is approx. 15% slower, but can be more flexible. Using the set() operator (and the '[]' operator) are marginally slower - (approx. 5%) than using an iterator, but the set() method has an - advantage that it also returns a bool if the value changed. This can be + (approx. 5%) than using an iterator, but the set() method has the + advantage of also returning a bool if the value changed. This can be useful for branching on changed values. @code @@ -65,7 +65,7 @@ Note The lazy evaluation used means that reading an out-of-range element returns zero, but does not affect the list size. Even in a non-const - context, only the assigment causes the element to be created. + context, only the assigment itself causes the element to be created. For example, @code list.resize(4); @@ -171,7 +171,7 @@ public: inline PackedList(const PackedList<nBits>&); //- Construct by transferring the parameter contents - inline PackedList(const Xfer<PackedList<nBits> >&); + inline PackedList(const Xfer< PackedList<nBits> >&); //- Construct from a list of labels PackedList(const UList<label>&); @@ -240,7 +240,6 @@ public: //- Reserve allocation space for at least this size. // Never shrinks the allocated size. - // Optionally provide an initialization value for new elements. inline void reserve(const label); //- Clear the list, i.e. set addressable size to zero. @@ -258,7 +257,7 @@ public: inline void transfer(PackedList<nBits>&); //- Transfer contents to the Xfer container - inline Xfer<PackedList<nBits> > xfer(); + inline Xfer< PackedList<nBits> > xfer(); // Member operators @@ -413,7 +412,7 @@ public: //- iterator set to the beginning of the PackedList inline iterator begin(); - //- iterator set to beyond the end of the HashTable + //- iterator set to beyond the end of the PackedList inline iterator end(); diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C index 01b92caceef2b29eddb3b53cfd10a1e2586eefca..482abb8bf38c3bccc018811a791b0df56f1d97ba 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C +++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C @@ -224,7 +224,16 @@ Foam::Istream& Foam::ISstream::read(token& t) } else { - t = label(atol(numberBuffer)); + long lt = atol(numberBuffer); + t = label(lt); + + // If the integer is too large to be represented as a label + // return it as a scalar + if (t.labelToken() != lt) + { + isScalar = true; + t = scalar(atof(numberBuffer)); + } } } else diff --git a/src/OpenFOAM/matrices/solution/solution.C b/src/OpenFOAM/matrices/solution/solution.C index 8c37d28b427786e3b932ed6bccaf55c5c0fcb1ed..030b3df9ae1296ebc8d42fe69b725e89a29503d4 100644 --- a/src/OpenFOAM/matrices/solution/solution.C +++ b/src/OpenFOAM/matrices/solution/solution.C @@ -134,7 +134,7 @@ Foam::label Foam::solution::upgradeSolverDict // write out information to help people adjust to the new syntax - if (verbose) + if (verbose && Pstream::master()) { Info<< "// using new solver syntax:\n" << iter().keyword() << subdict << endl; diff --git a/src/OpenFOAM/meshes/boundBox/boundBox.H b/src/OpenFOAM/meshes/boundBox/boundBox.H index e41b6efa46139795a8bb8f83f10e2329bc375fd0..38b852ef66a429a414911dd04545d9568e79745a 100644 --- a/src/OpenFOAM/meshes/boundBox/boundBox.H +++ b/src/OpenFOAM/meshes/boundBox/boundBox.H @@ -174,7 +174,7 @@ public: // Query - //- Completely contains other boundingBox? (inside or on edge) + //- Overlaps/touches boundingBox? bool overlaps(const boundBox& bb) const { return diff --git a/src/OpenFOAM/meshes/meshShapes/face/face.H b/src/OpenFOAM/meshes/meshShapes/face/face.H index 07dd39f93fc2cfad8fe3225e0704ecd54e737f1f..25a4f8fbce5b70f44c74ffd36a7c42c45e14ce99 100644 --- a/src/OpenFOAM/meshes/meshShapes/face/face.H +++ b/src/OpenFOAM/meshes/meshShapes/face/face.H @@ -222,16 +222,16 @@ public: ) const; //- Fast intersection with a ray. - // For a hit, the pointHit.distance() is the line parameter t : - // intersection=p+t*q. Only defined for FULL_RAY or - // HALF_RAY. + // Does face-center decomposition and returns triangle intersection + // point closest to p. See triangle::intersection for details. pointHit intersection ( const point& p, const vector& q, const point& ctr, const pointField& meshPoints, - const intersection::algorithm alg + const intersection::algorithm alg, + const scalar tol = 0.0 ) const; //- Return nearest point to face diff --git a/src/OpenFOAM/meshes/meshShapes/face/faceIntersection.C b/src/OpenFOAM/meshes/meshShapes/face/faceIntersection.C index b514af77499d00e66844fff35bcf9e78c48e0c9e..c5f9a80250b00e433d139011a9e2d2c7b33b28a3 100644 --- a/src/OpenFOAM/meshes/meshShapes/face/faceIntersection.C +++ b/src/OpenFOAM/meshes/meshShapes/face/faceIntersection.C @@ -136,7 +136,8 @@ Foam::pointHit Foam::face::intersection const vector& q, const point& ctr, const pointField& meshPoints, - const intersection::algorithm alg + const intersection::algorithm alg, + const scalar tol ) const { scalar nearestHitDist = VGREAT; @@ -154,7 +155,7 @@ Foam::pointHit Foam::face::intersection meshPoints[f[pI]], meshPoints[f[fcIndex(pI)]], ctr - ).intersection(p, q, alg); + ).intersection(p, q, alg, tol); if (curHit.hit()) { diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C index f4cbe6e2f3a60e247b7ca2a384b3845c3dc58eec..4bd093e6412905bda8b5402d828fbdd362777ab0 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C @@ -205,7 +205,7 @@ Foam::mapDistribute::mapDistribute const labelList& recvProcs ) : - constructSize_(sendProcs.size()), + constructSize_(0), schedulePtr_() { if (sendProcs.size() != recvProcs.size()) @@ -266,6 +266,8 @@ Foam::mapDistribute::mapDistribute { // I am the receiver. constructMap_[sendProc][nRecv[sendProc]++] = sampleI; + // Largest entry inside constructMap + constructSize_ = sampleI+1; } } } diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H index 4687c8a4b1d080087f06d3845361fd18b50513ec..3ccf81047697164d8cb2e7ed2a004a9feb8157f5 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H @@ -131,18 +131,36 @@ public: return constructSize_; } + //- Constructed data size + label& constructSize() + { + return constructSize_; + } + //- From subsetted data back to original data const labelListList& subMap() const { return subMap_; } + //- From subsetted data back to original data + labelListList& subMap() + { + return subMap_; + } + //- From subsetted data to new reconstructed data const labelListList& constructMap() const { return constructMap_; } + //- From subsetted data to new reconstructed data + labelListList& constructMap() + { + return constructMap_; + } + //- Calculate a schedule. See above. static List<labelPair> schedule ( diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C index 08e12b876eda2167a404c8879bda855ddd2ada2e..5f5d7a9fcf9793fe4f0c0df04e8c60e87e9c6d4f 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C @@ -52,13 +52,8 @@ void Foam::mapDistribute::distribute if (domain != Pstream::myProcNo() && map.size()) { - List<T> subField(map.size()); - forAll(map, i) - { - subField[i] = field[map[i]]; - } OPstream toNbr(Pstream::blocking, domain); - toNbr << subField; + toNbr << UIndirectList<T>(field, map); } } @@ -126,13 +121,7 @@ void Foam::mapDistribute::distribute List<T> newField(constructSize); // Subset myself - const labelList& mySubMap = subMap[Pstream::myProcNo()]; - - List<T> subField(mySubMap.size()); - forAll(mySubMap, i) - { - subField[i] = field[mySubMap[i]]; - } + UIndirectList<T> subField(field, subMap[Pstream::myProcNo()]); // Receive sub field from myself (subField) const labelList& map = constructMap[Pstream::myProcNo()]; @@ -152,16 +141,8 @@ void Foam::mapDistribute::distribute if (Pstream::myProcNo() == sendProc) { // I am sender. Send to recvProc. - const labelList& map = subMap[recvProc]; - - List<T> subField(map.size()); - forAll(map, i) - { - subField[i] = field[map[i]]; - } - OPstream toNbr(Pstream::scheduled, recvProc); - toNbr << subField; + toNbr << UIndirectList<T>(field, subMap[recvProc]); } else { @@ -374,13 +355,8 @@ void Foam::mapDistribute::distribute if (domain != Pstream::myProcNo() && map.size()) { - List<T> subField(map.size()); - forAll(map, i) - { - subField[i] = field[map[i]]; - } OPstream toNbr(Pstream::blocking, domain); - toNbr << subField; + toNbr << UIndirectList<T>(field, map); } } @@ -449,13 +425,7 @@ void Foam::mapDistribute::distribute List<T> newField(constructSize, nullValue); // Subset myself - const labelList& mySubMap = subMap[Pstream::myProcNo()]; - - List<T> subField(mySubMap.size()); - forAll(mySubMap, i) - { - subField[i] = field[mySubMap[i]]; - } + UIndirectList<T> subField(field, subMap[Pstream::myProcNo()]); // Receive sub field from myself (subField) const labelList& map = constructMap[Pstream::myProcNo()]; @@ -475,16 +445,8 @@ void Foam::mapDistribute::distribute if (Pstream::myProcNo() == sendProc) { // I am sender. Send to recvProc. - const labelList& map = subMap[recvProc]; - - List<T> subField(map.size()); - forAll(map, i) - { - subField[i] = field[map[i]]; - } - OPstream toNbr(Pstream::scheduled, recvProc); - toNbr << subField; + toNbr << UIndirectList<T>(field, subMap[recvProc]); } else { diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsCheck.C b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsCheck.C index 5fcec15c9586e44f9e52b267d9f02c2ec585e396..a644cd1934901290b85d83305034cb6f2bdf3d9d 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsCheck.C +++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsCheck.C @@ -58,7 +58,7 @@ Foam::PatchTools::checkOrientation { Info<< "Face[" << faceI << "] " << p[faceI] << " has fewer than 3 edges. Edges: " << edgeLabels - << nl; + << endl; } valid = false; } @@ -70,10 +70,12 @@ Foam::PatchTools::checkOrientation { if (report) { - Info<< "edge number " << edgeLabels[i] << " on face " << faceI + Info<< "edge number " << edgeLabels[i] + << " on face " << faceI << " out-of-range\n" << "This usually means the input surface has " - << "edges with more than 2 faces connected." << nl; + << "edges with more than 2 faces connected." + << endl; } valid = false; } @@ -91,9 +93,9 @@ Foam::PatchTools::checkOrientation //- Compute normal from 3 points, use the first as the origin // minor warpage should not be a problem const Face& f = p[faceI]; - const point p0(p.points()[f[0]]); - const point p1(p.points()[f[1]]); - const point p2(p.points()[f[f.size()-1]]); + const point& p0 = p.points()[f[0]]; + const point& p1 = p.points()[f[1]]; + const point& p2 = p.points()[f[f.size()-1]]; const vector pointNormal((p1 - p0) ^ (p2 - p0)); if ((pointNormal & p.faceNormals()[faceI]) < 0) @@ -103,12 +105,12 @@ Foam::PatchTools::checkOrientation if (report) { Info - << "Normal calculated from points inconsistent with faceNormal" - << nl + << "Normal calculated from points inconsistent" + << " with faceNormal" << nl << "face: " << f << nl << "points: " << p0 << ' ' << p1 << ' ' << p2 << nl << "pointNormal:" << pointNormal << nl - << "faceNormal:" << p.faceNormals()[faceI] << nl; + << "faceNormal:" << p.faceNormals()[faceI] << endl; } } } diff --git a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H index b24149300f5bd1aa8bd7939c0eb2a7f2c13c7671..3bc3ea38a809c1850057de2d25cc73d0cdc2413b 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H +++ b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H @@ -153,7 +153,7 @@ public: inline scalar sweptVol(const triangle& t) const; //- Return point intersection with a ray. - // For a hit, the distance is signed. Positive number + // For a hit, the distance is signed. Positive number // represents the point in front of triangle. // In case of miss pointHit is set to nearest point // on triangle and its distance to the distance between @@ -169,12 +169,14 @@ public: //- Fast intersection with a ray. // For a hit, the pointHit.distance() is the line parameter t : // intersection=p+t*q. Only defined for VISIBLE, FULL_RAY or - // HALF_RAY. + // HALF_RAY. tol increases the virtual size of the triangle + // by a relative factor. inline pointHit intersection ( const point& p, const vector& q, - const intersection::algorithm alg + const intersection::algorithm alg, + const scalar tol = 0.0 ) const; //- Return nearest point to p on triangle diff --git a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H index ad7ed2ea8bdd307ad249437a5d0e756ee4e31f74..33b3cab15e67775129d8997818a299add2d687f9 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H +++ b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H @@ -439,7 +439,8 @@ inline pointHit triangle<Point, PointRef>::intersection ( const point& orig, const vector& dir, - const intersection::algorithm alg + const intersection::algorithm alg, + const scalar tol ) const { const vector edge1 = b_ - a_; @@ -457,99 +458,61 @@ inline pointHit triangle<Point, PointRef>::intersection if (alg == intersection::VISIBLE) { // Culling branch - if (det < SMALL) + if (det < ROOTVSMALL) { - // return miss + // Ray on wrong side of triangle. Return miss return intersection; } - /* calculate distance from a_ to ray origin */ - const vector tVec = orig-a_; - - /* calculate U parameter and test bounds */ - scalar u = tVec & pVec; - - if (u < 0.0 || u > det) - { - // return miss - return intersection; - } - - /* prepare to test V parameter */ - const vector qVec = tVec ^ edge1; - - /* calculate V parameter and test bounds */ - scalar v = dir & qVec; - - if (v < 0.0 || u + v > det) - { - // return miss - return intersection; - } - - /* calculate t, scale parameters, ray intersects triangle */ - scalar t = edge2 & qVec; - scalar inv_det = 1.0 / det; - t *= inv_det; - u *= inv_det; - v *= inv_det; - - intersection.setHit(); - intersection.setPoint(a_ + u*edge1 + v*edge2); - intersection.setDistance(t); } else if (alg == intersection::HALF_RAY || alg == intersection::FULL_RAY) { // Non-culling branch - if (det > -SMALL && det < SMALL) + if (det > -ROOTVSMALL && det < ROOTVSMALL) { - // return miss + // Ray parallel to triangle. Return miss return intersection; } - const scalar inv_det = 1.0 / det; + } - /* calculate distance from a_ to ray origin */ - const vector tVec = orig - a_; - /* calculate U parameter and test bounds */ - const scalar u = (tVec & pVec)*inv_det; + const scalar inv_det = 1.0 / det; - if (u < 0.0 || u > 1.0) - { - // return miss - return intersection; - } - /* prepare to test V parameter */ - const vector qVec = tVec ^ edge1; - /* calculate V parameter and test bounds */ - const scalar v = (dir & qVec) * inv_det; + /* calculate distance from a_ to ray origin */ + const vector tVec = orig-a_; - if (v < 0.0 || u + v > 1.0) - { - // return miss - return intersection; - } - /* calculate t, ray intersects triangle */ - const scalar t = (edge2 & qVec) * inv_det; + /* calculate U parameter and test bounds */ + const scalar u = (tVec & pVec)*inv_det; - if (alg == intersection::HALF_RAY && t < 0) - { - // return miss - return intersection; - } + if (u < -tol || u > 1.0+tol) + { + // return miss + return intersection; + } - intersection.setHit(); - intersection.setPoint(a_ + u*edge1 + v*edge2); - intersection.setDistance(t); + /* prepare to test V parameter */ + const vector qVec = tVec ^ edge1; + + /* calculate V parameter and test bounds */ + const scalar v = (dir & qVec) * inv_det; + + if (v < -tol || u + v > 1.0+tol) + { + // return miss + return intersection; } - else + + /* calculate t, scale parameters, ray intersects triangle */ + const scalar t = (edge2 & qVec) * inv_det; + + if (alg == intersection::HALF_RAY && t < -tol) { - FatalErrorIn - ( - "triangle<Point, PointRef>::intersection(const point&" - ", const vector&, const intersection::algorithm)" - ) << "intersection only defined for VISIBLE, FULL_RAY or HALF_RAY" - << abort(FatalError); + // Wrong side of orig. Return miss + return intersection; } + intersection.setHit(); + intersection.setPoint(a_ + u*edge1 + v*edge2); + intersection.setDistance(t); + return intersection; } @@ -622,7 +585,7 @@ inline bool triangle<Point, PointRef>::classify bool hit = false; - if (Foam::mag(u1) < SMALL) + if (Foam::mag(u1) < ROOTVSMALL) { beta = u0/u2; diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.H b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.H index 9ae910b5a71c19965794151be42ef0d9759603d4..c0b7668d0ac6e68c56ab8a5a6546a61ce48b289d 100644 --- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.H +++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.H @@ -38,7 +38,6 @@ SourceFiles #include "autoPtr.H" #include "dictionary.H" -#include "boolList.H" #include "wallPoint.H" #include "searchableSurfaces.H" #include "refinementSurfaces.H" diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C index 8d3c0e1e76bc2adaa66e67ffbc402c8c0f87fa43..ee6cea3e121be5c1a516d7424d82107fa9c0bbee 100644 --- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C +++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C @@ -45,6 +45,7 @@ Description #include "OFstream.H" #include "layerParameters.H" #include "combineFaces.H" +#include "IOmanip.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -1414,8 +1415,11 @@ void Foam::autoLayerDriver::calculateLayerThickness const indirectPrimitivePatch& pp, const labelList& patchIDs, const scalarField& patchExpansionRatio, - const scalarField& patchFinalLayerRatio, - const scalarField& patchRelMinThickness, + + const bool relativeSizes, + const scalarField& patchFinalLayerThickness, + const scalarField& patchMinThickness, + const labelList& cellLevel, const labelList& patchNLayers, const scalar edge0Len, @@ -1428,22 +1432,100 @@ void Foam::autoLayerDriver::calculateLayerThickness const fvMesh& mesh = meshRefiner_.mesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh(); - if (min(patchRelMinThickness) < 0 || max(patchRelMinThickness) > 2) + + // Rework patch-wise layer parameters into minimum per point + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // Reuse input fields + expansionRatio.setSize(pp.nPoints()); + expansionRatio = GREAT; + thickness.setSize(pp.nPoints()); + thickness = GREAT; + minThickness.setSize(pp.nPoints()); + minThickness = GREAT; + + forAll(patchIDs, i) { - FatalErrorIn("calculateLayerThickness(..)") - << "Thickness should be factor of local undistorted cell size." - << " Valid values are [0..2]." << nl - << " minThickness:" << patchRelMinThickness - << exit(FatalError); + label patchI = patchIDs[i]; + + const labelList& meshPoints = patches[patchI].meshPoints(); + + forAll(meshPoints, patchPointI) + { + label ppPointI = pp.meshPointMap()[meshPoints[patchPointI]]; + + expansionRatio[ppPointI] = min + ( + expansionRatio[ppPointI], + patchExpansionRatio[patchI] + ); + thickness[ppPointI] = min + ( + thickness[ppPointI], + patchFinalLayerThickness[patchI] + ); + minThickness[ppPointI] = min + ( + minThickness[ppPointI], + patchMinThickness[patchI] + ); + } } + syncTools::syncPointList + ( + mesh, + pp.meshPoints(), + expansionRatio, + minEqOp<scalar>(), + GREAT, // null value + false // no separation + ); + syncTools::syncPointList + ( + mesh, + pp.meshPoints(), + thickness, + minEqOp<scalar>(), + GREAT, // null value + false // no separation + ); + syncTools::syncPointList + ( + mesh, + pp.meshPoints(), + minThickness, + minEqOp<scalar>(), + GREAT, // null value + false // no separation + ); + - // Per point the max cell level of connected cells - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Now the thicknesses are set according to the minimum of connected + // patches. - labelList maxPointLevel(pp.nPoints(), labelMin); + // Rework relative thickness into absolute + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // by multiplying with the internal cell size. + + if (relativeSizes) { + if (min(patchMinThickness) < 0 || max(patchMinThickness) > 2) + { + FatalErrorIn("calculateLayerThickness(..)") + << "Thickness should be factor of local undistorted cell size." + << " Valid values are [0..2]." << nl + << " minThickness:" << patchMinThickness + << exit(FatalError); + } + + + // Determine per point the max cell level of connected cells + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + labelList maxPointLevel(pp.nPoints(), labelMin); + forAll(pp, i) { label ownLevel = cellLevel[mesh.faceOwner()[pp.addressing()[i]]]; @@ -1465,113 +1547,44 @@ void Foam::autoLayerDriver::calculateLayerThickness labelMin, // null value false // no separation ); - } - // Rework patch-wise layer parameters into minimum per point - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - expansionRatio.setSize(pp.nPoints()); - expansionRatio = GREAT; - scalarField finalLayerRatio(pp.nPoints(), GREAT); - scalarField relMinThickness(pp.nPoints(), GREAT); - - { - forAll(patchIDs, i) + forAll(maxPointLevel, pointI) { - label patchI = patchIDs[i]; - - const labelList& meshPoints = patches[patchI].meshPoints(); - - forAll(meshPoints, patchPointI) - { - label ppPointI = pp.meshPointMap()[meshPoints[patchPointI]]; - - expansionRatio[ppPointI] = min - ( - expansionRatio[ppPointI], - patchExpansionRatio[patchI] - ); - finalLayerRatio[ppPointI] = min - ( - finalLayerRatio[ppPointI], - patchFinalLayerRatio[patchI] - ); - relMinThickness[ppPointI] = min - ( - relMinThickness[ppPointI], - patchRelMinThickness[patchI] - ); - } + // Find undistorted edge size for this level. + scalar edgeLen = edge0Len/(1<<maxPointLevel[pointI]); + thickness[pointI] *= edgeLen; + minThickness[pointI] *= edgeLen; } - - syncTools::syncPointList - ( - mesh, - pp.meshPoints(), - expansionRatio, - minEqOp<scalar>(), - GREAT, // null value - false // no separation - ); - syncTools::syncPointList - ( - mesh, - pp.meshPoints(), - finalLayerRatio, - minEqOp<scalar>(), - GREAT, // null value - false // no separation - ); - syncTools::syncPointList - ( - mesh, - pp.meshPoints(), - relMinThickness, - minEqOp<scalar>(), - GREAT, // null value - false // no separation - ); } - // Per mesh point the expansion parameters - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - thickness.setSize(pp.nPoints()); - minThickness.setSize(pp.nPoints()); + // Rework thickness (of final layer) into overall thickness of all layers + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - forAll(maxPointLevel, pointI) + forAll(thickness, pointI) { - // Find undistorted edge size for this level. - scalar edgeLen = edge0Len/(1<<maxPointLevel[pointI]); - // Calculate layer thickness based on expansion ratio // and final layer height if (expansionRatio[pointI] == 1) { - thickness[pointI] = - finalLayerRatio[pointI] - * patchNLayers[pointI] - * edgeLen; - minThickness[pointI] = relMinThickness[pointI]*edgeLen; + thickness[pointI] *= patchNLayers[pointI]; } else { + scalar invExpansion = 1.0 / expansionRatio[pointI]; label nLay = patchNLayers[pointI]; - thickness[pointI] = - finalLayerRatio[pointI] - * edgeLen - * (1.0 - pow(invExpansion, nLay)) + thickness[pointI] *= + (1.0 - pow(invExpansion, nLay)) / (1.0 - invExpansion); - minThickness[pointI] = relMinThickness[pointI]*edgeLen; } } - Info<< "calculateLayerThickness : min:" << gMin(thickness) - << " max:" << gMax(thickness) << endl; + + //Info<< "calculateLayerThickness : min:" << gMin(thickness) + // << " max:" << gMax(thickness) << endl; } @@ -2292,7 +2305,7 @@ bool Foam::autoLayerDriver::cellsUseFace Foam::label Foam::autoLayerDriver::checkAndUnmark ( const addPatchCellLayer& addLayer, - const dictionary& motionDict, + const dictionary& meshQualityDict, const indirectPrimitivePatch& pp, const fvMesh& newMesh, @@ -2304,7 +2317,7 @@ Foam::label Foam::autoLayerDriver::checkAndUnmark // Check the resulting mesh for errors Info<< nl << "Checking mesh with layer ..." << endl; faceSet wrongFaces(newMesh, "wrongFaces", newMesh.nFaces()/1000); - motionSmoother::checkMesh(false, newMesh, motionDict, wrongFaces); + motionSmoother::checkMesh(false, newMesh, meshQualityDict, wrongFaces); Info<< "Detected " << returnReduce(wrongFaces.size(), sumOp<label>()) << " illegal faces" << " (concave, zero area or negative cell pyramid volume)" @@ -2474,8 +2487,8 @@ void Foam::autoLayerDriver::mergePatchFacesUndo << " (cos:" << minCos << ')' << nl << " - as long as the resulting face doesn't become concave" << " by more than " - << layerParams.concaveAngle() - << " degrees (0=straight, 180=fully concave)" << nl + << layerParams.concaveAngle() << " degrees" << nl + << " (0=straight, 180=fully concave)" << nl << endl; label nChanged = mergePatchFacesUndo(minCos, concaveCos, motionDict); @@ -2621,8 +2634,11 @@ void Foam::autoLayerDriver::addLayers pp, meshMover.adaptPatchIDs(), layerParams.expansionRatio(), - layerParams.finalLayerRatio(), - layerParams.minThickness(), + + layerParams.relativeSizes(), // thickness relative to cellsize? + layerParams.finalLayerThickness(), // wanted thicknes + layerParams.minThickness(), // minimum thickness + cellLevel, patchNLayers, edge0Len, @@ -2632,6 +2648,79 @@ void Foam::autoLayerDriver::addLayers expansionRatio ); + + // Print a bit + { + const polyBoundaryMesh& patches = mesh.boundaryMesh(); + + Info<< nl + << "patch faces layers avg thickness[m]" << nl + << " near-wall overall" << nl + << "----- ----- ------ --------- -------" << endl; + + forAll(meshMover.adaptPatchIDs(), i) + { + label patchI = meshMover.adaptPatchIDs()[i]; + + const labelList& meshPoints = patches[patchI].meshPoints(); + + //scalar maxThickness = -VGREAT; + //scalar minThickness = VGREAT; + scalar sumThickness = 0; + scalar sumNearWallThickness = 0; + + forAll(meshPoints, patchPointI) + { + label ppPointI = pp.meshPointMap()[meshPoints[patchPointI]]; + + //maxThickness = max(maxThickness, thickness[ppPointI]); + //minThickness = min(minThickness, thickness[ppPointI]); + sumThickness += thickness[ppPointI]; + + label nLay = patchNLayers[ppPointI]; + if (nLay > 0) + { + if (expansionRatio[ppPointI] == 1) + { + sumNearWallThickness += thickness[ppPointI]/nLay; + } + else + { + scalar s = + (1.0-pow(expansionRatio[ppPointI], nLay)) + / (1.0-expansionRatio[ppPointI]); + sumNearWallThickness += thickness[ppPointI]/s; + } + } + } + + label totNPoints = returnReduce(meshPoints.size(), sumOp<label>()); + + //reduce(maxThickness, maxOp<scalar>()); + //reduce(minThickness, minOp<scalar>()); + scalar avgThickness = + returnReduce(sumThickness, sumOp<scalar>()) + / totNPoints; + scalar avgNearWallThickness = + returnReduce(sumNearWallThickness, sumOp<scalar>()) + / totNPoints; + + Info<< setf(ios_base::left) << setw(19) << patches[patchI].name(); + //Sout.unsetf(ios_base::left); + Info<< setprecision(3) + << " " << setw(8) + << returnReduce(patches[patchI].size(), sumOp<scalar>()) + << " " << setw(6) << layerParams.numLayers()[patchI] + << " " << setw(8) << avgNearWallThickness + << " " << setw(8) << avgThickness + //<< " " << setw(8) << minThickness + //<< " " << setw(8) << maxThickness + << endl; + } + Info<< endl; + } + + // Calculate wall to medial axis distance for smoothing displacement // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2709,8 +2798,12 @@ void Foam::autoLayerDriver::addLayers boolList flaggedCells; boolList flaggedFaces; - while (true) + for (label iteration = 0; iteration < layerParams.nLayerIter(); iteration++) { + Info<< nl + << "Layer addition iteration " << iteration << nl + << "--------------------------" << endl; + // Make sure displacement is equal on both sides of coupled patches. syncPatchDisplacement ( @@ -2831,7 +2924,8 @@ void Foam::autoLayerDriver::addLayers nPatchFaceLayers ); - // Calculate displacement for first layer for addPatchLayer + // Calculate displacement for first layer for addPatchLayer. + // (first layer = layer of cells next to the original mesh) vectorField firstDisp(patchNLayers.size(), vector::zero); forAll(patchNLayers, i) @@ -2847,9 +2941,9 @@ void Foam::autoLayerDriver::addLayers label nLay = nPatchPointLayers[i]; scalar h = pow(expansionRatio[i], nLay - 1) - * (mag(patchDisp[i])*(1.0 - expansionRatio[i])) + * (1.0 - expansionRatio[i]) / (1.0 - pow(expansionRatio[i], nLay)); - firstDisp[i] = h/mag(patchDisp[i])*patchDisp[i]; + firstDisp[i] = h*patchDisp[i]; } } } @@ -2864,7 +2958,7 @@ void Foam::autoLayerDriver::addLayers pp, nPatchFaceLayers, // layers per face nPatchPointLayers, // layers per point - firstDisp, // thickness of first layer + firstDisp, // thickness of layer nearest internal mesh meshMod ); @@ -2951,10 +3045,23 @@ void Foam::autoLayerDriver::addLayers } // Unset the extrusion at the pp. + const dictionary& meshQualityDict = + ( + iteration < layerParams.nRelaxedIter() + ? motionDict + : motionDict.subDict("relaxed") + ); + + if (iteration >= layerParams.nRelaxedIter()) + { + Info<< "Switched to relaxed meshQuality constraints." << endl; + } + + label nTotChanged = checkAndUnmark ( addLayer, - motionDict, + meshQualityDict, pp, newMesh, @@ -2976,6 +3083,8 @@ void Foam::autoLayerDriver::addLayers // Reset mesh points and start again meshMover.movePoints(oldPoints); meshMover.correct(); + + Info<< endl; } diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H index 41662df8c92b42f1d66a5466e76fe18cd884b3ee..6cdec2004b68cbe8206b3e71c0dabc7387f0cd1d 100644 --- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H +++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H @@ -255,9 +255,12 @@ class autoLayerDriver ( const indirectPrimitivePatch& pp, const labelList& patchIDs, + const scalarField& patchExpansionRatio, - const scalarField& patchFinalLayerRatio, - const scalarField& patchRelMinThickness, + const bool relativeSizes, + const scalarField& patchFinalLayerThickness, + const scalarField& patchMinThickness, + const labelList& cellLevel, const labelList& patchNLayers, const scalar edge0Len, diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C index e891cf761c7e452fa5003016cb4d92b868312997..9c4e0a17c521b8e06b4b2ecceb18ed80bb917d06 100644 --- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C +++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C @@ -95,7 +95,7 @@ Foam::label Foam::autoRefineDriver::readFeatureEdges Info<< "Refinement level " << featureLevels[i] << " for all cells crossed by feature " << featFileName << " (" << featureMeshes[i].points().size() << " points, " - << featureMeshes[i].edges().size() << ")." << endl; + << featureMeshes[i].edges().size() << " edges)." << endl; } Info<< "Read feature lines in = " diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.C b/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.C index ddf162dd0f2910d2aaaf89a0f2465a26b86926b7..fad664229652a22fa4f2949b69bc226009a7abbe 100644 --- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.C +++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.C @@ -163,7 +163,8 @@ Foam::layerParameters::layerParameters numLayers_.size(), readScalar(dict.lookup("expansionRatio")) ), - finalLayerRatio_ + relativeSizes_(false), + finalLayerThickness_ ( numLayers_.size(), readScalar(dict.lookup("finalLayerRatio")) @@ -211,8 +212,24 @@ Foam::layerParameters::layerParameters ( readLabel(dict.lookup("nBufferCellsNoExtrude")) ), - nSnap_(readLabel(dict.lookup("nSnap"))) -{} + nSnap_(readLabel(dict.lookup("nSnap"))), + nLayerIter_(readLabel(dict.lookup("nLayerIter"))), + nRelaxedIter_(labelMax) +{ + if (dict.found("nRelaxedIter")) + { + dict.lookup("nRelaxedIter") >> nRelaxedIter_; + } + + if (nLayerIter_ < 0 || nRelaxedIter_ < 0) + { + FatalErrorIn("layerParameters::layerParameters(..)") + << "Layer iterations should be >= 0." << endl + << "nLayerIter:" << nLayerIter_ + << " nRelaxedIter:" << nRelaxedIter_ + << exit(FatalError); + } +} // Construct from dictionary @@ -228,10 +245,11 @@ Foam::layerParameters::layerParameters boundaryMesh.size(), readScalar(dict.lookup("expansionRatio")) ), - finalLayerRatio_ + relativeSizes_(dict.lookup("relativeSizes")), + finalLayerThickness_ ( boundaryMesh.size(), - readScalar(dict.lookup("finalLayerRatio")) + readScalar(dict.lookup("finalLayerThickness")) ), minThickness_ ( @@ -276,8 +294,24 @@ Foam::layerParameters::layerParameters ( readLabel(dict.lookup("nBufferCellsNoExtrude")) ), - nSnap_(readLabel(dict.lookup("nRelaxIter"))) + nSnap_(readLabel(dict.lookup("nRelaxIter"))), + nLayerIter_(readLabel(dict.lookup("nLayerIter"))), + nRelaxedIter_(labelMax) { + if (dict.found("nRelaxedIter")) + { + dict.lookup("nRelaxedIter") >> nRelaxedIter_; + } + if (nLayerIter_ < 0 || nRelaxedIter_ < 0) + { + FatalErrorIn("layerParameters::layerParameters(..)") + << "Layer iterations should be >= 0." << endl + << "nLayerIter:" << nLayerIter_ + << " nRelaxedIter:" << nRelaxedIter_ + << exit(FatalError); + } + + const dictionary& layersDict = dict.subDict("layers"); forAll(boundaryMesh, patchI) @@ -291,14 +325,21 @@ Foam::layerParameters::layerParameters numLayers_[patchI] = readLabel(layerDict.lookup("nSurfaceLayers")); - //- Patch-wise layer parameters disabled for now. Just remove - // settings in initialiser list and uncomment below. - //expansionRatio_[patchI] = - // readScalar(layerDict.lookup("expansionRatio")); - //finalLayerRatio_[patchI] = - // readScalar(layerDict.lookup("finalLayerRatio")); - //minThickness_[patchI] = - // readScalar(layerDict.lookup("minThickness")); + layerDict.readIfPresent + ( + "expansionRatio", + expansionRatio_[patchI] + ); + layerDict.readIfPresent + ( + "finalLayerThickness", + finalLayerThickness_[patchI] + ); + layerDict.readIfPresent + ( + "minThickness", + minThickness_[patchI] + ); } } diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.H b/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.H index d96ce97cbd2167d6f1aa51d736e5fd6a9baca943..766897f43f83cc31b30ce3e2967d00edf15d7620 100644 --- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.H +++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.H @@ -39,6 +39,7 @@ SourceFiles #include "dictionary.H" #include "scalarField.H" #include "labelList.H" +#include "Switch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -70,14 +71,10 @@ class layerParameters scalarField expansionRatio_; - //- Wanted thickness of final added cell layer. If multiple layers - // is the thickness of the layer furthest away from the wall. - // Relative to undistorted size of cell outside layer. - scalarField finalLayerRatio_; + Switch relativeSizes_; + + scalarField finalLayerThickness_; - //- Minimum thickness of cell layer. If for any reason layer - // cannot be above minThickness do not add layer. - // Relative to undistorted size of cell outside layer. scalarField minThickness_; @@ -105,6 +102,10 @@ class layerParameters label nSnap_; + label nLayerIter_; + + label nRelaxedIter_; + // Private Member Functions @@ -160,18 +161,27 @@ public: return expansionRatio_; } + //- Are size parameters relative to inner cell size or + // absolute distances. + bool relativeSizes() const + { + return relativeSizes_; + } + //- Wanted thickness of final added cell layer. If multiple - // layers - // is the thickness of the layer furthest away from the wall. - // Relative to undistorted size of cell outside layer. - const scalarField& finalLayerRatio() const + // layers is the thickness of the layer furthest away + // from the wall (i.e. nearest the original mesh) + // If relativeSize() this number is relative to undistorted + // size of the cell outside layer. + const scalarField& finalLayerThickness() const { - return finalLayerRatio_; + return finalLayerThickness_; } //- Minimum thickness of cell layer. If for any reason layer // cannot be above minThickness do not add layer. - // Relative to undistorted size of cell outside layer. + // If relativeSize() this number is relative to undistorted + // size of the cell outside layer. const scalarField& minThickness() const { return minThickness_; @@ -196,26 +206,20 @@ public: return nGrow_; } - // Number of smoothing iterations of surface normals + //- Number of smoothing iterations of surface normals label nSmoothSurfaceNormals() const { return nSmoothSurfaceNormals_; } - // Number of smoothing iterations of interior mesh movement - // direction + //- Number of smoothing iterations of interior mesh movement + // direction label nSmoothNormals() const { return nSmoothNormals_; } - // Smooth layer thickness over surface patches - label nSmoothThickness() const - { - return nSmoothThickness_; - } - - // Stop layer growth on highly warped cells + //- Stop layer growth on highly warped cells scalar maxFaceThicknessRatio() const { return maxFaceThicknessRatio_; @@ -226,20 +230,26 @@ public: return layerTerminationCos_; } - // Reduce layer growth where ratio thickness to medial - // distance is large + //- Smooth layer thickness over surface patches + label nSmoothThickness() const + { + return nSmoothThickness_; + } + + //- Reduce layer growth where ratio thickness to medial + // distance is large scalar maxThicknessToMedialRatio() const { return maxThicknessToMedialRatio_; } - // Angle used to pick up medial axis points + //- Angle used to pick up medial axis points scalar minMedianAxisAngleCos() const { return minMedianAxisAngleCos_; } - // Create buffer region for new layer terminations + //- Create buffer region for new layer terminations label nBufferCellsNoExtrude() const { return nBufferCellsNoExtrude_; @@ -249,6 +259,24 @@ public: { return nSnap_; } + + // Overall + + //- Number of overall layer addition iterations + label nLayerIter() const + { + return nLayerIter_; + } + + //- Number of iterations after which relaxed motion rules + // are to be used. + label nRelaxedIter() const + { + return nRelaxedIter_; + } + + + }; diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointData.H b/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointData.H index ffb8a15d05505dbc74ec6703a1afdda3d7d53012..d27c62929d94e9ab167682fe5df98e6cb394cb1a 100644 --- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointData.H +++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointData.H @@ -42,9 +42,7 @@ SourceFiles #include "point.H" #include "label.H" -#include "scalar.H" #include "tensor.H" -#include "pTraits.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointDataI.H b/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointDataI.H index 234d569f85010eb6feac5c26a70acf52cb57102a..9832bbf877d0fe53c81b2f679a21aecd091dfbc9 100644 --- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointDataI.H +++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointDataI.H @@ -22,8 +22,6 @@ License along with OpenFOAM; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -Description - \*---------------------------------------------------------------------------*/ #include "polyMesh.H" diff --git a/src/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H b/src/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H index 0025f333323020779c7b72e7bbac2984afcf8121..06004c8a6e00bc12c093cb36afb2782638b4b2d3 100644 --- a/src/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H +++ b/src/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H @@ -47,7 +47,6 @@ SourceFiles #include "hexRef8.H" #include "mapPolyMesh.H" #include "autoPtr.H" -#include "pointIOField.H" #include "labelPair.H" #include "indirectPrimitivePatch.H" #include "pointFieldsFwd.H" diff --git a/src/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C b/src/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C index d42ac05b2233d1657f30a6511c825344c531924e..7aabbc6321cf9132e9e5c271d46e15abd7e00673 100644 --- a/src/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C +++ b/src/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C @@ -328,7 +328,7 @@ Foam::label Foam::meshRefinement::markFeatureRefinement // Database to pass into trackedParticle::move trackedParticle::trackData td(cloud, maxFeatureLevel); - // Track all particles to their end position. + // Track all particles to their end position (= starting feature point) cloud.move(td); // Reset level diff --git a/src/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.H b/src/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.H index e8fd3614018be8a862d01814eb150be7de5aa953..cee48bbe1f5effc3ed9cc0f6ad59193c87dce62e 100644 --- a/src/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.H +++ b/src/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.H @@ -38,7 +38,6 @@ SourceFiles #ifndef refinementSurfaces_H #define refinementSurfaces_H -#include "PackedBoolList.H" #include "triSurfaceGeoMesh.H" #include "triSurfaceFields.H" #include "vectorList.H" diff --git a/src/autoMesh/autoHexMesh/trackedParticle/ExactParticle.C b/src/autoMesh/autoHexMesh/trackedParticle/ExactParticle.C index bcf92e9747c92c3cdfd18c5ab63a002d47917681..237e35276c33e528be26b13430bc078ea66baab4 100644 --- a/src/autoMesh/autoHexMesh/trackedParticle/ExactParticle.C +++ b/src/autoMesh/autoHexMesh/trackedParticle/ExactParticle.C @@ -102,23 +102,7 @@ Foam::scalar Foam::ExactParticle<ParticleType>::trackToFace } } - - if (hitFacei != -1) - { - if (trackFraction > 1.0) - { - // Nearest intersection beyond endPosition so we hit endPosition. - this->position_ = endPosition; - this->facei_ = -1; - return 1.0; - } - else - { - this->position_ = intersection; - this->facei_ = hitFacei; - } - } - else + if (hitFacei == -1) { // Did not find any intersection. Fall back to original approximate // algorithm @@ -129,8 +113,23 @@ Foam::scalar Foam::ExactParticle<ParticleType>::trackToFace ); } + if (trackFraction >= (1.0-SMALL)) + { + // Nearest intersection beyond endPosition so we hit endPosition. + trackFraction = 1.0; + this->position_ = endPosition; + this->facei_ = -1; + return 1.0; + } + else + { + this->position_ = intersection; + this->facei_ = hitFacei; + } + - // Normal situation (trackFraction 0..1) + // Normal situation (trackFraction 0..1). Straight copy + // of Particle::trackToFace. bool internalFace = this->cloud().internalFace(this->facei_); diff --git a/src/decompositionMethods/decompositionMethods/Make/files b/src/decompositionMethods/decompositionMethods/Make/files index 9707bc7f2e9852519615faea8ae993dfa2cf7c2b..2acbfd56060aa85ed912373d83bb9e58a00b675e 100644 --- a/src/decompositionMethods/decompositionMethods/Make/files +++ b/src/decompositionMethods/decompositionMethods/Make/files @@ -2,7 +2,10 @@ decompositionMethod/decompositionMethod.C geomDecomp/geomDecomp.C simpleGeomDecomp/simpleGeomDecomp.C hierarchGeomDecomp/hierarchGeomDecomp.C -metisDecomp/metisDecomp.C manualDecomp/manualDecomp.C +scotchDecomp/scotchDecomp.C + +metisDecomp/metisDecomp.C + LIB = $(FOAM_LIBBIN)/libdecompositionMethods diff --git a/src/decompositionMethods/decompositionMethods/Make/options b/src/decompositionMethods/decompositionMethods/Make/options index 9ccb652d2bc1b807bb48da05d6b82456ffeabedb..97569aa663f2a4ab623cf3c5f30ec77cdbebd3c8 100644 --- a/src/decompositionMethods/decompositionMethods/Make/options +++ b/src/decompositionMethods/decompositionMethods/Make/options @@ -1,6 +1,8 @@ EXE_INC = \ + -I$(WM_THIRD_PARTY_DIR)/scotch_5.1/src/libscotch/lnInclude \ -I$(WM_THIRD_PARTY_DIR)/metis-5.0pre2/include LIB_LIBS = \ + -lscotch \ -lmetis \ -lGKlib diff --git a/src/decompositionMethods/decompositionMethods/scotchDecomp/scotchDecomp.C b/src/decompositionMethods/decompositionMethods/scotchDecomp/scotchDecomp.C new file mode 100644 index 0000000000000000000000000000000000000000..2746d8f4e9b86b3fb17bb178dfe6c61436f2cdad --- /dev/null +++ b/src/decompositionMethods/decompositionMethods/scotchDecomp/scotchDecomp.C @@ -0,0 +1,425 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +S Strat=b{job=t,map=t,poli=S,sep=(m{asc=b{bnd=d{pass=40,dif=1,rem=1}f{move=80,pass=-1,bal=0.005},org=f{move=80,pass=-1,bal=0.005},width=3},low=h{pass=10}f{move=80,pass=-1,bal=0.0005},type=h,vert=80,rat=0.8}|m{asc=b{bnd=d{pass=40,dif=1,rem=1}f{move=80,pass=-1,bal=0.005},org=f{move=80,pass=-1,bal=0.005},width=3},low=h{pass=10}f{move=80,pass=-1,bal=0.0005},type=h,vert=80,rat=0.8})} +\*---------------------------------------------------------------------------*/ + +#include "scotchDecomp.H" +#include "addToRunTimeSelectionTable.H" +#include "floatScalar.H" +#include "IFstream.H" +#include "Time.H" +#include "cyclicPolyPatch.H" + +extern "C" +{ +#define OMPI_SKIP_MPICXX +#include "module.h" +#include "common.h" +#include "scotch.h" +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(scotchDecomp, 0); + + addToRunTimeSelectionTable + ( + decompositionMethod, + scotchDecomp, + dictionaryMesh + ); +} + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::scotchDecomp::check(const int retVal, const char* str) +{ + if (retVal) + { + FatalErrorIn("scotchDecomp::decompose(..)") + << "Called to scotch routine " << str << " failed." + << exit(FatalError); + } +} + + +// Call Metis with options from dictionary. +Foam::label Foam::scotchDecomp::decompose +( + const List<int>& adjncy, + const List<int>& xadj, + + List<int>& finalDecomp +) +{ + // Strategy + // ~~~~~~~~ + // Default. + SCOTCH_Strat stradat; + check(SCOTCH_stratInit(&stradat), "SCOTCH_stratInit"); + //SCOTCH_stratGraphMap(&stradat, &argv[i][2]); + //fprintf(stdout, "S\tStrat="); + //SCOTCH_stratSave(&stradat, stdout); + //fprintf(stdout, "\n"); + + + // Graph + // ~~~~~ + + SCOTCH_Graph grafdat; + check(SCOTCH_graphInit(&grafdat), "SCOTCH_graphInit"); + check + ( + SCOTCH_graphBuild + ( + &grafdat, + 0, // baseval, c-style numbering + xadj.size()-1, // vertnbr, nCells + xadj.begin(), // verttab, start index per cell into adjncy + &xadj[1], // vendtab, end index ,, + NULL, // velotab, vertex weights + NULL, // vlbltab + adjncy.size(), // edgenbr, number of arcs + adjncy.begin(), // edgetab + NULL // edlotab, edge weights + ), + "SCOTCH_graphBuild" + ); + check(SCOTCH_graphCheck(&grafdat), "SCOTCH_graphCheck"); + + + + //// Architecture + //// ~~~~~~~~~~~~ + //// (fully connected network topology since using switch) + // + //SCOTCH_Arch archdat; + //check(SCOTCH_archInit(&archdat), "SCOTCH_archInit"); + //check + //( + // // SCOTCH_archCmpltw for weighted. + // SCOTCH_archCmplt(&archdat, nProcessors_), + // "SCOTCH_archCmplt" + //); + + + + + //SCOTCH_Mapping mapdat; + //SCOTCH_graphMapInit(&grafdat, &mapdat, &archdat, NULL); + //SCOTCH_graphMapCompute(&grafdat, &mapdat, &stradat); /* Perform mapping */ + + + finalDecomp.setSize(xadj.size()-1); + check + ( + SCOTCH_graphPart + ( + &grafdat, + nProcessors_, // partnbr + &stradat, // const SCOTCH_Strat * + finalDecomp.begin() // parttab + ), + "SCOTCH_graphPart" + ); + + // Release storage for graph + SCOTCH_graphExit(&grafdat); + SCOTCH_stratExit(&stradat); + //// Release storage for network topology + //SCOTCH_archExit(&archdat); + + return 0; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::scotchDecomp::scotchDecomp +( + const dictionary& decompositionDict, + const polyMesh& mesh +) +: + decompositionMethod(decompositionDict), + mesh_(mesh) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::labelList Foam::scotchDecomp::decompose(const pointField& points) +{ + if (points.size() != mesh_.nCells()) + { + FatalErrorIn("scotchDecomp::decompose(const pointField&)") + << "Can use this decomposition method only for the whole mesh" + << endl + << "and supply one coordinate (cellCentre) for every cell." << endl + << "The number of coordinates " << points.size() << endl + << "The number of cells in the mesh " << mesh_.nCells() + << exit(FatalError); + } + + // Make Metis CSR (Compressed Storage Format) storage + // adjncy : contains neighbours (= edges in graph) + // xadj(celli) : start of information in adjncy for celli + + List<int> xadj(mesh_.nCells()+1); + + // Initialise the number of internal faces of the cells to twice the + // number of internal faces + label nInternalFaces = 2*mesh_.nInternalFaces(); + + // Check the boundary for coupled patches and add to the number of + // internal faces + const polyBoundaryMesh& pbm = mesh_.boundaryMesh(); + + forAll(pbm, patchi) + { + if (isA<cyclicPolyPatch>(pbm[patchi])) + { + nInternalFaces += pbm[patchi].size(); + } + } + + // Create the adjncy array the size of the total number of internal and + // coupled faces + List<int> adjncy(nInternalFaces); + + // Fill in xadj + // ~~~~~~~~~~~~ + label freeAdj = 0; + + for (label cellI = 0; cellI < mesh_.nCells(); cellI++) + { + xadj[cellI] = freeAdj; + + const labelList& cFaces = mesh_.cells()[cellI]; + + forAll(cFaces, i) + { + label faceI = cFaces[i]; + + if + ( + mesh_.isInternalFace(faceI) + || isA<cyclicPolyPatch>(pbm[pbm.whichPatch(faceI)]) + ) + { + freeAdj++; + } + } + } + xadj[mesh_.nCells()] = freeAdj; + + + // Fill in adjncy + // ~~~~~~~~~~~~~~ + + labelList nFacesPerCell(mesh_.nCells(), 0); + + // Internal faces + for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++) + { + label own = mesh_.faceOwner()[faceI]; + label nei = mesh_.faceNeighbour()[faceI]; + + adjncy[xadj[own] + nFacesPerCell[own]++] = nei; + adjncy[xadj[nei] + nFacesPerCell[nei]++] = own; + } + + // Coupled faces. Only cyclics done. + forAll(pbm, patchi) + { + if (isA<cyclicPolyPatch>(pbm[patchi])) + { + const unallocLabelList& faceCells = pbm[patchi].faceCells(); + + label sizeby2 = faceCells.size()/2; + + for (label facei=0; facei<sizeby2; facei++) + { + label own = faceCells[facei]; + label nei = faceCells[facei + sizeby2]; + + adjncy[xadj[own] + nFacesPerCell[own]++] = nei; + adjncy[xadj[nei] + nFacesPerCell[nei]++] = own; + } + } + } + + // Decompose using default weights + List<int> finalDecomp; + decompose(adjncy, xadj, finalDecomp); + + // Copy back to labelList + labelList decomp(finalDecomp.size()); + forAll(decomp, i) + { + decomp[i] = finalDecomp[i]; + } + return decomp; +} + + +// From cell-cell connections to Metis format (like CompactListList) +void Foam::scotchDecomp::calcMetisCSR +( + const labelListList& cellCells, + List<int>& adjncy, + List<int>& xadj +) +{ + // Count number of internal faces + label nConnections = 0; + + forAll(cellCells, coarseI) + { + nConnections += cellCells[coarseI].size(); + } + + // Create the adjncy array as twice the size of the total number of + // internal faces + adjncy.setSize(nConnections); + + xadj.setSize(cellCells.size()+1); + + + // Fill in xadj + // ~~~~~~~~~~~~ + label freeAdj = 0; + + forAll(cellCells, coarseI) + { + xadj[coarseI] = freeAdj; + + const labelList& cCells = cellCells[coarseI]; + + forAll(cCells, i) + { + adjncy[freeAdj++] = cCells[i]; + } + } + xadj[cellCells.size()] = freeAdj; +} + + +Foam::labelList Foam::scotchDecomp::decompose +( + const labelList& agglom, + const pointField& agglomPoints +) +{ + if (agglom.size() != mesh_.nCells()) + { + FatalErrorIn + ( + "parMetisDecomp::decompose(const labelList&, const pointField&)" + ) << "Size of cell-to-coarse map " << agglom.size() + << " differs from number of cells in mesh " << mesh_.nCells() + << exit(FatalError); + } + + // Make Metis CSR (Compressed Storage Format) storage + // adjncy : contains neighbours (= edges in graph) + // xadj(celli) : start of information in adjncy for celli + List<int> adjncy; + List<int> xadj; + { + // Get cellCells on coarse mesh. + labelListList cellCells; + calcCellCells + ( + mesh_, + agglom, + agglomPoints.size(), + cellCells + ); + + calcMetisCSR(cellCells, adjncy, xadj); + } + + // Decompose using default weights + List<int> finalDecomp; + decompose(adjncy, xadj, finalDecomp); + + + // Rework back into decomposition for original mesh_ + labelList fineDistribution(agglom.size()); + + forAll(fineDistribution, i) + { + fineDistribution[i] = finalDecomp[agglom[i]]; + } + + return fineDistribution; +} + + +Foam::labelList Foam::scotchDecomp::decompose +( + const labelListList& globalCellCells, + const pointField& cellCentres +) +{ + if (cellCentres.size() != globalCellCells.size()) + { + FatalErrorIn + ( + "scotchDecomp::decompose(const pointField&, const labelListList&)" + ) << "Inconsistent number of cells (" << globalCellCells.size() + << ") and number of cell centres (" << cellCentres.size() + << ")." << exit(FatalError); + } + + + // Make Metis CSR (Compressed Storage Format) storage + // adjncy : contains neighbours (= edges in graph) + // xadj(celli) : start of information in adjncy for celli + + List<int> adjncy; + List<int> xadj; + calcMetisCSR(globalCellCells, adjncy, xadj); + + + // Decompose using default weights + List<int> finalDecomp; + decompose(adjncy, xadj, finalDecomp); + + // Copy back to labelList + labelList decomp(finalDecomp.size()); + forAll(decomp, i) + { + decomp[i] = finalDecomp[i]; + } + return decomp; +} + + +// ************************************************************************* // diff --git a/src/decompositionMethods/decompositionMethods/scotchDecomp/scotchDecomp.H b/src/decompositionMethods/decompositionMethods/scotchDecomp/scotchDecomp.H new file mode 100644 index 0000000000000000000000000000000000000000..e470f84f98c58170ee7bcc0f8e9298a1ba8f3a9e --- /dev/null +++ b/src/decompositionMethods/decompositionMethods/scotchDecomp/scotchDecomp.H @@ -0,0 +1,150 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::scotchDecomp + +Description + Scotch domain decomposition + +SourceFiles + scotchDecomp.C + +\*---------------------------------------------------------------------------*/ + +#ifndef scotchDecomp_H +#define scotchDecomp_H + +#include "decompositionMethod.H" + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class scotchDecomp Declaration +\*---------------------------------------------------------------------------*/ + +class scotchDecomp +: + public decompositionMethod +{ + // Private data + + const polyMesh& mesh_; + + + // Private Member Functions + + //- Check and print error message + static void check(const int, const char*); + + label decompose + ( + const List<int>& adjncy, + const List<int>& xadj, + List<int>& finalDecomp + ); + + //- Disallow default bitwise copy construct and assignment + void operator=(const scotchDecomp&); + scotchDecomp(const scotchDecomp&); + + +public: + + //- Runtime type information + TypeName("scotch"); + + + // Constructors + + //- Construct given the decomposition dictionary and mesh + scotchDecomp + ( + const dictionary& decompositionDict, + const polyMesh& mesh + ); + + + // Destructor + + virtual ~scotchDecomp() + {} + + + // Member Functions + + virtual bool parallelAware() const + { + // Metis does not know about proc boundaries + return false; + } + + //- Return for every coordinate the wanted processor number. Use the + // mesh connectivity (if needed) + virtual labelList decompose(const pointField&); + + //- Return for every coordinate the wanted processor number. Gets + // passed agglomeration map (from fine to coarse cells) and coarse cell + // location. Can be overridden by decomposers that provide this + // functionality natively. + virtual labelList decompose + ( + const labelList& agglom, + const pointField& + ); + + //- Return for every coordinate the wanted processor number. Explicitly + // provided mesh connectivity. + // The connectivity is equal to mesh.cellCells() except for + // - in parallel the cell numbers are global cell numbers (starting + // from 0 at processor0 and then incrementing all through the + // processors) + // - the connections are across coupled patches + virtual labelList decompose + ( + const labelListList& globalCellCells, + const pointField& cc + ); + + //- Helper to convert cellcells into compact row storage + static void calcMetisCSR + ( + const labelListList& globalCellCells, + List<int>& adjncy, + List<int>& xadj + ); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/dynamicMesh/motionSmoother/motionSmoother.C b/src/dynamicMesh/motionSmoother/motionSmoother.C index 18f5c85478e301085d49ca0eb05980d00a96e333..4f40827f4b3a8030217e79098e6716f8db96e018 100644 --- a/src/dynamicMesh/motionSmoother/motionSmoother.C +++ b/src/dynamicMesh/motionSmoother/motionSmoother.C @@ -825,6 +825,28 @@ bool Foam::motionSmoother::scaleMesh const bool smoothMesh, const label nAllowableErrors ) +{ + return scaleMesh + ( + checkFaces, + baffles, + paramDict_, + paramDict_, + smoothMesh, + nAllowableErrors + ); +} + + +bool Foam::motionSmoother::scaleMesh +( + labelList& checkFaces, + const List<labelPair>& baffles, + const dictionary& paramDict, + const dictionary& meshQualityDict, + const bool smoothMesh, + const label nAllowableErrors +) { if (!smoothMesh && adaptPatchIDs_.empty()) { @@ -859,9 +881,9 @@ bool Foam::motionSmoother::scaleMesh } const scalar errorReduction = - readScalar(paramDict_.lookup("errorReduction")); + readScalar(paramDict.lookup("errorReduction")); const label nSmoothScale = - readLabel(paramDict_.lookup("nSmoothScale")); + readLabel(paramDict.lookup("nSmoothScale")); // Note: displacement_ should already be synced already from setDisplacement @@ -921,7 +943,7 @@ bool Foam::motionSmoother::scaleMesh // Check. Returns parallel number of incorrect faces. faceSet wrongFaces(mesh_, "wrongFaces", mesh_.nFaces()/100+100); - checkMesh(false, mesh_, paramDict_, checkFaces, baffles, wrongFaces); + checkMesh(false, mesh_, meshQualityDict, checkFaces, baffles, wrongFaces); if (returnReduce(wrongFaces.size(), sumOp<label>()) <= nAllowableErrors) { diff --git a/src/dynamicMesh/motionSmoother/motionSmoother.H b/src/dynamicMesh/motionSmoother/motionSmoother.H index e5777a366459e75bde147a3e7e420a719ea3a361..e4aeac6f50756ec9a5f27da2602aa80ddad26036 100644 --- a/src/dynamicMesh/motionSmoother/motionSmoother.H +++ b/src/dynamicMesh/motionSmoother/motionSmoother.H @@ -52,7 +52,7 @@ Description @endverbatim Note - Shared points (parallel): a processor can have points which are part of + - Shared points (parallel): a processor can have points which are part of pp on another processor but have no pp itself (i.e. it has points and/or edges but no faces of pp). Hence we have to be careful when e.g. synchronising displacements that the value from the processor which has @@ -61,10 +61,13 @@ Note else. The combine operator used will give preference to non-zero values. - Various routines take baffles. These are sets of boundary faces that + - Various routines take baffles. These are sets of boundary faces that are treated as a single internal face. This is a hack used to apply movement to internal faces. + - Mesh constraints are looked up from the supplied dictionary. (uses + recursive lookup) + SourceFiles motionSmoother.C motionSmootherTemplates.C @@ -395,6 +398,17 @@ public: const label nAllow = 0 ); + //- Move mesh with externally provided mesh constraints + bool scaleMesh + ( + labelList& checkFaces, + const List<labelPair>& baffles, + const dictionary& paramDict, + const dictionary& meshQualityDict, + const bool smoothMesh = true, + const label nAllow = 0 + ); + //- Update topology void updateMesh(); diff --git a/src/dynamicMesh/motionSmoother/motionSmootherCheck.C b/src/dynamicMesh/motionSmoother/motionSmootherCheck.C index 06996c541f9270b8300eb5da110c9dfc521ed95b..7fcb9f1e7ac70660201f2a760565ac691aefd526 100644 --- a/src/dynamicMesh/motionSmoother/motionSmootherCheck.C +++ b/src/dynamicMesh/motionSmoother/motionSmootherCheck.C @@ -28,19 +28,6 @@ License #include "polyMeshGeometry.H" #include "IOmanip.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - - -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // bool Foam::motionSmoother::checkMesh @@ -74,17 +61,50 @@ bool Foam::motionSmoother::checkMesh labelHashSet& wrongFaces ) { - const scalar maxNonOrtho(readScalar(dict.lookup("maxNonOrtho"))); - const scalar minVol(readScalar(dict.lookup("minVol"))); - const scalar maxConcave(readScalar(dict.lookup("maxConcave"))); - const scalar minArea(readScalar(dict.lookup("minArea"))); - const scalar maxIntSkew(readScalar(dict.lookup("maxInternalSkewness"))); - const scalar maxBounSkew(readScalar(dict.lookup("maxBoundarySkewness"))); - const scalar minWeight(readScalar(dict.lookup("minFaceWeight"))); - const scalar minVolRatio(readScalar(dict.lookup("minVolRatio"))); - const scalar minTwist(readScalar(dict.lookup("minTwist"))); - const scalar minTriangleTwist(readScalar(dict.lookup("minTriangleTwist"))); - const scalar minDet(readScalar(dict.lookup("minDeterminant"))); + const scalar maxNonOrtho + ( + readScalar(dict.lookup("maxNonOrtho", true)) + ); + const scalar minVol + ( + readScalar(dict.lookup("minVol", true)) + ); + const scalar maxConcave + ( + readScalar(dict.lookup("maxConcave", true)) + ); + const scalar minArea + ( + readScalar(dict.lookup("minArea", true)) + ); + const scalar maxIntSkew + ( + readScalar(dict.lookup("maxInternalSkewness", true)) + ); + const scalar maxBounSkew + ( + readScalar(dict.lookup("maxBoundarySkewness", true)) + ); + const scalar minWeight + ( + readScalar(dict.lookup("minFaceWeight", true)) + ); + const scalar minVolRatio + ( + readScalar(dict.lookup("minVolRatio", true)) + ); + const scalar minTwist + ( + readScalar(dict.lookup("minTwist", true)) + ); + const scalar minTriangleTwist + ( + readScalar(dict.lookup("minTriangleTwist", true)) + ); + const scalar minDet + ( + readScalar(dict.lookup("minDeterminant", true)) + ); label nWrongFaces = 0; @@ -389,17 +409,50 @@ bool Foam::motionSmoother::checkMesh labelHashSet& wrongFaces ) { - const scalar maxNonOrtho(readScalar(dict.lookup("maxNonOrtho"))); - const scalar minVol(readScalar(dict.lookup("minVol"))); - const scalar maxConcave(readScalar(dict.lookup("maxConcave"))); - const scalar minArea(readScalar(dict.lookup("minArea"))); - const scalar maxIntSkew(readScalar(dict.lookup("maxInternalSkewness"))); - const scalar maxBounSkew(readScalar(dict.lookup("maxBoundarySkewness"))); - const scalar minWeight(readScalar(dict.lookup("minFaceWeight"))); - const scalar minVolRatio(readScalar(dict.lookup("minVolRatio"))); - const scalar minTwist(readScalar(dict.lookup("minTwist"))); - const scalar minTriangleTwist(readScalar(dict.lookup("minTriangleTwist"))); - const scalar minDet(readScalar(dict.lookup("minDeterminant"))); + const scalar maxNonOrtho + ( + readScalar(dict.lookup("maxNonOrtho", true)) + ); + const scalar minVol + ( + readScalar(dict.lookup("minVol", true)) + ); + const scalar maxConcave + ( + readScalar(dict.lookup("maxConcave", true)) + ); + const scalar minArea + ( + readScalar(dict.lookup("minArea", true)) + ); + const scalar maxIntSkew + ( + readScalar(dict.lookup("maxInternalSkewness", true)) + ); + const scalar maxBounSkew + ( + readScalar(dict.lookup("maxBoundarySkewness", true)) + ); + const scalar minWeight + ( + readScalar(dict.lookup("minFaceWeight", true)) + ); + const scalar minVolRatio + ( + readScalar(dict.lookup("minVolRatio", true)) + ); + const scalar minTwist + ( + readScalar(dict.lookup("minTwist", true)) + ); + const scalar minTriangleTwist + ( + readScalar(dict.lookup("minTriangleTwist", true)) + ); + const scalar minDet + ( + readScalar(dict.lookup("minDeterminant", true)) + ); label nWrongFaces = 0; diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.H b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.H index ea6a7674e46d6d11275b6990497944c39c0e9002..f03d23e2144fb22c5a9f093f221ed5fd86dc4a42 100644 --- a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.H +++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.H @@ -294,9 +294,10 @@ public: // - nPointLayers : number of layers per (patch)point // - nFaceLayers : number of layers per (patch) face // - firstDisplacement : displacement per point for first - // layer of points. If zero do not add point. + // layer of points (i.e. nearest to original mesh). If zero + // do not add point. // Layer thicknesses are calculated to constant geometric - // expansion. Use expansionRatio for constant size. + // expansion. Use expansionRatio 1 for constant size. // Sets addedPoints_ which is per pp point a list of points // added. // Note: firstDisplacement has to be parallel synchronised before diff --git a/src/engine/engineMesh/engineMesh/engineMesh.C b/src/engine/engineMesh/engineMesh/engineMesh.C index d425ee75f272278007111890a5f7d43efe4a7c81..329c1a3963d68f3ecc8b50a82e151ce5c4fca55d 100644 --- a/src/engine/engineMesh/engineMesh/engineMesh.C +++ b/src/engine/engineMesh/engineMesh/engineMesh.C @@ -43,7 +43,7 @@ Foam::engineMesh::engineMesh(const IOobject& io) linerIndex_(-1), cylinderHeadIndex_(-1), deckHeight_("deckHeight", dimLength, GREAT), - pistonPosition_("deckHeight", dimLength, GREAT) + pistonPosition_("pistonPosition", dimLength, -GREAT) { bool foundPiston = false; bool foundLiner = false; @@ -80,14 +80,14 @@ Foam::engineMesh::engineMesh(const IOobject& io) } if (!foundLiner) - { + { FatalErrorIn("engineMesh::engineMesh(const IOobject& io)") << "cannot find liner patch" << exit(FatalError); } if (!foundCylinderHead) - { + { FatalErrorIn("engineMesh::engineMesh(const IOobject& io)") << "cannot find cylinderHead patch" << exit(FatalError); @@ -96,17 +96,25 @@ Foam::engineMesh::engineMesh(const IOobject& io) { if (pistonIndex_ != -1) { - pistonPosition_.value() = - max(boundary()[pistonIndex_].patch().localPoints()).z(); + pistonPosition_.value() = -GREAT; + if (boundary()[pistonIndex_].patch().localPoints().size()) + { + pistonPosition_.value() = + max(boundary()[pistonIndex_].patch().localPoints()).z(); + } } - reduce(pistonPosition_.value(), minOp<scalar>()); + reduce(pistonPosition_.value(), maxOp<scalar>()); if (cylinderHeadIndex_ != -1) { - deckHeight_.value() = min - ( - boundary()[cylinderHeadIndex_].patch().localPoints() - ).z(); + deckHeight_.value() = GREAT; + if (boundary()[cylinderHeadIndex_].patch().localPoints().size()) + { + deckHeight_.value() = min + ( + boundary()[cylinderHeadIndex_].patch().localPoints() + ).z(); + } } reduce(deckHeight_.value(), minOp<scalar>()); diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files index 34a4606e088ade62d6f128c2c021c9524e81c33c..1ad24ecd168a95c73cb89317680c4f02915f82e9 100644 --- a/src/finiteVolume/Make/files +++ b/src/finiteVolume/Make/files @@ -24,6 +24,7 @@ $(constraintFvPatches)/processor/processorFvPatch.C derivedFvPatches = $(fvPatches)/derived $(derivedFvPatches)/wall/wallFvPatch.C $(derivedFvPatches)/directMapped/directMappedFvPatch.C +$(derivedFvPatches)/directMapped/directMappedWallFvPatch.C wallDist = fvMesh/wallDist $(wallDist)/wallPointYPlus/wallPointYPlus.C @@ -105,6 +106,7 @@ $(derivedFvPatchFields)/inletOutlet/inletOutletFvPatchFields.C $(derivedFvPatchFields)/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C $(derivedFvPatchFields)/flowRateInletVelocity/flowRateInletVelocityFvPatchVectorField.C $(derivedFvPatchFields)/movingWallVelocity/movingWallVelocityFvPatchVectorField.C +$(derivedFvPatchFields)/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.C $(derivedFvPatchFields)/oscillatingFixedValue/oscillatingFixedValueFvPatchFields.C $(derivedFvPatchFields)/outletInlet/outletInletFvPatchFields.C $(derivedFvPatchFields)/partialSlip/partialSlipFvPatchFields.C diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C index 5322cbf47b20cd663696118452b6bdc382dd49a6..0c3bf4340838d01e7dbbf264a9fb6fdb948ed6ce 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C @@ -25,7 +25,7 @@ License \*---------------------------------------------------------------------------*/ #include "directMappedFixedValueFvPatchField.H" -#include "directMappedFvPatch.H" +#include "directMappedPatchBase.H" #include "volFields.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -61,7 +61,7 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField setAverage_(ptf.setAverage_), average_(ptf.average_) { - if (!isType<directMappedFvPatch>(this->patch())) + if (!isA<directMappedPatchBase>(this->patch().patch())) { FatalErrorIn ( @@ -74,7 +74,7 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField " const fvPatchFieldMapper&\n" ")\n" ) << "\n patch type '" << p.type() - << "' not type '" << typeName << "'" + << "' not type '" << directMappedPatchBase::typeName << "'" << "\n for patch " << p.name() << " of field " << this->dimensionedInternalField().name() << " in file " << this->dimensionedInternalField().objectPath() @@ -95,7 +95,7 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField setAverage_(readBool(dict.lookup("setAverage"))), average_(pTraits<Type>(dict.lookup("average"))) { - if (!isType<directMappedFvPatch>(this->patch())) + if (!isA<directMappedPatchBase>(this->patch().patch())) { FatalErrorIn ( @@ -107,12 +107,19 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField " const dictionary& dict\n" ")\n" ) << "\n patch type '" << p.type() - << "' not type '" << typeName << "'" + << "' not type '" << directMappedPatchBase::typeName << "'" << "\n for patch " << p.name() << " of field " << this->dimensionedInternalField().name() << " in file " << this->dimensionedInternalField().objectPath() << exit(FatalError); } + + // Force calculation of schedule (uses parallel comms) + const directMappedPatchBase& mpp = refCast<const directMappedPatchBase> + ( + this->patch().patch() + ); + (void)mpp.map().schedule(); } @@ -143,70 +150,6 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -template<class Type> -void directMappedFixedValueFvPatchField<Type>::getNewValues -( - const directMappedPolyPatch& mpp, - const Field<Type>& sendValues, - Field<Type>& newValues -) const -{ - // Get the scheduling information - const List<labelPair>& schedule = mpp.schedule(); - const labelListList& sendLabels = mpp.sendLabels(); - const labelListList& receiveFaceLabels = mpp.receiveFaceLabels(); - - forAll(schedule, i) - { - const labelPair& twoProcs = schedule[i]; - label sendProc = twoProcs[0]; - label recvProc = twoProcs[1]; - - if (Pstream::myProcNo() == sendProc) - { - OPstream toProc(Pstream::scheduled, recvProc); - toProc<< UIndirectList<Type>(sendValues, sendLabels[recvProc])(); - } - else - { - // I am receiver. Receive from sendProc. - IPstream fromProc(Pstream::scheduled, sendProc); - - Field<Type> fromFld(fromProc); - - // Destination faces - const labelList& faceLabels = receiveFaceLabels[sendProc]; - - forAll(fromFld, i) - { - label patchFaceI = faceLabels[i]; - - newValues[patchFaceI] = fromFld[i]; - } - } - } - - // Do data from myself - { - UIndirectList<Type> fromFld - ( - sendValues, - sendLabels[Pstream::myProcNo()] - ); - - // Destination faces - const labelList& faceLabels = receiveFaceLabels[Pstream::myProcNo()]; - - forAll(fromFld, i) - { - label patchFaceI = faceLabels[i]; - - newValues[patchFaceI] = fromFld[i]; - } - } -} - - template<class Type> void directMappedFixedValueFvPatchField<Type>::updateCoeffs() { @@ -215,65 +158,94 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs() return; } - // Get the directMappedPolyPatch - const directMappedPolyPatch& mpp = refCast<const directMappedPolyPatch> + typedef GeometricField<Type, fvPatchField, volMesh> fieldType; + + // Get the scheduling information from the directMappedPatchBase + const directMappedPatchBase& mpp = refCast<const directMappedPatchBase> ( directMappedFixedValueFvPatchField<Type>::patch().patch() ); + const mapDistribute& distMap = mpp.map(); + const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh()); + const word& fldName = this->dimensionedInternalField().name(); - Field<Type> newValues(this->size()); + // Result of obtaining remote values + Field<Type> newValues; switch (mpp.mode()) { - case directMappedPolyPatch::NEARESTCELL: + case directMappedPatchBase::NEARESTCELL: { - getNewValues(mpp, this->internalField(), newValues); + if (mpp.sameRegion()) + { + newValues = this->internalField(); + } + else + { + newValues = nbrMesh.lookupObject<fieldType> + ( + fldName + ).internalField(); + } + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + newValues + ); break; } - case directMappedPolyPatch::NEARESTPATCHFACE: + case directMappedPatchBase::NEARESTPATCHFACE: { - const label patchID = - this->patch().patch().boundaryMesh().findPatchID - ( - mpp.samplePatch() - ); - if (patchID < 0) + const label nbrPatchID = nbrMesh.boundaryMesh().findPatchID + ( + mpp.samplePatch() + ); + if (nbrPatchID < 0) { FatalErrorIn ( "void directMappedFixedValueFvPatchField<Type>::" "updateCoeffs()" )<< "Unable to find sample patch " << mpp.samplePatch() + << " in region " << mpp.sampleRegion() << " for patch " << this->patch().name() << nl << abort(FatalError); } - typedef GeometricField<Type, fvPatchField, volMesh> fieldType; - const word& fieldName = this->dimensionedInternalField().name(); - const fieldType& sendField = - this->db().objectRegistry::lookupObject<fieldType>(fieldName); - getNewValues(mpp, sendField.boundaryField()[patchID], newValues); + const fieldType& nbrField = nbrMesh.lookupObject<fieldType> + ( + fldName + ); + newValues = nbrField.boundaryField()[nbrPatchID]; + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + newValues + ); break; } - case directMappedPolyPatch::NEARESTFACE: + case directMappedPatchBase::NEARESTFACE: { - typedef GeometricField<Type, fvPatchField, volMesh> fieldType; - const word& fieldName = this->dimensionedInternalField().name(); - const fieldType& sendField = - this->db().objectRegistry::lookupObject<fieldType>(fieldName); + Field<Type> allValues(nbrMesh.nFaces(), pTraits<Type>::zero); - Field<Type> allValues + const fieldType& nbrField = nbrMesh.lookupObject<fieldType> ( - this->patch().patch().boundaryMesh().mesh().nFaces(), - pTraits<Type>::zero + fldName ); - - forAll(sendField.boundaryField(), patchI) + forAll(nbrField.boundaryField(), patchI) { const fvPatchField<Type>& pf = - sendField.boundaryField()[patchI]; + nbrField.boundaryField()[patchI]; label faceStart = pf.patch().patch().start(); forAll(pf, faceI) @@ -282,9 +254,17 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs() } } - getNewValues(mpp, allValues, newValues); + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + allValues + ); - newValues = this->patch().patchSlice(newValues); + newValues = this->patch().patchSlice(allValues); break; } diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H index 8c8da590a8c78bef3865a28b0d3841159f08d719..2382b32db83dd06e21576e643123197ef2322086 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H @@ -62,18 +62,6 @@ class directMappedFixedValueFvPatchField // setAverage_ is set true Type average_; - - // Private member functions - - // Helper function to return the new field values - void getNewValues - ( - const directMappedPolyPatch& mpp, - const Field<Type>& sendValues, - Field<Type>& newValues - ) const; - - public: //- Runtime type information diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C index 92bf63e8c64c96a9722f3ebea511785b4e60dbb3..5ac329fe31a371fcb357c7b288ef43b56df873c7 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C @@ -26,7 +26,7 @@ License #include "directMappedVelocityFluxFixedValueFvPatchField.H" #include "fvPatchFieldMapper.H" -#include "directMappedFvPatch.H" +#include "directMappedPatchBase.H" #include "volFields.H" #include "surfaceFields.H" #include "addToRunTimeSelectionTable.H" @@ -62,12 +62,12 @@ directMappedVelocityFluxFixedValueFvPatchField fixedValueFvPatchVectorField(ptf, p, iF, mapper), phiName_(ptf.phiName_) { - if (!isType<directMappedFvPatch>(patch())) + if (!isType<directMappedPatchBase>(this->patch().patch())) { FatalErrorIn ( "directMappedVelocityFluxFixedValueFvPatchField::" - "directMappedFixedValueFvPatchField\n" + "directMappedVelocityFluxFixedValueFvPatchField\n" "(\n" " const directMappedVelocityFluxFixedValueFvPatchField&,\n" " const fvPatch&,\n" @@ -75,7 +75,7 @@ directMappedVelocityFluxFixedValueFvPatchField " const fvPatchFieldMapper&\n" ")\n" ) << "\n patch type '" << p.type() - << "' not type '" << typeName << "'" + << "' not type '" << directMappedPatchBase::typeName << "'" << "\n for patch " << p.name() << " of field " << dimensionedInternalField().name() << " in file " << dimensionedInternalField().objectPath() @@ -95,24 +95,31 @@ directMappedVelocityFluxFixedValueFvPatchField fixedValueFvPatchVectorField(p, iF, dict), phiName_(dict.lookup("phi")) { - if (!isType<directMappedFvPatch>(patch())) + if (!isType<directMappedPatchBase>(this->patch().patch())) { FatalErrorIn ( "directMappedVelocityFluxFixedValueFvPatchField::" - "directMappedFixedValueFvPatchField\n" + "directMappedVelocityFluxFixedValueFvPatchField\n" "(\n" " const fvPatch& p,\n" " const DimensionedField<vector, volMesh>& iF,\n" " const dictionary& dict\n" ")\n" ) << "\n patch type '" << p.type() - << "' not type '" << typeName << "'" + << "' not type '" << directMappedPatchBase::typeName << "'" << "\n for patch " << p.name() << " of field " << dimensionedInternalField().name() << " in file " << dimensionedInternalField().objectPath() << exit(FatalError); } + + // Force calculation of schedule (uses parallel comms) + const directMappedPolyPatch& mpp = refCast<const directMappedPolyPatch> + ( + patch().patch() + ); + (void)mpp.map().schedule(); } @@ -139,85 +146,6 @@ directMappedVelocityFluxFixedValueFvPatchField {} -void directMappedVelocityFluxFixedValueFvPatchField::getNewValues -( - const directMappedPolyPatch& mpp, - const vectorField& sendUValues, - const scalarField& sendPhiValues, - vectorField& newUValues, - scalarField& newPhiValues -) const -{ - // Get the scheduling information - const List<labelPair>& schedule = mpp.schedule(); - const labelListList& sendLabels = mpp.sendLabels(); - const labelListList& receiveFaceLabels = mpp.receiveFaceLabels(); - - forAll(schedule, i) - { - const labelPair& twoProcs = schedule[i]; - label sendProc = twoProcs[0]; - label recvProc = twoProcs[1]; - - if (Pstream::myProcNo() == sendProc) - { - OPstream toProc(Pstream::scheduled, recvProc); - toProc<< UIndirectList<vector>(sendUValues, sendLabels[recvProc])(); - toProc<< UIndirectList<scalar> - ( - sendPhiValues, - sendLabels[recvProc] - )(); - } - else - { - // I am receiver. Receive from sendProc. - IPstream fromProc(Pstream::scheduled, sendProc); - - vectorField fromUFld(fromProc); - scalarField fromPhiFld(fromProc); - - // Destination faces - const labelList& faceLabels = receiveFaceLabels[sendProc]; - - forAll(fromUFld, i) - { - label patchFaceI = faceLabels[i]; - - newUValues[patchFaceI] = fromUFld[i]; - newPhiValues[patchFaceI] = fromPhiFld[i]; - } - } - } - - // Do data from myself - { - UIndirectList<vector> fromUFld - ( - sendUValues, - sendLabels[Pstream::myProcNo()] - ); - - UIndirectList<scalar> fromPhiFld - ( - sendPhiValues, - sendLabels[Pstream::myProcNo()] - ); - - // Destination faces - const labelList& faceLabels = receiveFaceLabels[Pstream::myProcNo()]; - - forAll(fromUFld, i) - { - label patchFaceI = faceLabels[i]; - - newUValues[patchFaceI] = fromUFld[i]; - newPhiValues[patchFaceI] = fromPhiFld[i]; - } - } -} - - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs() @@ -227,37 +155,33 @@ void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs() return; } - // Get the directMappedPolyPatch - const directMappedPolyPatch& mpp = refCast<const directMappedPolyPatch> + // Get the directMappedPatchBase + const directMappedPatchBase& mpp = refCast<const directMappedPatchBase> ( directMappedVelocityFluxFixedValueFvPatchField::patch().patch() ); - - vectorField newUValues(size()); - scalarField newPhiValues(size()); - + const mapDistribute& distMap = mpp.map(); + const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh()); const word& fieldName = dimensionedInternalField().name(); - const volVectorField& UField = db().lookupObject<volVectorField>(fieldName); + const volVectorField& UField = nbrMesh.lookupObject<volVectorField> + ( + fieldName + ); surfaceScalarField& phiField = const_cast<surfaceScalarField&> ( - db().lookupObject<surfaceScalarField>(phiName_) + nbrMesh.lookupObject<surfaceScalarField>(phiName_) ); + vectorField newUValues; + scalarField newPhiValues; + switch (mpp.mode()) { case directMappedPolyPatch::NEARESTFACE: { - vectorField allUValues - ( - patch().patch().boundaryMesh().mesh().nFaces(), - vector::zero - ); - scalarField allPhiValues - ( - patch().patch().boundaryMesh().mesh().nFaces(), - 0.0 - ); + vectorField allUValues(nbrMesh.nFaces(), vector::zero); + scalarField allPhiValues(nbrMesh.nFaces(), 0.0); forAll(UField.boundaryField(), patchI) { @@ -273,34 +197,58 @@ void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs() } } - getNewValues + mapDistribute::distribute ( - mpp, - allUValues, - allPhiValues, - newUValues, - newPhiValues + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + allUValues ); - newUValues = patch().patchSlice(newUValues); + + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + newPhiValues + ); newPhiValues = patch().patchSlice(newPhiValues); break; } case directMappedPolyPatch::NEARESTPATCHFACE: { - const label patchID = - patch().patch().boundaryMesh().findPatchID - ( - mpp.samplePatch() - ); + const label nbrPatchID = nbrMesh.boundaryMesh().findPatchID + ( + mpp.samplePatch() + ); + + newUValues = UField.boundaryField()[nbrPatchID]; + + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + newUValues + ); + + newPhiValues = phiField.boundaryField()[nbrPatchID]; - getNewValues + mapDistribute::distribute ( - mpp, - UField.boundaryField()[patchID], - phiField.boundaryField()[patchID], - newUValues, + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), newPhiValues ); diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H index b92372eb3a30b37789d87c74b771ac6beaf32d37..6ec34d62e100683ed147cd544d88554bf90f71bf 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H @@ -57,20 +57,6 @@ class directMappedVelocityFluxFixedValueFvPatchField //- Name of flux field word phiName_; - - // Private member functions - - // Helper function to return the new field values - void getNewValues - ( - const directMappedPolyPatch& mpp, - const vectorField& sendUValues, - const scalarField& sendPhiValues, - vectorField& newUValues, - scalarField& newPhiValues - ) const; - - public: //- Runtime type information diff --git a/src/finiteVolume/fields/fvPatchFields/derived/fixedInternalValueFvPatchField/fixedInternalValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/fixedInternalValueFvPatchField/fixedInternalValueFvPatchField.C index eba3522e36ec98f0cc4f3447de0cdabf52b2ffc3..1cbd6fd72dd3c97596c7cb8d9e53cdacaf982e2c 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/fixedInternalValueFvPatchField/fixedInternalValueFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/fixedInternalValueFvPatchField/fixedInternalValueFvPatchField.C @@ -63,9 +63,7 @@ Foam::fixedInternalValueFvPatchField<Type>::fixedInternalValueFvPatchField ) : zeroGradientFvPatchField<Type>(p, iF, dict) -{ - fvPatchField<Type>::operator=(this->patchInternalField()); -} +{} template<class Type> diff --git a/src/finiteVolume/fields/fvPatchFields/derived/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/derived/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C index 7d316f21fa812d741966846d2dddd1bdb42800b4..d6a83b07cbd6e53f16793b3b6e62fd55e5aa2315 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C @@ -189,7 +189,8 @@ void Foam::inletOutletTotalTemperatureFvPatchScalarField::updateCoeffs() } -void Foam::inletOutletTotalTemperatureFvPatchScalarField::write(Ostream& os) const +void Foam::inletOutletTotalTemperatureFvPatchScalarField::write(Ostream& os) +const { fvPatchScalarField::write(os); if (UName_ != "U") diff --git a/src/finiteVolume/fields/fvPatchFields/derived/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.C b/src/finiteVolume/fields/fvPatchFields/derived/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.C new file mode 100644 index 0000000000000000000000000000000000000000..7b5a1dbc45bfe8f5b2b743a7098dde6cf91d323d --- /dev/null +++ b/src/finiteVolume/fields/fvPatchFields/derived/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.C @@ -0,0 +1,153 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "rotatingWallVelocityFvPatchVectorField.H" +#include "addToRunTimeSelectionTable.H" +#include "volFields.H" +#include "surfaceFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +rotatingWallVelocityFvPatchVectorField::rotatingWallVelocityFvPatchVectorField +( + const fvPatch& p, + const DimensionedField<vector, volMesh>& iF +) +: + fixedValueFvPatchField<vector>(p, iF), + origin_(vector::zero), + axis_(vector::zero), + omega_(0) +{} + + +rotatingWallVelocityFvPatchVectorField::rotatingWallVelocityFvPatchVectorField +( + const rotatingWallVelocityFvPatchVectorField& ptf, + const fvPatch& p, + const DimensionedField<vector, volMesh>& iF, + const fvPatchFieldMapper& mapper +) +: + fixedValueFvPatchField<vector>(ptf, p, iF, mapper), + origin_(ptf.origin_), + axis_(ptf.axis_), + omega_(ptf.omega_) +{} + + +rotatingWallVelocityFvPatchVectorField::rotatingWallVelocityFvPatchVectorField +( + const fvPatch& p, + const DimensionedField<vector, volMesh>& iF, + const dictionary& dict +) +: + fixedValueFvPatchField<vector>(p, iF), + origin_(dict.lookup("origin")), + axis_(dict.lookup("axis")), + omega_(readScalar(dict.lookup("omega"))) +{ + // Evaluate the wall velocity + updateCoeffs(); +} + + +rotatingWallVelocityFvPatchVectorField::rotatingWallVelocityFvPatchVectorField +( + const rotatingWallVelocityFvPatchVectorField& pivpvf +) +: + fixedValueFvPatchField<vector>(pivpvf), + origin_(pivpvf.origin_), + axis_(pivpvf.axis_), + omega_(pivpvf.omega_) +{} + + +rotatingWallVelocityFvPatchVectorField::rotatingWallVelocityFvPatchVectorField +( + const rotatingWallVelocityFvPatchVectorField& pivpvf, + const DimensionedField<vector, volMesh>& iF +) +: + fixedValueFvPatchField<vector>(pivpvf, iF), + origin_(pivpvf.origin_), + axis_(pivpvf.axis_), + omega_(pivpvf.omega_) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void rotatingWallVelocityFvPatchVectorField::updateCoeffs() +{ + if (updated()) + { + return; + } + + // Calculate the rotating wall velocity from the specification of the motion + vectorField Up = (-omega_)*((patch().Cf() - origin_) ^ (axis_/mag(axis_))); + + // Remove the component of Up normal to the wall + // just in case it is not exactly circular + vectorField n = patch().nf(); + vectorField::operator=(Up - n*(n & Up)); + + fixedValueFvPatchVectorField::updateCoeffs(); +} + + +void rotatingWallVelocityFvPatchVectorField::write(Ostream& os) const +{ + fvPatchVectorField::write(os); + os.writeKeyword("origin") << origin_ << token::END_STATEMENT << nl; + os.writeKeyword("axis") << axis_ << token::END_STATEMENT << nl; + os.writeKeyword("omega") << omega_ << token::END_STATEMENT << nl; + writeEntry("value", os); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +makePatchTypeField +( + fvPatchVectorField, + rotatingWallVelocityFvPatchVectorField +); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/derived/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.H b/src/finiteVolume/fields/fvPatchFields/derived/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.H new file mode 100644 index 0000000000000000000000000000000000000000..5eed0e60ea464e39bf176e0448c67f90a32533b7 --- /dev/null +++ b/src/finiteVolume/fields/fvPatchFields/derived/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.H @@ -0,0 +1,192 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::rotatingWallVelocityFvPatchVectorField + +Description + Foam::rotatingWallVelocityFvPatchVectorField + +SourceFiles + rotatingWallVelocityFvPatchVectorField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef rotatingWallVelocityFvPatchVectorField_H +#define rotatingWallVelocityFvPatchVectorField_H + +#include "fixedValueFvPatchFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class rotatingWallVelocityFvPatch Declaration +\*---------------------------------------------------------------------------*/ + +class rotatingWallVelocityFvPatchVectorField +: + public fixedValueFvPatchVectorField +{ + // Private data + + //- Origin of the rotation + vector origin_; + + //- Axis of the rotation + vector axis_; + + //- Rotational speed + scalar omega_; + + +public: + + //- Runtime type information + TypeName("rotatingWallVelocity"); + + + // Constructors + + //- Construct from patch and internal field + rotatingWallVelocityFvPatchVectorField + ( + const fvPatch&, + const DimensionedField<vector, volMesh>& + ); + + //- Construct from patch, internal field and dictionary + rotatingWallVelocityFvPatchVectorField + ( + const fvPatch&, + const DimensionedField<vector, volMesh>&, + const dictionary& + ); + + //- Construct by mapping given rotatingWallVelocityFvPatchVectorField + // onto a new patch + rotatingWallVelocityFvPatchVectorField + ( + const rotatingWallVelocityFvPatchVectorField&, + const fvPatch&, + const DimensionedField<vector, volMesh>&, + const fvPatchFieldMapper& + ); + + //- Construct as copy + rotatingWallVelocityFvPatchVectorField + ( + const rotatingWallVelocityFvPatchVectorField& + ); + + //- Construct and return a clone + virtual tmp<fvPatchVectorField> clone() const + { + return tmp<fvPatchVectorField> + ( + new rotatingWallVelocityFvPatchVectorField(*this) + ); + } + + //- Construct as copy setting internal field reference + rotatingWallVelocityFvPatchVectorField + ( + const rotatingWallVelocityFvPatchVectorField&, + const DimensionedField<vector, volMesh>& + ); + + //- Construct and return a clone setting internal field reference + virtual tmp<fvPatchVectorField> clone + ( + const DimensionedField<vector, volMesh>& iF + ) const + { + return tmp<fvPatchVectorField> + ( + new rotatingWallVelocityFvPatchVectorField(*this, iF) + ); + } + + + + // Member functions + + // Access functions + + //- Return the origin of the rotation + const vector& origin() const + { + return origin_; + } + + //- Return the axis of the rotation + const vector& axis() const + { + return axis_; + } + + //- Return the rotational speed + const scalar& omega() const + { + return omega_; + } + + //- Return non-const access to the origin of the rotation + vector& origin() + { + return origin_; + } + + //- Return non-const access to the axis of the rotation + vector& axis() + { + return axis_; + } + + //- Return non-const access to the rotational speed + scalar& omega() + { + return omega_; + } + + + //- Update the coefficients associated with the patch field + virtual void updateCoeffs(); + + //- Write + virtual void write(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.C new file mode 100644 index 0000000000000000000000000000000000000000..413d5f86c2df747298ba770019f9efcea96b8fb4 --- /dev/null +++ b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.C @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "directMappedWallFvPatch.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(directMappedWallFvPatch, 0); + addToRunTimeSelectionTable(fvPatch, directMappedWallFvPatch, polyPatch); +} + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.H new file mode 100644 index 0000000000000000000000000000000000000000..4be7eed59274e264b6cf7acda28aa1bea1e001ed --- /dev/null +++ b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.H @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::directMappedWallFvPatch + +Description + Foam::directMappedWallFvPatch + +SourceFiles + directMappedWallFvPatch.C + +\*---------------------------------------------------------------------------*/ + +#ifndef directMappedWallFvPatch_H +#define directMappedWallFvPatch_H + +#include "fvPatch.H" +#include "directMappedWallPolyPatch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class directMappedWallFvPatch Declaration +\*---------------------------------------------------------------------------*/ + +class directMappedWallFvPatch +: + public fvPatch +{ + +public: + + //- Runtime type information + TypeName(directMappedWallPolyPatch::typeName_()); + + + // Constructors + + //- Construct from components + directMappedWallFvPatch + ( + const polyPatch& patch, + const fvBoundaryMesh& bm + ) + : + fvPatch(patch, bm) + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files index 9f849c58945b11d04d9193da1fe201653c09f01d..d5133cb33dad9e45beb50fa4785fdaee749b2d39 100644 --- a/src/meshTools/Make/files +++ b/src/meshTools/Make/files @@ -141,7 +141,10 @@ triSurface/triSurfaceTools/geompack/geompack.C twoDPointCorrector/twoDPointCorrector.C +directMapped/directMappedPolyPatch/directMappedPatchBase.C directMapped/directMappedPolyPatch/directMappedPolyPatch.C +directMapped/directMappedPolyPatch/directMappedWallPolyPatch.C directMapped/directMappedPointPatch/directMappedPointPatch.C +directMapped/directMappedPointPatch/directMappedWallPointPatch.C LIB = $(FOAM_LIBBIN)/libmeshTools diff --git a/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.C b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.C new file mode 100644 index 0000000000000000000000000000000000000000..4633d73ecf64e16932247f36966b30fcc0ea6261 --- /dev/null +++ b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.C @@ -0,0 +1,52 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "directMappedWallPointPatch.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +defineTypeNameAndDebug(directMappedWallPointPatch, 0); + +// Add the patch constructor functions to the hash tables +addToRunTimeSelectionTable +( + facePointPatch, + directMappedWallPointPatch, + polyPatch +); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.H b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.H new file mode 100644 index 0000000000000000000000000000000000000000..28bb87710518a8537bcdca5fafea01132081da5c --- /dev/null +++ b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.H @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::directMappedWallPointPatch + +Description + DirectMapped patch. + +SourceFiles + directMappedWallPointPatch.C + +\*---------------------------------------------------------------------------*/ + +#ifndef directMappedWallPointPatch_H +#define directMappedWallPointPatch_H + +#include "facePointPatch.H" +#include "directMappedWallPolyPatch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class directMappedWallPointPatch Declaration +\*---------------------------------------------------------------------------*/ + +class directMappedWallPointPatch +: + public facePointPatch +{ + +public: + + //- Runtime type information + TypeName(directMappedWallPolyPatch::typeName_()); + + + // Constructors + + //- Construct from polyPatch + directMappedWallPointPatch + ( + const polyPatch& patch, + const pointBoundaryMesh& bm + ) + : + facePointPatch(patch, bm) + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.C b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.C new file mode 100644 index 0000000000000000000000000000000000000000..81ef42bee9bd9e7813ae0a091c83cd2841c419e0 --- /dev/null +++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.C @@ -0,0 +1,657 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "directMappedPatchBase.H" +#include "addToRunTimeSelectionTable.H" +#include "ListListOps.H" +#include "meshSearch.H" +#include "meshTools.H" +#include "OFstream.H" +#include "Random.H" +#include "treeDataFace.H" +#include "indexedOctree.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(directMappedPatchBase, 0); + + template<> + const char* NamedEnum<directMappedPatchBase::sampleMode, 3>::names[] = + { + "nearestCell", + "nearestPatchFace", + "nearestFace" + }; + + const NamedEnum<directMappedPatchBase::sampleMode, 3> + directMappedPatchBase::sampleModeNames_; +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::directMappedPatchBase::collectSamples +( + pointField& samples, + labelList& patchFaceProcs, + labelList& patchFaces, + pointField& patchFc +) const +{ + + // Collect all sample points and the faces they come from. + List<pointField> globalFc(Pstream::nProcs()); + List<pointField> globalSamples(Pstream::nProcs()); + labelListList globalFaces(Pstream::nProcs()); + + globalFc[Pstream::myProcNo()] = patch_.faceCentres(); + globalSamples[Pstream::myProcNo()] = globalFc[Pstream::myProcNo()]+offset_; + globalFaces[Pstream::myProcNo()] = identity(patch_.size()); + + // Distribute to all processors + Pstream::gatherList(globalSamples); + Pstream::scatterList(globalSamples); + Pstream::gatherList(globalFaces); + Pstream::scatterList(globalFaces); + Pstream::gatherList(globalFc); + Pstream::scatterList(globalFc); + + // Rework into straight list + samples = ListListOps::combine<pointField> + ( + globalSamples, + accessOp<pointField>() + ); + patchFaces = ListListOps::combine<labelList> + ( + globalFaces, + accessOp<labelList>() + ); + patchFc = ListListOps::combine<pointField> + ( + globalFc, + accessOp<pointField>() + ); + + patchFaceProcs.setSize(patchFaces.size()); + labelList nPerProc + ( + ListListOps::subSizes + ( + globalFaces, + accessOp<labelList>() + ) + ); + label sampleI = 0; + forAll(nPerProc, procI) + { + for (label i = 0; i < nPerProc[procI]; i++) + { + patchFaceProcs[sampleI++] = procI; + } + } +} + + +// Find the processor/cell containing the samples. Does not account +// for samples being found in two processors. +void Foam::directMappedPatchBase::findSamples +( + const pointField& samples, + labelList& sampleProcs, + labelList& sampleIndices, + pointField& sampleLocations +) const +{ + // Lookup the correct region + const polyMesh& mesh = sampleMesh(); + + // All the info for nearest. Construct to miss + List<nearInfo> nearest(samples.size()); + + switch (mode_) + { + case NEARESTCELL: + { + if (samplePatch_.size() && samplePatch_ != "none") + { + FatalErrorIn + ( + "directMappedPatchBase::findSamples(const pointField&," + " labelList&, labelList&, pointField&) const" + ) << "No need to supply a patch name when in " + << sampleModeNames_[mode_] << " mode." << exit(FatalError); + } + + // Octree based search engine + meshSearch meshSearchEngine(mesh, false); + + forAll(samples, sampleI) + { + const point& sample = samples[sampleI]; + + label cellI = meshSearchEngine.findCell(sample); + + if (cellI == -1) + { + nearest[sampleI].second().first() = Foam::sqr(GREAT); + nearest[sampleI].second().second() = Pstream::myProcNo(); + } + else + { + const point& cc = mesh.cellCentres()[cellI]; + + nearest[sampleI].first() = pointIndexHit + ( + true, + cc, + cellI + ); + nearest[sampleI].second().first() = magSqr(cc-sample); + nearest[sampleI].second().second() = Pstream::myProcNo(); + } + } + break; + } + + case NEARESTPATCHFACE: + { + Random rndGen(123456); + + const polyPatch& pp = samplePolyPatch(); + + if (pp.empty()) + { + forAll(samples, sampleI) + { + nearest[sampleI].second().first() = Foam::sqr(GREAT); + nearest[sampleI].second().second() = Pstream::myProcNo(); + } + } + else + { + // patch faces + const labelList patchFaces(identity(pp.size()) + pp.start()); + + treeBoundBox patchBb + ( + treeBoundBox(pp.points(), pp.meshPoints()).extend + ( + rndGen, + 1E-4 + ) + ); + patchBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + patchBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + + indexedOctree<treeDataFace> boundaryTree + ( + treeDataFace // all information needed to search faces + ( + false, // do not cache bb + mesh, + patchFaces // boundary faces only + ), + patchBb, // overall search domain + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity + ); + + forAll(samples, sampleI) + { + const point& sample = samples[sampleI]; + + pointIndexHit& nearInfo = nearest[sampleI].first(); + nearInfo = boundaryTree.findNearest + ( + sample, + magSqr(patchBb.span()) + ); + + if (!nearInfo.hit()) + { + nearest[sampleI].second().first() = Foam::sqr(GREAT); + nearest[sampleI].second().second() = + Pstream::myProcNo(); + } + else + { + point fc(pp[nearInfo.index()].centre(pp.points())); + nearInfo.setPoint(fc); + nearest[sampleI].second().first() = magSqr(fc-sample); + nearest[sampleI].second().second() = + Pstream::myProcNo(); + } + } + } + break; + } + + case NEARESTFACE: + { + if (samplePatch_.size() && samplePatch_ != "none") + { + FatalErrorIn + ( + "directMappedPatchBase::findSamples(const pointField&," + " labelList&, labelList&, pointField&) const" + ) << "No need to supply a patch name when in " + << sampleModeNames_[mode_] << " mode." << exit(FatalError); + } + + // Octree based search engine + meshSearch meshSearchEngine(mesh, false); + + forAll(samples, sampleI) + { + const point& sample = samples[sampleI]; + + label faceI = meshSearchEngine.findNearestFace(sample); + + if (faceI == -1) + { + nearest[sampleI].second().first() = Foam::sqr(GREAT); + nearest[sampleI].second().second() = Pstream::myProcNo(); + } + else + { + const point& fc = mesh.faceCentres()[faceI]; + + nearest[sampleI].first() = pointIndexHit + ( + true, + fc, + faceI + ); + nearest[sampleI].second().first() = magSqr(fc-sample); + nearest[sampleI].second().second() = Pstream::myProcNo(); + } + } + break; + } + + default: + { + FatalErrorIn("directMappedPatchBase::findSamples(..)") + << "problem." << abort(FatalError); + } + } + + + // Find nearest. + Pstream::listCombineGather(nearest, nearestEqOp()); + Pstream::listCombineScatter(nearest); + + if (debug) + { + Info<< "directMappedPatchBase::findSamples on mesh " << sampleRegion_ + << " : " << endl; + forAll(nearest, sampleI) + { + label procI = nearest[sampleI].second().second(); + label localI = nearest[sampleI].first().index(); + + Info<< " " << sampleI << " coord:"<< samples[sampleI] + << " found on processor:" << procI + << " in local cell/face:" << localI + << " with cc:" << nearest[sampleI].first().rawPoint() << endl; + } + } + + // Check for samples not being found + forAll(nearest, sampleI) + { + if (!nearest[sampleI].first().hit()) + { + FatalErrorIn + ( + "directMappedPatchBase::findSamples" + "(const pointField&, labelList&" + ", labelList&, pointField&)" + ) << "Did not find sample " << samples[sampleI] + << " on any processor of region" << sampleRegion_ + << exit(FatalError); + } + } + + + // Convert back into proc+local index + sampleProcs.setSize(samples.size()); + sampleIndices.setSize(samples.size()); + sampleLocations.setSize(samples.size()); + + forAll(nearest, sampleI) + { + sampleProcs[sampleI] = nearest[sampleI].second().second(); + sampleIndices[sampleI] = nearest[sampleI].first().index(); + sampleLocations[sampleI] = nearest[sampleI].first().hitPoint(); + } +} + + +void Foam::directMappedPatchBase::calcMapping() const +{ + if (mapPtr_.valid()) + { + FatalErrorIn("directMappedPatchBase::calcMapping() const") + << "Mapping already calculated" << exit(FatalError); + } + + if + ( + offset_ == vector::zero + && sampleRegion_ == patch_.boundaryMesh().mesh().name() + ) + { + FatalErrorIn("directMappedPatchBase::calcMapping() const") + << "Invalid offset " << offset_ << endl + << "Offset is the vector added to the patch face centres to" + << " find the cell supplying the data." + << exit(FatalError); + } + + + // Get global list of all samples and the processor and face they come from. + pointField samples; + labelList patchFaceProcs; + labelList patchFaces; + pointField patchFc; + collectSamples(samples, patchFaceProcs, patchFaces, patchFc); + + // Find processor and cell/face samples are in and actual location. + labelList sampleProcs; + labelList sampleIndices; + pointField sampleLocations; + findSamples(samples, sampleProcs, sampleIndices, sampleLocations); + + + // Now we have all the data we need: + // - where sample originates from (so destination when mapping): + // patchFaces, patchFaceProcs. + // - cell/face sample is in (so source when mapping) + // sampleIndices, sampleProcs. + + //forAll(samples, i) + //{ + // Info<< i << " need data in region " + // << patch_.boundaryMesh().mesh().name() + // << " for proc:" << patchFaceProcs[i] + // << " face:" << patchFaces[i] + // << " at:" << patchFc[i] << endl + // << "Found data in region " << sampleRegion_ + // << " at proc:" << sampleProcs[i] + // << " face:" << sampleIndices[i] + // << " at:" << sampleLocations[i] + // << nl << endl; + //} + + + + if (debug && Pstream::master()) + { + OFstream str + ( + patch_.boundaryMesh().mesh().time().path() + / patch_.name() + + "_directMapped.obj" + ); + Pout<< "Dumping mapping as lines from patch faceCentres to" + << " sampled cellCentres to file " << str.name() << endl; + + label vertI = 0; + + forAll(patchFc, i) + { + meshTools::writeOBJ(str, patchFc[i]); + vertI++; + meshTools::writeOBJ(str, sampleLocations[i]); + vertI++; + str << "l " << vertI-1 << ' ' << vertI << nl; + } + } + + + // Check that actual offset vector (sampleLocations - patchFc) is more or + // less constant. + if (Pstream::master()) + { + const scalarField magOffset(mag(sampleLocations - patchFc)); + const scalar avgOffset(average(magOffset)); + + forAll(magOffset, sampleI) + { + if (mag(magOffset[sampleI]-avgOffset) > max(SMALL, 0.001*avgOffset)) + { + WarningIn("directMappedPatchBase::calcMapping() const") + << "The actual cell/face centres picked up using offset " + << offset_ << " are not" << endl + << " on a single plane." + << " This might give numerical problems." << endl + << " At patchface " << patchFc[sampleI] + << " the sampled cell/face " << sampleLocations[sampleI] + << endl + << " is not on a plane " << avgOffset + << " offset from the patch." << endl + << " You might want to shift your plane offset." + << " Set the debug flag to get a dump of sampled cells." + << endl; + break; + } + } + } + + + // Determine schedule. + mapPtr_.reset(new mapDistribute(sampleProcs, patchFaceProcs)); + + // Rework the schedule from indices into samples to cell data to send, + // face data to receive. + + labelListList& subMap = mapPtr_().subMap(); + labelListList& constructMap = mapPtr_().constructMap(); + + forAll(subMap, procI) + { + subMap[procI] = UIndirectList<label> + ( + sampleIndices, + subMap[procI] + ); + constructMap[procI] = UIndirectList<label> + ( + patchFaces, + constructMap[procI] + ); + + if (debug) + { + Pout<< "To proc:" << procI << " sending values of cells/faces:" + << subMap[procI] << endl; + Pout<< "From proc:" << procI << " receiving values of patch faces:" + << constructMap[procI] << endl; + } + } + + // Redo constructSize + mapPtr_().constructSize() = patch_.size(); + + if (debug) + { + // Check that all elements get a value. + PackedBoolList used(patch_.size()); + forAll(constructMap, procI) + { + const labelList& map = constructMap[procI]; + + forAll(map, i) + { + label faceI = map[i]; + + if (used[faceI] == 0) + { + used[faceI] = 1; + } + else + { + FatalErrorIn("directMappedPatchBase::calcMapping() const") + << "On patch " << patch_.name() + << " patchface " << faceI + << " is assigned to more than once." + << abort(FatalError); + } + } + } + forAll(used, faceI) + { + if (used[faceI] == 0) + { + FatalErrorIn("directMappedPatchBase::calcMapping() const") + << "On patch " << patch_.name() + << " patchface " << faceI + << " is never assigned to." + << abort(FatalError); + } + } + } +} + + +// * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * * * // + +Foam::directMappedPatchBase::directMappedPatchBase +( + const polyPatch& pp +) +: + patch_(pp), + sampleRegion_(patch_.boundaryMesh().mesh().name()), + mode_(NEARESTPATCHFACE), + samplePatch_("none"), + offset_(vector::zero), + sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()), + mapPtr_(NULL) +{} + + +Foam::directMappedPatchBase::directMappedPatchBase +( + const polyPatch& pp, + const dictionary& dict +) +: + patch_(pp), + sampleRegion_ + ( + dict.lookupOrDefault + ( + "sampleRegion", + patch_.boundaryMesh().mesh().name() + ) + ), + mode_(sampleModeNames_.read(dict.lookup("sampleMode"))), + samplePatch_(dict.lookup("samplePatch")), + offset_(dict.lookup("offset")), + sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()), + mapPtr_(NULL) +{} + + +Foam::directMappedPatchBase::directMappedPatchBase +( + const polyPatch& pp, + const directMappedPatchBase& dmp +) +: + patch_(pp), + sampleRegion_(dmp.sampleRegion_), + mode_(dmp.mode_), + samplePatch_(dmp.samplePatch_), + offset_(dmp.offset_), + sameRegion_(dmp.sameRegion_), + mapPtr_(NULL) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::directMappedPatchBase::~directMappedPatchBase() +{ + clearOut(); +} + + +void Foam::directMappedPatchBase::clearOut() +{ + mapPtr_.clear(); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +const Foam::polyMesh& Foam::directMappedPatchBase::sampleMesh() const +{ + return patch_.boundaryMesh().mesh().time().lookupObject<polyMesh> + ( + sampleRegion_ + ); +} + + +const Foam::polyPatch& Foam::directMappedPatchBase::samplePolyPatch() const +{ + const polyMesh& nbrMesh = sampleMesh(); + + label patchI = nbrMesh.boundaryMesh().findPatchID(samplePatch_); + + if (patchI == -1) + { + FatalErrorIn("directMappedPatchBase::samplePolyPatch() ") + << "Cannot find patch " << samplePatch_ + << " in region " << sampleRegion_ << endl + << "Valid patches are " << nbrMesh.boundaryMesh().names() + << exit(FatalError); + } + + return nbrMesh.boundaryMesh()[patchI]; +} + + +void Foam::directMappedPatchBase::write(Ostream& os) const +{ + os.writeKeyword("sampleMode") << sampleModeNames_[mode_] + << token::END_STATEMENT << nl; + os.writeKeyword("sampleRegion") << sampleRegion_ + << token::END_STATEMENT << nl; + os.writeKeyword("samplePatch") << samplePatch_ + << token::END_STATEMENT << nl; + os.writeKeyword("offset") << offset_ << token::END_STATEMENT << nl; +} + + +// ************************************************************************* // diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.H b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.H new file mode 100644 index 0000000000000000000000000000000000000000..1a476f66a9eb392021ac0d8085bfbe804f82bccf --- /dev/null +++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.H @@ -0,0 +1,248 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::directMappedPatchBase + +Description + Determines a mapping between patch face centres and mesh cell or face + centres and processors they're on. + +Note + Storage is not optimal. It temporary collects all (patch)face centres + on all processors to keep the addressing calculation simple. + +SourceFiles + directMappedPatchBase.C + +\*---------------------------------------------------------------------------*/ + +#ifndef directMappedPatchBase_H +#define directMappedPatchBase_H + +#include "pointField.H" +#include "Tuple2.H" +#include "pointIndexHit.H" +#include "mapDistribute.H" + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class polyPatch; +class polyMesh; + +/*---------------------------------------------------------------------------*\ + Class directMappedPatchBase Declaration +\*---------------------------------------------------------------------------*/ + +class directMappedPatchBase +{ + +public: + + //- Mesh items to sample + enum sampleMode + { + NEARESTCELL, + NEARESTPATCHFACE, + NEARESTFACE + }; + +private: + + // Private data + + static const NamedEnum<sampleMode, 3> sampleModeNames_; + + //- Patch to sample + const polyPatch& patch_; + + //- Region to sample + const word sampleRegion_; + + //- What to sample + const sampleMode mode_; + + //- Patch (only if NEARESTBOUNDARY) + const word samplePatch_; + + //- Offset vector + const vector offset_; + + //- Same region + const bool sameRegion_; + + + // Derived information + + //- Communication schedule: + // - Cells/faces to sample per processor + // - Patch faces to receive per processor + // - schedule + mutable autoPtr<mapDistribute> mapPtr_; + + // Private Member Functions + + //- Collect single list of samples and originating processor+face. + void collectSamples + ( + pointField&, + labelList& patchFaceProcs, + labelList& patchFaces, + pointField& patchFc + ) const; + + //- Find cells/faces containing samples + void findSamples + ( + const pointField&, + labelList& sampleProcs, // processor containing sample + labelList& sampleIndices, // local index of cell/face + pointField& sampleLocations // actual representative location + ) const; + + //- Calculate matching + void calcMapping() const; + + + // Private class + + //- Private class for finding nearest + // - point+local index + // - sqr(distance) + // - processor + typedef Tuple2<pointIndexHit, Tuple2<scalar, label> > nearInfo; + + class nearestEqOp + { + + public: + + void operator()(nearInfo& x, const nearInfo& y) const + { + if (y.first().hit()) + { + if (!x.first().hit()) + { + x = y; + } + else if (y.second().first() < x.second().first()) + { + x = y; + } + } + } + }; + + +public: + + //- Runtime type information + ClassName("directMappedPatchBase"); + + + // Constructors + + //- Construct from components + directMappedPatchBase(const polyPatch&); + + //- Construct from dictionary + directMappedPatchBase(const polyPatch&, const dictionary&); + + //- Construct as copy, resetting patch + directMappedPatchBase(const polyPatch&, const directMappedPatchBase&); + + + // Destructor + + ~directMappedPatchBase(); + + void clearOut(); + + + // Member functions + + //- What to sample + const sampleMode& mode() const + { + return mode_; + } + + //- Region to sample + const word& sampleRegion() const + { + return sampleRegion_; + } + + //- Patch (only if NEARESTBOUNDARY) + const word& samplePatch() const + { + return samplePatch_; + } + + //- Offset vector (from patch faces to destination mesh objects) + const vector& offset() const + { + return offset_; + } + + //- Return reference to the parallel distribution map + const mapDistribute& map() const + { + if (mapPtr_.empty()) + { + calcMapping(); + } + return mapPtr_(); + } + + //- Cached sampleRegion != mesh.name() + bool sameRegion() const + { + return sameRegion_; + } + + //- Get the region mesh + const polyMesh& sampleMesh() const; + + //- Get the patch on the region + const polyPatch& samplePolyPatch() const; + + //- Write as a dictionary + virtual void write(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.C b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.C index 9dbe7e8c1331ef7a68bdb0d4ade891b8aa002aef..0058c84d0df42bd5448ff9e3ba15fd4f1674c95e 100644 --- a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.C +++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.C @@ -26,11 +26,6 @@ License #include "directMappedPolyPatch.H" #include "addToRunTimeSelectionTable.H" -#include "ListListOps.H" -#include "meshSearch.H" -#include "mapDistribute.H" -#include "meshTools.H" -#include "OFstream.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -40,469 +35,11 @@ namespace Foam addToRunTimeSelectionTable(polyPatch, directMappedPolyPatch, word); addToRunTimeSelectionTable(polyPatch, directMappedPolyPatch, dictionary); - - - template<> - const char* NamedEnum<directMappedPolyPatch::sampleMode, 3>::names[] = - { - "nearestCell", - "nearestPatchFace", - "nearestFace" - }; - - const NamedEnum<directMappedPolyPatch::sampleMode, 3> - directMappedPolyPatch::sampleModeNames_; } // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -void Foam::directMappedPolyPatch::collectSamples -( - pointField& samples, - labelList& patchFaceProcs, - labelList& patchFaces, - pointField& patchFc -) const -{ - - // Collect all sample points and the faces they come from. - List<pointField> globalFc(Pstream::nProcs()); - List<pointField> globalSamples(Pstream::nProcs()); - labelListList globalFaces(Pstream::nProcs()); - - globalFc[Pstream::myProcNo()] = this->faceCentres(); - globalSamples[Pstream::myProcNo()] = globalFc[Pstream::myProcNo()]+offset_; - globalFaces[Pstream::myProcNo()] = identity(size()); - - // Distribute to all processors - Pstream::gatherList(globalSamples); - Pstream::scatterList(globalSamples); - Pstream::gatherList(globalFaces); - Pstream::scatterList(globalFaces); - Pstream::gatherList(globalFc); - Pstream::scatterList(globalFc); - - // Rework into straight list - samples = ListListOps::combine<pointField> - ( - globalSamples, - accessOp<pointField>() - ); - patchFaces = ListListOps::combine<labelList> - ( - globalFaces, - accessOp<labelList>() - ); - patchFc = ListListOps::combine<pointField> - ( - globalFc, - accessOp<pointField>() - ); - - patchFaceProcs.setSize(patchFaces.size()); - labelList nPerProc - ( - ListListOps::subSizes - ( - globalFaces, - accessOp<labelList>() - ) - ); - label sampleI = 0; - forAll(nPerProc, procI) - { - for (label i = 0; i < nPerProc[procI]; i++) - { - patchFaceProcs[sampleI++] = procI; - } - } -} - - -// Find the processor/cell containing the samples. Does not account -// for samples being found in two processors. -void Foam::directMappedPolyPatch::findSamples -( - const pointField& samples, - labelList& sampleProcs, - labelList& sampleIndices, - pointField& sampleLocations -) const -{ - const polyMesh& mesh = boundaryMesh().mesh(); - - // All the info for nearest. Construct to miss - List<nearInfo> nearest(samples.size()); - - switch (mode_) - { - case NEARESTCELL: - { - if (samplePatch_.size() && samplePatch_ != "none") - { - FatalErrorIn - ( - "directMappedPolyPatch::findSamples(const pointField&," - " labelList&, labelList&, pointField&) const" - ) << "No need to supply a patch name when in " - << sampleModeNames_[mode_] << " mode." << exit(FatalError); - } - - // Octree based search engine - meshSearch meshSearchEngine(mesh, false); - - forAll(samples, sampleI) - { - const point& sample = samples[sampleI]; - - label cellI = meshSearchEngine.findCell(sample); - - if (cellI == -1) - { - nearest[sampleI].second().first() = Foam::sqr(GREAT); - nearest[sampleI].second().second() = Pstream::myProcNo(); - } - else - { - const point& cc = mesh.cellCentres()[cellI]; - - nearest[sampleI].first() = pointIndexHit - ( - true, - cc, - cellI - ); - nearest[sampleI].second().first() = magSqr(cc-sample); - nearest[sampleI].second().second() = Pstream::myProcNo(); - } - } - break; - } - - case NEARESTPATCHFACE: - { - label patchI = boundaryMesh().findPatchID(samplePatch_); - - if (patchI == -1) - { - FatalErrorIn("directMappedPolyPatch::findSamples(..)") - << "Cannot find patch " << samplePatch_ << endl - << "Valid patches are " << boundaryMesh().names() - << exit(FatalError); - } - - Random rndGen(123456); - - const polyPatch& pp = boundaryMesh()[patchI]; - - if (pp.empty()) - { - forAll(samples, sampleI) - { - nearest[sampleI].second().first() = Foam::sqr(GREAT); - nearest[sampleI].second().second() = Pstream::myProcNo(); - } - } - else - { - // patch faces - const labelList patchFaces(identity(pp.size()) + pp.start()); - - treeBoundBox patchBb - ( - treeBoundBox(pp.points(), pp.meshPoints()).extend - ( - rndGen, - 1E-4 - ) - ); - patchBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); - patchBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); - - autoPtr<indexedOctree<treeDataFace> > boundaryTree - ( - new indexedOctree<treeDataFace> - ( - treeDataFace // all information needed to search faces - ( - false, // do not cache bb - mesh, - patchFaces // boundary faces only - ), - patchBb, // overall search domain - 8, // maxLevel - 10, // leafsize - 3.0 // duplicity - ) - ); - - forAll(samples, sampleI) - { - const point& sample = samples[sampleI]; - - pointIndexHit& nearInfo = nearest[sampleI].first(); - nearInfo = boundaryTree().findNearest - ( - sample, - magSqr(patchBb.span()) - ); - - if (!nearInfo.hit()) - { - nearest[sampleI].second().first() = Foam::sqr(GREAT); - nearest[sampleI].second().second() = - Pstream::myProcNo(); - } - else - { - point fc(pp[nearInfo.index()].centre(pp.points())); - nearInfo.setPoint(fc); - nearest[sampleI].second().first() = magSqr(fc-sample); - nearest[sampleI].second().second() = - Pstream::myProcNo(); - } - } - } - break; - } - - case NEARESTFACE: - { - if (samplePatch_.size() && samplePatch_ != "none") - { - FatalErrorIn - ( - "directMappedPolyPatch::findSamples(const pointField&," - " labelList&, labelList&, pointField&) const" - ) << "No need to supply a patch name when in " - << sampleModeNames_[mode_] << " mode." << exit(FatalError); - } - - // Octree based search engine - meshSearch meshSearchEngine(mesh, false); - - forAll(samples, sampleI) - { - const point& sample = samples[sampleI]; - - label faceI = meshSearchEngine.findNearestFace(sample); - - if (faceI == -1) - { - nearest[sampleI].second().first() = Foam::sqr(GREAT); - nearest[sampleI].second().second() = Pstream::myProcNo(); - } - else - { - const point& fc = mesh.faceCentres()[faceI]; - - nearest[sampleI].first() = pointIndexHit - ( - true, - fc, - faceI - ); - nearest[sampleI].second().first() = magSqr(fc-sample); - nearest[sampleI].second().second() = Pstream::myProcNo(); - } - } - break; - } - - default: - { - FatalErrorIn("directMappedPolyPatch::findSamples(..)") - << "problem." << abort(FatalError); - } - } - - - // Find nearest. - Pstream::listCombineGather(nearest, nearestEqOp()); - Pstream::listCombineScatter(nearest); - - if (debug) - { - Info<< "directMappedPolyPatch::findSamples : " << endl; - forAll(nearest, sampleI) - { - label procI = nearest[sampleI].second().second(); - label localI = nearest[sampleI].first().index(); - - Info<< " " << sampleI << " coord:"<< samples[sampleI] - << " found on processor:" << procI - << " in local cell/face:" << localI - << " with cc:" << nearest[sampleI].first().rawPoint() << endl; - } - } - - // Check for samples not being found - forAll(nearest, sampleI) - { - if (!nearest[sampleI].first().hit()) - { - FatalErrorIn - ( - "directMappedPolyPatch::findSamples" - "(const pointField&, labelList&" - ", labelList&, pointField&)" - ) << "Did not find sample " << samples[sampleI] - << " on any processor." << exit(FatalError); - } - } - - - // Convert back into proc+local index - sampleProcs.setSize(samples.size()); - sampleIndices.setSize(samples.size()); - sampleLocations.setSize(samples.size()); - - forAll(nearest, sampleI) - { - sampleProcs[sampleI] = nearest[sampleI].second().second(); - sampleIndices[sampleI] = nearest[sampleI].first().index(); - sampleLocations[sampleI] = nearest[sampleI].first().hitPoint(); - } -} - - -void Foam::directMappedPolyPatch::calcMapping() const -{ - if (sendLabelsPtr_.valid()) - { - FatalErrorIn("directMappedPolyPatch::calcMapping() const") - << "Mapping already calculated" << exit(FatalError); - } - - if (offset_ == vector::zero) - { - FatalErrorIn("directMappedPolyPatch::calcMapping() const") - << "Invalid offset " << offset_ << endl - << "Offset is the vector added to the patch face centres to" - << " find the cell supplying the data." - << exit(FatalError); - } - - - // Get global list of all samples and the processor and face they come from. - pointField samples; - labelList patchFaceProcs; - labelList patchFaces; - pointField patchFc; - collectSamples(samples, patchFaceProcs, patchFaces, patchFc); - - // Find processor and cell/face samples are in and actual location. - labelList sampleProcs; - labelList sampleIndices; - pointField sampleLocations; - findSamples(samples, sampleProcs, sampleIndices, sampleLocations); - - - // Now we have all the data we need: - // - where sample originates from (so destination when mapping): - // patchFaces, patchFaceProcs. - // - cell/face sample is in (so source when mapping) - // sampleIndices, sampleProcs. - - - if (debug && Pstream::master()) - { - OFstream str - ( - boundaryMesh().mesh().time().path() - / name() - + "_directMapped.obj" - ); - Pout<< "Dumping mapping as lines from patch faceCentres to" - << " sampled cellCentres to file " << str.name() << endl; - - label vertI = 0; - - forAll(patchFc, i) - { - meshTools::writeOBJ(str, patchFc[i]); - vertI++; - meshTools::writeOBJ(str, sampleLocations[i]); - vertI++; - str << "l " << vertI-1 << ' ' << vertI << nl; - } - } - - - // Check that actual offset vector (sampleLocations - patchFc) is more or - // less constant. - if (Pstream::master()) - { - const scalarField magOffset(mag(sampleLocations - patchFc)); - const scalar avgOffset(average(magOffset)); - - forAll(magOffset, sampleI) - { - if (mag(magOffset[sampleI]-avgOffset) > 0.001*avgOffset) - { - WarningIn("directMappedPolyPatch::calcMapping() const") - << "The actual cell centres picked up using offset " - << offset_ << " are not" << endl - << " on a single plane." - << " This might give numerical problems." << endl - << " At patchface " << patchFc[sampleI] - << " the sampled cell " << sampleLocations[sampleI] << endl - << " is not on a plane " << avgOffset - << " offset from the patch." << endl - << " You might want to shift your plane offset." - << " Set the debug flag to get a dump of sampled cells." - << endl; - break; - } - } - } - - - // Determine schedule. - mapDistribute distMap(sampleProcs, patchFaceProcs); - - // Rework the schedule to cell data to send, face data to receive. - schedulePtr_.reset(new List<labelPair>(distMap.schedule())); - - const labelListList& subMap = distMap.subMap(); - const labelListList& constructMap = distMap.constructMap(); - - // Extract the particular data I need to send and receive. - sendLabelsPtr_.reset(new labelListList(subMap.size())); - labelListList& sendLabels = sendLabelsPtr_(); - - forAll(subMap, procI) - { - sendLabels[procI] = UIndirectList<label> - ( - sampleIndices, - subMap[procI] - ); - - if (debug) - { - Pout<< "To proc:" << procI << " sending values of cells/faces:" - << sendLabels[procI] << endl; - } - } - - receiveFaceLabelsPtr_.reset(new labelListList(constructMap.size())); - labelListList& receiveFaceLabels = receiveFaceLabelsPtr_(); - - forAll(constructMap, procI) - { - receiveFaceLabels[procI] = - UIndirectList<label>(patchFaces, constructMap[procI]); - - if (debug) - { - Pout<< "From proc:" << procI << " receiving values of patch faces:" - << receiveFaceLabels[procI] << endl; - } - } -} - // * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * * * // @@ -516,12 +53,7 @@ Foam::directMappedPolyPatch::directMappedPolyPatch ) : polyPatch(name, size, start, index, bm), - mode_(NEARESTPATCHFACE), - samplePatch_("none"), - offset_(vector::zero), - schedulePtr_(NULL), - sendLabelsPtr_(NULL), - receiveFaceLabelsPtr_(NULL) + directMappedPatchBase(static_cast<const polyPatch&>(*this)) {} @@ -534,12 +66,7 @@ Foam::directMappedPolyPatch::directMappedPolyPatch ) : polyPatch(name, dict, index, bm), - mode_(sampleModeNames_.read(dict.lookup("sampleMode"))), - samplePatch_(dict.lookup("samplePatch")), - offset_(dict.lookup("offset")), - schedulePtr_(NULL), - sendLabelsPtr_(NULL), - receiveFaceLabelsPtr_(NULL) + directMappedPatchBase(*this, dict) {} @@ -550,12 +77,7 @@ Foam::directMappedPolyPatch::directMappedPolyPatch ) : polyPatch(pp, bm), - mode_(pp.mode_), - samplePatch_(pp.samplePatch_), - offset_(pp.offset_), - schedulePtr_(NULL), - sendLabelsPtr_(NULL), - receiveFaceLabelsPtr_(NULL) + directMappedPatchBase(*this, pp) {} @@ -569,12 +91,7 @@ Foam::directMappedPolyPatch::directMappedPolyPatch ) : polyPatch(pp, bm, index, newSize, newStart), - mode_(pp.mode_), - samplePatch_(pp.samplePatch_), - offset_(pp.offset_), - schedulePtr_(NULL), - sendLabelsPtr_(NULL), - receiveFaceLabelsPtr_(NULL) + directMappedPatchBase(*this, pp) {} @@ -582,28 +99,59 @@ Foam::directMappedPolyPatch::directMappedPolyPatch Foam::directMappedPolyPatch::~directMappedPolyPatch() { - clearOut(); + directMappedPatchBase::clearOut(); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::directMappedPolyPatch::clearOut() +//- Initialise the calculation of the patch geometry +void Foam::directMappedPolyPatch::initGeometry() +{ + polyPatch::initGeometry(); + directMappedPatchBase::clearOut(); +} + +//- Calculate the patch geometry +void Foam::directMappedPolyPatch::calcGeometry() +{ + polyPatch::calcGeometry(); + directMappedPatchBase::clearOut(); +} + +//- Initialise the patches for moving points +void Foam::directMappedPolyPatch::initMovePoints(const pointField& p) +{ + polyPatch::initMovePoints(p); + directMappedPatchBase::clearOut(); +} + +//- Correct patches after moving points +void Foam::directMappedPolyPatch::movePoints(const pointField& p) +{ + polyPatch::movePoints(p); + directMappedPatchBase::clearOut(); +} + +//- Initialise the update of the patch topology +void Foam::directMappedPolyPatch::initUpdateMesh() +{ + polyPatch::initUpdateMesh(); + directMappedPatchBase::clearOut(); +} + +//- Update of the patch topology +void Foam::directMappedPolyPatch::updateMesh() { - schedulePtr_.clear(); - sendLabelsPtr_.clear(); - receiveFaceLabelsPtr_.clear(); + polyPatch::updateMesh(); + directMappedPatchBase::clearOut(); } void Foam::directMappedPolyPatch::write(Ostream& os) const { polyPatch::write(os); - os.writeKeyword("sampleMode") << sampleModeNames_[mode_] - << token::END_STATEMENT << nl; - os.writeKeyword("samplePatch") << samplePatch_ - << token::END_STATEMENT << nl; - os.writeKeyword("offset") << offset_ << token::END_STATEMENT << nl; + directMappedPatchBase::write(os); } diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.H b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.H index 413737aa80c5cbb694fccb8dc8db7866c8d643b5..e07f78a958cfc3c85c4d361b253f9f068a342433 100644 --- a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.H +++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.H @@ -42,9 +42,7 @@ SourceFiles #define directMappedPolyPatch_H #include "polyPatch.H" -#include "labelPair.H" -#include "Tuple2.H" -#include "pointIndexHit.H" +#include "directMappedPatchBase.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -52,154 +50,43 @@ SourceFiles namespace Foam { +class polyMesh; + /*---------------------------------------------------------------------------*\ Class directMappedPolyPatch Declaration \*---------------------------------------------------------------------------*/ class directMappedPolyPatch : - public polyPatch + public polyPatch, + public directMappedPatchBase { -public: - - //- Mesh items to sample - enum sampleMode - { - NEARESTCELL, - NEARESTPATCHFACE, - NEARESTFACE - }; - -private: - - // Private data - - static const NamedEnum<sampleMode, 3> sampleModeNames_; - - //- What to sample - sampleMode mode_; - - //- Patch (only if NEARESTBOUNDARY) - const word samplePatch_; - - //- Offset vector - const vector offset_; - - - - // Derived information - - //- Communication schedule. - mutable autoPtr<List<labelPair> > schedulePtr_; - - //- Cells/faces to sample per processor - mutable autoPtr<labelListList> sendLabelsPtr_; - - //- Patch faces to receive per processor - mutable autoPtr<labelListList> receiveFaceLabelsPtr_; - - - // Private Member Functions - - //- Collect single list of samples and originating processor+face. - void collectSamples - ( - pointField&, - labelList& patchFaceProcs, - labelList& patchFaces, - pointField& patchFc - ) const; - - //- Find cells/faces containing samples - void findSamples - ( - const pointField&, - labelList& sampleProcs, // processor containing sample - labelList& sampleIndices, // local index of cell/face - pointField& sampleLocations // actual representative location - ) const; - - //- Calculate matching - void calcMapping() const; - - - // Private class - - //- Private class for finding nearest - // - point+local index - // - sqr(distance) - // - processor - typedef Tuple2<pointIndexHit, Tuple2<scalar, label> > nearInfo; - - class nearestEqOp - { - - public: - - void operator()(nearInfo& x, const nearInfo& y) const - { - if (y.first().hit()) - { - if (!x.first().hit()) - { - x = y; - } - else if (y.second().first() < x.second().first()) - { - x = y; - } - } - } - }; - - - protected: - void clearOut(); - //- Initialise the calculation of the patch geometry - virtual void initGeometry() - { - clearOut(); - } + virtual void initGeometry(); //- Calculate the patch geometry - virtual void calcGeometry() - { - clearOut(); - } + virtual void calcGeometry(); //- Initialise the patches for moving points - virtual void initMovePoints(const pointField&) - { - clearOut(); - } + virtual void initMovePoints(const pointField&); //- Correct patches after moving points - virtual void movePoints(const pointField& p) - { - clearOut(); - } + virtual void movePoints(const pointField&); //- Initialise the update of the patch topology - virtual void initUpdateMesh() - { - clearOut(); - } + virtual void initUpdateMesh(); //- Update of the patch topology - virtual void updateMesh() - { - clearOut(); - } + virtual void updateMesh(); public: //- Runtime type information - TypeName("directMappedPatch"); + TypeName("directMapped"); // Constructors @@ -271,72 +158,6 @@ public: // Member functions - //- What to sample - const sampleMode& mode() const - { - return mode_; - } - - //- Patch (only if NEARESTBOUNDARY) - const word& samplePatch() const - { - return samplePatch_; - } - - //- Offset vector (from patch faces to destination mesh objects) - const vector& offset() const - { - return offset_; - } - - //- Access to communication. - const List<labelPair>& schedule() const - { - if (schedulePtr_.empty()) - { - calcMapping(); - } - return schedulePtr_(); - } - - //- Cells/faces to sample per processor - const labelListList& sendLabels() const - { - if (debug) - { - Pout<< "Asking for sendLabels." << endl; - } - - if (sendLabelsPtr_.empty()) - { - if (debug) - { - Pout<< "Calculating mapping." << endl; - calcMapping(); - } - } - return sendLabelsPtr_(); - } - - //- Patch faces to receive per processor - const labelListList& receiveFaceLabels() const - { - if (debug) - { - Pout<< "Asking for receiveFaceLabels." << endl; - } - - if (receiveFaceLabelsPtr_.empty()) - { - if (debug) - { - Pout<< "Calculating mapping." << endl; - calcMapping(); - } - } - return receiveFaceLabelsPtr_(); - } - //- Write the polyPatch data as a dictionary virtual void write(Ostream&) const; }; diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.C b/src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.C new file mode 100644 index 0000000000000000000000000000000000000000..daaee3bcb4adf2b275627ede0a7489de6ca1115a --- /dev/null +++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.C @@ -0,0 +1,163 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "directMappedWallPolyPatch.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(directMappedWallPolyPatch, 0); + + addToRunTimeSelectionTable(polyPatch, directMappedWallPolyPatch, word); + addToRunTimeSelectionTable + ( + polyPatch, + directMappedWallPolyPatch, + dictionary + ); +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + + +// * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * * * // + +Foam::directMappedWallPolyPatch::directMappedWallPolyPatch +( + const word& name, + const label size, + const label start, + const label index, + const polyBoundaryMesh& bm +) +: + wallPolyPatch(name, size, start, index, bm), + directMappedPatchBase(static_cast<const polyPatch&>(*this)) +{} + + +Foam::directMappedWallPolyPatch::directMappedWallPolyPatch +( + const word& name, + const dictionary& dict, + const label index, + const polyBoundaryMesh& bm +) +: + wallPolyPatch(name, dict, index, bm), + directMappedPatchBase(*this, dict) +{} + + +Foam::directMappedWallPolyPatch::directMappedWallPolyPatch +( + const directMappedWallPolyPatch& pp, + const polyBoundaryMesh& bm +) +: + wallPolyPatch(pp, bm), + directMappedPatchBase(*this, pp) +{} + + +Foam::directMappedWallPolyPatch::directMappedWallPolyPatch +( + const directMappedWallPolyPatch& pp, + const polyBoundaryMesh& bm, + const label index, + const label newSize, + const label newStart +) +: + wallPolyPatch(pp, bm, index, newSize, newStart), + directMappedPatchBase(*this, pp) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::directMappedWallPolyPatch::~directMappedWallPolyPatch() +{ + directMappedPatchBase::clearOut(); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +//- Initialise the calculation of the patch geometry +void Foam::directMappedWallPolyPatch::initGeometry() +{ + wallPolyPatch::initGeometry(); + directMappedPatchBase::clearOut(); +} + +//- Calculate the patch geometry +void Foam::directMappedWallPolyPatch::calcGeometry() +{ + wallPolyPatch::calcGeometry(); + directMappedPatchBase::clearOut(); +} + +//- Initialise the patches for moving points +void Foam::directMappedWallPolyPatch::initMovePoints(const pointField& p) +{ + wallPolyPatch::initMovePoints(p); + directMappedPatchBase::clearOut(); +} + +//- Correct patches after moving points +void Foam::directMappedWallPolyPatch::movePoints(const pointField& p) +{ + wallPolyPatch::movePoints(p); + directMappedPatchBase::clearOut(); +} + +//- Initialise the update of the patch topology +void Foam::directMappedWallPolyPatch::initUpdateMesh() +{ + wallPolyPatch::initUpdateMesh(); + directMappedPatchBase::clearOut(); +} + +//- Update of the patch topology +void Foam::directMappedWallPolyPatch::updateMesh() +{ + wallPolyPatch::updateMesh(); + directMappedPatchBase::clearOut(); +} + + +void Foam::directMappedWallPolyPatch::write(Ostream& os) const +{ + wallPolyPatch::write(os); + directMappedPatchBase::write(os); +} + + +// ************************************************************************* // diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.H b/src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.H new file mode 100644 index 0000000000000000000000000000000000000000..407d62ddda2c07958a45b0ea642567ceaf4c1078 --- /dev/null +++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.H @@ -0,0 +1,181 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::directMappedWallPolyPatch + +Description + Determines a mapping between patch face centres and mesh cell or face + centres and processors they're on. + +Note + Storage is not optimal. It stores all face centres and cells on all + processors to keep the addressing calculation simple. + +SourceFiles + directMappedWallPolyPatch.C + +\*---------------------------------------------------------------------------*/ + +#ifndef directMappedWallPolyPatch_H +#define directMappedWallPolyPatch_H + +#include "wallPolyPatch.H" +#include "directMappedPatchBase.H" + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class polyMesh; + +/*---------------------------------------------------------------------------*\ + Class directMappedWallPolyPatch Declaration +\*---------------------------------------------------------------------------*/ + +class directMappedWallPolyPatch +: + public wallPolyPatch, + public directMappedPatchBase +{ + +protected: + + //- Initialise the calculation of the patch geometry + virtual void initGeometry(); + + //- Calculate the patch geometry + virtual void calcGeometry(); + + //- Initialise the patches for moving points + virtual void initMovePoints(const pointField&); + + //- Correct patches after moving points + virtual void movePoints(const pointField&); + + //- Initialise the update of the patch topology + virtual void initUpdateMesh(); + + //- Update of the patch topology + virtual void updateMesh(); + + +public: + + //- Runtime type information + TypeName("directMappedWall"); + + + // Constructors + + //- Construct from components + directMappedWallPolyPatch + ( + const word& name, + const label size, + const label start, + const label index, + const polyBoundaryMesh& bm + ); + + //- Construct from dictionary + directMappedWallPolyPatch + ( + const word& name, + const dictionary& dict, + const label index, + const polyBoundaryMesh& bm + ); + + //- Construct as copy, resetting the boundary mesh + directMappedWallPolyPatch + ( + const directMappedWallPolyPatch&, + const polyBoundaryMesh& + ); + + //- Construct given the original patch and resetting the + // face list and boundary mesh information + directMappedWallPolyPatch + ( + const directMappedWallPolyPatch& pp, + const polyBoundaryMesh& bm, + const label index, + const label newSize, + const label newStart + ); + + //- Construct and return a clone, resetting the boundary mesh + virtual autoPtr<polyPatch> clone(const polyBoundaryMesh& bm) const + { + return autoPtr<polyPatch>(new directMappedWallPolyPatch(*this, bm)); + } + + //- Construct and return a clone, resetting the face list + // and boundary mesh + virtual autoPtr<polyPatch> clone + ( + const polyBoundaryMesh& bm, + const label index, + const label newSize, + const label newStart + ) const + { + return autoPtr<polyPatch> + ( + new directMappedWallPolyPatch + ( + *this, + bm, + index, + newSize, + newStart + ) + ); + } + + + // Destructor + + ~directMappedWallPolyPatch(); + + + // Member functions + + //- Write the polyPatch data as a dictionary + virtual void write(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/indexedOctree/indexedOctree.C b/src/meshTools/indexedOctree/indexedOctree.C index 2131c3aaf6ef936fcf18bbe8f4cc39ffcdde93c5..4f555649996a3deb0ed264dedb43451002ad8479 100644 --- a/src/meshTools/indexedOctree/indexedOctree.C +++ b/src/meshTools/indexedOctree/indexedOctree.C @@ -29,6 +29,12 @@ License #include "meshTools.H" #include "OFstream.H" +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +template <class Type> +Foam::scalar Foam::indexedOctree<Type>::perturbTol_ = 10*SMALL; + + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // Does bb intersect a sphere around sample? Or is any corner point of bb @@ -203,7 +209,7 @@ Foam::indexedOctree<Type>::divide || bb.min()[2] >= bb.max()[2] ) { - FatalErrorIn("indexedOctree<Type>::divide") + FatalErrorIn("indexedOctree<Type>::divide(..)") << "Badly formed bounding box:" << bb << abort(FatalError); } @@ -674,100 +680,815 @@ void Foam::indexedOctree<Type>::findNearest } +template <class Type> +Foam::treeBoundBox Foam::indexedOctree<Type>::subBbox +( + const label parentNodeI, + const direction octant +) const +{ + // Get type of node at octant + const node& nod = nodes_[parentNodeI]; + labelBits index = nod.subNodes_[octant]; + + if (isNode(index)) + { + // Use stored bb + return nodes_[getNode(index)].bb_; + } + else + { + // Calculate subBb + return nod.bb_.subBbox(octant); + } +} + + +// Takes a bb and a point on/close to the edge of the bb and pushes the point +// inside by a small fraction. +template <class Type> +Foam::point Foam::indexedOctree<Type>::pushPoint +( + const treeBoundBox& bb, + const point& pt, + const bool pushInside +) +{ + // Get local length scale. + const vector perturbVec = perturbTol_*(bb.span()); + + point perturbedPt(pt); + + // Modify all components which are close to any face of the bb to be + // well inside/outside them. + + if (pushInside) + { + for (direction dir = 0; dir < vector::nComponents; dir++) + { + if (mag(pt[dir]-bb.min()[dir]) < mag(perturbVec[dir])) + { + // Close to 'left' side. Push well beyond left side. + scalar perturbDist = perturbVec[dir] + ROOTVSMALL; + perturbedPt[dir] = bb.min()[dir] + perturbDist; + } + else if (mag(pt[dir]-bb.max()[dir]) < mag(perturbVec[dir])) + { + // Close to 'right' side. Push well beyond right side. + scalar perturbDist = perturbVec[dir] + ROOTVSMALL; + perturbedPt[dir] = bb.max()[dir] - perturbDist; + } + } + } + else + { + for (direction dir = 0; dir < vector::nComponents; dir++) + { + if (mag(pt[dir]-bb.min()[dir]) < mag(perturbVec[dir])) + { + scalar perturbDist = perturbVec[dir] + ROOTVSMALL; + perturbedPt[dir] = bb.min()[dir] - perturbDist; + } + else if (mag(pt[dir]-bb.max()[dir]) < mag(perturbVec[dir])) + { + scalar perturbDist = perturbVec[dir] + ROOTVSMALL; + perturbedPt[dir] = bb.max()[dir] + perturbDist; + } + } + } + + if (debug) + { + if (pushInside != bb.contains(perturbedPt)) + { + FatalErrorIn("indexedOctree<Type>::pushPoint(..)") + << "pushed point:" << pt + << " to:" << perturbedPt + << " wanted side:" << pushInside + << " obtained side:" << bb.contains(perturbedPt) + << " of bb:" << bb + << abort(FatalError); + } + } + + return perturbedPt; +} + + +// Takes a bb and a point on the edge of the bb and pushes the point +// outside by a small fraction. +template <class Type> +Foam::point Foam::indexedOctree<Type>::pushPoint +( + const treeBoundBox& bb, + const direction faceID, + const point& pt, + const bool pushInside +) +{ + // Get local length scale. + const vector perturbVec = perturbTol_*bb.span(); + + point perturbedPt(pt); + + // Modify all components which are close to any face of the bb to be + // well outside them. + + if (faceID == 0) + { + FatalErrorIn("indexedOctree<Type>::pushPoint(..)") + << abort(FatalError); + } + + if (faceID & treeBoundBox::LEFTBIT) + { + if (pushInside) + { + perturbedPt[0] = bb.min()[0] + (perturbVec[0] + ROOTVSMALL); + } + else + { + perturbedPt[0] = bb.min()[0] - (perturbVec[0] + ROOTVSMALL); + } + } + else if (faceID & treeBoundBox::RIGHTBIT) + { + if (pushInside) + { + perturbedPt[0] = bb.max()[0] - (perturbVec[0] + ROOTVSMALL); + } + else + { + perturbedPt[0] = bb.max()[0] + (perturbVec[0] + ROOTVSMALL); + } + } + + if (faceID & treeBoundBox::BOTTOMBIT) + { + if (pushInside) + { + perturbedPt[1] = bb.min()[1] + (perturbVec[1] + ROOTVSMALL); + } + else + { + perturbedPt[1] = bb.min()[1] - (perturbVec[1] + ROOTVSMALL); + } + } + else if (faceID & treeBoundBox::TOPBIT) + { + if (pushInside) + { + perturbedPt[1] = bb.max()[1] - (perturbVec[1] + ROOTVSMALL); + } + else + { + perturbedPt[1] = bb.max()[1] + (perturbVec[1] + ROOTVSMALL); + } + } + + if (faceID & treeBoundBox::BACKBIT) + { + if (pushInside) + { + perturbedPt[2] = bb.min()[2] + (perturbVec[2] + ROOTVSMALL); + } + else + { + perturbedPt[2] = bb.min()[2] - (perturbVec[2] + ROOTVSMALL); + } + } + else if (faceID & treeBoundBox::FRONTBIT) + { + if (pushInside) + { + perturbedPt[2] = bb.max()[2] - (perturbVec[2] + ROOTVSMALL); + } + else + { + perturbedPt[2] = bb.max()[2] + (perturbVec[2] + ROOTVSMALL); + } + } + + if (debug) + { + if (pushInside != bb.contains(perturbedPt)) + { + FatalErrorIn("indexedOctree<Type>::pushPoint(..)") + << "pushed point:" << pt << " on face:" << faceString(faceID) + << " to:" << perturbedPt + << " wanted side:" << pushInside + << " obtained side:" << bb.contains(perturbedPt) + << " of bb:" << bb + << abort(FatalError); + } + } + + return perturbedPt; +} + + +// Guarantees that if pt is on a face it gets perturbed so it is away +// from the face edges. +// If pt is not on a face does nothing. +template <class Type> +Foam::point Foam::indexedOctree<Type>::pushPointIntoFace +( + const treeBoundBox& bb, + const vector& dir, // end-start + const point& pt +) +{ + if (debug) + { + if (bb.posBits(pt) != 0) + { + FatalErrorIn("indexedOctree<Type>::pushPointIntoFace(..)") + << " bb:" << bb << endl + << "does not contain point " << pt << abort(FatalError); + } + } + + + // Handle two cases: + // - point exactly on multiple faces. Push away from all but one. + // - point on a single face. Push away from edges of face. + + direction ptFaceID = bb.faceBits(pt); + + direction nFaces = 0; + FixedList<direction, 3> faceIndices; + + if (ptFaceID & treeBoundBox::LEFTBIT) + { + faceIndices[nFaces++] = treeBoundBox::LEFT; + } + else if (ptFaceID & treeBoundBox::RIGHTBIT) + { + faceIndices[nFaces++] = treeBoundBox::RIGHT; + } + + if (ptFaceID & treeBoundBox::BOTTOMBIT) + { + faceIndices[nFaces++] = treeBoundBox::BOTTOM; + } + else if (ptFaceID & treeBoundBox::TOPBIT) + { + faceIndices[nFaces++] = treeBoundBox::TOP; + } + + if (ptFaceID & treeBoundBox::BACKBIT) + { + faceIndices[nFaces++] = treeBoundBox::BACK; + } + else if (ptFaceID & treeBoundBox::FRONTBIT) + { + faceIndices[nFaces++] = treeBoundBox::FRONT; + } + + + // Determine the face we want to keep the point on + + direction keepFaceID; + + if (nFaces == 0) + { + // Return original point + return pt; + } + else if (nFaces == 1) + { + keepFaceID = faceIndices[0]; + } + else + { + // Determine best face out of faceIndices[0 .. nFaces-1]. + // The best face is the one most perpendicular to the ray direction. + + keepFaceID = faceIndices[0]; + scalar maxInproduct = mag(treeBoundBox::faceNormals[keepFaceID] & dir); + + for (direction i = 1; i < nFaces; i++) + { + direction face = faceIndices[i]; + scalar s = mag(treeBoundBox::faceNormals[face] & dir); + if (s > maxInproduct) + { + maxInproduct = s; + keepFaceID = face; + } + } + } + + + // 1. Push point into bb, away from all corners + + point facePoint(pushPoint(bb, pt, true)); + direction faceID = 0; + + // 2. Snap it back onto the preferred face + + if (keepFaceID == treeBoundBox::LEFT) + { + facePoint.x() = bb.min().x(); + faceID = treeBoundBox::LEFTBIT; + } + else if (keepFaceID == treeBoundBox::RIGHT) + { + facePoint.x() = bb.max().x(); + faceID = treeBoundBox::RIGHTBIT; + } + else if (keepFaceID == treeBoundBox::BOTTOM) + { + facePoint.y() = bb.min().y(); + faceID = treeBoundBox::BOTTOMBIT; + } + else if (keepFaceID == treeBoundBox::TOP) + { + facePoint.y() = bb.max().y(); + faceID = treeBoundBox::TOPBIT; + } + else if (keepFaceID == treeBoundBox::BACK) + { + facePoint.z() = bb.min().z(); + faceID = treeBoundBox::BACKBIT; + } + else if (keepFaceID == treeBoundBox::FRONT) + { + facePoint.z() = bb.max().z(); + faceID = treeBoundBox::FRONTBIT; + } + + + if (debug) + { + if (faceID != bb.faceBits(facePoint)) + { + FatalErrorIn("indexedOctree<Type>::pushPointIntoFace(..)") + << "Pushed point from " << pt + << " on face:" << ptFaceID << " of bb:" << bb << endl + << "onto " << facePoint + << " on face:" << faceID + << " which is not consistent with geometric face " + << bb.faceBits(facePoint) + << abort(FatalError); + } + if (bb.posBits(facePoint) != 0) + { + FatalErrorIn("indexedOctree<Type>::pushPointIntoFace(..)") + << " bb:" << bb << endl + << "does not contain perturbed point " + << facePoint << abort(FatalError); + } + } + + + return facePoint; +} + + +//// Takes a bb and a point on the outside of the bb. Checks if on multiple faces +//// and if so perturbs point so it is only on one face. +//template <class Type> +//void Foam::indexedOctree<Type>::checkMultipleFaces +//( +// const treeBoundBox& bb, +// const vector& dir, // end-start +// pointIndexHit& faceHitInfo, +// direction& faceID +//) +//{ +// // Do the quick elimination of no or one face. +// if +// ( +// (faceID == 0) +// || (faceID == treeBoundBox::LEFTBIT) +// || (faceID == treeBoundBox::RIGHTBIT) +// || (faceID == treeBoundBox::BOTTOMBIT) +// || (faceID == treeBoundBox::TOPBIT) +// || (faceID == treeBoundBox::BACKBIT) +// || (faceID == treeBoundBox::FRONTBIT) +// ) +// { +// return; +// } +// +// +// // Check the direction of vector w.r.t. faces being intersected. +// FixedList<scalar, 6> inproducts(-GREAT); +// +// direction nFaces = 0; +// +// if (faceID & treeBoundBox::LEFTBIT) +// { +// inproducts[treeBoundBox::LEFT] = mag +// ( +// treeBoundBox::faceNormals[treeBoundBox::LEFT] +// & dir +// ); +// nFaces++; +// } +// if (faceID & treeBoundBox::RIGHTBIT) +// { +// inproducts[treeBoundBox::RIGHT] = mag +// ( +// treeBoundBox::faceNormals[treeBoundBox::RIGHT] +// & dir +// ); +// nFaces++; +// } +// +// if (faceID & treeBoundBox::BOTTOMBIT) +// { +// inproducts[treeBoundBox::BOTTOM] = mag +// ( +// treeBoundBox::faceNormals[treeBoundBox::BOTTOM] +// & dir +// ); +// nFaces++; +// } +// if (faceID & treeBoundBox::TOPBIT) +// { +// inproducts[treeBoundBox::TOP] = mag +// ( +// treeBoundBox::faceNormals[treeBoundBox::TOP] +// & dir +// ); +// nFaces++; +// } +// +// if (faceID & treeBoundBox::BACKBIT) +// { +// inproducts[treeBoundBox::BACK] = mag +// ( +// treeBoundBox::faceNormals[treeBoundBox::BACK] +// & dir +// ); +// nFaces++; +// } +// if (faceID & treeBoundBox::FRONTBIT) +// { +// inproducts[treeBoundBox::FRONT] = mag +// ( +// treeBoundBox::faceNormals[treeBoundBox::FRONT] +// & dir +// ); +// nFaces++; +// } +// +// if (nFaces == 0 || nFaces == 1 || nFaces > 3) +// { +// FatalErrorIn("indexedOctree<Type>::checkMultipleFaces(..)") +// << "Problem : nFaces:" << nFaces << abort(FatalError); +// } +// +// // Keep point on most perpendicular face; shift it away from the aligned +// // ones. +// // E.g. line hits top and left face: +// // a +// // ----+----+ +// // | | +// // | | +// // +----+ +// // Shift point down (away from top): +// // +// // a+----+ +// // ----| | +// // | | +// // +----+ +// +// label maxIndex = -1; +// scalar maxInproduct = -GREAT; +// +// for (direction i = 0; i < 6; i++) +// { +// if (inproducts[i] > maxInproduct) +// { +// maxInproduct = inproducts[i]; +// maxIndex = i; +// } +// } +// +// if (maxIndex == -1) +// { +// FatalErrorIn("indexedOctree<Type>::checkMultipleFaces(..)") +// << "Problem maxIndex:" << maxIndex << " inproducts:" << inproducts +// << abort(FatalError); +// } +// +// const point oldPoint(faceHitInfo.rawPoint()); +// const direction oldFaceID = faceID; +// +// // 1. Push point into bb, away from all corners +// +// faceHitInfo.rawPoint() = pushPoint(bb, oldFaceID, oldPoint, true); +// +// // 2. Snap it back onto the preferred face +// +// if (maxIndex == treeBoundBox::LEFT) +// { +// faceHitInfo.rawPoint().x() = bb.min().x(); +// faceID = treeBoundBox::LEFTBIT; +// } +// else if (maxIndex == treeBoundBox::RIGHT) +// { +// faceHitInfo.rawPoint().x() = bb.max().x(); +// faceID = treeBoundBox::RIGHTBIT; +// } +// else if (maxIndex == treeBoundBox::BOTTOM) +// { +// faceHitInfo.rawPoint().y() = bb.min().y(); +// faceID = treeBoundBox::BOTTOMBIT; +// } +// else if (maxIndex == treeBoundBox::TOP) +// { +// faceHitInfo.rawPoint().y() = bb.max().y(); +// faceID = treeBoundBox::TOPBIT; +// } +// else if (maxIndex == treeBoundBox::BACK) +// { +// faceHitInfo.rawPoint().z() = bb.min().z(); +// faceID = treeBoundBox::BACKBIT; +// } +// else if (maxIndex == treeBoundBox::FRONT) +// { +// faceHitInfo.rawPoint().z() = bb.max().z(); +// faceID = treeBoundBox::FRONTBIT; +// } +// +// Pout<< "From ray:" << dir +// << " from point:" << oldPoint +// << " on faces:" << faceString(oldFaceID) +// << " of bb:" << bb +// << " with inprods:" << inproducts +// << " maxIndex:" << maxIndex << endl +// << "perturbed to point:" << faceHitInfo.rawPoint() +// << " on face:" << faceString(faceID) +// << endl; +// +// +// if (debug) +// { +// if (faceID != bb.faceBits(faceHitInfo.rawPoint())) +// { +// FatalErrorIn("indexedOctree<Type>::checkMultipleFaces(..)") +// << "Pushed point from " << oldPoint +// << " on face:" << oldFaceID << " of bb:" << bb << endl +// << "onto " << faceHitInfo.rawPoint() +// << " on face:" << faceID +// << " which is not consistent with geometric face " +// << bb.faceBits(faceHitInfo.rawPoint()) +// << abort(FatalError); +// } +// } +//} + + +// Get parent node and octant. Return false if top of tree reached. +template <class Type> +bool Foam::indexedOctree<Type>::walkToParent +( + const label nodeI, + const direction octant, + + label& parentNodeI, + label& parentOctant +) const +{ + parentNodeI = nodes_[nodeI].parent_; + + if (parentNodeI == -1) + { + // Reached edge of tree + return false; + } + + const node& parentNode = nodes_[parentNodeI]; + + // Find octant nodeI is in. + parentOctant = 255; + + for (direction i = 0; i < parentNode.subNodes_.size(); i++) + { + labelBits index = parentNode.subNodes_[i]; + + if (isNode(index) && getNode(index) == nodeI) + { + parentOctant = i; + break; + } + } + + if (parentOctant == 255) + { + FatalErrorIn("walkToParent(..)") + << "Problem: no parent found for octant:" << octant + << " node:" << nodeI + << abort(FatalError); + } + + return true; +} + + // Walk tree to neighbouring node. Gets current position as // node and octant in this node and walks in the direction given by -// the faceID (one of treeBoundBox::LEFTBIT, RIGHTBIT etc.) +// the facePointBits (combination of treeBoundBox::LEFTBIT, TOPBIT etc.) // Returns false if edge of tree hit. template <class Type> bool Foam::indexedOctree<Type>::walkToNeighbour ( const point& facePoint, - const direction faceID, // direction to walk in + const direction faceID, // face(s) that facePoint is on label& nodeI, direction& octant ) const { + label oldNodeI = nodeI; + direction oldOctant = octant; + // Find out how to test for octant. Say if we want to go left we need // to traverse up the tree until we hit a node where our octant is // on the right. + // Coordinate direction to test + const direction X = treeBoundBox::RIGHTHALF; + const direction Y = treeBoundBox::TOPHALF; + const direction Z = treeBoundBox::FRONTHALF; + direction octantMask = 0; - direction valueMask = 0; + direction wantedValue = 0; if ((faceID & treeBoundBox::LEFTBIT) != 0) { - // We want to go left so check if in right octant. - octantMask |= treeBoundBox::RIGHTHALF; - valueMask |= treeBoundBox::RIGHTHALF; + // We want to go left so check if in right octant (i.e. x-bit is set) + octantMask |= X; + wantedValue |= X; } else if ((faceID & treeBoundBox::RIGHTBIT) != 0) { - octantMask |= treeBoundBox::RIGHTHALF; // valueMask already 0 + octantMask |= X; // wantedValue already 0 } if ((faceID & treeBoundBox::BOTTOMBIT) != 0) { - octantMask |= treeBoundBox::TOPHALF; - valueMask |= treeBoundBox::TOPHALF; + // Want to go down so check for y-bit set. + octantMask |= Y; + wantedValue |= Y; } else if ((faceID & treeBoundBox::TOPBIT) != 0) { - octantMask |= treeBoundBox::TOPHALF; + // Want to go up so check for y-bit not set. + octantMask |= Y; } if ((faceID & treeBoundBox::BACKBIT) != 0) { - octantMask |= treeBoundBox::FRONTHALF; - valueMask |= treeBoundBox::FRONTHALF; + octantMask |= Z; + wantedValue |= Z; } else if ((faceID & treeBoundBox::FRONTBIT) != 0) { - octantMask |= treeBoundBox::FRONTHALF; + octantMask |= Z; } + // So now we have the coordinate directions in the octant we need to check + // and the resulting value. + + /* + // +---+---+ + // | | | + // | | | + // | | | + // +---+-+-+ + // | | | | + // | a+-+-+ + // | |\| | + // +---+-+-+ + // \ + // + // e.g. ray is at (a) in octant 0(or 4) with faceIDs : LEFTBIT+TOPBIT. + // If we would be in octant 1(or 5) we could go to the correct octant + // in the same node by just flipping the x and y bits (exoring). + // But if we are not in octant 1/5 we have to go up until we are. + // In general for leftbit+topbit: + // - we have to check for x and y : octantMask = 011 + // - the checked bits have to be : wantedValue = ?01 + */ + + //Pout<< "For point " << facePoint << endl; + // Go up until we have chance to cross to the wanted direction - while (valueMask != (octant & octantMask)) + while (wantedValue != (octant & octantMask)) { - label parentNodeI = nodes_[nodeI].parent_; + // Go up to the parent. - if (parentNodeI == -1) + // Remove the directions that are not on the boundary of the parent. + // See diagram above + if (wantedValue & X) // && octantMask&X { - // Reached edge of tree - return false; + // Looking for right octant. + if (octant & X) + { + // My octant is one of the left ones so punch out the x check + octantMask &= ~X; + wantedValue &= ~X; + } + } + else + { + if (!(octant & X)) + { + // My octant is right but I want to go left. + octantMask &= ~X; + wantedValue &= ~X; + } } - const node& parentNode = nodes_[parentNodeI]; - - // Find octant nodeI is in. - direction parentOctant = 255; - - for (direction i = 0; i < parentNode.subNodes_.size(); i++) + if (wantedValue & Y) { - labelBits index = parentNode.subNodes_[i]; + if (octant & Y) + { + octantMask &= ~Y; + wantedValue &= ~Y; + } + } + else + { + if (!(octant & Y)) + { + octantMask &= ~Y; + wantedValue &= ~Y; + } + } - if (isNode(index) && getNode(index) == nodeI) + if (wantedValue & Z) + { + if (octant & Z) + { + octantMask &= ~Z; + wantedValue &= ~Z; + } + } + else + { + if (!(octant & Z)) { - parentOctant = i; - break; + octantMask &= ~Z; + wantedValue &= ~Z; } } - if (parentOctant == 255) + + label parentNodeI; + label parentOctant; + walkToParent(nodeI, octant, parentNodeI, parentOctant); + + if (parentNodeI == -1) { - FatalErrorIn("walkToNeighbour") - << abort(FatalError); + // Reached edge of tree + return false; } + + //Pout<< " walked from node:" << nodeI << " octant:" << octant + // << " bb:" << nodes_[nodeI].bb_.subBbox(octant) << endl + // << " to:" << parentNodeI << " octant:" << parentOctant + // << " bb:" << nodes_[parentNodeI].bb_.subBbox(parentOctant) + // << endl; + // + //Pout<< " octantMask:" << octantMask + // << " wantedValue:" << wantedValue << endl; + nodeI = parentNodeI; octant = parentOctant; } - // So now we hit the correct parent node. Switch to the correct octant + // So now we hit the correct parent node. Switch to the correct octant. + // Is done by jumping to the 'other half' so if e.g. in x direction in + // right half we now jump to the left half. octant ^= octantMask; + //Pout<< " to node:" << nodeI << " octant:" << octant + // << " subBb:" <<subBbox(nodeI, octant) << endl; + + + if (debug) + { + const treeBoundBox subBb(subBbox(nodeI, octant)); + + if (!subBb.contains(facePoint)) + { + FatalErrorIn("indexedOctree<Type>::walkToNeighbour(..)") + << "When searching for " << facePoint + << " ended up in node:" << nodeI + << " octant:" << octant + << " with bb:" << subBb + << abort(FatalError); + } + } + + // See if we need to travel down. Note that we already go into the - // the first level ourselves (instead of having findNode decide) since - // the facePoint is now exactly on the mid of the node so there could - // be truncation problems. + // the first level ourselves (instead of having findNode decide) labelBits index = nodes_[nodeI].subNodes_[octant]; if (isNode(index)) @@ -778,49 +1499,82 @@ bool Foam::indexedOctree<Type>::walkToNeighbour octant = getOctant(node); } + + if (debug) + { + const treeBoundBox subBb(subBbox(nodeI, octant)); + + if (nodeI == oldNodeI && octant == oldOctant) + { + FatalErrorIn("indexedOctree<Type>::walkToNeighbour(..)") + << "Did not go to neighbour when searching for " << facePoint + << endl + << " starting from face:" << faceString(faceID) + << " node:" << nodeI + << " octant:" << octant + << " bb:" << subBb + << abort(FatalError); + } + + if (!subBb.contains(facePoint)) + { + FatalErrorIn("indexedOctree<Type>::walkToNeighbour(..)") + << "When searching for " << facePoint + << " ended up in node:" << nodeI + << " octant:" << octant + << " bb:" << subBb + << abort(FatalError); + } + } + + return true; } -// Return unique number for the face of a bounding box a point is on. -// (number is single bit but not really nessecary) -// Return 0 if point not on any face of bb. template <class Type> -Foam::direction Foam::indexedOctree<Type>::getFace +Foam::word Foam::indexedOctree<Type>::faceString ( - const treeBoundBox& bb, - const point& pt + const direction faceID ) { - direction faceID = 0; + word desc; - if (pt.x() <= bb.min().x()) + if (faceID == 0) { - faceID |= treeBoundBox::LEFTBIT; + desc = "noFace"; } - if (pt.x() >= bb.max().x()) + if (faceID & treeBoundBox::LEFTBIT) { - faceID |= treeBoundBox::RIGHTBIT; + if (!desc.empty()) desc += "+"; + desc += "left"; } - - if (pt.y() <= bb.min().y()) + if (faceID & treeBoundBox::RIGHTBIT) { - faceID |= treeBoundBox::BOTTOMBIT; + if (!desc.empty()) desc += "+"; + desc += "right"; } - if (pt.y() >= bb.max().y()) + if (faceID & treeBoundBox::BOTTOMBIT) { - faceID |= treeBoundBox::TOPBIT; + if (!desc.empty()) desc += "+"; + desc += "bottom"; } - - if (pt.z() <= bb.min().z()) + if (faceID & treeBoundBox::TOPBIT) { - faceID |= treeBoundBox::BACKBIT; + if (!desc.empty()) desc += "+"; + desc += "top"; } - if (pt.z() >= bb.max().z()) + if (faceID & treeBoundBox::BACKBIT) { - faceID |= treeBoundBox::FRONTBIT; + if (!desc.empty()) desc += "+"; + desc += "back"; } - return faceID; + if (faceID & treeBoundBox::FRONTBIT) + { + if (!desc.empty()) desc += "+"; + desc += "front"; + } + return desc; } @@ -829,21 +1583,37 @@ Foam::direction Foam::indexedOctree<Type>::getFace // hitInfo.point = point on shape // Else return a miss and the bounding box face hit: // hitInfo.point = coordinate of intersection of ray with bounding box -// faceID = index of bounding box face +// hitBits = posbits of point on bounding box template <class Type> void Foam::indexedOctree<Type>::traverseNode ( const bool findAny, + const point& treeStart, + const vector& treeVec, + const point& start, const point& end, - const vector& dir, const label nodeI, const direction octant, pointIndexHit& hitInfo, - direction& faceID + direction& hitBits ) const { + if (debug) + { + const treeBoundBox octantBb(subBbox(nodeI, octant)); + + if (octantBb.posBits(start) != 0) + { + FatalErrorIn("indexedOctree<Type>::traverseNode(..)") + << "Node:" << nodeI << " octant:" << octant + << " bb:" << octantBb << endl + << "does not contain point " << start << abort(FatalError); + } + } + + const node& nod = nodes_[nodeI]; labelBits index = nod.subNodes_[octant]; @@ -909,49 +1679,72 @@ void Foam::indexedOctree<Type>::traverseNode // Nothing intersected in this node // Traverse to end of node. Do by ray tracing back from end and finding // intersection with bounding box of node. + // start point is now considered to be inside bounding box. + + const treeBoundBox octantBb(subBbox(nodeI, octant)); point pt; + bool intersected = octantBb.intersects + ( + end, //treeStart, + (start-end), //treeVec, - if (isNode(index)) - { - const treeBoundBox& subBb = nodes_[getNode(index)].bb_; + end, + start, - if (!subBb.intersects(end, start, pt)) - { - faceID = 0; + pt, + hitBits + ); - FatalErrorIn("indexedOctree<Type>::traverseNode(..)") - << "Did not hit side of box " << subBb - << " with ray from " << start << " to " << end - << abort(FatalError); - } - else - { - faceID = getFace(subBb, pt); - } + + if (intersected) + { + // Return miss. Set misspoint to face. + hitInfo.setPoint(pt); } else { - const treeBoundBox subBb(nod.bb_.subBbox(octant)); + // Rare case: did not find intersection of ray with octantBb. Can + // happen if end is on face/edge of octantBb. Do like + // lagrangian and re-track with perturbed vector (slightly pushed out + // of bounding box) - if (!subBb.intersects(end, start, pt)) - { - faceID = 0; + point perturbedEnd(pushPoint(octantBb, end, false)); - FatalErrorIn("indexedOctree<Type>::traverseNode(..)") - << "Did not hit side of box " << subBb - << " with ray from " << start << " to " << end - << abort(FatalError); - } - else + + //if (debug) { - faceID = getFace(subBb, pt); + // Dump octantBb to obj + writeOBJ(nodeI, octant); + // Dump ray to obj as well + { + OFstream str("ray.obj"); + meshTools::writeOBJ(str, start); + meshTools::writeOBJ(str, end); + str << "l 1 2" << nl; + } + WarningIn("indexedOctree<Type>::traverseNode(..)") + << "Did not intersect ray from endpoint:" << end + << " to startpoint:" << start + << " with bounding box:" << octantBb << nl + << "Re-intersecting with perturbed endpoint:" << perturbedEnd + << endl; } - } + traverseNode + ( + findAny, + treeStart, + treeVec, + start, + perturbedEnd, + nodeI, + octant, - // Return miss. Set misspoint to face. - hitInfo.setPoint(pt); + hitInfo, + hitBits + ); + } } @@ -963,40 +1756,75 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine const point& treeStart, const point& treeEnd, const label startNodeI, - const direction startOctant + const direction startOctant, + const bool verbose ) const { - const vector dir(treeEnd - treeStart); + const vector treeVec(treeEnd - treeStart); // Current node as parent+octant label nodeI = startNodeI; direction octant = startOctant; + if (verbose) + { + Pout<< "findLine : treeStart:" << treeStart + << " treeEnd:" << treeEnd << endl + << "node:" << nodeI + << " octant:" << octant + << " bb:" << subBbox(nodeI, octant) << endl; + } + // Current position. Initialize to miss pointIndexHit hitInfo(false, treeStart, -1); - // Side of current bounding box current point is on - direction faceID = 0; - - while (true) + //while (true) + label i = 0; + for (; i < 100000; i++) { + if (verbose) + { + Pout<< "iter:" << i + << " at startPoint:" << hitInfo.rawPoint() << endl + << " node:" << nodeI + << " octant:" << octant + << " bb:" << subBbox(nodeI, octant) << endl; + } + + // Ray-trace to end of current node. Updates point (either on triangle // in case of hit or on node bounding box in case of miss) - point startPoint(hitInfo.rawPoint()); + const treeBoundBox octantBb(subBbox(nodeI, octant)); + + // Make sure point is away from any edges/corners + point startPoint + ( + pushPointIntoFace + ( + octantBb, + treeVec, + hitInfo.rawPoint() + ) + ); + + // Faces of current bounding box current point is on + direction hitFaceID = 0; traverseNode ( findAny, + treeStart, + treeVec, + startPoint, // Note: pass in copy since hitInfo // also used in return value. - treeEnd, - dir, + treeEnd, // pass in overall end so is nicely outside bb nodeI, octant, hitInfo, - faceID + hitFaceID ); // Did we hit a triangle? @@ -1005,29 +1833,48 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine break; } - if (faceID == 0) + if (hitFaceID == 0) { - // Was never inside the tree. Return miss. + // endpoint inside the tree. Return miss. break; } - //Pout<< "findLine : treeStart:" << treeStart - // << " treeEnd:" << treeEnd - // << " tracked from " << startPoint << " to edge of nodeBb:" - // << hitInfo.missPoint() - // << " node:" << nodeI << " octant:" << octant - // << " subBb:" - // << nodes_[nodeI].bb_.subBbox(octant) - // << endl; + + if (verbose) + { + Pout<< " iter:" << i + << " hit face:" << faceString(hitFaceID) + << " at:" << hitInfo.rawPoint() << nl + << " node:" << nodeI + << " octant:" << octant + << " bb:" << subBbox(nodeI, octant) << nl + << " walking to neighbour containing:" + << pushPoint + ( + octantBb, + hitFaceID, + hitInfo.rawPoint(), + false // push outside of octantBb + ) + << endl; + } // Nothing hit so we are on face of bounding box (given as node+octant+ - // faceID). Traverse to neighbouring node. + // position bits). Traverse to neighbouring node. Use slightly perturbed + // point. bool ok = walkToNeighbour ( - hitInfo.rawPoint(), // point on face - faceID, // direction to walk in + pushPoint + ( + octantBb, + hitFaceID, + hitInfo.rawPoint(), + false // push outside of octantBb + ), + hitFaceID, // face(s) that hitInfo is on + nodeI, octant ); @@ -1037,7 +1884,53 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine // Hit the edge of the tree. Return miss. break; } + + if (verbose) + { + const treeBoundBox octantBb(subBbox(nodeI, octant)); + Pout<< " walked for point:" << hitInfo.rawPoint() << endl + << " to neighbour node:" << nodeI + << " octant:" << octant + << " face:" << faceString(octantBb.faceBits(hitInfo.rawPoint())) + << " of octantBb:" << octantBb << endl + << endl; + } + } + + if (i == 100000) + { + // Probably in loop. + if (!verbose) + { + // Redo intersection but now with verbose flag switched on. + return findLine + ( + findAny, + treeStart, + treeEnd, + startNodeI, + startOctant, + true //verbose + ); + } + if (debug) + { + FatalErrorIn("indexedOctree<Type>::findLine(..)") + << "Got stuck in loop raytracing from:" << treeStart + << " to:" << treeEnd << endl + << "inside top box:" << subBbox(startNodeI, startOctant) + << abort(FatalError); + } + else + { + WarningIn("indexedOctree<Type>::findLine(..)") + << "Got stuck in loop raytracing from:" << treeStart + << " to:" << treeEnd << endl + << "inside top box:" << subBbox(startNodeI, startOctant) + << endl; + } } + return hitInfo; } @@ -1057,6 +1950,9 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine { const treeBoundBox& treeBb = nodes_[0].bb_; + // No effort is made to deal with points which are on edge of tree + // bounding box for now. + direction startBit = treeBb.posBits(start); direction endBit = treeBb.posBits(end); @@ -1066,6 +1962,9 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine return pointIndexHit(false, vector::zero, -1); } + + // Trim segment to treeBb + point trackStart(start); point trackEnd(end); @@ -1087,6 +1986,7 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine } } + // Find lowest level tree node that start is in. labelBits index = findNode(0, trackStart); @@ -1234,32 +2134,6 @@ void Foam::indexedOctree<Type>::writeOBJ str<< "l " << e[0]+pointVertI+1 << ' ' << e[1]+pointVertI+1 << nl; } - - - //// Dump triangles - //if (isContent(index)) - //{ - // const labelList& indices = contents_[getContent(index)]; - // const triSurface& surf = shapes_.surface(); - // const pointField& points = surf.points(); - // - // forAll(indices, i) - // { - // label shapeI = indices[i]; - // - // const labelledTri& f = surf[shapeI]; - // - // meshTools::writeOBJ(str, points[f[0]]); - // vertI++; - // meshTools::writeOBJ(str, points[f[1]]); - // vertI++; - // meshTools::writeOBJ(str, points[f[2]]); - // vertI++; - // - // str<< "l " << vertI-2 << ' ' << vertI-1 << ' ' << vertI << ' ' - // << vertI-2 << nl; - // } - //} } @@ -1305,6 +2179,14 @@ Foam::indexedOctree<Type>::indexedOctree contents_(0), nodeTypes_(0) { + if (debug) + { + Pout<< "indexedOctree<Type>::indexedOctree:" << nl + << " shapes:" << shapes.size() << nl + << " bb:" << bb << nl + << endl; + } + if (shapes.size() == 0) { return; @@ -1409,7 +2291,6 @@ Foam::indexedOctree<Type>::indexedOctree nodes_.transfer(nodes); nodes.clear(); - if (debug) { label nEntries = 0; @@ -1418,14 +2299,18 @@ Foam::indexedOctree<Type>::indexedOctree nEntries += contents_[i].size(); } - Pout<< "indexedOctree<Type>::indexedOctree : finished construction:" + Pout<< "indexedOctree<Type>::indexedOctree" + << " : finished construction of tree of:" << shapes.typeName << nl + << " bb:" << this->bb() << nl << " shapes:" << shapes.size() << nl << " nLevels:" << nLevels << nl << " treeNodes:" << nodes_.size() << nl << " nEntries:" << nEntries << nl - << " per treeLeaf:" << nEntries/contents.size() << nl - << " per shape (duplicity):" << nEntries/shapes.size() << nl + << " per treeLeaf:" + << scalar(nEntries)/contents.size() << nl + << " per shape (duplicity):" + << scalar(nEntries)/shapes.size() << nl << endl; } } @@ -1447,6 +2332,13 @@ Foam::indexedOctree<Type>::indexedOctree // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template <class Type> +Foam::scalar& Foam::indexedOctree<Type>::perturbTol() +{ + return perturbTol_; +} + + template <class Type> Foam::pointIndexHit Foam::indexedOctree<Type>::findNearest ( @@ -1570,6 +2462,16 @@ Foam::labelBits Foam::indexedOctree<Type>::findNode const node& nod = nodes_[nodeI]; + if (debug) + { + if (!nod.bb_.contains(sample)) + { + FatalErrorIn("findNode(..)") + << "Cannot find " << sample << " in node " << nodeI + << abort(FatalError); + } + } + direction octant = nod.bb_.subOctant(sample); labelBits index = nod.subNodes_[octant]; diff --git a/src/meshTools/indexedOctree/indexedOctree.H b/src/meshTools/indexedOctree/indexedOctree.H index b4aad9a3052f520a6ffd599a921f31645f32e933..6c2bfa3c6e6f1408f6b80dfa6375ab60ba511522 100644 --- a/src/meshTools/indexedOctree/indexedOctree.H +++ b/src/meshTools/indexedOctree/indexedOctree.H @@ -128,6 +128,15 @@ public: private: + // Static data + + //- Relative peturbation tolerance. Determines when point is + // considered to be close to face/edge of bb of node. + // The tolerance is relative to the bounding box of the smallest + // node. + static scalar perturbTol_; + + // Private data //- Underlying shapes for geometric queries. @@ -144,8 +153,9 @@ private: // Private Member Functions - //- Like above but now bb is implicitly provided as parent bb + mid - // + octant + //- Helper: does bb intersect a sphere around sample? Or is any + // corner point of bb closer than nearestDistSqr to sample. + // (bb is implicitly provided as parent bb + octant) static bool overlaps ( const treeBoundBox& parentBb, @@ -215,6 +225,60 @@ private: point& nearestPoint ) const; + //- Return bbox of octant + treeBoundBox subBbox + ( + const label parentNodeI, + const direction octant + ) const; + + //- Helper: take a point on/close to face of bb and push it + // inside or outside of bb. + static point pushPoint + ( + const treeBoundBox&, + const point&, + const bool pushInside + ); + + //- Helper: take a point on face of bb and push it + // inside or outside of bb. + static point pushPoint + ( + const treeBoundBox&, + const direction, + const point&, + const bool pushInside + ); + + //- Helper: take point on face(s) of bb and push it away from + // edges of face. + static point pushPointIntoFace + ( + const treeBoundBox& bb, + const vector& dir, // end-start + const point& pt + ); + + ////- Push point on multiple faces away from any corner/edge. + //static void checkMultipleFaces + //( + // const treeBoundBox& bb, + // const vector& dir, // end-start + // pointIndexHit& faceHitInfo, + // direction& faceID + //); + + //- Walk to parent of node+octant. + bool walkToParent + ( + const label nodeI, + const direction octant, + + label& parentNodeI, + label& parentOctant + ) const; + //- Walk tree to neighbouring node. Return false if edge of tree // hit. bool walkToNeighbour @@ -225,8 +289,8 @@ private: direction& octant ) const; - //- Categorize point on bounding box. - static direction getFace(const treeBoundBox&, const point&); + //- Debug: return verbose the bounding box faces + static word faceString(const direction faceID); //- Traverse a node. If intersects a triangle return first // intersection point. @@ -235,9 +299,11 @@ private: void traverseNode ( const bool findAny, + const point& treeStart, + const vector& treeVec, + const point& start, const point& end, - const vector& dir, const label nodeI, const direction octantI, @@ -252,7 +318,8 @@ private: const point& treeStart, const point& treeEnd, const label startNodeI, - const direction startOctantI + const direction startOctantI, + const bool verbose = false ) const; //- Find any or nearest intersection of line between start and end. @@ -310,6 +377,10 @@ private: public: + //- Get the perturbation tolerance + static scalar& perturbTol(); + + // Constructors //- Construct null @@ -505,6 +576,7 @@ public: const point& sample ); + // Write //- Print tree. Either print all indices (printContent = true) or diff --git a/src/meshTools/indexedOctree/treeDataCell.H b/src/meshTools/indexedOctree/treeDataCell.H index 4f09188942e52ed86bdeccdbc7e8365013b4e0f9..100dcb62cf7659a852daf95532ec31f0e3bfde4a 100644 --- a/src/meshTools/indexedOctree/treeDataCell.H +++ b/src/meshTools/indexedOctree/treeDataCell.H @@ -37,9 +37,7 @@ SourceFiles #ifndef treeDataCell_H #define treeDataCell_H -#include "treeBoundBox.H" #include "treeBoundBoxList.H" -#include "labelList.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/meshTools/indexedOctree/treeDataEdge.C b/src/meshTools/indexedOctree/treeDataEdge.C index c4bb08f3744ac1f6360660ca037c4a0041debfd8..12f347c16483afff5664c6295b9211123f6c69f2 100644 --- a/src/meshTools/indexedOctree/treeDataEdge.C +++ b/src/meshTools/indexedOctree/treeDataEdge.C @@ -22,16 +22,15 @@ License along with OpenFOAM; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -Description - \*---------------------------------------------------------------------------*/ #include "treeDataEdge.H" #include "indexedOctree.H" -#include "polyMesh.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // +defineTypeNameAndDebug(Foam::treeDataEdge, 0); + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // diff --git a/src/meshTools/indexedOctree/treeDataEdge.H b/src/meshTools/indexedOctree/treeDataEdge.H index 916bad870ec358ff4e2b6ff8ab13eab2bb6fb736..5dad366b3b624121c54dad883bc4c4259ef1ddb0 100644 --- a/src/meshTools/indexedOctree/treeDataEdge.H +++ b/src/meshTools/indexedOctree/treeDataEdge.H @@ -36,8 +36,6 @@ SourceFiles #ifndef treeDataEdge_H #define treeDataEdge_H -#include "treeBoundBox.H" -#include "pointField.H" #include "treeBoundBoxList.H" #include "linePointRef.H" diff --git a/src/meshTools/indexedOctree/treeDataPoint.C b/src/meshTools/indexedOctree/treeDataPoint.C index c64fc04ee584282fa9e74747a6f3700d4a1e5eb8..5303156518e93277e21f8b110de84f78456b9dc4 100644 --- a/src/meshTools/indexedOctree/treeDataPoint.C +++ b/src/meshTools/indexedOctree/treeDataPoint.C @@ -32,6 +32,11 @@ Description #include "polyMesh.H" #include "triangleFuncs.H" +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +defineTypeNameAndDebug(Foam::treeDataPoint, 0); + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components diff --git a/src/meshTools/indexedOctree/treeDataTriSurface.C b/src/meshTools/indexedOctree/treeDataTriSurface.C index 06a496ee881c9f71db430c8bd01fbd59416f28f7..ea519291e3a275351622082b35d45413ddab825d 100644 --- a/src/meshTools/indexedOctree/treeDataTriSurface.C +++ b/src/meshTools/indexedOctree/treeDataTriSurface.C @@ -22,8 +22,6 @@ License along with OpenFOAM; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -Description - \*---------------------------------------------------------------------------*/ #include "treeDataTriSurface.H" @@ -226,7 +224,7 @@ Foam::label Foam::treeDataTriSurface::getVolumeType if (!pHit.hit()) { - FatalErrorIn("treeDataTriSurface::getVolumeType") + FatalErrorIn("treeDataTriSurface::getVolumeType(..)") << "treeBb:" << treeBb << " sample:" << sample << " pHit:" << pHit @@ -238,7 +236,8 @@ Foam::label Foam::treeDataTriSurface::getVolumeType surface_, sample, pHit.index(), - pHit.hitPoint() + pHit.hitPoint(), + indexedOctree<treeDataTriSurface>::perturbTol() ); if (t == triSurfaceTools::UNKNOWN) @@ -255,12 +254,13 @@ Foam::label Foam::treeDataTriSurface::getVolumeType } else { - FatalErrorIn("treeDataTriSurface::getVolumeType") + FatalErrorIn("treeDataTriSurface::getVolumeType(..)") << "problem" << abort(FatalError); return indexedOctree<treeDataTriSurface>::UNKNOWN; } } + // Check if any point on triangle is inside cubeBb. bool Foam::treeDataTriSurface::overlaps ( @@ -305,6 +305,7 @@ bool Foam::treeDataTriSurface::overlaps // Now we have the difficult case: all points are outside but connecting // edges might go through cube. Use fast intersection of bounding box. + //return triangleFuncs::intersectBbExact(p0, p1, p2, cubeBb); return triangleFuncs::intersectBb(p0, p1, p2, cubeBb); } @@ -445,7 +446,15 @@ bool Foam::treeDataTriSurface::intersects const vector dir(end - start); - pointHit inter = tri.intersection(start, dir, intersection::HALF_RAY); + // Use relative tolerance (from octree) to determine intersection. + + pointHit inter = tri.intersection + ( + start, + dir, + intersection::HALF_RAY, + indexedOctree<treeDataTriSurface>::perturbTol() + ); if (inter.hit() && inter.distance() <= 1) { @@ -459,6 +468,16 @@ bool Foam::treeDataTriSurface::intersects { return false; } + + + //- Using exact intersections + //pointHit info = f.tri(points).intersectionExact(start, end); + // + //if (info.hit()) + //{ + // intersectionPoint = info.hitPoint(); + //} + //return info.hit(); } diff --git a/src/meshTools/meshSearch/meshSearch.C b/src/meshTools/meshSearch/meshSearch.C index ef1aa46f67430fc9cbb4b2870c334f51130ca556..2c803a277251bf72faff28f83dbd889d11fbeeef 100644 --- a/src/meshTools/meshSearch/meshSearch.C +++ b/src/meshTools/meshSearch/meshSearch.C @@ -27,9 +27,11 @@ License #include "meshSearch.H" #include "polyMesh.H" #include "indexedOctree.H" -#include "pointIndexHit.H" #include "DynamicList.H" #include "demandDrivenData.H" +#include "treeDataCell.H" +#include "treeDataFace.H" +#include "treeDataPoint.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // diff --git a/src/meshTools/meshSearch/meshSearch.H b/src/meshTools/meshSearch/meshSearch.H index 7b99a7159c5e6dfee2d1eff12a7697d72c564b1c..c8d44bdd489b045469538fbcb0179cbc59571b10 100644 --- a/src/meshTools/meshSearch/meshSearch.H +++ b/src/meshTools/meshSearch/meshSearch.H @@ -37,9 +37,6 @@ SourceFiles #ifndef meshSearch_H #define meshSearch_H -#include "treeDataCell.H" -#include "treeDataFace.H" -#include "treeDataPoint.H" #include "pointIndexHit.H" #include "Cloud.H" #include "passiveParticle.H" @@ -51,6 +48,10 @@ namespace Foam // Forward declaration of classes class polyMesh; +class treeDataCell; +class treeDataFace; +class treeDataPoint; +template<class Type> class indexedOctree; /*---------------------------------------------------------------------------*\ Class meshSearch Declaration diff --git a/src/meshTools/octree/treeBoundBox.C b/src/meshTools/octree/treeBoundBox.C index ce62c471924a26b1d138f2d49b0e6c91a42dd5b7..6133bc3106f9c3e8e07edd53b0d3e7a639211bda 100644 --- a/src/meshTools/octree/treeBoundBox.C +++ b/src/meshTools/octree/treeBoundBox.C @@ -309,12 +309,14 @@ bool Foam::treeBoundBox::overlaps // This makes sure that posBits tests 'inside' bool Foam::treeBoundBox::intersects ( + const point& overallStart, + const vector& overallVec, const point& start, const point& end, - point& pt + point& pt, + direction& ptOnFaces ) const { - const vector vec(end - start); const direction endBits = posBits(end); pt = start; @@ -325,80 +327,106 @@ bool Foam::treeBoundBox::intersects if (ptBits == 0) { // pt inside bb + ptOnFaces = faceBits(pt); return true; } if ((ptBits & endBits) != 0) { // pt and end in same block outside of bb + ptOnFaces = faceBits(pt); return false; } if (ptBits & LEFTBIT) { // Intersect with plane V=min, n=-1,0,0 - if (Foam::mag(vec.x()) > VSMALL) + if (Foam::mag(overallVec.x()) > VSMALL) + { + scalar s = (min().x() - overallStart.x())/overallVec.x(); + pt.x() = min().x(); + pt.y() = overallStart.y() + overallVec.y()*s; + pt.z() = overallStart.z() + overallVec.z()*s; + } + else { - scalar s = (min().x() - pt.x())/vec.x(); + // Vector not in x-direction. But still intersecting bb planes. + // So must be close - just snap to bb. pt.x() = min().x(); - pt.y() = pt.y() + vec.y()*s; - pt.z() = pt.z() + vec.z()*s; } } - if (ptBits & RIGHTBIT) + else if (ptBits & RIGHTBIT) { // Intersect with plane V=max, n=1,0,0 - if (Foam::mag(vec.x()) > VSMALL) + if (Foam::mag(overallVec.x()) > VSMALL) + { + scalar s = (max().x() - overallStart.x())/overallVec.x(); + pt.x() = max().x(); + pt.y() = overallStart.y() + overallVec.y()*s; + pt.z() = overallStart.z() + overallVec.z()*s; + } + else { - scalar s = (max().x() - pt.x())/vec.x(); pt.x() = max().x(); - pt.y() = pt.y() + vec.y()*s; - pt.z() = pt.z() + vec.z()*s; } } - - if (ptBits & BOTTOMBIT) + else if (ptBits & BOTTOMBIT) { // Intersect with plane V=min, n=0,-1,0 - if (Foam::mag(vec.y()) > VSMALL) + if (Foam::mag(overallVec.y()) > VSMALL) { - scalar s = (min().y() - pt.y())/vec.y(); - pt.x() = pt.x() + vec.x()*s; + scalar s = (min().y() - overallStart.y())/overallVec.y(); + pt.x() = overallStart.x() + overallVec.x()*s; pt.y() = min().y(); - pt.z() = pt.z() + vec.z()*s; + pt.z() = overallStart.z() + overallVec.z()*s; + } + else + { + pt.x() = min().y(); } } - if (ptBits & TOPBIT) + else if (ptBits & TOPBIT) { // Intersect with plane V=max, n=0,1,0 - if (Foam::mag(vec.y()) > VSMALL) + if (Foam::mag(overallVec.y()) > VSMALL) + { + scalar s = (max().y() - overallStart.y())/overallVec.y(); + pt.x() = overallStart.x() + overallVec.x()*s; + pt.y() = max().y(); + pt.z() = overallStart.z() + overallVec.z()*s; + } + else { - scalar s = (max().y() - pt.y())/vec.y(); - pt.x() = pt.x() + vec.x()*s; pt.y() = max().y(); - pt.z() = pt.z() + vec.z()*s; } } - - if (ptBits & BACKBIT) + else if (ptBits & BACKBIT) { // Intersect with plane V=min, n=0,0,-1 - if (Foam::mag(vec.z()) > VSMALL) + if (Foam::mag(overallVec.z()) > VSMALL) + { + scalar s = (min().z() - overallStart.z())/overallVec.z(); + pt.x() = overallStart.x() + overallVec.x()*s; + pt.y() = overallStart.y() + overallVec.y()*s; + pt.z() = min().z(); + } + else { - scalar s = (min().z() - pt.z())/vec.z(); - pt.x() = pt.x() + vec.x()*s; - pt.y() = pt.y() + vec.y()*s; pt.z() = min().z(); } } - if (ptBits & FRONTBIT) + else if (ptBits & FRONTBIT) { // Intersect with plane V=max, n=0,0,1 - if (Foam::mag(vec.z()) > VSMALL) + if (Foam::mag(overallVec.z()) > VSMALL) + { + scalar s = (max().z() - overallStart.z())/overallVec.z(); + pt.x() = overallStart.x() + overallVec.x()*s; + pt.y() = overallStart.y() + overallVec.y()*s; + pt.z() = max().z(); + } + else { - scalar s = (max().z() - pt.z())/vec.z(); - pt.x() = pt.x() + vec.x()*s; - pt.y() = pt.y() + vec.y()*s; pt.z() = max().z(); } } @@ -406,6 +434,18 @@ bool Foam::treeBoundBox::intersects } +bool Foam::treeBoundBox::intersects +( + const point& start, + const point& end, + point& pt +) const +{ + direction ptBits; + return intersects(start, end-start, start, end, pt, ptBits); +} + + // this.bb fully contains bb bool Foam::treeBoundBox::contains(const treeBoundBox& bb) const { @@ -452,6 +492,40 @@ bool Foam::treeBoundBox::contains(const vector& dir, const point& pt) const } +// Code position of pt on bounding box faces +Foam::direction Foam::treeBoundBox::faceBits(const point& pt) const +{ + direction faceBits = 0; + if (pt.x() == min().x()) + { + faceBits |= LEFTBIT; + } + else if (pt.x() == max().x()) + { + faceBits |= RIGHTBIT; + } + + if (pt.y() == min().y()) + { + faceBits |= BOTTOMBIT; + } + else if (pt.y() == max().y()) + { + faceBits |= TOPBIT; + } + + if (pt.z() == min().z()) + { + faceBits |= BACKBIT; + } + else if (pt.z() == max().z()) + { + faceBits |= FRONTBIT; + } + return faceBits; +} + + // Code position of point relative to box Foam::direction Foam::treeBoundBox::posBits(const point& pt) const { @@ -461,7 +535,7 @@ Foam::direction Foam::treeBoundBox::posBits(const point& pt) const { posBits |= LEFTBIT; } - if (pt.x() > max().x()) + else if (pt.x() > max().x()) { posBits |= RIGHTBIT; } @@ -470,7 +544,7 @@ Foam::direction Foam::treeBoundBox::posBits(const point& pt) const { posBits |= BOTTOMBIT; } - if (pt.y() > max().y()) + else if (pt.y() > max().y()) { posBits |= TOPBIT; } @@ -479,7 +553,7 @@ Foam::direction Foam::treeBoundBox::posBits(const point& pt) const { posBits |= BACKBIT; } - if (pt.z() > max().z()) + else if (pt.z() > max().z()) { posBits |= FRONTBIT; } diff --git a/src/meshTools/octree/treeBoundBox.H b/src/meshTools/octree/treeBoundBox.H index 77498b2935212cf1b49a29892a20e270657bdad9..69791e04a85b8ddac668cc924a0f46f48b67a5b4 100644 --- a/src/meshTools/octree/treeBoundBox.H +++ b/src/meshTools/octree/treeBoundBox.H @@ -120,12 +120,12 @@ public: enum faceBit { NOFACE = 0, - LEFTBIT = 0x1 << LEFT, - RIGHTBIT = 0x1 << RIGHT, - BOTTOMBIT = 0x1 << BOTTOM, - TOPBIT = 0x1 << TOP, - BACKBIT = 0x1 << BACK, - FRONTBIT = 0x1 << FRONT, + LEFTBIT = 0x1 << LEFT, //1 + RIGHTBIT = 0x1 << RIGHT, //2 + BOTTOMBIT = 0x1 << BOTTOM, //4 + TOPBIT = 0x1 << TOP, //8 + BACKBIT = 0x1 << BACK, //16 + FRONTBIT = 0x1 << FRONT, //32 }; //- Edges codes. @@ -265,9 +265,25 @@ public: //- Overlaps boundingSphere (centre + sqr(radius))? bool overlaps(const point&, const scalar radiusSqr) const; - //- Intersects segment; set point to intersection position, + //- Intersects segment; set point to intersection position and face, // return true if intersection found. - // (intPt argument used during calculation even if not intersecting) + // (pt argument used during calculation even if not intersecting). + // Calculates intersections from outside supplied vector + // (overallStart, overallVec). This is so when + // e.g. tracking through lots of consecutive boxes + // (typical octree) we're not accumulating truncation errors. Set + // to start, (end-start) if not used. + bool intersects + ( + const point& overallStart, + const vector& overallVec, + const point& start, + const point& end, + point& pt, + direction& ptBits + ) const; + + //- Like above but does not return faces point is on bool intersects ( const point& start, @@ -285,6 +301,9 @@ public: // dir would cause it to go inside. bool contains(const vector& dir, const point&) const; + //- Code position of pt on bounding box faces + direction faceBits(const point& pt) const; + //- Position of point relative to bounding box direction posBits(const point&) const; diff --git a/src/meshTools/searchableSurface/searchableCylinder.C b/src/meshTools/searchableSurface/searchableCylinder.C index e2b8426f1fec5448dc51fbc9347b0893e6e9eb60..fcaa42194aab42ce1f06f9e199f215548b92c627 100644 --- a/src/meshTools/searchableSurface/searchableCylinder.C +++ b/src/meshTools/searchableSurface/searchableCylinder.C @@ -105,6 +105,13 @@ Foam::pointIndexHit Foam::searchableCylinder::findNearest } +Foam::scalar Foam::searchableCylinder::radius2(const point& pt) const +{ + const vector x = (pt-point1_) ^ unitDir_; + return x&x; +} + + // From http://www.gamedev.net/community/forums/topic.asp?topic_id=467789 - // intersection of cylinder with ray void Foam::searchableCylinder::findLineAll @@ -118,13 +125,91 @@ void Foam::searchableCylinder::findLineAll near.setMiss(); far.setMiss(); - // Line as P = start + t*V - const vector V(end-start); + vector point1Start(start-point1_); + vector point2Start(start-point2_); + vector point1End(end-point1_); + + // Quick rejection of complete vector outside endcaps + scalar s1 = point1Start&unitDir_; + scalar s2 = point1End&unitDir_; + + if ((s1 < 0 && s2 < 0) || (s1 > magDir_ && s2 > magDir_)) + { + return; + } + + // Line as P = start+t*V where V is unit vector and t=[0..mag(end-start)] + vector V(end-start); + scalar magV = mag(V); + if (magV < ROOTVSMALL) + { + return; + } + V /= magV; + + + // We now get the nearest intersections to start. This can either be + // the intersection with the end plane or with the cylinder side. + + // Get the two points (expressed in t) on the end planes. This is to + // clip any cylinder intersection against. + scalar tPoint1; + scalar tPoint2; + + // Maintain the two intersections with the endcaps + scalar tNear = VGREAT; + scalar tFar = VGREAT; + + { + scalar s = (V&unitDir_); + if (mag(s) > VSMALL) + { + tPoint1 = -s1/s; + tPoint2 = -(point2Start&unitDir_)/s; + if (tPoint2 < tPoint1) + { + Swap(tPoint1, tPoint2); + } + if (tPoint1 > magV || tPoint2 < 0) + { + return; + } + + // See if the points on the endcaps are actually inside the cylinder + if (tPoint1 >= 0 && tPoint1 <= magV) + { + if (radius2(start+tPoint1*V) <= sqr(radius_)) + { + tNear = tPoint1; + } + } + if (tPoint2 >= 0 && tPoint2 <= magV) + { + if (radius2(start+tPoint2*V) <= sqr(radius_)) + { + // Check if already have a near hit from point1 + if (tNear <= 1) + { + tFar = tPoint2; + } + else + { + tNear = tPoint2; + } + } + } + } + else + { + // Vector perpendicular to cylinder. Check for outside already done + // above so just set tpoint to allow all. + tPoint1 = -VGREAT; + tPoint2 = VGREAT; + } + } -//Pout<< "point1:" << point1_ << " point2:" << point2_ -// << " start:" << start << " end:" << end << endl; - const vector x = (start-point1_) ^ unitDir_; + const vector x = point1Start ^ unitDir_; const vector y = V ^ unitDir_; const scalar d = sqr(radius_); @@ -135,11 +220,12 @@ void Foam::searchableCylinder::findLineAll const scalar disc = b*b-4*a*c; -//Pout<< "a:" << a << " b:" << b << " c:" << c << " disc:" << disc -// << endl; + scalar t1 = -VGREAT; + scalar t2 = VGREAT; if (disc < 0) { + // Fully outside return; } else if (disc < ROOTVSMALL) @@ -147,12 +233,40 @@ void Foam::searchableCylinder::findLineAll // Single solution if (mag(a) > ROOTVSMALL) { - scalar t = -b/(2*a); - if (t >= 0 && t <= 1) + t1 = -b/(2*a); + + //Pout<< "single solution t:" << t1 + // << " for start:" << start << " end:" << end + // << " c:" << c << endl; + + if (t1 >= 0 && t1 <= magV && t1 >= tPoint1 && t1 <= tPoint2) + { + // valid. Insert sorted. + if (t1 < tNear) + { + tFar = tNear; + tNear = t1; + } + else if (t1 < tFar) + { + tFar = t1; + } + } + else { - near.setPoint(start + t*V); - near.setHit(); - near.setIndex(0); + return; + } + } + else + { + // Aligned with axis. Check if outside radius + //Pout<< "small discriminant:" << disc + // << " for start:" << start << " end:" << end + // << " magV:" << magV + // << " c:" << c << endl; + if (c > 0) + { + return; } } } @@ -162,41 +276,79 @@ void Foam::searchableCylinder::findLineAll { scalar sqrtDisc = sqrt(disc); - scalar t1 = (-b + sqrtDisc)/2*a; - scalar t2 = (-b - sqrtDisc)/2*a; + t1 = (-b - sqrtDisc)/(2*a); + t2 = (-b + sqrtDisc)/(2*a); + if (t2 < t1) + { + Swap(t1, t2); + } - if (t1 < t2) + if (t1 >= 0 && t1 <= magV && t1 >= tPoint1 && t1 <= tPoint2) { - if (t1 >= 0 && t1 <= 1) + // valid. Insert sorted. + if (t1 < tNear) { - near.setPoint(start + t1*V); - near.setHit(); - near.setIndex(0); + tFar = tNear; + tNear = t1; } - if (t2 >= 0 && t2 <= 1) + else if (t1 < tFar) { - far.setPoint(start + t2*V); - far.setHit(); - far.setIndex(0); + tFar = t1; } } - else + if (t2 >= 0 && t2 <= magV && t2 >= tPoint1 && t2 <= tPoint2) { - if (t2 >= 0 && t2 <= 1) + // valid. Insert sorted. + if (t2 < tNear) { - near.setPoint(start + t2*V); - near.setHit(); - near.setIndex(0); + tFar = tNear; + tNear = t2; } - if (t1 >= 0 && t1 <= 1) + else if (t2 < tFar) { - far.setPoint(start + t1*V); - far.setHit(); - far.setIndex(0); + tFar = t2; } } + //Pout<< "two solutions t1:" << t1 << " t2:" << t2 + // << " for start:" << start << " end:" << end + // << " magV:" << magV + // << " c:" << c << endl; + } + else + { + // Aligned with axis. Check if outside radius + //Pout<< "large discriminant:" << disc + // << " small a:" << a + // << " for start:" << start << " end:" << end + // << " magV:" << magV + // << " c:" << c << endl; + if (c > 0) + { + return; + } + } + } + + // Check tNear, tFar + if (tNear >= 0 && tNear <= magV) + { + near.setPoint(start+tNear*V); + near.setHit(); + near.setIndex(0); + + if (tFar <= magV) + { + far.setPoint(start+tFar*V); + far.setHit(); + far.setIndex(0); } } + else if (tFar >= 0 && tFar <= magV) + { + near.setPoint(start+tFar*V); + near.setHit(); + near.setIndex(0); + } } @@ -216,13 +368,7 @@ Foam::searchableCylinder::searchableCylinder magDir_(mag(point2_-point1_)), unitDir_((point2_-point1_)/magDir_), radius_(radius) -{ - Pout<< "point1_:" << point1_ << endl; - Pout<< "point2_:" << point2_ << endl; - Pout<< "magDir_:" << magDir_ << endl; - Pout<< "unitDir_:" << unitDir_ << endl; - Pout<< "radius_:" << radius_ << endl; -} +{} Foam::searchableCylinder::searchableCylinder @@ -237,13 +383,7 @@ Foam::searchableCylinder::searchableCylinder magDir_(mag(point2_-point1_)), unitDir_((point2_-point1_)/magDir_), radius_(readScalar(dict.lookup("radius"))) -{ - Pout<< "point1_:" << point1_ << endl; - Pout<< "point2_:" << point2_ << endl; - Pout<< "magDir_:" << magDir_ << endl; - Pout<< "unitDir_:" << unitDir_ << endl; - Pout<< "radius_:" << radius_ << endl; -} +{} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // @@ -290,11 +430,10 @@ void Foam::searchableCylinder::findLine { info.setSize(start.size()); - pointIndexHit b; - forAll(start, i) { // Pick nearest intersection. If none intersected take second one. + pointIndexHit b; findLineAll(start[i], end[i], info[i], b); if (!info[i].hit() && b.hit()) { @@ -313,11 +452,10 @@ void Foam::searchableCylinder::findLineAny { info.setSize(start.size()); - pointIndexHit b; - forAll(start, i) { // Discard far intersection + pointIndexHit b; findLineAll(start[i], end[i], info[i], b); if (!info[i].hit() && b.hit()) { diff --git a/src/meshTools/searchableSurface/searchableCylinder.H b/src/meshTools/searchableSurface/searchableCylinder.H index 55ee0354ddd0665e6e37ec85320aca072fe29a25..cae0f058db2863db95ff479381d207c8ad9e57cf 100644 --- a/src/meshTools/searchableSurface/searchableCylinder.H +++ b/src/meshTools/searchableSurface/searchableCylinder.H @@ -86,6 +86,8 @@ private: const scalar nearestDistSqr ) const; + scalar radius2(const point& pt) const; + //- Find intersection with cylinder void findLineAll ( diff --git a/src/meshTools/searchableSurface/triSurfaceMesh.C b/src/meshTools/searchableSurface/triSurfaceMesh.C index 877f2643414d78b9fc986fa2d765b56aac04b816..950cd13285334a4849f187b61f678f0dc21b309d 100644 --- a/src/meshTools/searchableSurface/triSurfaceMesh.C +++ b/src/meshTools/searchableSurface/triSurfaceMesh.C @@ -237,6 +237,7 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s) ) ), triSurface(s), + tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()), surfaceClosed_(-1) {} @@ -279,6 +280,7 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io) searchableSurface::objectPath() ) ), + tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()), surfaceClosed_(-1) {} @@ -324,6 +326,7 @@ Foam::triSurfaceMesh::triSurfaceMesh searchableSurface::objectPath() ) ), + tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()), surfaceClosed_(-1) { scalar scaleFactor = 0; @@ -332,8 +335,18 @@ Foam::triSurfaceMesh::triSurfaceMesh // eg, CAD geometries are often done in millimeters if (dict.readIfPresent("scale", scaleFactor) && scaleFactor > 0) { + Info<< searchableSurface::name() << " : using scale " << scaleFactor + << endl; triSurface::scalePoints(scaleFactor); } + + + // Have optional non-standard search tolerance for gappy surfaces. + if (dict.readIfPresent("tolerance", tolerance_) && tolerance_ > 0) + { + Info<< searchableSurface::name() << " : using intersection tolerance " + << tolerance_ << endl; + } } @@ -380,6 +393,9 @@ const Foam::indexedOctree<Foam::treeDataTriSurface>& bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); + indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; + tree_.reset ( new indexedOctree<treeDataTriSurface> @@ -391,6 +407,8 @@ const Foam::indexedOctree<Foam::treeDataTriSurface>& 3.0 // duplicity ) ); + + indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; } return tree_(); @@ -491,6 +509,9 @@ void Foam::triSurfaceMesh::findNearest info.setSize(samples.size()); + scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); + indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; + forAll(samples, i) { static_cast<pointIndexHit&>(info[i]) = octree.findNearest @@ -499,6 +520,8 @@ void Foam::triSurfaceMesh::findNearest nearestDistSqr[i] ); } + + indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; } @@ -513,6 +536,9 @@ void Foam::triSurfaceMesh::findLine info.setSize(start.size()); + scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); + indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; + forAll(start, i) { static_cast<pointIndexHit&>(info[i]) = octree.findLine @@ -521,6 +547,8 @@ void Foam::triSurfaceMesh::findLine end[i] ); } + + indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; } @@ -535,6 +563,9 @@ void Foam::triSurfaceMesh::findLineAny info.setSize(start.size()); + scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); + indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; + forAll(start, i) { static_cast<pointIndexHit&>(info[i]) = octree.findLineAny @@ -543,6 +574,8 @@ void Foam::triSurfaceMesh::findLineAny end[i] ); } + + indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; } @@ -557,6 +590,9 @@ void Foam::triSurfaceMesh::findLineAll info.setSize(start.size()); + scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); + indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; + // Work array DynamicList<pointIndexHit, 1, 1> hits; @@ -570,7 +606,7 @@ void Foam::triSurfaceMesh::findLineAll const scalarField magSqrDirVec(magSqr(dirVec)); const vectorField smallVec ( - Foam::sqrt(SMALL)*dirVec + indexedOctree<treeDataTriSurface>::perturbTol()*dirVec + vector(ROOTVSMALL,ROOTVSMALL,ROOTVSMALL) ); @@ -613,6 +649,8 @@ void Foam::triSurfaceMesh::findLineAll info[pointI].clear(); } } + + indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; } @@ -649,7 +687,13 @@ void Foam::triSurfaceMesh::getNormal { if (info[i].hit()) { - normal[i] = faceNormals()[info[i].index()]; + label triI = info[i].index(); + //- Cached: + //normal[i] = faceNormals()[triI]; + + //- Uncached + normal[i] = triSurface::operator[](triI).normal(points()); + normal[i] /= mag(normal[i]) + VSMALL; } else { @@ -691,6 +735,9 @@ void Foam::triSurfaceMesh::getVolumeType { volType.setSize(points.size()); + scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); + indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; + forAll(points, pointI) { const point& pt = points[pointI]; @@ -699,6 +746,8 @@ void Foam::triSurfaceMesh::getVolumeType // - cheat conversion since same values volType[pointI] = static_cast<volumeType>(tree().getVolumeType(pt)); } + + indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; } diff --git a/src/meshTools/searchableSurface/triSurfaceMesh.H b/src/meshTools/searchableSurface/triSurfaceMesh.H index b2ec61c14a943e4c6d4268306d5dfc4ee9157359..4ae415fafa441090bc9589b1b582aec298281d2b 100644 --- a/src/meshTools/searchableSurface/triSurfaceMesh.H +++ b/src/meshTools/searchableSurface/triSurfaceMesh.H @@ -28,6 +28,11 @@ Class Description IOoject and searching on triSurface + Note: when constructing from dictionary has optional parameters: + - scale : scaling factor. + - tolerance : relative tolerance for doing intersections + (see triangle::intersection) + SourceFiles triSurfaceMesh.C @@ -63,6 +68,9 @@ private: // Private member data + //- Optional tolerance to use in searches + scalar tolerance_; + //- Search tree (triangles) mutable autoPtr<indexedOctree<treeDataTriSurface> > tree_; diff --git a/src/meshTools/triSurface/orientedSurface/orientedSurface.C b/src/meshTools/triSurface/orientedSurface/orientedSurface.C index 10e1fa8f2f930e9457352190159ea80584ef3623..f4c165d83f40ee11ee1dffcc2a997f28282f9eba 100644 --- a/src/meshTools/triSurface/orientedSurface/orientedSurface.C +++ b/src/meshTools/triSurface/orientedSurface/orientedSurface.C @@ -121,8 +121,8 @@ Foam::labelList Foam::orientedSurface::edgeToFace label face0 = eFaces[0]; label face1 = eFaces[1]; - const labelledTri& f0 = s[face0]; - const labelledTri& f1 = s[face1]; + const labelledTri& f0 = s.localFaces()[face0]; + const labelledTri& f1 = s.localFaces()[face1]; if (flip[face0] == UNVISITED) { @@ -238,7 +238,8 @@ void Foam::orientedSurface::propagateOrientation s, samplePoint, nearestFaceI, - nearestPt + nearestPt, + 10*SMALL ); if (side == triSurfaceTools::UNKNOWN) @@ -348,7 +349,10 @@ Foam::orientedSurface::orientedSurface : triSurface(surf) { - point outsidePoint = 2 * treeBoundBox(localPoints()).span(); + // BoundBox calculation without localPoints + treeBoundBox bb(surf.points(), surf.meshPoints()); + + point outsidePoint = bb.max() + bb.span(); orient(*this, outsidePoint, orientOutside); } diff --git a/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.C b/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.C index 08138f450be02188245c335841a6a3f638ae1974..b89afdab63b372cb73ad5839afec77febf4d14d0 100644 --- a/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.C +++ b/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.C @@ -2203,7 +2203,8 @@ Foam::triSurfaceTools::sideType Foam::triSurfaceTools::surfaceSide const triSurface& surf, const point& sample, const label nearestFaceI, // nearest face - const point& nearestPoint // nearest point on nearest face + const point& nearestPoint, // nearest point on nearest face + const scalar tol ) { const labelledTri& f = surf[nearestFaceI]; @@ -2217,7 +2218,7 @@ Foam::triSurfaceTools::sideType Foam::triSurfaceTools::surfaceSide points[f[0]], points[f[1]], points[f[2]] - ).classify(nearestPoint, 1E-6, nearType, nearLabel); + ).classify(nearestPoint, tol, nearType, nearLabel); if (nearType == triPointRef::NONE) { diff --git a/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.H b/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.H index 8ddac22a2994296ec86010bac901d3abe02d05d7..b88d460b77bbc934438df741bc351375eab62ce4 100644 --- a/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.H +++ b/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.H @@ -454,13 +454,14 @@ public: //- Given nearest point (to sample) on surface determines which side // sample is. Uses either face normal, edge normal or point normal - // (non-trivial). Feed in output of e.g. triangle::classify. + // (non-trivial). Uses triangle::classify. static sideType surfaceSide ( const triSurface& surf, const point& sample, const label nearestFaceI, // nearest face - const point& nearestPt // nearest point on nearest face + const point& nearestPt, // nearest point on nearest face + const scalar tol // tolerance for nearness test. ); // Triangulation of faces diff --git a/src/meshTools/triSurface/triangleFuncs/triangleFuncs.C b/src/meshTools/triSurface/triangleFuncs/triangleFuncs.C index be83b6326cc52d558ce6130ffac5d77c3388bc9c..1bef529b0325f6242c8ce98574eafe9b4b4c398b 100644 --- a/src/meshTools/triSurface/triangleFuncs/triangleFuncs.C +++ b/src/meshTools/triSurface/triangleFuncs/triangleFuncs.C @@ -22,8 +22,6 @@ License along with OpenFOAM; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -Description - \*---------------------------------------------------------------------------*/ #include "triangleFuncs.H" @@ -31,8 +29,6 @@ Description #include "treeBoundBox.H" #include "SortableList.H" #include "boolList.H" -#include "scalar.H" - // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -170,7 +166,6 @@ bool Foam::triangleFuncs::intersectAxesBundle } - // Intersect triangle with bounding box. Return true if // any of the faces of bb intersect triangle. // Note: so returns false if triangle inside bb. @@ -262,6 +257,272 @@ bool Foam::triangleFuncs::intersectBb } +//// Intersect triangle with bounding box. Return true if +//// any of the faces of bb intersect triangle. +//// Note: so returns false if triangle inside bb. +//bool Foam::triangleFuncs::intersectBbExact +//( +// const point& p0, +// const point& p1, +// const point& p2, +// const treeBoundBox& cubeBb +//) +//{ +// const point& min = cubeBb.min(); +// const point& max = cubeBb.max(); +// +// const point& cube0 = min; +// const point cube1(min.x(), min.y(), max.z()); +// const point cube2(max.x(), min.y(), max.z()); +// const point cube3(max.x(), min.y(), min.z()); +// +// const point cube4(min.x(), max.y(), min.z()); +// const point cube5(min.x(), max.y(), max.z()); +// const point& cube6 = max; +// const point cube7(max.x(), max.y(), min.z()); +// +// // Test intersection of triangle with twelve edges of box. +// { +// triPointRef tri(p0, p1, p2); +// if (tri.intersectionExact(cube0, cube1).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(cube1, cube2).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(cube2, cube3).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(cube3, cube0).hit()) +// { +// return true; +// } +// +// if (tri.intersectionExact(cube4, cube5).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(cube5, cube6).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(cube6, cube7).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(cube7, cube4).hit()) +// { +// return true; +// } +// +// if (tri.intersectionExact(cube0, cube4).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(cube1, cube5).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(cube2, cube6).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(cube3, cube7).hit()) +// { +// return true; +// } +// } +// // Test intersection of triangle edges with bounding box +// { +// triPointRef tri(cube0, cube1, cube2); +// if (tri.intersectionExact(p0, p1).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p1, p2).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p2, p0).hit()) +// { +// return true; +// } +// } +// { +// triPointRef tri(cube2, cube3, cube0); +// if (tri.intersectionExact(p0, p1).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p1, p2).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p2, p0).hit()) +// { +// return true; +// } +// } +// { +// triPointRef tri(cube4, cube5, cube6); +// if (tri.intersectionExact(p0, p1).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p1, p2).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p2, p0).hit()) +// { +// return true; +// } +// } +// { +// triPointRef tri(cube6, cube7, cube4); +// if (tri.intersectionExact(p0, p1).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p1, p2).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p2, p0).hit()) +// { +// return true; +// } +// } +// +// +// { +// triPointRef tri(cube4, cube5, cube1); +// if (tri.intersectionExact(p0, p1).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p1, p2).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p2, p0).hit()) +// { +// return true; +// } +// } +// { +// triPointRef tri(cube1, cube0, cube4); +// if (tri.intersectionExact(p0, p1).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p1, p2).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p2, p0).hit()) +// { +// return true; +// } +// } +// { +// triPointRef tri(cube7, cube6, cube2); +// if (tri.intersectionExact(p0, p1).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p1, p2).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p2, p0).hit()) +// { +// return true; +// } +// } +// { +// triPointRef tri(cube2, cube3, cube7); +// if (tri.intersectionExact(p0, p1).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p1, p2).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p2, p0).hit()) +// { +// return true; +// } +// } +// +// { +// triPointRef tri(cube0, cube4, cube7); +// if (tri.intersectionExact(p0, p1).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p1, p2).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p2, p0).hit()) +// { +// return true; +// } +// } +// { +// triPointRef tri(cube7, cube3, cube0); +// if (tri.intersectionExact(p0, p1).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p1, p2).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p2, p0).hit()) +// { +// return true; +// } +// } +// { +// triPointRef tri(cube1, cube5, cube6); +// if (tri.intersectionExact(p0, p1).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p1, p2).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p2, p0).hit()) +// { +// return true; +// } +// } +// { +// triPointRef tri(cube6, cube2, cube1); +// if (tri.intersectionExact(p0, p1).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p1, p2).hit()) +// { +// return true; +// } +// if (tri.intersectionExact(p2, p0).hit()) +// { +// return true; +// } +// } +// return false; +//} + + bool Foam::triangleFuncs::intersect ( const point& va0, @@ -470,145 +731,4 @@ bool Foam::triangleFuncs::intersect } -bool Foam::triangleFuncs::classify -( - const point& baseVertex, - const vector& E0, - const vector& E1, - const vector& n, - const point& pInter, - const scalar tol, - label& nearType, - label& nearLabel -) -{ - // Get largest component of normal - scalar magX = Foam::mag(n.x()); - scalar magY = Foam::mag(n.y()); - scalar magZ = Foam::mag(n.z()); - - label i0 = -1; - if ((magX >= magY) && (magX >= magZ)) - { - i0 = 0; - } - else if ((magY >= magX) && (magY >= magZ)) - { - i0 = 1; - } - else - { - i0 = 2; - } - - // Get other components - label i1 = (i0 + 1) % 3; - label i2 = (i1 + 1) % 3; - - scalar u1 = E0[i1]; - scalar v1 = E0[i2]; - - scalar u2 = E1[i1]; - scalar v2 = E1[i2]; - - scalar det = v2*u1 - u2*v1; - - scalar u0 = pInter[i1] - baseVertex[i1]; - scalar v0 = pInter[i2] - baseVertex[i2]; - - scalar alpha = 0; - scalar beta = 0; - - bool hit = false; - - if (Foam::mag(u1) < ROOTVSMALL) - { - beta = u0/u2; - - alpha = (v0 - beta*v2)/v1; - - hit = ((alpha >= 0) && ((alpha + beta) <= 1)); - } - else - { - beta = (v0*u1 - u0*v1)/det; - - alpha = (u0 - beta*u2)/u1; - - hit = ((alpha >= 0) && ((alpha + beta) <= 1)); - } - - // - // Now alpha, beta are the coordinates in the triangle local coordinate - // system E0, E1 - // - - nearType = NONE; - nearLabel = -1; - - if (mag(alpha+beta-1) < tol) - { - // On edge between vert 1-2 (=edge 1) - - if (mag(alpha) < tol) - { - nearType = POINT; - nearLabel = 2; - } - else if (mag(beta) < tol) - { - nearType = POINT; - nearLabel = 1; - } - else if ((alpha >= 0) && (alpha <= 1) && (beta >= 0) && (beta <= 1)) - { - nearType = EDGE; - nearLabel = 1; - } - } - else if (mag(alpha) < tol) - { - // On edge between vert 2-0 (=edge 2) - - if (mag(beta) < tol) - { - nearType = POINT; - nearLabel = 0; - } - else if (mag(beta-1) < tol) - { - nearType = POINT; - nearLabel = 2; - } - else if ((beta >= 0) && (beta <= 1)) - { - nearType = EDGE; - nearLabel = 2; - } - } - else if (mag(beta) < tol) - { - // On edge between vert 0-1 (= edge 0) - - if (mag(alpha) < tol) - { - nearType = POINT; - nearLabel = 0; - } - else if (mag(alpha-1) < tol) - { - nearType = POINT; - nearLabel = 1; - } - else if ((alpha >= 0) && (alpha <= 1)) - { - nearType = EDGE; - nearLabel = 0; - } - } - - return hit; -} - - // ************************************************************************* // diff --git a/src/meshTools/triSurface/triangleFuncs/triangleFuncs.H b/src/meshTools/triSurface/triangleFuncs/triangleFuncs.H index 1180e10195399aa79640a86e7a5c9eeecce3939d..0aa2a4c1c406bdb76ce407d559deb2fe4314bccc 100644 --- a/src/meshTools/triSurface/triangleFuncs/triangleFuncs.H +++ b/src/meshTools/triSurface/triangleFuncs/triangleFuncs.H @@ -147,25 +147,6 @@ public: point& pInter0, point& pInter1 ); - - - //- Classify point on triangle plane w.r.t. triangle edges. - // - inside/outside (returned) - // - near point (0, 1, 2) - // - near edge (0, 1, 2). Note: edges are counted from starting vertex - // so e.g. edge 2 is from f[2] to f[0] - static bool classify - ( - const point& baseVertex, - const vector& E0, - const vector& E1, - const vector& n, - const point& pInter, - const scalar tol, - label& nearType, - label& nearLabel - ); - }; diff --git a/src/triSurface/triSurface/triSurface.C b/src/triSurface/triSurface/triSurface.C index 9b63d3de86259314aad1db4227c38f16476c11ec..b17aa88bb58ca26d7d6fad3cc2a223a68863428d 100644 --- a/src/triSurface/triSurface/triSurface.C +++ b/src/triSurface/triSurface/triSurface.C @@ -347,127 +347,6 @@ void Foam::triSurface::checkEdges(const bool verbose) } -// Check normals and orientation -Foam::boolList Foam::triSurface::checkOrientation(const bool verbose) -{ - const edgeList& es = edges(); - const labelListList& faceEs = faceEdges(); - - // Check edge normals, face normals, point normals. - forAll(faceEs, facei) - { - const labelList& edgeLabels = faceEs[facei]; - - if (edgeLabels.size() != 3) - { - FatalErrorIn("triSurface::checkOrientation(bool)") - << "triangle " << (*this)[facei] - << " does not have 3 edges. Edges:" << edgeLabels - << exit(FatalError); - } - - bool valid = true; - forAll(edgeLabels, i) - { - if (edgeLabels[i] < 0 || edgeLabels[i] >= nEdges()) - { - WarningIn - ( - "triSurface::checkOrientation(bool)" - ) << "edge number " << edgeLabels[i] << " on face " << facei - << " out-of-range\n" - << "This usually means that the input surface has " - << "edges with more than 2 triangles connected.\n" - << endl; - valid = false; - } - } - if (! valid) - { - continue; - } - - - // - //- Compute normal from triangle points. - // - - const labelledTri& tri = (*this)[facei]; - const point pa(points()[tri[0]]); - const point pb(points()[tri[1]]); - const point pc(points()[tri[2]]); - - const vector pointNormal((pc - pb) ^ (pa - pb)); - if ((pointNormal & faceNormals()[facei]) < 0) - { - FatalErrorIn("triSurface::checkOrientation(bool)") - << "Normal calculated from points not consistent with" - " faceNormal" << endl - << "triangle:" << tri << endl - << "points:" << pa << ' ' << pb << ' ' << pc << endl - << "pointNormal:" << pointNormal << endl - << "faceNormal:" << faceNormals()[facei] - << exit(FatalError); - } - } - - - const labelListList& eFaces = edgeFaces(); - - // Storage for holding status of edge. True if normal flips across this - // edge - boolList borderEdge(nEdges(), false); - - forAll(es, edgeI) - { - const edge& e = es[edgeI]; - const labelList& neighbours = eFaces[edgeI]; - - if (neighbours.size() == 2) - { - const labelledTri& faceA = (*this)[neighbours[0]]; - const labelledTri& faceB = (*this)[neighbours[1]]; - - // The edge cannot be going in the same direction if both faces - // are oriented counterclockwise. - // Thus the next face point *must* different between the faces. - if - ( - faceA[faceA.fcIndex(findIndex(faceA, e.start()))] - == faceB[faceB.fcIndex(findIndex(faceB, e.start()))] - ) - { - borderEdge[edgeI] = true; - if (verbose) - { - WarningIn("PrimitivePatchExtra::checkOrientation(bool)") - << "face orientation incorrect." << nl - << "edge[" << edgeI << "] " << e - << " between faces " << neighbours << ":" << nl - << "face[" << neighbours[0] << "] " << faceA << nl - << "face[" << neighbours[1] << "] " << faceB << endl; - } - } - } - else if (neighbours.size() != 1) - { - if (verbose) - { - WarningIn("triSurface::checkOrientation(bool)") - << "Wrong number of edge neighbours." << endl - << "edge[" << edgeI << "] " << e - << "with points:" << localPoints()[e.start()] - << ' ' << localPoints()[e.end()] - << " has neighbours:" << neighbours << endl; - } - borderEdge[edgeI] = true; - } - } - - return borderEdge; -} - - // Read triangles, points from Istream bool Foam::triSurface::read(Istream& is) { diff --git a/src/triSurface/triSurface/triSurface.H b/src/triSurface/triSurface/triSurface.H index e6fb6239afec2313987fcd7ec582774740e29a02..9ee5b5ca4d9ee85e2bf1b392feba92928f7aa2ff 100644 --- a/src/triSurface/triSurface/triSurface.H +++ b/src/triSurface/triSurface/triSurface.H @@ -326,17 +326,12 @@ public: //- Scale points. A non-positive factor is ignored virtual void scalePoints(const scalar&); - //- Check/fix duplicate/degenerate triangles + //- Check/remove duplicate/degenerate triangles void checkTriangles(const bool verbose); - //- Check triply (or more) connected edges. Return list of faces - // sharing these edges. + //- Check triply (or more) connected edges. void checkEdges(const bool verbose); - //- Check orientation (normals) and normals of neighbouring - // triangles - boolList checkOrientation(const bool verbose); - //- Remove non-valid triangles void cleanup(const bool verbose); diff --git a/src/turbulenceModels/compressible/RAS/LRR/LRR.C b/src/turbulenceModels/compressible/RAS/LRR/LRR.C index 6521d8130c401d89f9b526f6497294210b00eb3e..a6588ba17c00bca4df37048b09deef3133bf46b3 100644 --- a/src/turbulenceModels/compressible/RAS/LRR/LRR.C +++ b/src/turbulenceModels/compressible/RAS/LRR/LRR.C @@ -337,7 +337,7 @@ void LRR::correct() RASModel::correct(); volSymmTensorField P = -twoSymm(R_ & fvc::grad(U_)); - volScalarField G("G", 0.5*mag(tr(P))); + volScalarField G("RASModel::G", 0.5*mag(tr(P))); // Update espsilon and G at the wall epsilon_.boundaryField().updateCoeffs(); diff --git a/src/turbulenceModels/compressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C b/src/turbulenceModels/compressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C index 4a9987131f24f15042be7ef406404fceb7fc31a8..e677d86a50fde3c5659523d82e103c981c8399a9 100644 --- a/src/turbulenceModels/compressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C +++ b/src/turbulenceModels/compressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C @@ -367,7 +367,7 @@ void LaunderGibsonRSTM::correct() } volSymmTensorField P = -twoSymm(R_ & fvc::grad(U_)); - volScalarField G("G", 0.5*mag(tr(P))); + volScalarField G("RASModel::G", 0.5*mag(tr(P))); // Update espsilon and G at the wall epsilon_.boundaryField().updateCoeffs(); diff --git a/src/turbulenceModels/compressible/RAS/RNGkEpsilon/RNGkEpsilon.C b/src/turbulenceModels/compressible/RAS/RNGkEpsilon/RNGkEpsilon.C index 3d294ebcebb8764ad1c055faf3e41120e3fae85e..9e50de343fbd104c457cbc95440c1566ef14883a 100644 --- a/src/turbulenceModels/compressible/RAS/RNGkEpsilon/RNGkEpsilon.C +++ b/src/turbulenceModels/compressible/RAS/RNGkEpsilon/RNGkEpsilon.C @@ -300,7 +300,7 @@ void RNGkEpsilon::correct() volScalarField S2 = (tgradU() && dev(twoSymm(tgradU()))); tgradU.clear(); - volScalarField G("G", mut_*S2); + volScalarField G("RASModel::G", mut_*S2); volScalarField eta = sqrt(mag(S2))*k_/epsilon_; volScalarField eta3 = eta*sqr(eta); diff --git a/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C b/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C index c86f2f43ebd8d8fe37894d04543c825b2266313a..657dfbb48e629f38f435eb7cbd6d19f5fe48432b 100644 --- a/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C +++ b/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C @@ -64,8 +64,8 @@ tmp<volScalarField> autoCreateAlphat } else { - Info<< "--> Upgrading " << fieldName << " to employ run-time " - << "selectable wall functions" << endl; + Info<< "--> Creating " << fieldName + << " to employ run-time selectable wall functions" << endl; const fvBoundaryMesh& bm = mesh.boundary(); @@ -104,7 +104,7 @@ tmp<volScalarField> autoCreateAlphat ) ); - Info<< " Writing updated " << fieldName << endl; + Info<< " Writing new " << fieldName << endl; alphat().write(); return alphat; @@ -134,8 +134,8 @@ tmp<volScalarField> autoCreateMut } else { - Info<< "--> Upgrading " << fieldName << " to employ run-time " - << "selectable wall functions" << endl; + Info<< "--> Creating " << fieldName + << " to employ run-time selectable wall functions" << endl; const fvBoundaryMesh& bm = mesh.boundary(); @@ -174,7 +174,7 @@ tmp<volScalarField> autoCreateMut ) ); - Info<< " Writing updated " << fieldName << endl; + Info<< " Writing new " << fieldName << endl; mut().write(); return mut; diff --git a/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C b/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C index 98c750c71acc40564ea78ce2b0c8b92683280b70..91f739abfb9d6d6624bf3e0a7413dffd58a55eaa 100644 --- a/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C +++ b/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C @@ -26,6 +26,7 @@ License #include "backwardsCompatibilityWallFunctions.H" #include "Time.H" +#include "OSspecific.H" #include "wallPolyPatch.H" @@ -77,27 +78,35 @@ autoCreateWallFunctionField } else { - Info<< "--> Upgrading " << fieldName << " to employ run-time " - << "selectable wall functions" << endl; + Info<< "--> Upgrading " << fieldName + << " to employ run-time selectable wall functions" << endl; + + // Read existing field + IOobject ioObj + ( + fieldName, + mesh.time().timeName(), + mesh, + IOobject::MUST_READ, + IOobject::NO_WRITE, + false + ); - // Read existing epsilon field tmp<fieldType> fieldOrig ( new fieldType ( - IOobject - ( - fieldName, - mesh.time().timeName(), - mesh, - IOobject::MUST_READ, - IOobject::NO_WRITE, - false - ), + ioObj, mesh ) ); + // rename file + Info<< " Backup original " << fieldName << " to " + << fieldName << ".old" << endl; + mv(ioObj.objectPath(), ioObj.objectPath() + ".old"); + + PtrList<fvPatchField<Type> > newPatchFields(mesh.boundary().size()); forAll(newPatchFields, patchI) @@ -145,11 +154,6 @@ autoCreateWallFunctionField ) ); - Info<< " Writing backup of original " << fieldName << " to " - << fieldName << ".old" << endl; - fieldOrig().rename(fieldName + ".old"); - fieldOrig().write(); - Info<< " Writing updated " << fieldName << endl; fieldNew().write(); diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentHeatFluxTemperature/turbulentHeatFluxTemperatureFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentHeatFluxTemperature/turbulentHeatFluxTemperatureFvPatchScalarField.H index 4640acc7db1a4c6fc9446e4751dea16fc6b04bbb..f7581102df9f8d328715b7b295548f2e8d051326 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentHeatFluxTemperature/turbulentHeatFluxTemperatureFvPatchScalarField.H +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentHeatFluxTemperature/turbulentHeatFluxTemperatureFvPatchScalarField.H @@ -66,7 +66,7 @@ class turbulentHeatFluxTemperatureFvPatchScalarField public: //- Runtime type information - TypeName("turbulentHeatFluxTemperature"); + TypeName("compressible::turbulentHeatFluxTemperature"); // Constructors diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthDissipationRateInlet/turbulentMixingLengthDissipationRateInletFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthDissipationRateInlet/turbulentMixingLengthDissipationRateInletFvPatchScalarField.H index dcadbdd8b954ee2efcf025bd4926c87d4edc9bc1..1eb669f06b370bff6d9fdcb581beff706899fb42 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthDissipationRateInlet/turbulentMixingLengthDissipationRateInletFvPatchScalarField.H +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthDissipationRateInlet/turbulentMixingLengthDissipationRateInletFvPatchScalarField.H @@ -72,7 +72,7 @@ class turbulentMixingLengthDissipationRateInletFvPatchScalarField public: //- Runtime type information - TypeName("turbulentMixingLengthDissipationRateInlet"); + TypeName("compressible::turbulentMixingLengthDissipationRateInlet"); // Constructors diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthFrequencyInlet/turbulentMixingLengthFrequencyInletFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthFrequencyInlet/turbulentMixingLengthFrequencyInletFvPatchScalarField.H index 90d374a33639eab4a5061647632c17e61684affc..45d8d2663c91fb2368d297ba489ecd49c97e2fa9 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthFrequencyInlet/turbulentMixingLengthFrequencyInletFvPatchScalarField.H +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthFrequencyInlet/turbulentMixingLengthFrequencyInletFvPatchScalarField.H @@ -76,7 +76,7 @@ class turbulentMixingLengthFrequencyInletFvPatchScalarField public: //- Runtime type information - TypeName("turbulentMixingLengthFrequencyInlet"); + TypeName("compressible::turbulentMixingLengthFrequencyInlet"); // Constructors diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/alphatWallFunctions/alphatWallFunction/alphatWallFunctionFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/alphatWallFunctions/alphatWallFunction/alphatWallFunctionFvPatchScalarField.H index da71e80a2ff15dee2a7edb451153111d4f497b0b..c49a0bc4826377334289fbbfc681906f0abd8ff7 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/alphatWallFunctions/alphatWallFunction/alphatWallFunctionFvPatchScalarField.H +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/alphatWallFunctions/alphatWallFunction/alphatWallFunctionFvPatchScalarField.H @@ -66,7 +66,7 @@ class alphatWallFunctionFvPatchScalarField public: //- Runtime type information - TypeName("alphatWallFunction"); + TypeName("compressible::alphatWallFunction"); // Constructors diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C index 387f54df338b67e36b947ddb9dd634c883c76a88..d7b7547e0ad896e5b342758fcafc72cebc458c02 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C @@ -67,7 +67,7 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField fixedInternalValueFvPatchField<scalar>(p, iF), UName_("U"), kName_("k"), - GName_("G"), + GName_("RASModel::G"), rhoName_("rho"), muName_("mu"), mutName_("mut") @@ -106,7 +106,7 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField fixedInternalValueFvPatchField<scalar>(p, iF, dict), UName_(dict.lookupOrDefault<word>("U", "U")), kName_(dict.lookupOrDefault<word>("k", "k")), - GName_(dict.lookupOrDefault<word>("G", "G")), + GName_(dict.lookupOrDefault<word>("G", "RASModel::G")), rhoName_(dict.lookupOrDefault<word>("rho", "rho")), muName_(dict.lookupOrDefault<word>("mu", "mu")), mutName_(dict.lookupOrDefault<word>("mut", "mut")) @@ -229,7 +229,7 @@ void epsilonWallFunctionFvPatchScalarField::write(Ostream& os) const fixedInternalValueFvPatchField<scalar>::write(os); writeEntryIfDifferent<word>(os, "U", "U", UName_); writeEntryIfDifferent<word>(os, "k", "k", kName_); - writeEntryIfDifferent<word>(os, "G", "G", GName_); + writeEntryIfDifferent<word>(os, "G", "RASModel::G", GName_); writeEntryIfDifferent<word>(os, "rho", "rho", rhoName_); writeEntryIfDifferent<word>(os, "mu", "mu", muName_); writeEntryIfDifferent<word>(os, "mut", "mut", mutName_); diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H index 42bdeea6818c8716c2c9fc8e9d8d5a1c5aad2efe..506e9f8c2d693d34fac20302774dfeb31d6c3104 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H @@ -87,7 +87,7 @@ class epsilonWallFunctionFvPatchScalarField public: //- Runtime type information - TypeName("epsilonWallFunction"); + TypeName("compressible::epsilonWallFunction"); // Constructors diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/kQRWallFunctions/kQRWallFunction/kQRWallFunctionFvPatchField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/kQRWallFunctions/kQRWallFunction/kQRWallFunctionFvPatchField.H index 05ed2fbcb81d08f9d21ca1ba104f4649c7057c43..a4a9ddbc30894b2679503131475386d3e4526e39 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/kQRWallFunctions/kQRWallFunction/kQRWallFunctionFvPatchField.H +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/kQRWallFunctions/kQRWallFunction/kQRWallFunctionFvPatchField.H @@ -67,7 +67,7 @@ class kQRWallFunctionFvPatchField public: //- Runtime type information - TypeName("kQRWallFunction"); + TypeName("compressible::kQRWallFunction"); // Constructors diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C index eacf26b1d42a2b81e4bafb52bb11d039dee35f4a..897a8c1162ca26c06eed190859fbdc98da331b81 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C @@ -68,7 +68,7 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField UName_("U"), rhoName_("rho"), kName_("k"), - GName_("G"), + GName_("RASModel::G"), muName_("mu"), mutName_("mut") { @@ -107,7 +107,7 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField UName_(dict.lookupOrDefault<word>("U", "U")), rhoName_(dict.lookupOrDefault<word>("rho", "rho")), kName_(dict.lookupOrDefault<word>("k", "k")), - GName_(dict.lookupOrDefault<word>("G", "G")), + GName_(dict.lookupOrDefault<word>("G", "RASModel::G")), muName_(dict.lookupOrDefault<word>("mu", "mu")), mutName_(dict.lookupOrDefault<word>("mut", "mut")) { @@ -221,7 +221,7 @@ void omegaWallFunctionFvPatchScalarField::write(Ostream& os) const writeEntryIfDifferent<word>(os, "U", "U", UName_); writeEntryIfDifferent<word>(os, "rho", "rho", rhoName_); writeEntryIfDifferent<word>(os, "k", "k", kName_); - writeEntryIfDifferent<word>(os, "G", "G", GName_); + writeEntryIfDifferent<word>(os, "G", "RASModel::G", GName_); writeEntryIfDifferent<word>(os, "mu", "mu", muName_); writeEntryIfDifferent<word>(os, "mut", "mut", mutName_); writeEntry("value", os); diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H index 6dfe7a772ba574110e3cba1a183fe5d99bd2bc60..675d3a16fbafda9e911c232a9dce8f836d2b8fdb 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H @@ -85,7 +85,7 @@ class omegaWallFunctionFvPatchScalarField public: //- Runtime type information - TypeName("omegaWallFunction"); + TypeName("compressible::omegaWallFunction"); // Constructors diff --git a/src/turbulenceModels/compressible/RAS/kEpsilon/kEpsilon.C b/src/turbulenceModels/compressible/RAS/kEpsilon/kEpsilon.C index 609ee8300d3dac50ae7dcdf45fe411f9bd28397d..3e076722a2297e9045a5e59fd7a7319cb9e47f6f 100644 --- a/src/turbulenceModels/compressible/RAS/kEpsilon/kEpsilon.C +++ b/src/turbulenceModels/compressible/RAS/kEpsilon/kEpsilon.C @@ -278,7 +278,7 @@ void kEpsilon::correct() } tmp<volTensorField> tgradU = fvc::grad(U_); - volScalarField G("G", mut_*(tgradU() && dev(twoSymm(tgradU())))); + volScalarField G("RASModel::G", mut_*(tgradU() && dev(twoSymm(tgradU())))); tgradU.clear(); // Update espsilon and G at the wall diff --git a/src/turbulenceModels/compressible/RAS/kOmegaSST/kOmegaSST.C b/src/turbulenceModels/compressible/RAS/kOmegaSST/kOmegaSST.C index 52cfaf2df838c5dd72ed4b5d678d80ccb32be7da..e8a7e06895caa1a987cbe756940b1aeb66a5a124 100644 --- a/src/turbulenceModels/compressible/RAS/kOmegaSST/kOmegaSST.C +++ b/src/turbulenceModels/compressible/RAS/kOmegaSST/kOmegaSST.C @@ -381,7 +381,7 @@ void kOmegaSST::correct() tmp<volTensorField> tgradU = fvc::grad(U_); volScalarField S2 = magSqr(symm(tgradU())); volScalarField GbyMu = (tgradU() && dev(twoSymm(tgradU()))); - volScalarField G("G", mut_*GbyMu); + volScalarField G("RASModel::G", mut_*GbyMu); tgradU.clear(); // Update omega and G at the wall diff --git a/src/turbulenceModels/compressible/RAS/realizableKE/realizableKE.C b/src/turbulenceModels/compressible/RAS/realizableKE/realizableKE.C index d55321fdb44372e9c5c820eab7a8bd3264ee606c..c08516aa2714f73f02f3314f016e8924cde25fec 100644 --- a/src/turbulenceModels/compressible/RAS/realizableKE/realizableKE.C +++ b/src/turbulenceModels/compressible/RAS/realizableKE/realizableKE.C @@ -317,7 +317,7 @@ void realizableKE::correct() volScalarField eta = magS*k_/epsilon_; volScalarField C1 = max(eta/(scalar(5) + eta), scalar(0.43)); - volScalarField G("G", mut_*(gradU && dev(twoSymm(gradU)))); + volScalarField G("RASModel::G", mut_*(gradU && dev(twoSymm(gradU)))); // Update espsilon and G at the wall epsilon_.boundaryField().updateCoeffs(); diff --git a/src/turbulenceModels/incompressible/RAS/LRR/LRR.C b/src/turbulenceModels/incompressible/RAS/LRR/LRR.C index f720a0312d932dc4a06dfbc94e3909feef52df99..0c361c97ff1cb453d8b2ee0f554efd26d7d88511 100644 --- a/src/turbulenceModels/incompressible/RAS/LRR/LRR.C +++ b/src/turbulenceModels/incompressible/RAS/LRR/LRR.C @@ -297,7 +297,7 @@ void LRR::correct() } volSymmTensorField P = -twoSymm(R_ & fvc::grad(U_)); - volScalarField G("G", 0.5*mag(tr(P))); + volScalarField G("RASModel::G", 0.5*mag(tr(P))); // Update espsilon and G at the wall epsilon_.boundaryField().updateCoeffs(); diff --git a/src/turbulenceModels/incompressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C b/src/turbulenceModels/incompressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C index 6f130f2a31256f2c2bc4ef475e6dff780df0c3d0..60f32bf14f07b2dd0dc2c9a594ed33d8057bdfa8 100644 --- a/src/turbulenceModels/incompressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C +++ b/src/turbulenceModels/incompressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C @@ -329,7 +329,7 @@ void LaunderGibsonRSTM::correct() } volSymmTensorField P = -twoSymm(R_ & fvc::grad(U_)); - volScalarField G("G", 0.5*mag(tr(P))); + volScalarField G("RASModel::G", 0.5*mag(tr(P))); // Update espsilon and G at the wall epsilon_.boundaryField().updateCoeffs(); diff --git a/src/turbulenceModels/incompressible/RAS/LienCubicKE/LienCubicKE.C b/src/turbulenceModels/incompressible/RAS/LienCubicKE/LienCubicKE.C index bb442dc24093a7ba99294c64083849cfd891f59b..41e6a851b7b8b58bdfc3fdf3e02afe339bc844c1 100644 --- a/src/turbulenceModels/incompressible/RAS/LienCubicKE/LienCubicKE.C +++ b/src/turbulenceModels/incompressible/RAS/LienCubicKE/LienCubicKE.C @@ -328,7 +328,7 @@ void LienCubicKE::correct() volScalarField G ( - "G", + "RASModel::G", Cmu_*sqr(k_)/epsilon_*S2 - (nonlinearStress_ && gradU_) ); diff --git a/src/turbulenceModels/incompressible/RAS/RNGkEpsilon/RNGkEpsilon.C b/src/turbulenceModels/incompressible/RAS/RNGkEpsilon/RNGkEpsilon.C index 6285fb17bf29cf9b8bd8e6af47e78cb77d995c83..533aca878af81e60dc0206b12b097c8e9265807f 100644 --- a/src/turbulenceModels/incompressible/RAS/RNGkEpsilon/RNGkEpsilon.C +++ b/src/turbulenceModels/incompressible/RAS/RNGkEpsilon/RNGkEpsilon.C @@ -249,7 +249,7 @@ void RNGkEpsilon::correct() volScalarField S2 = 2*magSqr(symm(fvc::grad(U_))); - volScalarField G("G", nut_*S2); + volScalarField G("RASModel::G", nut_*S2); volScalarField eta = sqrt(S2)*k_/epsilon_; volScalarField R = diff --git a/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C b/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C index 949c33472636b63641a0ce01807d380bd9eb2879..f7b144a03b4bdce4890b2d06eaeb83a278a3b402 100644 --- a/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C +++ b/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C @@ -63,8 +63,8 @@ tmp<volScalarField> autoCreateNut } else { - Info<< "--> Upgrading " << fieldName << " to employ run-time " - << "selectable wall functions" << endl; + Info<< "--> Creating " << fieldName + << " to employ run-time selectable wall functions" << endl; const fvBoundaryMesh& bm = mesh.boundary(); @@ -103,7 +103,7 @@ tmp<volScalarField> autoCreateNut ) ); - Info<< " Writing updated " << fieldName << endl; + Info<< " Writing new " << fieldName << endl; nut().write(); return nut; diff --git a/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C b/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C index 563f529d619b43adf41b9ee49338b5b851a2781c..10247d493eae3d934035a20af26b8ea493a30b19 100644 --- a/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C +++ b/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C @@ -26,6 +26,7 @@ License #include "backwardsCompatibilityWallFunctions.H" #include "Time.H" +#include "OSspecific.H" #include "wallPolyPatch.H" @@ -77,27 +78,35 @@ autoCreateWallFunctionField } else { - Info<< "--> Upgrading " << fieldName << " to employ run-time " - << "selectable wall functions" << endl; + Info<< "--> Upgrading " << fieldName + << " to employ run-time selectable wall functions" << endl; + + // Read existing field + IOobject ioObj + ( + fieldName, + mesh.time().timeName(), + mesh, + IOobject::MUST_READ, + IOobject::NO_WRITE, + false + ); - // Read existing epsilon field tmp<fieldType> fieldOrig ( new fieldType ( - IOobject - ( - fieldName, - mesh.time().timeName(), - mesh, - IOobject::MUST_READ, - IOobject::NO_WRITE, - false - ), + ioObj, mesh ) ); + // rename file + Info<< " Backup original " << fieldName << " to " + << fieldName << ".old" << endl; + mv(ioObj.objectPath(), ioObj.objectPath() + ".old"); + + PtrList<fvPatchField<Type> > newPatchFields(mesh.boundary().size()); forAll(newPatchFields, patchI) @@ -145,11 +154,6 @@ autoCreateWallFunctionField ) ); - Info<< " Writing backup of original " << fieldName << " to " - << fieldName << ".old" << endl; - fieldOrig().rename(fieldName + ".old"); - fieldOrig().write(); - Info<< " Writing updated " << fieldName << endl; fieldNew().write(); diff --git a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C index ae8a57c303d3c686212acb5c8f5175c677c9bad2..371d912c8ab00c955c5c214a7ae711bbdf19ddae 100644 --- a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C +++ b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C @@ -67,7 +67,7 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField fixedInternalValueFvPatchField<scalar>(p, iF), UName_("U"), kName_("k"), - GName_("G"), + GName_("RASModel::G"), nuName_("nu"), nutName_("nut") { @@ -104,7 +104,7 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField fixedInternalValueFvPatchField<scalar>(p, iF, dict), UName_(dict.lookupOrDefault<word>("U", "U")), kName_(dict.lookupOrDefault<word>("k", "k")), - GName_(dict.lookupOrDefault<word>("G", "G")), + GName_(dict.lookupOrDefault<word>("G", "RASModel::G")), nuName_(dict.lookupOrDefault<word>("nu", "nu")), nutName_(dict.lookupOrDefault<word>("nut", "nut")) { @@ -219,7 +219,7 @@ void epsilonWallFunctionFvPatchScalarField::write(Ostream& os) const fixedInternalValueFvPatchField<scalar>::write(os); writeEntryIfDifferent<word>(os, "U", "U", UName_); writeEntryIfDifferent<word>(os, "k", "k", kName_); - writeEntryIfDifferent<word>(os, "G", "G", GName_); + writeEntryIfDifferent<word>(os, "G", "RASModel::G", GName_); writeEntryIfDifferent<word>(os, "nu", "nu", nuName_); writeEntryIfDifferent<word>(os, "nut", "nut", nutName_); writeEntry("value", os); diff --git a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C index f6a3b6a191fdeeef6fb8de8d729259989d129183..d4351bf243cc22d3358840d6e48181400f741caf 100644 --- a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C +++ b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C @@ -67,7 +67,7 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField fixedInternalValueFvPatchField<scalar>(p, iF), UName_("U"), kName_("k"), - GName_("G"), + GName_("RASModel::G"), nuName_("nu"), nutName_("nut") { @@ -104,7 +104,7 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField fixedInternalValueFvPatchField<scalar>(p, iF, dict), UName_(dict.lookupOrDefault<word>("U", "U")), kName_(dict.lookupOrDefault<word>("k", "k")), - GName_(dict.lookupOrDefault<word>("G", "G")), + GName_(dict.lookupOrDefault<word>("G", "RASModel::G")), nuName_(dict.lookupOrDefault<word>("nu", "nu")), nutName_(dict.lookupOrDefault<word>("nut", "nut")) { @@ -210,7 +210,7 @@ void omegaWallFunctionFvPatchScalarField::write(Ostream& os) const fixedInternalValueFvPatchField<scalar>::write(os); writeEntryIfDifferent<word>(os, "U", "U", UName_); writeEntryIfDifferent<word>(os, "k", "k", kName_); - writeEntryIfDifferent<word>(os, "G", "G", GName_); + writeEntryIfDifferent<word>(os, "G", "RASModel::G", GName_); writeEntryIfDifferent<word>(os, "nu", "nu", nuName_); writeEntryIfDifferent<word>(os, "nut", "nut", nutName_); writeEntry("value", os); diff --git a/src/turbulenceModels/incompressible/RAS/kEpsilon/kEpsilon.C b/src/turbulenceModels/incompressible/RAS/kEpsilon/kEpsilon.C index a5953a4cb7df244fcd042a1b21f31187bfd61b27..1f65b2d2ba8386073a30c8e82274e626b582a709 100644 --- a/src/turbulenceModels/incompressible/RAS/kEpsilon/kEpsilon.C +++ b/src/turbulenceModels/incompressible/RAS/kEpsilon/kEpsilon.C @@ -129,7 +129,7 @@ kEpsilon::kEpsilon autoCreateNut("nut", mesh_) ) { - nut_ == Cmu_*sqr(k_)/(epsilon_ + epsilonSmall_); + nut_ = Cmu_*sqr(k_)/(epsilon_ + epsilonSmall_); nut_.correctBoundaryConditions(); printCoeffs(); @@ -216,7 +216,7 @@ void kEpsilon::correct() return; } - volScalarField G("G", nut_*2*magSqr(symm(fvc::grad(U_)))); + volScalarField G("RASModel::G", nut_*2*magSqr(symm(fvc::grad(U_)))); // Update espsilon and G at the wall epsilon_.boundaryField().updateCoeffs(); @@ -259,7 +259,7 @@ void kEpsilon::correct() // Re-calculate viscosity - nut_ == Cmu_*sqr(k_)/epsilon_; + nut_ = Cmu_*sqr(k_)/epsilon_; nut_.correctBoundaryConditions(); } diff --git a/src/turbulenceModels/incompressible/RAS/kOmega/kOmega.C b/src/turbulenceModels/incompressible/RAS/kOmega/kOmega.C index a45ff8c33b1594741ab0d0c61fefd967fe5655b1..d29291885a61ad8de82ee3486bea86e7e8646e5d 100644 --- a/src/turbulenceModels/incompressible/RAS/kOmega/kOmega.C +++ b/src/turbulenceModels/incompressible/RAS/kOmega/kOmega.C @@ -225,7 +225,7 @@ void kOmega::correct() return; } - volScalarField G("G", nut_*2*magSqr(symm(fvc::grad(U_)))); + volScalarField G("RASModel::G", nut_*2*magSqr(symm(fvc::grad(U_)))); // Update omega and G at the wall omega_.boundaryField().updateCoeffs(); diff --git a/src/turbulenceModels/incompressible/RAS/kOmegaSST/kOmegaSST.C b/src/turbulenceModels/incompressible/RAS/kOmegaSST/kOmegaSST.C index 6a737fce49fb5b4c1cb41f39818d314fa5ed4ad7..2ae7d8be6a970ca7ec78bce42832d50dc29af79f 100644 --- a/src/turbulenceModels/incompressible/RAS/kOmegaSST/kOmegaSST.C +++ b/src/turbulenceModels/incompressible/RAS/kOmegaSST/kOmegaSST.C @@ -343,7 +343,7 @@ void kOmegaSST::correct() } volScalarField S2 = magSqr(symm(fvc::grad(U_))); - volScalarField G("G", nut_*2*S2); + volScalarField G("RASModel::G", nut_*2*S2); // Update omega and G at the wall omega_.boundaryField().updateCoeffs(); diff --git a/src/turbulenceModels/incompressible/RAS/realizableKE/realizableKE.C b/src/turbulenceModels/incompressible/RAS/realizableKE/realizableKE.C index 2f70b0ed2a7303ce422b878b8b5c29a877152142..d92a765ee2191751fd6415952a9f12884b936488 100644 --- a/src/turbulenceModels/incompressible/RAS/realizableKE/realizableKE.C +++ b/src/turbulenceModels/incompressible/RAS/realizableKE/realizableKE.C @@ -277,7 +277,7 @@ void realizableKE::correct() volScalarField eta = magS*k_/epsilon_; volScalarField C1 = max(eta/(scalar(5) + eta), scalar(0.43)); - volScalarField G("G", nut_*S2); + volScalarField G("RASModel::G", nut_*S2); // Update espsilon and G at the wall epsilon_.boundaryField().updateCoeffs(); diff --git a/tutorials/compressible/rhoPisoFoam/ras/cavity/constant/polyMesh/boundary b/tutorials/compressible/rhoPisoFoam/ras/cavity/constant/polyMesh/boundary index 52f27af65188a35fc12861a6314b2cbe72d660d5..61feadd97403fbf58a57c925fc262f3de46ec95a 100644 --- a/tutorials/compressible/rhoPisoFoam/ras/cavity/constant/polyMesh/boundary +++ b/tutorials/compressible/rhoPisoFoam/ras/cavity/constant/polyMesh/boundary @@ -1,8 +1,8 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: 1.5 | -| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile @@ -10,32 +10,31 @@ FoamFile version 2.0; format ascii; class polyBoundaryMesh; + location "constant/polyMesh"; object boundary; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 3 ( -movingWall -{ - type wall; - nFaces 20; - startFace 760; -} - -fixedWalls -{ - type wall; - nFaces 60; - startFace 780; -} - -frontAndBack -{ - type empty; - nFaces 800; - startFace 840; -} + movingWall + { + type wall; + nFaces 20; + startFace 760; + } + fixedWalls + { + type wall; + nFaces 60; + startFace 780; + } + frontAndBack + { + type empty; + nFaces 800; + startFace 840; + } ) // ************************************************************************* // diff --git a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/epsilon b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/epsilon index 471f122da8e2a81955aac14f408a0fec3c7c19f7..23851291dc60d3b0df3be887acfbeb0bb5067ef8 100644 --- a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/epsilon +++ b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/epsilon @@ -15,7 +15,7 @@ FoamFile } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -dimensions [ 0 2 -3 0 0 0 0 ]; +dimensions [0 2 -3 0 0 0 0]; internalField uniform 0.01; @@ -23,20 +23,18 @@ boundaryField { floor { - type epsilonWallFunction; - value uniform 0; + type compressible::epsilonWallFunction; + value uniform 0.01; } - ceiling { - type epsilonWallFunction; - value uniform 0; + type compressible::epsilonWallFunction; + value uniform 0.01; } - fixedWalls { - type epsilonWallFunction; - value uniform 0; + type compressible::epsilonWallFunction; + value uniform 0.01; } } diff --git a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/k b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/k index e0c92b9c4f9463d1f90ff2ef32188125d092c301..4ec7f08960c175a6d955e2c1d3cfb98453524647 100644 --- a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/k +++ b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/k @@ -15,7 +15,7 @@ FoamFile } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -dimensions [ 0 2 -2 0 0 0 0 ]; +dimensions [0 2 -2 0 0 0 0]; internalField uniform 0.1; @@ -23,20 +23,18 @@ boundaryField { floor { - type kQRWallFunction; - value uniform 0; + type compressible::kQRWallFunction; + value uniform 0.1; } - ceiling { - type kQRWallFunction; - value uniform 0; + type compressible::kQRWallFunction; + value uniform 0.1; } - fixedWalls { - type kQRWallFunction; - value uniform 0; + type compressible::kQRWallFunction; + value uniform 0.1; } } diff --git a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/mut b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/mut deleted file mode 100644 index f78d7659f90151e17c9011c88f9c96806ca7bcaf..0000000000000000000000000000000000000000 --- a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/mut +++ /dev/null @@ -1,44 +0,0 @@ -/*--------------------------------*- C++ -*----------------------------------*\ -| ========= | | -| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: dev | -| \\ / A nd | Web: www.OpenFOAM.org | -| \\/ M anipulation | | -\*---------------------------------------------------------------------------*/ -FoamFile -{ - version 2.0; - format ascii; - class volScalarField; - location "0"; - object mut; -} -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -dimensions [ 1 -1 -1 0 0 0 0 ]; - -internalField uniform 0; - -boundaryField -{ - floor - { - type mutWallFunction; - value uniform 0; - } - - ceiling - { - type mutWallFunction; - value uniform 0; - } - - fixedWalls - { - type mutWallFunction; - value uniform 0; - } -} - - -// ************************************************************************* // diff --git a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/constant/polyMesh/boundary b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/constant/polyMesh/boundary index 713344455a1a29c3cccb21bfcfb43f423eaa5cf3..0d4d0e498dae524c835cc1addc9707eb5af47fb3 100644 --- a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/constant/polyMesh/boundary +++ b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/constant/polyMesh/boundary @@ -1,8 +1,8 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: 1.5 | -| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile @@ -10,6 +10,7 @@ FoamFile version 2.0; format ascii; class polyBoundaryMesh; + location "constant/polyMesh"; object boundary; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/controlDict b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/controlDict index f413425423be7e5cce874661512daa4f490ec0fb..cb2e7470f67597540554a58b19942872bab68d34 100644 --- a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/controlDict +++ b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/controlDict @@ -43,5 +43,8 @@ timePrecision 6; runTimeModifiable yes; +adjustTimeStep no; + +maxCo 0.5; // ************************************************************************* // diff --git a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/fvSchemes b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/fvSchemes index 1006ba6d1fa7c94161a12979af2b5fd49da985f5..583bf08e11cb06903ecea9b68ba94a197d2ebed3 100644 --- a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/fvSchemes +++ b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/fvSchemes @@ -33,6 +33,7 @@ divSchemes div(phi,k) Gauss upwind; div(phi,epsilon) Gauss upwind; div(phi,R) Gauss upwind; + div(phiU,p) Gauss linear; div(R) Gauss linear; div((muEff*dev2(grad(U).T()))) Gauss linear; } diff --git a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/epsilon b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/epsilon index fcda1ad91f0555e9302263cb3bc42b7e70960b7a..23851291dc60d3b0df3be887acfbeb0bb5067ef8 100644 --- a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/epsilon +++ b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/epsilon @@ -1,8 +1,8 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: 1.5 | -| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile @@ -23,17 +23,17 @@ boundaryField { floor { - type epsilonWallFunction; + type compressible::epsilonWallFunction; value uniform 0.01; } ceiling { - type epsilonWallFunction; + type compressible::epsilonWallFunction; value uniform 0.01; } fixedWalls { - type epsilonWallFunction; + type compressible::epsilonWallFunction; value uniform 0.01; } } diff --git a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/k b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/k index 93cd1e0334ff778d059a5d6c43fef6b118f39d18..4ec7f08960c175a6d955e2c1d3cfb98453524647 100644 --- a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/k +++ b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/k @@ -1,8 +1,8 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: 1.5 | -| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile @@ -23,17 +23,17 @@ boundaryField { floor { - type kQRWallFunction; + type compressible::kQRWallFunction; value uniform 0.1; } ceiling { - type kQRWallFunction; + type compressible::kQRWallFunction; value uniform 0.1; } fixedWalls { - type kQRWallFunction; + type compressible::kQRWallFunction; value uniform 0.1; } } diff --git a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/mut b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/mut deleted file mode 100644 index fca37fcb40bdec040dd0e57f6fecaebe4c58562c..0000000000000000000000000000000000000000 --- a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/mut +++ /dev/null @@ -1,42 +0,0 @@ -/*--------------------------------*- C++ -*----------------------------------*\ -| ========= | | -| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: 1.5 | -| \\ / A nd | Web: http://www.OpenFOAM.org | -| \\/ M anipulation | | -\*---------------------------------------------------------------------------*/ -FoamFile -{ - version 2.0; - format ascii; - class volScalarField; - location "0"; - object mut; -} -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -dimensions [1 -1 -1 0 0 0 0]; - -internalField uniform 0; - -boundaryField -{ - floor - { - type mutWallFunction; - value uniform 0; - } - ceiling - { - type mutWallFunction; - value uniform 0; - } - fixedWalls - { - type mutWallFunction; - value uniform 0; - } -} - - -// ************************************************************************* // diff --git a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/Allrun b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/Allrun index 0b8cae611d1d464cf8e766070789a9444e0cb4af..6a98e5715d655d25f6569da8915ed83d6d3cbbb1 100755 --- a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/Allrun +++ b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/Allrun @@ -4,7 +4,7 @@ application="buoyantSimpleFoam" -compileApplication ../../buoyantFoam/hotRoom/setHotRoom +compileApplication ../../buoyantPisoFoam/hotRoom/setHotRoom runApplication blockMesh runApplication setHotRoom runApplication $application diff --git a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/constant/polyMesh/boundary b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/constant/polyMesh/boundary index d0eb52935f2b14b9b94f41a477063f46188ccf5f..0d4d0e498dae524c835cc1addc9707eb5af47fb3 100644 --- a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/constant/polyMesh/boundary +++ b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/constant/polyMesh/boundary @@ -1,8 +1,8 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: 1.5 | -| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile diff --git a/tutorials/heatTransfer/buoyantSimpleRadiationFoam/hotRadiationRoom/0/mut b/tutorials/heatTransfer/buoyantSimpleRadiationFoam/hotRadiationRoom/0/mut deleted file mode 100644 index c609cbf3d2c865212d20992980a9b59a349b9c68..0000000000000000000000000000000000000000 --- a/tutorials/heatTransfer/buoyantSimpleRadiationFoam/hotRadiationRoom/0/mut +++ /dev/null @@ -1,50 +0,0 @@ -/*--------------------------------*- C++ -*----------------------------------*\ -| ========= | | -| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: dev | -| \\ / A nd | Web: www.OpenFOAM.org | -| \\/ M anipulation | | -\*---------------------------------------------------------------------------*/ -FoamFile -{ - version 2.0; - format ascii; - class volScalarField; - location "0"; - object mut; -} -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -dimensions [ 1 -1 -1 0 0 0 0 ]; - -internalField uniform 0; - -boundaryField -{ - box - { - type mutWallFunction; - value uniform 0; - } - - floor - { - type mutWallFunction; - value uniform 0; - } - - ceiling - { - type mutWallFunction; - value uniform 0; - } - - fixedWalls - { - type mutWallFunction; - value uniform 0; - } -} - - -// ************************************************************************* // diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/alphat b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/alphat index 3a5286b6dbfcffb06d6a45c99fe29429f6cba062..c90550f0b844a0a1a91c867c22d704ee1f4f5c81 100644 --- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/alphat +++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/alphat @@ -21,6 +21,11 @@ internalField uniform 0; boundaryField { + minY + { + type alphatWallFunction; + value uniform 0; + } maxY { type alphatWallFunction; diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/epsilon b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/epsilon index bb298dd95dd506ba55c7acde5da6e7a1b8f41bcb..c72b3362c06b88dfd24cd8b3a9be926742fc5057 100644 --- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/epsilon +++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/epsilon @@ -21,6 +21,11 @@ internalField uniform 0.01; boundaryField { + minY + { + type epsilonWallFunction; + value uniform 0.01; + } maxY { type epsilonWallFunction; diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/k b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/k index e4db2c837d0bd8d76ad06e085cf27900d8308e9e..49df1e0d2bbc086f04854475877bdd9fe4b596ee 100644 --- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/k +++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/k @@ -21,6 +21,11 @@ internalField uniform 0.1; boundaryField { + minY + { + type kQRWallFunction; + value uniform 0.1; + } maxY { type kQRWallFunction; diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/mut b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/mut deleted file mode 100644 index ece854fd06176af32e1d06503c0c3461c1a3b77c..0000000000000000000000000000000000000000 --- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/mut +++ /dev/null @@ -1,67 +0,0 @@ -/*--------------------------------*- C++ -*----------------------------------*\ -| ========= | | -| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: dev | -| \\ / A nd | Web: www.OpenFOAM.org | -| \\/ M anipulation | | -\*---------------------------------------------------------------------------*/ -FoamFile -{ - version 2.0; - format ascii; - class volScalarField; - location "0.001"; - object mut; -} -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -dimensions [1 -1 -1 0 0 0 0]; - -internalField uniform 0; - -boundaryField -{ - maxY - { - type mutWallFunction; - value uniform 0; - } - minX - { - type calculated; - value uniform 0; - } - maxX - { - type calculated; - value uniform 0; - } - minZ - { - type mutWallFunction; - value uniform 0; - } - maxZ - { - type mutWallFunction; - value uniform 0; - } - topAir_to_leftSolid - { - type calculated; - value uniform 0; - } - topAir_to_heater - { - type calculated; - value uniform 0; - } - topAir_to_rightSolid - { - type calculated; - value uniform 0; - } -} - - -// ************************************************************************* // diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/bottomAir/fvSolution b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/bottomAir/fvSolution index b4f773aaa4b412012acf405c551618a62bdbf9d6..84839fe0ac905869edce0e444073487c84f3c61e 100644 --- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/bottomAir/fvSolution +++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/bottomAir/fvSolution @@ -16,26 +16,30 @@ FoamFile solvers { - rho PCG + rho { - preconditioner DIC; - tolerance 1e-6; - relTol 0; + solver PCG + preconditioner DIC; + tolerance 1e-6; + relTol 0; }; -// pd PCG +// pd // { +// solver PCG // preconditioner DIC; // tolerance 1e-6; // relTol 0.1; // }; -// pdFinal PCG +// pdFinal // { +// solver PCG; // preconditioner DIC; // tolerance 1e-08; // relTol 0; // }; - pd GAMG + pd { + solver GAMG; tolerance 1e-6; relTol 0.1; @@ -46,8 +50,9 @@ solvers agglomerator faceAreaPair; mergeLevels 1; }; - pdFinal GAMG + pdFinal { + solver GAMG; tolerance 1e-6; relTol 0; @@ -58,32 +63,37 @@ solvers agglomerator faceAreaPair; mergeLevels 1; }; - U PBiCG + U { + solver PBiCG; preconditioner DILU; tolerance 1e-08; relTol 0; }; - h PBiCG + h { + solver PBiCG; preconditioner DILU; tolerance 1e-06; relTol 0; }; - k PBiCG + k { + solver PBiCG; preconditioner DILU; tolerance 1e-06; relTol 0; }; - epsilon PBiCG + epsilon { + solver PBiCG; preconditioner DILU; tolerance 1e-06; relTol 0; }; - R PBiCG + R { + solver PBiCG; preconditioner DILU; tolerance 1e-06; relTol 0; diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/fvSchemes b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/fvSchemes index e8078b2b209d98dacf01c6263cf26202d00cd1e8..4c5f890224ae9fc5c14ce322600ab186c3d05c72 100644 --- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/fvSchemes +++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/fvSchemes @@ -14,5 +14,33 @@ FoamFile } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +ddtSchemes +{ +} + +gradSchemes +{ +} + +divSchemes +{ +} + +laplacianSchemes +{ +} + +interpolationSchemes +{ +} + +snGradSchemes +{ +} + +fluxRequired +{ +} + // ************************************************************************* // diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/heater/fvSolution b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/heater/fvSolution index e1bc5f8416d0c16cb569690f3e11f6f376062c35..d1c768d4d4444eb6e1937e1840ddde4a19096376 100644 --- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/heater/fvSolution +++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/heater/fvSolution @@ -16,8 +16,9 @@ FoamFile solvers { - T PCG + T { + solver PCG; preconditioner DIC; tolerance 1E-06; relTol 0; diff --git a/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/constant/polyMesh/boundary b/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/constant/polyMesh/boundary index 0b56bb9f5e8be426cd22b962d4b254728ac55ab7..4530c7b820cd84a5d66dfda299ca4ac6620a2c8b 100644 --- a/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/constant/polyMesh/boundary +++ b/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/constant/polyMesh/boundary @@ -20,7 +20,7 @@ FoamFile ( inlet { - type directMappedPatch; + type directMapped; nFaces 30; startFace 27238; sampleMode nearestCell; diff --git a/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/system/changeDictionaryDict b/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/system/changeDictionaryDict index 9490b8433231b6579abeff8ee805e39857951c3b..5a186d193ec03ee6ba5eda0a643e7ec85c3e4163 100644 --- a/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/system/changeDictionaryDict +++ b/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/system/changeDictionaryDict @@ -23,6 +23,7 @@ dictionaryReplacement { type directMappedPatch; offset ( 0.0495 0 0 ); + sampleRegion region0; sampleMode nearestCell; samplePatch none; } diff --git a/tutorials/mesh/snappyHexMesh/iglooWithFridges/constant/triSurface/fridgeA.eMesh b/tutorials/mesh/snappyHexMesh/iglooWithFridges/constant/triSurface/fridgeA.eMesh new file mode 100644 index 0000000000000000000000000000000000000000..ff7aab4b8f14cabed8622a7ddcb1e4ec2b635b2f --- /dev/null +++ b/tutorials/mesh/snappyHexMesh/iglooWithFridges/constant/triSurface/fridgeA.eMesh @@ -0,0 +1,58 @@ +/*---------------------------------------------------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.3.1 | +| \\ / A nd | Web: http://www.openfoam.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ + +FoamFile +{ + version 2.0; + format ascii; + + root ".."; + case "cavity"; + instance ""constant""; + local "polyMesh"; + + class featureEdgeMesh; + object points; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Points +( +(1.99 1.99 0.01) //0 +(3.01 1.99 0.01) //1 +(3.01 3.01 0.01) //2 +(1.99 3.01 0.01) //3 + +(1.99 1.99 2.01) //4 +(3.01 1.99 2.01) //5 +(3.01 3.01 2.01) //6 +(1.99 3.01 2.01) //7 +) + +// Edges +( +(0 1) +(1 2) +(2 3) +(3 0) + +(4 5) +(5 6) +(6 7) +(7 4) + +(0 4) +(1 5) +(2 6) +(3 7) +) + + + +// ************************************************************************* // diff --git a/tutorials/mesh/snappyHexMesh/iglooWithFridges/system/snappyHexMeshDict b/tutorials/mesh/snappyHexMesh/iglooWithFridges/system/snappyHexMeshDict index 19ef2afec1d08e169d49fd7907cc518d0eccd94b..be30045c6d4d77a2bf014349a0e4890ff5d963bd 100644 --- a/tutorials/mesh/snappyHexMesh/iglooWithFridges/system/snappyHexMeshDict +++ b/tutorials/mesh/snappyHexMesh/iglooWithFridges/system/snappyHexMeshDict @@ -143,10 +143,10 @@ castellatedMeshControls // This is a featureEdgeMesh, read from constant/triSurface for now. features ( -// { -// file "fridgeA.eMesh"; -// level 3; -// } + { + file "fridgeA.eMesh"; + level 3; + } ); @@ -308,6 +308,10 @@ addLayersControls // Create buffer region for new layer terminations nBufferCellsNoExtrude 0; + + + // Overall max number of layer addition iterations + nLayerIter 50; } diff --git a/tutorials/mesh/snappyHexMesh/motorBike/system/snappyHexMeshDict b/tutorials/mesh/snappyHexMesh/motorBike/system/snappyHexMeshDict index 3f0ff0417e6b92047878cb285aa71452c8fd3c74..0d84177d8b422d750ef38dbf1536c4ba8383c6dc 100644 --- a/tutorials/mesh/snappyHexMesh/motorBike/system/snappyHexMeshDict +++ b/tutorials/mesh/snappyHexMesh/motorBike/system/snappyHexMeshDict @@ -160,7 +160,7 @@ snapControls //- Relative distance for points to be attracted by surface feature point // or edge. True distance is this factor times local // maximum edge length. - tolerance 4; + tolerance 4.0; //- Number of mesh displacement relaxation iterations. nSolveIter 30; @@ -182,344 +182,14 @@ addLayersControls nSurfaceLayers 1; } - motorBike_frt-fairing:001%1 - { - nSurfaceLayers 1; - } - - motorBike_windshield:002%2 - { - nSurfaceLayers 1; - } - - motorBike_rr-wh-rim:005%5 - { - nSurfaceLayers 1; - } - - motorBike_rr-wh-rim:010%10 - { - nSurfaceLayers 1; - } - - motorBike_fr-wh-rim:011%11 - { - nSurfaceLayers 1; - } - - motorBike_fr-wh-brake-disk:012%12 - { - nSurfaceLayers 1; - } - - motorBike_frame:016-shadow%13 - { - nSurfaceLayers 1; - } - - motorBike_rear-susp:014%14 - { - nSurfaceLayers 1; - } - - motorBike_rear-susp:014-shadow%15 - { - nSurfaceLayers 1; - } - - motorBike_frame:016%16 - { - nSurfaceLayers 1; - } - - motorBike_rr-wh-rim:005-shadow%17 - { - nSurfaceLayers 1; - } - - motorBike_rr-wh-chain-hub:022%22 - { - nSurfaceLayers 1; - } - - motorBike_rearseat%24 - { - nSurfaceLayers 1; - } - - motorBike_frt-fairing%25 - { - nSurfaceLayers 1; - } - - motorBike_windshield%26 - { - nSurfaceLayers 1; - } - - motorBike_headlights%27 - { - nSurfaceLayers 1; - } - - motorBike_driversseat%28 - { - nSurfaceLayers 1; - } - - motorBike_rear-body%29 - { - nSurfaceLayers 1; - } - - motorBike_fuel-tank%30 - { - nSurfaceLayers 1; - } - - motorBike_exhaust%31 - { - nSurfaceLayers 1; - } - - motorBike_rr-wh-rim%32 - { - nSurfaceLayers 1; - } - - motorBike_fr-mud-guard%33 - { - nSurfaceLayers 1; - } - - motorBike_fr-wh-rim%34 - { - nSurfaceLayers 1; - } - - motorBike_fr-wh-brake-disk%35 - { - nSurfaceLayers 1; - } - - motorBike_fr-brake-caliper%36 - { - nSurfaceLayers 1; - } - - motorBike_fr-wh-tyre%37 - { - nSurfaceLayers 1; - } - - motorBike_hbars%38 - { - nSurfaceLayers 1; - } - - motorBike_fr-forks%39 - { - nSurfaceLayers 1; - } - - motorBike_chain%40 - { - nSurfaceLayers 1; - } - - motorBike_rr-wh-tyre%41 - { - nSurfaceLayers 1; - } - - motorBike_square-dial%42 - { - nSurfaceLayers 1; - } - - motorBike_round-dial%43 - { - nSurfaceLayers 1; - } - - motorBike_dial-holder%44 - { - nSurfaceLayers 1; - } - - motorBike_rear-susp%45 - { - nSurfaceLayers 1; - } - - motorBike_rear-brake-lights%46 - { - nSurfaceLayers 1; - } - - motorBike_rear-light-bracket%47 - { - nSurfaceLayers 1; - } - - motorBike_frame%48 - { - nSurfaceLayers 1; - } - - motorBike_rear-mud-guard%49 - { - nSurfaceLayers 1; - } - - motorBike_rear-susp-spring-damp%50 - { - nSurfaceLayers 1; - } - - motorBike_fairing-inner-plate%51 - { - nSurfaceLayers 1; - } - - motorBike_clutch-housing%52 - { - nSurfaceLayers 1; - } - - motorBike_radiator%53 - { - nSurfaceLayers 1; - } - - motorBike_water-pipe%54 - { - nSurfaceLayers 1; - } - - motorBike_water-pump%55 - { - nSurfaceLayers 1; - } - - motorBike_engine%56 - { - nSurfaceLayers 1; - } - - motorBike_rear-shock-link%57 - { - nSurfaceLayers 1; - } - - motorBike_rear-brake-fluid-pot-bracket%58 - { - nSurfaceLayers 1; - } - - motorBike_rear-brake-fluid-pot%59 - { - nSurfaceLayers 1; - } - - motorBike_footpeg%60 - { - nSurfaceLayers 1; - } - - motorBike_rr-wh-chain-hub%61 - { - nSurfaceLayers 1; - } - - motorBike_rear-brake-caliper%62 - { - nSurfaceLayers 1; - } - - motorBike_rider-helmet%65 - { - nSurfaceLayers 1; - } - - motorBike_rider-visor%66 - { - nSurfaceLayers 1; - } - - motorBike_rider-boots%67 - { - nSurfaceLayers 1; - } - - motorBike_rider-gloves%68 - { - nSurfaceLayers 1; - } - - motorBike_rider-body%69 - { - nSurfaceLayers 1; - } - - motorBike_frame:0%70 - { - nSurfaceLayers 1; - } - - motorBike_frt-fairing:001-shadow%74 - { - nSurfaceLayers 1; - } - - motorBike_windshield-shadow%75 - { - nSurfaceLayers 1; - } - - motorBike_fr-mud-guard-shadow%81 - { - nSurfaceLayers 1; - } - - motorBike_fr-wh-brake-disk-shadow%83 - { - nSurfaceLayers 1; - } - - motorBike_rear-mud-guard-shadow%84 - { - nSurfaceLayers 1; - } - - motorBike_rear-susp-spring-damp-shadow%85 - { - nSurfaceLayers 1; - } - - motorBike_radiator-shadow%86 - { - nSurfaceLayers 1; - } - - motorBike_rear-shock-link-shadow%87 - { - nSurfaceLayers 1; - } - - motorBike_rear-brake-fluid-pot-bracket-shadow%88 - { - nSurfaceLayers 1; - } - - motorBike_rr-wh-chain-hub-shadow%89 + "motorBike_.*" { nSurfaceLayers 1; } } // Expansion factor for layer mesh - expansionRatio 1; + expansionRatio 1.0; //- Wanted thickness of final added cell layer. If multiple layers // is the @@ -569,6 +239,10 @@ addLayersControls // Create buffer region for new layer terminations nBufferCellsNoExtrude 0; + + + // Overall max number of layer addition iterations + nLayerIter 50; } diff --git a/wmake/rules/General/bison b/wmake/rules/General/bison index 4c63c1f56577dad50619076214228f7797cef2fc..fe2e00a0977f6e4c06f1d1e8169e5a69e011a89d 100644 --- a/wmake/rules/General/bison +++ b/wmake/rules/General/bison @@ -1,8 +1,8 @@ .SUFFIXES: .y .Y -ytoo = bison -v $(YYPREFIX) -d $$SOURCE ; mv $$SOURCE_DIR/*.tab.c $*.c ; mv $$SOURCE_DIR/*.tab.h $*.h ; $(cc) $(cFLAGS) -c $*.c -o $@ +ytoo = bison -v -d -y $$SOURCE ; mv y.tab.c $*.c ; mv y.tab.h $*.h ; $(cc) $(cFLAGS) -c $*.c -o $@ -Ytoo = bison -v $(YYPREFIX) -d $$SOURCE ; mv $$SOURCE_DIR/*.tab.c $*.C ; mv $$SOURCE_DIR/*.tab.h $*.H ; $(CC) $(c++FLAGS) -c $*.C -o $@ +Ytoo = bison -v -d -y $$SOURCE ; mv y.tab.c $*.C ; mv y.tab.h $*.H ; $(CC) $(c++FLAGS) -c $*.C -o $@ .y.dep: $(MAKE_DEP) diff --git a/wmake/rules/General/flex b/wmake/rules/General/flex index c33195546a337046c2002d98114516a199963fe7..06defbb03d3d42e9f803ab3d8cce3184228258ce 100644 --- a/wmake/rules/General/flex +++ b/wmake/rules/General/flex @@ -1,6 +1,6 @@ .SUFFIXES: .l -ltoo = flex $$SOURCE ; mv lex.yy.c $*.C ; $(CC) $(c++FLAGS) -c $*.C -o $@ +ltoo = flex $$SOURCE ; mv lex.yy.c $*.c ; $(cc) $(cFLAGS) -c $*.c -o $@ .l.dep: $(MAKE_DEP) diff --git a/wmake/rules/General/standard b/wmake/rules/General/standard index 8e5e436d32aa2754691dbb1ad89418083daceb95..7752bef0846ab9f047864dfa74bb99d0870d09c2 100644 --- a/wmake/rules/General/standard +++ b/wmake/rules/General/standard @@ -5,6 +5,7 @@ include $(GENERAL_RULES)/sourceToDep include $(GENERAL_RULES)/java include $(GENERAL_RULES)/flex include $(GENERAL_RULES)/flex++ -include $(GENERAL_RULES)/byacc -include $(GENERAL_RULES)/btyacc++ +#include $(GENERAL_RULES)/byacc +#include $(GENERAL_RULES)/btyacc++ +include $(GENERAL_RULES)/bison include $(GENERAL_RULES)/moc