diff --git a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C index 7d0909ba5b52ab8c6630462f0673682b484a2f7d..8f9c0b9d7bb8cfa0dcb446fc317064c43c04e174 100644 --- a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C +++ b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C @@ -704,7 +704,7 @@ int main(int argc, char *argv[]) regionName, runTimeExtruded.constant(), runTimeExtruded, - IOobject::NO_READ, + IOobject::READ_IF_PRESENT, // Read fv* if present IOobject::AUTO_WRITE, false ), diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkMesh.C b/applications/utilities/mesh/manipulation/checkMesh/checkMesh.C index 836b2515e265d0a1d99bf7e0f3368b2bd6dad715..ec1a2314b1fc2b548d03fb8fd2f51af21ec5f7b2 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/checkMesh.C +++ b/applications/utilities/mesh/manipulation/checkMesh/checkMesh.C @@ -154,6 +154,7 @@ int main(int argc, char *argv[]) "cellShapes", "cellVolume", "cellVolumeRatio", + "cellAspectRatio", "minTetVolume", "minPyrVolume", "cellRegion", diff --git a/applications/utilities/mesh/manipulation/checkMesh/writeFields.C b/applications/utilities/mesh/manipulation/checkMesh/writeFields.C index dfc825a817b84f53c0efffe1a34dcbf3ec14f1cd..92e6e73f47585531638e3f7c435b8a8fddce4edc 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/writeFields.C +++ b/applications/utilities/mesh/manipulation/checkMesh/writeFields.C @@ -7,6 +7,7 @@ #include "tetPointRef.H" #include "regionSplit.H" #include "wallDist.H" +#include "cellAspectRatio.H" using namespace Foam; @@ -318,6 +319,32 @@ void Foam::writeFields aspectRatio.write(); } + if (selectedFields.found("cellAspectRatio")) + { + volScalarField aspectRatio + ( + IOobject + ( + "cellAspectRatio", + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::AUTO_WRITE, + false + ), + mesh, + dimensionedScalar(dimless, Zero), + zeroGradientFvPatchScalarField::typeName + ); + + aspectRatio.ref().field() = cellAspectRatio(mesh); + + aspectRatio.correctBoundaryConditions(); + Info<< " Writing approximate aspect ratio to " + << aspectRatio.name() << endl; + aspectRatio.write(); + } + // cell type // ~~~~~~~~~ diff --git a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C index 22060652a6d38f39aa2556e69424ad6513950494..aa84e3c65a868b5c86da9b4e05cdf34f6dfe4efe 100644 --- a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C +++ b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C @@ -680,7 +680,7 @@ autoPtr<mapPolyMesh> createRegionMesh regionName, mesh.time().timeName(), mesh.time(), - IOobject::NO_READ, + IOobject::READ_IF_PRESENT, // read fv* if present IOobject::AUTO_WRITE ), mesh diff --git a/applications/utilities/parallelProcessing/redistributePar/loadOrCreateMesh.C b/applications/utilities/parallelProcessing/redistributePar/loadOrCreateMesh.C index dbcec2a27a4327cdb4b7f815d7d856a26bfe85d1..5983fc8538c99ebcfcd2e338ad7ca8e229484c3e 100644 --- a/applications/utilities/parallelProcessing/redistributePar/loadOrCreateMesh.C +++ b/applications/utilities/parallelProcessing/redistributePar/loadOrCreateMesh.C @@ -36,6 +36,7 @@ License #include "pointSet.H" #include "faceSet.H" #include "cellSet.H" +#include "basicFvGeometryScheme.H" // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // @@ -254,6 +255,19 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh auto meshPtr = autoPtr<fvMesh>::New(io); fvMesh& mesh = *meshPtr; + // Make sure to use a non-parallel geometry calculation method + { + tmp<fvGeometryScheme> basicGeometry + ( + fvGeometryScheme::New + ( + mesh, + dictionary(), + basicFvGeometryScheme::typeName + ) + ); + mesh.geometry(basicGeometry); + } // Sync patches diff --git a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C index 1d2f5a5a11c76e96502fc748cd04efe9667b9336..32e8ea53e4454d78176e865fc4f69e7021470682 100644 --- a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C +++ b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C @@ -92,6 +92,7 @@ Usage #include "zeroGradientFvPatchFields.H" #include "topoSet.H" #include "regionProperties.H" +#include "basicFvGeometryScheme.H" #include "parFvFieldReconstructor.H" #include "parLagrangianRedistributor.H" @@ -152,6 +153,30 @@ scalar getMergeDistance } +void setBasicGeometry(fvMesh& mesh) +{ + // Set the fvGeometryScheme to basic since it does not require + // any parallel communication to construct the geometry. During + // redistributePar one might temporarily end up with processors + // with zero procBoundaries. Normally procBoundaries trigger geometry + // calculation (e.g. send over cellCentres) so on the processors without + // procBoundaries this will not happen. The call to the geometry calculation + // is not synchronised and this might lead to a hang for geometry schemes + // that do require synchronisation + + tmp<fvGeometryScheme> basicGeometry + ( + fvGeometryScheme::New + ( + mesh, + dictionary(), + basicFvGeometryScheme::typeName + ) + ); + mesh.geometry(basicGeometry); +} + + void printMeshData(const polyMesh& mesh) { // Collect all data on master @@ -2675,6 +2700,10 @@ int main(int argc, char *argv[]) ); fvMesh& mesh = meshPtr(); + // Use basic geometry calculation to avoid synchronisation + // problems. See comment in routine + setBasicGeometry(mesh); + // Global matching tolerance const scalar tolDim = getMergeDistance ( @@ -2736,6 +2765,8 @@ int main(int argc, char *argv[]) ), true // read on master only ); + setBasicGeometry(baseMeshPtr()); + Info<< "Reading local, decomposed mesh" << endl; autoPtr<fvMesh> meshPtr = loadOrCreateMesh diff --git a/src/OpenFOAM/db/IOobject/IOobject.C b/src/OpenFOAM/db/IOobject/IOobject.C index f3062e9be05706324d1261e4722003273c22bc28..e25418fef3b5cea2e6d2ecb3bc6ec650940cb2fb 100644 --- a/src/OpenFOAM/db/IOobject/IOobject.C +++ b/src/OpenFOAM/db/IOobject/IOobject.C @@ -438,6 +438,20 @@ Foam::IOobject::IOobject {} +Foam::IOobject::IOobject +( + const IOobject& io, + readOption ro, + writeOption wo +) +: + IOobject(io) +{ + rOpt_ = ro; + wOpt_ = wo; +} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // const Foam::objectRegistry& Foam::IOobject::db() const diff --git a/src/OpenFOAM/db/IOobject/IOobject.H b/src/OpenFOAM/db/IOobject/IOobject.H index d6cfba3ba7e5a745cb902bdc3399dfc0320f614b..a4ed73506691a2769ce116b7ed3f2ff228a585a5 100644 --- a/src/OpenFOAM/db/IOobject/IOobject.H +++ b/src/OpenFOAM/db/IOobject/IOobject.H @@ -340,6 +340,14 @@ public: const word& name ); + //- Copy construct, resetting io options + IOobject + ( + const IOobject& io, + readOption, + writeOption + ); + //- Clone autoPtr<IOobject> clone() const { diff --git a/src/OpenFOAM/include/createMesh.H b/src/OpenFOAM/include/createMesh.H index 8d53556a9c1f59bdb907d21e2462c8b523db1f11..a4452382f5c18cab4ee4342979cde7284eb6b710 100644 --- a/src/OpenFOAM/include/createMesh.H +++ b/src/OpenFOAM/include/createMesh.H @@ -63,9 +63,11 @@ else runTime.timeName(), runTime, Foam::IOobject::MUST_READ - ) + ), + false ) ); + meshPtr().init(true); // initialise all (lower levels and current) } Foam::fvMesh& mesh = meshPtr(); diff --git a/src/OpenFOAM/include/createNamedMesh.H b/src/OpenFOAM/include/createNamedMesh.H index 707effa653f3a9dd52567f8922eec9a41b219592..a66327b470f2ff0af5c4179a75b56c81bca0d37a 100644 --- a/src/OpenFOAM/include/createNamedMesh.H +++ b/src/OpenFOAM/include/createNamedMesh.H @@ -21,5 +21,7 @@ Foam::fvMesh mesh runTime.timeName(), runTime, Foam::IOobject::MUST_READ - ) + ), + false ); +mesh.init(true); // initialise all (lower levels and current) diff --git a/src/OpenFOAM/matrices/solution/solution.C b/src/OpenFOAM/matrices/solution/solution.C index b38406b32d40dc9efee511414034764c7cebee5e..498503ff4779297a202502ea1b2455d5b0a4f67e 100644 --- a/src/OpenFOAM/matrices/solution/solution.C +++ b/src/OpenFOAM/matrices/solution/solution.C @@ -155,6 +155,50 @@ Foam::solution::solution } +Foam::solution::solution +( + const objectRegistry& obr, + const fileName& dictName, + const dictionary& dict +) +: + IOdictionary + ( + IOobject + ( + dictName, + obr.time().system(), + obr, + ( + obr.readOpt() == IOobject::MUST_READ + || obr.readOpt() == IOobject::READ_IF_PRESENT + ? IOobject::MUST_READ_IF_MODIFIED + : obr.readOpt() + ), + IOobject::NO_WRITE + ), + dict + ), + cache_(dictionary::null), + caching_(false), + fieldRelaxDict_(dictionary::null), + eqnRelaxDict_(dictionary::null), + fieldRelaxDefault_(0), + eqnRelaxDefault_(0), + solvers_(dictionary::null) +{ + if + ( + readOpt() == IOobject::MUST_READ + || readOpt() == IOobject::MUST_READ_IF_MODIFIED + || (readOpt() == IOobject::READ_IF_PRESENT && headerOk()) + ) + { + read(solutionDict()); + } +} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // Foam::label Foam::solution::upgradeSolverDict diff --git a/src/OpenFOAM/matrices/solution/solution.H b/src/OpenFOAM/matrices/solution/solution.H index 88da0ece221ff4f482ec619760c05790435d31a9..793cd3520eecad526b56fc770394b1ee10a34a5e 100644 --- a/src/OpenFOAM/matrices/solution/solution.H +++ b/src/OpenFOAM/matrices/solution/solution.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -101,13 +102,22 @@ public: // Constructors - //- Construct for given objectRegistry and dictionary + //- Construct for given objectRegistry and dictionary name solution ( const objectRegistry& obr, const fileName& dictName ); + //- Construct for given objectRegistry, dictionary name and (optional) + // content (gets used in case of NO_READ or dictionary cannot be read) + solution + ( + const objectRegistry& obr, + const fileName& dictName, + const dictionary& dict + ); + // Member Functions diff --git a/src/OpenFOAM/meshes/data/data.C b/src/OpenFOAM/meshes/data/data.C index 95712bb7d0854030befcea120c6b6b15636d079b..15e419193fb30629e65203aad28c5496c7d3f7c1 100644 --- a/src/OpenFOAM/meshes/data/data.C +++ b/src/OpenFOAM/meshes/data/data.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -54,6 +55,24 @@ Foam::data::data(const objectRegistry& obr) } +Foam::data::data(const objectRegistry& obr, const dictionary& dict) +: + IOdictionary + ( + IOobject + ( + "data", + obr.time().system(), + obr, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + dict + ), + prevTimeIndex_(0) +{} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // const Foam::dictionary& Foam::data::solverPerformanceDict() const diff --git a/src/OpenFOAM/meshes/data/data.H b/src/OpenFOAM/meshes/data/data.H index 7c5c95951f567a59747f7873e356d63d9c60ff9c..91da9a93d4401f22c55519cd0282a7085e49fd69 100644 --- a/src/OpenFOAM/meshes/data/data.H +++ b/src/OpenFOAM/meshes/data/data.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -82,6 +83,9 @@ public: //- Construct for objectRegistry data(const objectRegistry& obr); + //- Construct for objectRegistry and initial contents + data(const objectRegistry& obr, const dictionary& dict); + // Member Functions diff --git a/src/OpenFOAM/meshes/polyMesh/polyMesh.C b/src/OpenFOAM/meshes/polyMesh/polyMesh.C index 81fcd21f7f18b0680a2cf3a5f15317f7437d4bbe..232cb3de794dddf0d266638435296db80091f8ca 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyMesh.C +++ b/src/OpenFOAM/meshes/polyMesh/polyMesh.C @@ -70,20 +70,29 @@ void Foam::polyMesh::calcDirections() const forAll(boundaryMesh(), patchi) { - if (boundaryMesh()[patchi].size()) + const polyPatch& pp = boundaryMesh()[patchi]; + if (isA<emptyPolyPatch>(pp)) { - if (isA<emptyPolyPatch>(boundaryMesh()[patchi])) + // Force calculation of geometric properties, independent of + // size. This avoids parallel synchronisation problems. + const vectorField::subField fa(pp.faceAreas()); + + if (pp.size()) { nEmptyPatches++; - emptyDirVec += sum(cmptMag(boundaryMesh()[patchi].faceAreas())); + emptyDirVec += sum(cmptMag(fa)); } - else if (isA<wedgePolyPatch>(boundaryMesh()[patchi])) - { - const wedgePolyPatch& wpp = refCast<const wedgePolyPatch> - ( - boundaryMesh()[patchi] - ); + } + else if (isA<wedgePolyPatch>(pp)) + { + const wedgePolyPatch& wpp = refCast<const wedgePolyPatch>(pp); + + // Force calculation of geometric properties, independent of + // size. This avoids parallel synchronisation problems. + (void)wpp.faceNormals(); + if (pp.size()) + { nWedgePatches++; wedgeDirVec += cmptMag(wpp.centreNormal()); } @@ -161,7 +170,7 @@ Foam::autoPtr<Foam::labelIOList> Foam::polyMesh::readTetBasePtIs() const // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::polyMesh::polyMesh(const IOobject& io) +Foam::polyMesh::polyMesh(const IOobject& io, const bool doInit) : objectRegistry(io), primitiveMesh(), @@ -328,12 +337,6 @@ Foam::polyMesh::polyMesh(const IOobject& io) neighbour_.write(); } - // Calculate topology for the patches (processor-processor comms etc.) - boundary_.updateMesh(); - - // Calculate the geometry for the patches (transformation tensors etc.) - boundary_.calcGeometry(); - // Warn if global empty mesh if (returnReduce(boundary_.empty(), orOp<bool>())) { @@ -352,8 +355,30 @@ Foam::polyMesh::polyMesh(const IOobject& io) } } + if (doInit) + { + polyMesh::init(false); // do not init lower levels + } +} + + +bool Foam::polyMesh::init(const bool doInit) +{ + if (doInit) + { + primitiveMesh::init(doInit); + } + + // Calculate topology for the patches (processor-processor comms etc.) + boundary_.updateMesh(); + + // Calculate the geometry for the patches (transformation tensors etc.) + boundary_.calcGeometry(); + // Initialise demand-driven data calcDirections(); + + return false; } @@ -377,7 +402,7 @@ Foam::polyMesh::polyMesh instance(), meshSubDir, *this, - io.readOpt(), + IOobject::NO_READ, //io.readOpt(), io.writeOpt() ), std::move(points) @@ -390,7 +415,7 @@ Foam::polyMesh::polyMesh instance(), meshSubDir, *this, - io.readOpt(), + IOobject::NO_READ, //io.readOpt(), io.writeOpt() ), std::move(faces) @@ -403,7 +428,7 @@ Foam::polyMesh::polyMesh instance(), meshSubDir, *this, - io.readOpt(), + IOobject::NO_READ, //io.readOpt(), io.writeOpt() ), std::move(owner) @@ -416,7 +441,7 @@ Foam::polyMesh::polyMesh instance(), meshSubDir, *this, - io.readOpt(), + IOobject::NO_READ, //io.readOpt(), io.writeOpt() ), std::move(neighbour) @@ -430,7 +455,7 @@ Foam::polyMesh::polyMesh instance(), meshSubDir, *this, - io.readOpt(), + IOobject::NO_READ, //io.readOpt(), io.writeOpt() ), *this, @@ -440,7 +465,7 @@ Foam::polyMesh::polyMesh comm_(UPstream::worldComm), geometricD_(Zero), solutionD_(Zero), - tetBasePtIsPtr_(readTetBasePtIs()), + tetBasePtIsPtr_(nullptr), cellTreePtr_(nullptr), pointZones_ ( @@ -450,7 +475,7 @@ Foam::polyMesh::polyMesh instance(), meshSubDir, *this, - io.readOpt(), + IOobject::NO_READ, //io.readOpt(), IOobject::NO_WRITE ), *this, @@ -464,7 +489,7 @@ Foam::polyMesh::polyMesh instance(), meshSubDir, *this, - io.readOpt(), + IOobject::NO_READ, //io.readOpt(), IOobject::NO_WRITE ), *this, @@ -478,7 +503,7 @@ Foam::polyMesh::polyMesh instance(), meshSubDir, *this, - io.readOpt(), + IOobject::NO_READ, //io.readOpt(), IOobject::NO_WRITE ), *this, @@ -591,7 +616,7 @@ Foam::polyMesh::polyMesh comm_(UPstream::worldComm), geometricD_(Zero), solutionD_(Zero), - tetBasePtIsPtr_(readTetBasePtIs()), + tetBasePtIsPtr_(nullptr), cellTreePtr_(nullptr), pointZones_ ( diff --git a/src/OpenFOAM/meshes/polyMesh/polyMesh.H b/src/OpenFOAM/meshes/polyMesh/polyMesh.H index 5441e564cadeb7b8018c9dbc1a264c4ad20e63a0..6851fb68ebb8ff99e2d99e2d70e61f06469e6b48 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyMesh.H +++ b/src/OpenFOAM/meshes/polyMesh/polyMesh.H @@ -319,11 +319,11 @@ public: // Constructors //- Read construct from IOobject - explicit polyMesh(const IOobject& io); + polyMesh(const IOobject& io, const bool doInit = true); //- Construct from IOobject or as zero-sized mesh // Boundary is added using addPatches() member function - polyMesh(const IOobject& io, const zero, bool syncPar=true); + polyMesh(const IOobject& io, const zero, const bool syncPar=true); //- Construct from IOobject or from components. // Boundary is added using addPatches() member function @@ -593,6 +593,9 @@ public: const List<cellZone*>& cz ); + //- Initialise all non-demand-driven data + virtual bool init(const bool doInit); + //- Update the mesh based on the mesh files saved in // time directories virtual readUpdateState readUpdate(); diff --git a/src/OpenFOAM/meshes/polyMesh/polyMeshCheck/polyMeshCheck.C b/src/OpenFOAM/meshes/polyMesh/polyMeshCheck/polyMeshCheck.C index 34d9a2f5173e6d1b2b43936e09f8931bc420fc3d..04fc7a63b7875c4e0aa407480d7f34e33cde0d3a 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyMeshCheck/polyMeshCheck.C +++ b/src/OpenFOAM/meshes/polyMesh/polyMeshCheck/polyMeshCheck.C @@ -753,13 +753,26 @@ bool Foam::polyMesh::checkMeshMotion vectorField fCtrs(nFaces()); vectorField fAreas(nFaces()); - makeFaceCentresAndAreas(newPoints, fCtrs, fAreas); + primitiveMeshTools::makeFaceCentresAndAreas + ( + *this, + newPoints, + fCtrs, + fAreas + ); // Check cell volumes and calculate new cell centres vectorField cellCtrs(nCells()); scalarField cellVols(nCells()); - makeCellCentresAndVols(fCtrs, fAreas, cellCtrs, cellVols); + primitiveMeshTools::makeCellCentresAndVols + ( + *this, + fCtrs, + fAreas, + cellCtrs, + cellVols + ); // Check cell volumes bool error = checkCellVolumes diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.C index 027d3d6825e4b5a6243950a5d41ee41b23914bfc..2f3cb10efc22cf13d1759f68cfc2f9a1d6dab865 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.C +++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.C @@ -281,6 +281,44 @@ void Foam::primitiveMesh::reset } +void Foam::primitiveMesh::resetGeometry +( + pointField&& faceCentres, + pointField&& faceAreas, + pointField&& cellCentres, + scalarField&& cellVolumes +) +{ + if + ( + faceCentres.size() != nFaces_ + || faceAreas.size() != nFaces_ + || cellCentres.size() != nCells_ + || cellVolumes.size() != nCells_ + ) + { + FatalErrorInFunction + << "Wrong sizes of passed in face/cell data" + << abort(FatalError); + } + + // Remove old geometry + clearGeom(); + + faceCentresPtr_ = new pointField(std::move(faceCentres)); + faceAreasPtr_ = new pointField(std::move(faceAreas)); + cellCentresPtr_ = new pointField(std::move(cellCentres)); + cellVolumesPtr_ = new scalarField(std::move(cellVolumes)); + + if (debug) + { + Pout<< "primitiveMesh::resetGeometry : geometry reset for" + << " nFaces:" << faceCentresPtr_->size() + << " nCells:" << cellCentresPtr_->size() << endl; + } +} + + Foam::tmp<Foam::scalarField> Foam::primitiveMesh::movePoints ( const pointField& newPoints, @@ -324,4 +362,26 @@ const Foam::cellShapeList& Foam::primitiveMesh::cellShapes() const } + +void Foam::primitiveMesh::updateGeom() +{ + if (!faceCentresPtr_) + { + calcFaceCentresAndAreas(); + } + if (!faceAreasPtr_) + { + calcFaceCentresAndAreas(); + } + if (!cellCentresPtr_) + { + calcCellCentresAndVols(); + } + if (!cellVolumesPtr_) + { + calcCellCentresAndVols(); + } +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.H b/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.H index d7cc8bf32366037bfb680d59422a5e2978c0b80c..3ef4a22261aea55f2c3f7a5f08953802deb7bf62 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.H +++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.H @@ -255,22 +255,9 @@ protected: //- Calculate face centres and areas void calcFaceCentresAndAreas() const; - void makeFaceCentresAndAreas - ( - const pointField& p, - vectorField& fCtrs, - vectorField& fAreas - ) const; //- Calculate cell centres and volumes void calcCellCentresAndVols() const; - void makeCellCentresAndVols - ( - const vectorField& fCtrs, - const vectorField& fAreas, - vectorField& cellCtrs, - scalarField& cellVols - ) const; //- Calculate edge vectors void calcEdgeVectors() const; @@ -476,6 +463,21 @@ public: cellList& cells ); + //- Reset the local geometry + void resetGeometry + ( + pointField&& faceCentres, + pointField&& faceAreas, + pointField&& cellCentres, + scalarField&& cellVolumes + ); + + //- Initialise all non-demand-driven data + virtual bool init(const bool doInit) + { + return false; + } + // Access @@ -891,6 +893,8 @@ public: const labelList& cellEdges(const label celli) const; + //- Update all geometric data + virtual void updateGeom(); //- Clear geometry void clearGeom(); diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCellCentresAndVols.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCellCentresAndVols.C index 5f0ff8bcef5c846ead5f82ac8307259145c36ca4..f8a1e323408bbfa11bdddf749bd4f16eaca72e21 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCellCentresAndVols.C +++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCellCentresAndVols.C @@ -30,7 +30,7 @@ Description \*---------------------------------------------------------------------------*/ #include "primitiveMesh.H" -#include "PrecisionAdaptor.H" +#include "primitiveMeshTools.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -61,7 +61,14 @@ void Foam::primitiveMesh::calcCellCentresAndVols() const scalarField& cellVols = *cellVolumesPtr_; // Make centres and volumes - makeCellCentresAndVols(faceCentres(), faceAreas(), cellCtrs, cellVols); + primitiveMeshTools::makeCellCentresAndVols + ( + *this, + faceCentres(), + faceAreas(), + cellCtrs, + cellVols + ); if (debug) { @@ -72,111 +79,14 @@ void Foam::primitiveMesh::calcCellCentresAndVols() const } -void Foam::primitiveMesh::makeCellCentresAndVols -( - const vectorField& fCtrs, - const vectorField& fAreas, - vectorField& cellCtrs_s, - scalarField& cellVols_s -) const -{ - typedef Vector<solveScalar> solveVector; - - PrecisionAdaptor<solveVector, vector> tcellCtrs(cellCtrs_s, false); - Field<solveVector>& cellCtrs = tcellCtrs.ref(); - PrecisionAdaptor<solveScalar, scalar> tcellVols(cellVols_s, false); - Field<solveScalar>& cellVols = tcellVols.ref(); - - cellCtrs = Zero; - cellVols = 0.0; - - const labelList& own = faceOwner(); - const labelList& nei = faceNeighbour(); - - // first estimate the approximate cell centre as the average of - // face centres - - Field<solveVector> cEst(nCells(), Zero); - labelField nCellFaces(nCells(), Zero); - - forAll(own, facei) - { - cEst[own[facei]] += solveVector(fCtrs[facei]); - ++nCellFaces[own[facei]]; - } - - forAll(nei, facei) - { - cEst[nei[facei]] += solveVector(fCtrs[facei]); - ++nCellFaces[nei[facei]]; - } - - forAll(cEst, celli) - { - cEst[celli] /= nCellFaces[celli]; - } - - forAll(own, facei) - { - const solveVector fc(fCtrs[facei]); - const solveVector fA(fAreas[facei]); - - // Calculate 3*face-pyramid volume - solveScalar pyr3Vol = - fA & (fc - cEst[own[facei]]); - - // Calculate face-pyramid centre - solveVector pc = (3.0/4.0)*fc + (1.0/4.0)*cEst[own[facei]]; - - // Accumulate volume-weighted face-pyramid centre - cellCtrs[own[facei]] += pyr3Vol*pc; - - // Accumulate face-pyramid volume - cellVols[own[facei]] += pyr3Vol; - } - - forAll(nei, facei) - { - const solveVector fc(fCtrs[facei]); - const solveVector fA(fAreas[facei]); - - // Calculate 3*face-pyramid volume - solveScalar pyr3Vol = - fA & (cEst[nei[facei]] - fc); - - // Calculate face-pyramid centre - solveVector pc = (3.0/4.0)*fc + (1.0/4.0)*cEst[nei[facei]]; - - // Accumulate volume-weighted face-pyramid centre - cellCtrs[nei[facei]] += pyr3Vol*pc; - - // Accumulate face-pyramid volume - cellVols[nei[facei]] += pyr3Vol; - } - - forAll(cellCtrs, celli) - { - if (mag(cellVols[celli]) > VSMALL) - { - cellCtrs[celli] /= cellVols[celli]; - } - else - { - cellCtrs[celli] = cEst[celli]; - } - } - - cellVols *= (1.0/3.0); -} - - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // const Foam::vectorField& Foam::primitiveMesh::cellCentres() const { if (!cellCentresPtr_) { - calcCellCentresAndVols(); + //calcCellCentresAndVols(); + const_cast<primitiveMesh&>(*this).updateGeom(); } return *cellCentresPtr_; @@ -187,7 +97,8 @@ const Foam::scalarField& Foam::primitiveMesh::cellVolumes() const { if (!cellVolumesPtr_) { - calcCellCentresAndVols(); + //calcCellCentresAndVols(); + const_cast<primitiveMesh&>(*this).updateGeom(); } return *cellVolumesPtr_; diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.C index 98a8b032b7332216ce0bfd939ba8b8fa4bcf9157..46b62d3466bfcce3a29d30b5f89baedd646ecbcd 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.C +++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.C @@ -27,11 +27,182 @@ License \*---------------------------------------------------------------------------*/ #include "primitiveMeshTools.H" +#include "primitiveMesh.H" #include "syncTools.H" #include "pyramidPointFaceRef.H" +#include "PrecisionAdaptor.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // +void Foam::primitiveMeshTools::makeFaceCentresAndAreas +( + const primitiveMesh& mesh, + const pointField& p, + vectorField& fCtrs, + vectorField& fAreas +) +{ + const faceList& fs = mesh.faces(); + + forAll(fs, facei) + { + const labelList& f = fs[facei]; + const label nPoints = f.size(); + + // If the face is a triangle, do a direct calculation for efficiency + // and to avoid round-off error-related problems + if (nPoints == 3) + { + fCtrs[facei] = (1.0/3.0)*(p[f[0]] + p[f[1]] + p[f[2]]); + fAreas[facei] = 0.5*((p[f[1]] - p[f[0]])^(p[f[2]] - p[f[0]])); + } + else + { + typedef Vector<solveScalar> solveVector; + + solveVector sumN = Zero; + solveScalar sumA = 0.0; + solveVector sumAc = Zero; + + solveVector fCentre = p[f[0]]; + for (label pi = 1; pi < nPoints; pi++) + { + fCentre += solveVector(p[f[pi]]); + } + + fCentre /= nPoints; + + for (label pi = 0; pi < nPoints; pi++) + { + const label nextPi(pi == nPoints-1 ? 0 : pi+1); + const solveVector nextPoint(p[f[nextPi]]); + const solveVector thisPoint(p[f[pi]]); + + solveVector c = thisPoint + nextPoint + fCentre; + solveVector n = (nextPoint - thisPoint)^(fCentre - thisPoint); + solveScalar a = mag(n); + sumN += n; + sumA += a; + sumAc += a*c; + } + + // This is to deal with zero-area faces. Mark very small faces + // to be detected in e.g., processorPolyPatch. + if (sumA < ROOTVSMALL) + { + fCtrs[facei] = fCentre; + fAreas[facei] = Zero; + } + else + { + fCtrs[facei] = (1.0/3.0)*sumAc/sumA; + fAreas[facei] = 0.5*sumN; + } + } + } +} + + +void Foam::primitiveMeshTools::makeCellCentresAndVols +( + const primitiveMesh& mesh, + const vectorField& fCtrs, + const vectorField& fAreas, + vectorField& cellCtrs_s, + scalarField& cellVols_s +) +{ + typedef Vector<solveScalar> solveVector; + + PrecisionAdaptor<solveVector, vector> tcellCtrs(cellCtrs_s); + Field<solveVector>& cellCtrs = tcellCtrs.ref(); + PrecisionAdaptor<solveScalar, scalar> tcellVols(cellVols_s); + Field<solveScalar>& cellVols = tcellVols.ref(); + + // Clear the fields for accumulation + cellCtrs = Zero; + cellVols = 0.0; + + const labelList& own = mesh.faceOwner(); + const labelList& nei = mesh.faceNeighbour(); + + // first estimate the approximate cell centre as the average of + // face centres + + Field<solveVector> cEst(mesh.nCells(), Zero); + labelField nCellFaces(mesh.nCells(), Zero); + + forAll(own, facei) + { + cEst[own[facei]] += solveVector(fCtrs[facei]); + ++nCellFaces[own[facei]]; + } + + forAll(nei, facei) + { + cEst[nei[facei]] += solveVector(fCtrs[facei]); + ++nCellFaces[nei[facei]]; + } + + forAll(cEst, celli) + { + cEst[celli] /= nCellFaces[celli]; + } + + forAll(own, facei) + { + const solveVector fc(fCtrs[facei]); + const solveVector fA(fAreas[facei]); + + // Calculate 3*face-pyramid volume + solveScalar pyr3Vol = + fA & (fc - cEst[own[facei]]); + + // Calculate face-pyramid centre + solveVector pc = (3.0/4.0)*fc + (1.0/4.0)*cEst[own[facei]]; + + // Accumulate volume-weighted face-pyramid centre + cellCtrs[own[facei]] += pyr3Vol*pc; + + // Accumulate face-pyramid volume + cellVols[own[facei]] += pyr3Vol; + } + + forAll(nei, facei) + { + const solveVector fc(fCtrs[facei]); + const solveVector fA(fAreas[facei]); + + // Calculate 3*face-pyramid volume + solveScalar pyr3Vol = + fA & (cEst[nei[facei]] - fc); + + // Calculate face-pyramid centre + solveVector pc = (3.0/4.0)*fc + (1.0/4.0)*cEst[nei[facei]]; + + // Accumulate volume-weighted face-pyramid centre + cellCtrs[nei[facei]] += pyr3Vol*pc; + + // Accumulate face-pyramid volume + cellVols[nei[facei]] += pyr3Vol; + } + + forAll(cellCtrs, celli) + { + if (mag(cellVols[celli]) > VSMALL) + { + cellCtrs[celli] /= cellVols[celli]; + } + else + { + cellCtrs[celli] = cEst[celli]; + } + } + + cellVols *= (1.0/3.0); +} + + Foam::scalar Foam::primitiveMeshTools::faceSkewness ( const primitiveMesh& mesh, diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.H b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.H index 9803acac367998e5d4dac590f335bd2cd8a14b6a..3bfef13593f5076de14e1b86596ba6c58ebbb1cb 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.H +++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.H @@ -38,22 +38,45 @@ SourceFiles #ifndef primitiveMeshTools_H #define primitiveMeshTools_H -#include "primitiveMesh.H" #include "bitSet.H" +#include "primitiveFields.H" +#include "pointField.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { +// Forward declarations +class primitiveMesh; + /*---------------------------------------------------------------------------*\ - Namespace primitiveMeshTools Declaration + Namespace primitiveMeshTools Declaration \*---------------------------------------------------------------------------*/ class primitiveMeshTools { public: + //- Calculate face centres and areas + static void makeFaceCentresAndAreas + ( + const primitiveMesh& mesh, + const pointField& p, + vectorField& fCtrs, + vectorField& fAreas + ); + + //- Calculate cell centres and volumes from face properties + static void makeCellCentresAndVols + ( + const primitiveMesh& mesh, + const vectorField& fCtrs, + const vectorField& fAreas, + vectorField& cellCtrs, + scalarField& cellVols + ); + //- Generate non-orthogonality field (internal faces only) static tmp<scalarField> faceOrthogonality ( diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshFaceCentresAndAreas.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshFaceCentresAndAreas.C index defcfae7731c144025a1d450bb1abef0697dae37..dda3e3634c414e618c5a27b3cfc48e22885c2ed4 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshFaceCentresAndAreas.C +++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshFaceCentresAndAreas.C @@ -33,6 +33,7 @@ Description \*---------------------------------------------------------------------------*/ #include "primitiveMesh.H" +#include "primitiveMeshTools.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -60,7 +61,7 @@ void Foam::primitiveMesh::calcFaceCentresAndAreas() const faceAreasPtr_ = new vectorField(nFaces()); vectorField& fAreas = *faceAreasPtr_; - makeFaceCentresAndAreas(points(), fCtrs, fAreas); + primitiveMeshTools::makeFaceCentresAndAreas(*this, points(), fCtrs, fAreas); if (debug) { @@ -71,81 +72,14 @@ void Foam::primitiveMesh::calcFaceCentresAndAreas() const } -void Foam::primitiveMesh::makeFaceCentresAndAreas -( - const pointField& p, - vectorField& fCtrs, - vectorField& fAreas -) const -{ - const faceList& fs = faces(); - - forAll(fs, facei) - { - const labelList& f = fs[facei]; - const label nPoints = f.size(); - - // If the face is a triangle, do a direct calculation for efficiency - // and to avoid round-off error-related problems - if (nPoints == 3) - { - fCtrs[facei] = (1.0/3.0)*(p[f[0]] + p[f[1]] + p[f[2]]); - fAreas[facei] = 0.5*((p[f[1]] - p[f[0]])^(p[f[2]] - p[f[0]])); - } - else - { - typedef Vector<solveScalar> solveVector; - - solveVector sumN = Zero; - solveScalar sumA = 0.0; - solveVector sumAc = Zero; - - solveVector fCentre = p[f[0]]; - for (label pi = 1; pi < nPoints; pi++) - { - fCentre += solveVector(p[f[pi]]); - } - - fCentre /= nPoints; - - for (label pi = 0; pi < nPoints; pi++) - { - const label nextPi(pi == nPoints-1 ? 0 : pi+1); - const solveVector nextPoint(p[f[nextPi]]); - const solveVector thisPoint(p[f[pi]]); - - solveVector c = thisPoint + nextPoint + fCentre; - solveVector n = (nextPoint - thisPoint)^(fCentre - thisPoint); - solveScalar a = mag(n); - sumN += n; - sumA += a; - sumAc += a*c; - } - - // This is to deal with zero-area faces. Mark very small faces - // to be detected in e.g., processorPolyPatch. - if (sumA < ROOTVSMALL) - { - fCtrs[facei] = fCentre; - fAreas[facei] = Zero; - } - else - { - fCtrs[facei] = (1.0/3.0)*sumAc/sumA; - fAreas[facei] = 0.5*sumN; - } - } - } -} - - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // const Foam::vectorField& Foam::primitiveMesh::faceCentres() const { if (!faceCentresPtr_) { - calcFaceCentresAndAreas(); + //calcFaceCentresAndAreas(); + const_cast<primitiveMesh&>(*this).updateGeom(); } return *faceCentresPtr_; @@ -156,7 +90,8 @@ const Foam::vectorField& Foam::primitiveMesh::faceAreas() const { if (!faceAreasPtr_) { - calcFaceCentresAndAreas(); + //calcFaceCentresAndAreas(); + const_cast<primitiveMesh&>(*this).updateGeom(); } return *faceAreasPtr_; diff --git a/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMesh.H b/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMesh.H index 8a0a7e3563600a7c0d8c36d426af563708efa4cd..c59bdbd23ca20f6d22563786700c262e95320052 100644 --- a/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMesh.H +++ b/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMesh.H @@ -104,7 +104,7 @@ public: // Constructors //- Construct from an IOobject - explicit dynamicFvMesh(const IOobject& io); + explicit dynamicFvMesh(const IOobject& io); //, const bool doInit=true); //- Construct from components without boundary. // Boundary is added using addFvPatches() member function @@ -139,7 +139,11 @@ public: //- Select, construct and return the dynamicFvMesh // If the constant/dynamicMeshDict does not exist // a staticFvMesh is returned - static autoPtr<dynamicFvMesh> New(const IOobject& io); + static autoPtr<dynamicFvMesh> New + ( + const IOobject& io //, + //const bool doInit=true + ); //- Select, construct and return the dynamicFvMesh @@ -148,7 +152,8 @@ public: static autoPtr<dynamicFvMesh> New ( const argList& args, - const Time& runTime + const Time& runTime //, + //const bool doInit=true ); @@ -158,6 +163,9 @@ public: // Member Functions + //- Initialise all non-demand-driven data + //virtual bool init(const bool doInit); + //- Is mesh dynamic virtual bool dynamic() const { diff --git a/src/dynamicFvMesh/include/createDynamicFvMesh.H b/src/dynamicFvMesh/include/createDynamicFvMesh.H index 543bcbfe34fd146bbe985797858952d14be460b9..d447d12dd6d4ed8afb0e6e71ec2ac76ab285b90b 100644 --- a/src/dynamicFvMesh/include/createDynamicFvMesh.H +++ b/src/dynamicFvMesh/include/createDynamicFvMesh.H @@ -1,6 +1,9 @@ Info<< "Create mesh for time = " << runTime.timeName() << nl << endl; -autoPtr<dynamicFvMesh> meshPtr(dynamicFvMesh::New(args, runTime)); +autoPtr<dynamicFvMesh> meshPtr(dynamicFvMesh::New(args, runTime));//, false)); dynamicFvMesh& mesh = meshPtr(); + +// initialise all (lower levels and current) +mesh.init(true); diff --git a/src/dynamicMesh/fvMeshSubset/fvMeshSubset.C b/src/dynamicMesh/fvMeshSubset/fvMeshSubset.C index 98a5fac060874ae99bd58a821c1a36f0d513c550..416442f4fb34062c74cb0e536dfef3c7d698b8ef 100644 --- a/src/dynamicMesh/fvMeshSubset/fvMeshSubset.C +++ b/src/dynamicMesh/fvMeshSubset/fvMeshSubset.C @@ -268,7 +268,7 @@ void Foam::fvMeshSubset::removeCellsImpl baseMesh().name(), baseMesh().time().timeName(), baseMesh().time(), - IOobject::NO_READ, + IOobject::READ_IF_PRESENT, // read fv* if present IOobject::NO_WRITE ), baseMesh(), @@ -980,9 +980,10 @@ void Foam::fvMeshSubset::setCellSubset baseMesh().name(), baseMesh().time().timeName(), baseMesh().time(), - IOobject::NO_READ, + IOobject::NO_READ, // do not read any dictionaries IOobject::NO_WRITE ), + baseMesh(), // get dictionaries from base mesh std::move(newPoints), std::move(newFaces), std::move(newCells), diff --git a/src/dynamicMesh/polyMeshFilter/polyMeshFilter.C b/src/dynamicMesh/polyMeshFilter/polyMeshFilter.C index d563d0e5e97f283bc09c3d526dd5a3f20be1eaba..3f2e76dc4f6c2dc6ddfabc7c7a17e9a0881af14e 100644 --- a/src/dynamicMesh/polyMeshFilter/polyMeshFilter.C +++ b/src/dynamicMesh/polyMeshFilter/polyMeshFilter.C @@ -79,7 +79,7 @@ Foam::autoPtr<Foam::fvMesh> Foam::polyMeshFilter::copyMesh(const fvMesh& mesh) mesh.name(), mesh.polyMesh::instance(), mesh.time(), - IOobject::NO_READ, + IOobject::READ_IF_PRESENT, // read fv* if present IOobject::NO_WRITE, false ), diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files index 1f175aafaa45dc6c6044486efb2c137a8a87a6b2..e2f15cf369cbbc36b3d41e4126e47b138ba8b663 100644 --- a/src/finiteVolume/Make/files +++ b/src/finiteVolume/Make/files @@ -1,6 +1,17 @@ fvMesh/fvMeshGeometry.C fvMesh/fvMesh.C +fvGeometryScheme = fvMesh/fvGeometryScheme +$(fvGeometryScheme)/fvGeometryScheme/fvGeometryScheme.C +$(fvGeometryScheme)/basic/basicFvGeometryScheme.C +$(fvGeometryScheme)/highAspectRatio/highAspectRatioFvGeometryScheme.C +$(fvGeometryScheme)/highAspectRatio/cellAspectRatio.C +$(fvGeometryScheme)/averageNeighbour/averageNeighbourFvGeometryScheme.C +$(fvGeometryScheme)/stabilised/stabilisedFvGeometryScheme.C + +surfaceInterpolation = interpolation/surfaceInterpolation +$(surfaceInterpolation)/surfaceInterpolation/surfaceInterpolation.C + fvMesh/singleCellFvMesh/singleCellFvMesh.C fvMesh/simplifiedFvMesh/simplifiedFvMesh/simplifiedFvMesh.C @@ -53,7 +64,6 @@ fvMeshMapper = fvMesh/fvMeshMapper $(fvMeshMapper)/fvPatchMapper.C $(fvMeshMapper)/fvSurfaceMapper.C - extendedStencil = fvMesh/extendedStencil cellToCell = $(extendedStencil)/cellToCell @@ -316,8 +326,6 @@ volPointInterpolation = interpolation/volPointInterpolation $(volPointInterpolation)/volPointInterpolation.C $(volPointInterpolation)/pointConstraints.C -surfaceInterpolation = interpolation/surfaceInterpolation -$(surfaceInterpolation)/surfaceInterpolation/surfaceInterpolation.C $(surfaceInterpolation)/surfaceInterpolationScheme/surfaceInterpolationSchemes.C $(surfaceInterpolation)/blendedSchemeBase/blendedSchemeBaseName.C diff --git a/src/finiteVolume/finiteVolume/fvSchemes/fvSchemes.C b/src/finiteVolume/finiteVolume/fvSchemes/fvSchemes.C index f65ae4c1b1ff58562a1d0d5110ba733b4f943f81..b67b65de6b4b0386e5ba299c26066ae3405d5a80 100644 --- a/src/finiteVolume/finiteVolume/fvSchemes/fvSchemes.C +++ b/src/finiteVolume/finiteVolume/fvSchemes/fvSchemes.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation - Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -327,6 +327,140 @@ Foam::fvSchemes::fvSchemes(const objectRegistry& obr) } +Foam::fvSchemes::fvSchemes(const objectRegistry& obr, const dictionary& dict) +: + IOdictionary + ( + IOobject + ( + "fvSchemes", + obr.time().system(), + obr, + ( + obr.readOpt() == IOobject::MUST_READ + || obr.readOpt() == IOobject::READ_IF_PRESENT + ? IOobject::MUST_READ_IF_MODIFIED + : obr.readOpt() + ), + IOobject::NO_WRITE + ), + dict + ), + ddtSchemes_ + ( + ITstream + ( + objectPath() + ".ddtSchemes", + tokenList() + )() + ), + defaultDdtScheme_ + ( + ddtSchemes_.name() + ".default", + tokenList() + ), + d2dt2Schemes_ + ( + ITstream + ( + objectPath() + ".d2dt2Schemes", + tokenList() + )() + ), + defaultD2dt2Scheme_ + ( + d2dt2Schemes_.name() + ".default", + tokenList() + ), + interpolationSchemes_ + ( + ITstream + ( + objectPath() + ".interpolationSchemes", + tokenList() + )() + ), + defaultInterpolationScheme_ + ( + interpolationSchemes_.name() + ".default", + tokenList() + ), + divSchemes_ + ( + ITstream + ( + objectPath() + ".divSchemes", + tokenList() + )() + ), + defaultDivScheme_ + ( + divSchemes_.name() + ".default", + tokenList() + ), + gradSchemes_ + ( + ITstream + ( + objectPath() + ".gradSchemes", + tokenList() + )() + ), + defaultGradScheme_ + ( + gradSchemes_.name() + ".default", + tokenList() + ), + snGradSchemes_ + ( + ITstream + ( + objectPath() + ".snGradSchemes", + tokenList() + )() + ), + defaultSnGradScheme_ + ( + snGradSchemes_.name() + ".default", + tokenList() + ), + laplacianSchemes_ + ( + ITstream + ( + objectPath() + ".laplacianSchemes", + tokenList() + )() + ), + defaultLaplacianScheme_ + ( + laplacianSchemes_.name() + ".default", + tokenList() + ), + fluxRequired_ + ( + ITstream + ( + objectPath() + ".fluxRequired", + tokenList() + )() + ), + defaultFluxRequired_(false), + steady_(false) +{ + if + ( + readOpt() == IOobject::MUST_READ + || readOpt() == IOobject::MUST_READ_IF_MODIFIED + || (readOpt() == IOobject::READ_IF_PRESENT && headerOk()) + ) + { + read(schemesDict()); + } +} + + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // bool Foam::fvSchemes::read() diff --git a/src/finiteVolume/finiteVolume/fvSchemes/fvSchemes.H b/src/finiteVolume/finiteVolume/fvSchemes/fvSchemes.H index 81f1edecaff4d22712a28c07e9085cba1ccf7146..f129c2320833081753d10cd15fb1ad534c2ef6fa 100644 --- a/src/finiteVolume/finiteVolume/fvSchemes/fvSchemes.H +++ b/src/finiteVolume/finiteVolume/fvSchemes/fvSchemes.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -111,6 +112,11 @@ public: //- Construct for objectRegistry fvSchemes(const objectRegistry& obr); + //- Construct from objectRegistry and supplied (optional) content + // (gets used in case of NO_READ or fvSchemes dictionary cannot be + // read) + fvSchemes(const objectRegistry& obr, const dictionary& dict); + // Member Functions diff --git a/src/finiteVolume/finiteVolume/fvSolution/fvSolution.H b/src/finiteVolume/finiteVolume/fvSolution/fvSolution.H index 7cf1aed1f362d0df741f6966fdbf76d88861271a..bdafb4c86b47dd718ed124a4f6d0b5140bf5e690 100644 --- a/src/finiteVolume/finiteVolume/fvSolution/fvSolution.H +++ b/src/finiteVolume/finiteVolume/fvSolution/fvSolution.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -69,6 +70,12 @@ public: : solution(obr, "fvSolution") {} + + //- Construct for objectRegistry and optional contents + fvSolution(const objectRegistry& obr, const dictionary& dict) + : + solution(obr, "fvSolution", dict) + {} }; diff --git a/src/finiteVolume/fvMesh/fvGeometryScheme/averageNeighbour/averageNeighbourFvGeometryScheme.C b/src/finiteVolume/fvMesh/fvGeometryScheme/averageNeighbour/averageNeighbourFvGeometryScheme.C new file mode 100644 index 0000000000000000000000000000000000000000..507f3121d3631c0e8b474526ffcad70ccf9dfc31 --- /dev/null +++ b/src/finiteVolume/fvMesh/fvGeometryScheme/averageNeighbour/averageNeighbourFvGeometryScheme.C @@ -0,0 +1,880 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 3 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, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "averageNeighbourFvGeometryScheme.H" +#include "addToRunTimeSelectionTable.H" +#include "fvMesh.H" +#include "cellAspectRatio.H" +#include "syncTools.H" +#include "polyMeshTools.H" +#include "unitConversion.H" +#include "OBJstream.H" +#include "surfaceWriter.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(averageNeighbourFvGeometryScheme, 0); + addToRunTimeSelectionTable + ( + fvGeometryScheme, + averageNeighbourFvGeometryScheme, + dict + ); +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::label Foam::averageNeighbourFvGeometryScheme::clipFaceTet +( + const scalar minRatio, + const vectorField& faceCentres, + const vectorField& faceNormals, + + vectorField& faceCorrection +) const +{ + // Clip correction vector if any triangle becomes too small. Return number + // of correction vectors clipped + + typedef Vector<solveScalar> solveVector; + + const pointField& p = mesh_.points(); + + label nClipped = 0; + for (label facei = 0; facei < mesh_.nFaces(); facei++) + { + const vector& fcCorr = faceCorrection[facei]; + if (fcCorr != vector::zero) + { + const vector& fn = faceNormals[facei]; + const point& fc = faceCentres[facei]; + const face& f = mesh_.faces()[facei]; + + forAll(f, fp) + { + const solveVector thisPt(p[f[fp]]); + const solveVector nextPt(p[f.fcValue(fp)]); + const solveVector d(nextPt-thisPt); + + // Calculate triangle area with correction + const solveVector nCorr(d^(fc+fcCorr - thisPt)); + + if ((nCorr & fn) < 0) + { + // Triangle points wrong way + faceCorrection[facei] = vector::zero; + nClipped++; + break; + } + else + { + // Calculate triangle area without correction + const solveVector n(d^(fc - thisPt)); + if ((n & fn) < 0) + { + // Original triangle points the wrong way, new one is ok + } + else + { + // Both point correctly. Make sure triangle doesn't get + // too small + if (mag(nCorr) < minRatio*mag(n)) + { + faceCorrection[facei] = vector::zero; + nClipped++; + break; + } + } + } + } + } + } + return returnReduce(nClipped, sumOp<label>()); +} + + +void Foam::averageNeighbourFvGeometryScheme::makePyrHeights +( + const pointField& cellCentres, + const vectorField& faceCentres, + const vectorField& faceNormals, + + scalarField& ownHeight, + scalarField& neiHeight +) const +{ + ownHeight.setSize(mesh_.nFaces()); + neiHeight.setSize(mesh_.nInternalFaces()); + + typedef Vector<solveScalar> solveVector; + + const labelList& own = mesh_.faceOwner(); + const labelList& nei = mesh_.faceNeighbour(); + + for (label facei = 0; facei < mesh_.nInternalFaces(); facei++) + { + const solveVector n = faceNormals[facei]; + const solveVector fc = faceCentres[facei]; + ownHeight[facei] = ((fc-cellCentres[own[facei]])&n); + neiHeight[facei] = ((cellCentres[nei[facei]]-fc)&n); + } + + for (label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); facei++) + { + const solveVector n = faceNormals[facei]; + const solveVector fc = faceCentres[facei]; + ownHeight[facei] = ((fc-cellCentres[own[facei]])&n); + } +} + + +Foam::label Foam::averageNeighbourFvGeometryScheme::clipPyramids +( + const pointField& cellCentres, + const vectorField& faceCentres, + const vectorField& faceNormals, + + const scalarField& minOwnHeight, + const scalarField& minNeiHeight, + + vectorField& correction +) const +{ + // Clip correction vector if any pyramid becomes too small. Return number of + // cells clipped + + typedef Vector<solveScalar> solveVector; + + const labelList& own = mesh_.faceOwner(); + const labelList& nei = mesh_.faceNeighbour(); + + label nClipped = 0; + for (label facei = 0; facei < mesh_.nInternalFaces(); facei++) + { + const vector& n = faceNormals[facei]; + const point& fc = faceCentres[facei]; + + const label ownCelli = own[facei]; + if (correction[ownCelli] != vector::zero) + { + const solveVector ownCc(cellCentres[ownCelli]+correction[ownCelli]); + const scalar ownHeight = ((fc-ownCc)&n); + if (ownHeight < minOwnHeight[facei]) + { + //Pout<< " internalface:" << fc + // << " own:" << ownCc + // << " pyrHeight:" << ownHeight + // << " minHeight:" << minOwnHeight[facei] + // << endl; + correction[ownCelli] = vector::zero; + nClipped++; + } + } + + const label neiCelli = nei[facei]; + if (correction[neiCelli] != vector::zero) + { + const solveVector neiCc(cellCentres[neiCelli]+correction[neiCelli]); + const scalar neiHeight = ((neiCc-fc)&n); + if (neiHeight < minNeiHeight[facei]) + { + //Pout<< " internalface:" << fc + // << " nei:" << neiCc + // << " pyrHeight:" << neiHeight + // << " minHeight:" << minNeiHeight[facei] + // << endl; + correction[neiCelli] = vector::zero; + nClipped++; + } + } + } + + for (label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); facei++) + { + const vector& n = faceNormals[facei]; + const point& fc = faceCentres[facei]; + + const label ownCelli = own[facei]; + if (correction[ownCelli] != vector::zero) + { + const solveVector ownCc(cellCentres[ownCelli]+correction[ownCelli]); + const scalar ownHeight = ((fc-ownCc)&n); + if (ownHeight < minOwnHeight[facei]) + { + //Pout<< " boundaryface:" << fc + // << " own:" << ownCc + // << " pyrHeight:" << ownHeight + // << " minHeight:" << minOwnHeight[facei] + // << endl; + correction[ownCelli] = vector::zero; + nClipped++; + } + } + } + return returnReduce(nClipped, sumOp<label>()); +} + + +Foam::tmp<Foam::pointField> +Foam::averageNeighbourFvGeometryScheme::averageNeighbourCentres +( + const pointField& cellCentres, + const vectorField& faceNormals, + const scalarField& faceWeights +) const +{ + typedef Vector<solveScalar> solveVector; + + const labelList& own = mesh_.faceOwner(); + const labelList& nei = mesh_.faceNeighbour(); + + + tmp<pointField> tcc(new pointField(mesh_.nCells(), Zero)); + pointField& cc = tcc.ref(); + + Field<solveScalar> cellWeights(mesh_.nCells(), Zero); + + // Internal faces + for (label facei = 0; facei < mesh_.nInternalFaces(); facei++) + { + const vector& n = faceNormals[facei]; + const point& ownCc = cellCentres[own[facei]]; + const point& neiCc = cellCentres[nei[facei]]; + + solveVector d(neiCc-ownCc); + + // 1. Normalise contribution. This increases actual non-ortho + // since it does not 'see' the tangential offset of neighbours + //neiCc = ownCc + (d&n)*n; + + // 2. Remove normal contribution, i.e. get tangential vector + // (= non-ortho correction vector?) + d -= (d&n)*n; + + // Apply half to both sides (as a correction) + // Note: should this be linear weights instead of 0.5? + const scalar w = 0.5*faceWeights[facei]; + cc[own[facei]] += w*d; + cellWeights[own[facei]] += w; + + cc[nei[facei]] -= w*d; + cellWeights[nei[facei]] += w; + } + + + // Boundary faces. Bypass stored cell centres + pointField neiCellCentres; + syncTools::swapBoundaryCellPositions(mesh_, cellCentres, neiCellCentres); + + const polyBoundaryMesh& pbm = mesh_.boundaryMesh(); + forAll(pbm, patchi) + { + const polyPatch& pp = pbm[patchi]; + if (pp.coupled()) + { + const labelUList& fc = pp.faceCells(); + + forAll(fc, i) + { + const label meshFacei = pp.start()+i; + const label bFacei = meshFacei-mesh_.nInternalFaces(); + + const vector& n = faceNormals[meshFacei]; + + const point& ownCc = cellCentres[fc[i]]; + const point& neiCc = neiCellCentres[bFacei]; + + solveVector d(neiCc-ownCc); + + // 1. Normalise contribution. This increases actual non-ortho + // since it does not 'see' the tangential offset of neighbours + //neiCc = ownCc + (d&n)*n; + + // 2. Remove normal contribution, i.e. get tangential vector + // (= non-ortho correction vector?) + d -= (d&n)*n; + + // Apply half to both sides (as a correction) + const scalar w = 0.5*faceWeights[meshFacei]; + cc[fc[i]] += w*d; + cellWeights[fc[i]] += w; + } + } + } + + // Now cc is still the correction vector. Add to cell original centres. + forAll(cc, celli) + { + if (cellWeights[celli] > VSMALL) + { + cc[celli] = cellCentres[celli] + cc[celli]/cellWeights[celli]; + } + else + { + cc[celli] = cellCentres[celli]; + } + } + + return tcc; +} + + +Foam::tmp<Foam::pointField> +Foam::averageNeighbourFvGeometryScheme::averageCentres +( +// const scalar ratio, // Amount of change in face-triangles area + const pointField& cellCentres, + const pointField& faceCentres, + const vectorField& faceNormals +) const +{ + typedef Vector<solveScalar> solveVector; + + const labelList& own = mesh_.faceOwner(); + const labelList& nei = mesh_.faceNeighbour(); + + + tmp<pointField> tnewFc(new pointField(faceCentres)); + pointField& newFc = tnewFc.ref(); + + // Internal faces + for (label facei = 0; facei < mesh_.nInternalFaces(); facei++) + { + const vector& n = faceNormals[facei]; + const point& oldFc = faceCentres[facei]; + + const solveVector ownCc(cellCentres[own[facei]]); + const solveVector neiCc(cellCentres[nei[facei]]); + + solveVector deltaCc(neiCc-ownCc); + solveVector deltaFc(oldFc-ownCc); + + //solveVector d(neiCc-ownCc); + //// 1. Normalise contribution. This increases actual non-ortho + //// since it does not 'see' the tangential offset of neighbours + ////neiCc = ownCc + s*n; + // + //// 2. Remove normal contribution, i.e. get tangential vector + //// (= non-ortho correction vector?) + //d -= s*n; + //newFc[facei] = faceCentres[facei]+d; + + // Get linear weight (normal distance to face) + const solveScalar f = (deltaFc&n)/(deltaCc&n); + const solveVector avgCc((1.0-f)*ownCc + f*neiCc); + + solveVector d(avgCc-oldFc); + // Remove normal contribution, i.e. get tangential vector + // (= non-ortho correction vector?) + d -= (d&n)*n; + +// // Clip to limit change in +// d *= ratio; + + + newFc[facei] = oldFc + d; + } + + + // Boundary faces. Bypass stored cell centres + pointField neiCellCentres; + syncTools::swapBoundaryCellPositions(mesh_, cellCentres, neiCellCentres); + + const polyBoundaryMesh& pbm = mesh_.boundaryMesh(); + forAll(pbm, patchi) + { + const polyPatch& pp = pbm[patchi]; + const labelUList& fc = pp.faceCells(); + + if (pp.coupled()) + { + forAll(fc, i) + { + // Same as internal faces + const label facei = pp.start()+i; + const label bFacei = facei-mesh_.nInternalFaces(); + + const vector& n = faceNormals[facei]; + const point& oldFc = faceCentres[facei]; + + const solveVector ownCc(cellCentres[fc[i]]); + const solveVector neiCc(neiCellCentres[bFacei]); + + solveVector deltaCc(neiCc-ownCc); + solveVector deltaFc(oldFc-ownCc); + + // Get linear weight (normal distance to face) + const solveScalar f = (deltaFc&n)/(deltaCc&n); + const solveVector avgCc((1.0-f)*ownCc + f*neiCc); + + solveVector d(avgCc-oldFc); + // Remove normal contribution, i.e. get tangential vector + // (= non-ortho correction vector?) + d -= (d&n)*n; + + newFc[facei] = oldFc + d; + } + } + else + { + // Zero-grad? + forAll(fc, i) + { + const label facei = pp.start()+i; + + const vector& n = faceNormals[facei]; + const point& oldFc = faceCentres[facei]; + const solveVector ownCc(cellCentres[fc[i]]); + + solveVector d(ownCc-oldFc); + // Remove normal contribution, i.e. get tangential vector + // (= non-ortho correction vector?) + d -= (d&n)*n; + + newFc[facei] = oldFc+d; + } + } + } + + return tnewFc; +} + + +void Foam::averageNeighbourFvGeometryScheme::makeNonOrthoWeights +( + const pointField& cellCentres, + const vectorField& faceNormals, + + scalarField& cosAngles, + scalarField& faceWeights +) const +{ + cosAngles = + max + ( + scalar(0), + min + ( + scalar(1), + polyMeshTools::faceOrthogonality + ( + mesh_, + faceNormals, + cellCentres + ) + ) + ); + + + // Make weight: 0 for ortho faces, 1 for 90degrees non-ortho + //const scalarField faceWeights(scalar(1)-cosAngles); + faceWeights.setSize(cosAngles.size()); + { + const scalar minCos = Foam::cos(degToRad(80)); + const scalar maxCos = Foam::cos(degToRad(10)); + + forAll(cosAngles, facei) + { + const scalar cosAngle = cosAngles[facei]; + if (cosAngle < minCos) + { + faceWeights[facei] = 1.0; + } + else if (cosAngle > maxCos) + { + faceWeights[facei] = 0.0; + } + else + { + faceWeights[facei] = + 1.0-(cosAngle-minCos)/(maxCos-minCos); + } + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::averageNeighbourFvGeometryScheme::averageNeighbourFvGeometryScheme +( + const fvMesh& mesh, + const dictionary& dict +) +: + highAspectRatioFvGeometryScheme(mesh, dict), + nIters_ + ( + dict.getCheckOrDefault<label> + ( + "nIters", + 1, + [&](const label& nIters) + { + return nIters >= 0; + } + ) + ), + relax_ + ( + dict.getCheck<scalar> + ( + "relax", + [&](const scalar& relax) + { + return relax > 0 && relax <= 1; + } + ) + ), + minRatio_ + ( + dict.getCheckOrDefault<scalar> + ( + "minRatio", + 0.5, + [&](const scalar& minRatio) + { + return minRatio >= 0 && minRatio <= 1; + } + ) + ) +{ + if (debug) + { + Pout<< "averageNeighbourFvGeometryScheme :" + << " nIters:" << nIters_ + << " relax:" << relax_ + << " minRatio:" << minRatio_ << endl; + } + + // Force local calculation + movePoints(); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::averageNeighbourFvGeometryScheme::movePoints() +{ + if (debug) + { + Pout<< "averageNeighbourFvGeometryScheme::movePoints() : " + << "recalculating primitiveMesh centres" << endl; + } + + //if + //( + // !mesh_.hasCellCentres() + //&& !mesh_.hasFaceCentres() + //&& !mesh_.hasCellVolumes() + //&& !mesh_.hasFaceAreas() + //) + { + highAspectRatioFvGeometryScheme::movePoints(); + + // Note: at this point the highAspectRatioFvGeometryScheme constructor + // will have already reset the primitive geometry! + + vectorField faceAreas(mesh_.faceAreas()); + const scalarField magFaceAreas(mag(faceAreas)); + const vectorField faceNormals(faceAreas/magFaceAreas); + + + // Calculate aspectratio weights + // - 0 if aratio < minAspect_ + // - 1 if aratio >= maxAspect_ + scalarField cellWeight, faceWeight; + calcAspectRatioWeights(cellWeight, faceWeight); + + // Relaxation + cellWeight *= relax_; + //faceWeight *= relax_; + + // Calculate current pyramid heights + scalarField minOwnHeight; + scalarField minNeiHeight; + makePyrHeights + ( + mesh_.cellCentres(), + mesh_.faceCentres(), + faceNormals, + + minOwnHeight, + minNeiHeight + ); + + // How much is the cell centre to vary inside the cell. + minOwnHeight *= minRatio_; + minNeiHeight *= minRatio_; + + + + autoPtr<OBJstream> osPtr; + autoPtr<surfaceWriter> writerPtr; + if (debug) + { + osPtr.set + ( + new OBJstream + ( + mesh_.time().timePath() + / "cellCentre_correction.obj" + ) + ); + Pout<< "averageNeighbourFvGeometryScheme::movePoints() :" + << " writing cell centre path to " << osPtr().name() << endl; + + + // Write current non-ortho + fileName outputDir = + ( + mesh_.time().globalPath() + / functionObject::outputPrefix + / mesh_.pointsInstance() + ); + outputDir.clean(); + writerPtr = surfaceWriter::New + ( + "ensight" //"vtk" + // options + ); + + // Use outputDir/TIME/surface-name + writerPtr->useTimeDir() = true; + + writerPtr->beginTime(mesh_.time()); + + writerPtr->open + ( + mesh_.points(), + mesh_.faces(), + (outputDir / "cosAngle"), + true // merge parallel bits + ); + + writerPtr->endTime(); + } + + + // Current cellCentres. These get adjusted to lower the + // non-orthogonality + pointField cellCentres(mesh_.cellCentres()); + + // Modify cell centres to be more in-line with the face normals + for (label iter = 0; iter < nIters_; iter++) + { + // Get neighbour average (weighted by face area). This gives + // preference to the dominant faces. However if the non-ortho + // is not caused by the dominant faces this moves to the wrong + // direction. + //tmp<pointField> tcc + //( + // averageNeighbourCentres + // ( + // cellCentres, + // faceNormals, + // magFaceAreas + // ) + //); + + // Get neighbour average weighted by non-ortho. Question: how to + // weight boundary faces? + tmp<pointField> tcc; + { + scalarField cosAngles; + scalarField faceWeights; + makeNonOrthoWeights + ( + cellCentres, + faceNormals, + + cosAngles, + faceWeights + ); + + if (writerPtr.valid()) + { + writerPtr->beginTime(instant(scalar(iter))); + writerPtr->write("cosAngles", cosAngles); + writerPtr->endTime(); + } + + if (debug) + { + forAll(cosAngles, facei) + { + if (cosAngles[facei] < Foam::cos(degToRad(85.0))) + { + Pout<< " face:" << facei + << " at:" << mesh_.faceCentres()[facei] + << " cosAngle:" << cosAngles[facei] + << " faceWeight:" << faceWeights[facei] + << endl; + } + } + } + + tcc = averageNeighbourCentres + ( + cellCentres, + faceNormals, + faceWeights + ); + } + + + // Calculate correction for cell centres. Leave low-aspect + // ratio cells unaffected (i.e. correction = 0) + vectorField correction(cellWeight*(tcc-cellCentres)); + + // Clip correction vector if pyramid becomes too small + const label nClipped = clipPyramids + ( + cellCentres, + mesh_.faceCentres(), + faceNormals, + + minOwnHeight, // minimum owner pyramid height. Usually fraction + minNeiHeight, // of starting mesh + + correction + ); + + cellCentres += correction; + + if (debug) + { + forAll(cellCentres, celli) + { + const point& cc = cellCentres[celli]; + osPtr().write(linePointRef(cc-correction[celli], cc)); + } + + const scalarField magCorrection(mag(correction)); + const scalarField faceOrthogonality + ( + min + ( + scalar(1), + polyMeshTools::faceOrthogonality + ( + mesh_, + faceAreas, + cellCentres + ) + ) + ); + const scalarField nonOrthoAngle + ( + radToDeg + ( + Foam::acos(faceOrthogonality) + ) + ); + Pout<< " iter:" << iter + << " nClipped:" << nClipped + << " average displacement:" << gAverage(magCorrection) + << " non-ortho angle : average:" << gAverage(nonOrthoAngle) + << " max:" << gMax(nonOrthoAngle) << endl; + } + } + + tmp<pointField> tfc + ( + averageCentres + ( + cellCentres, + mesh_.faceCentres(), + faceNormals + ) + ); + vectorField faceCorrection(faceWeight*(tfc-mesh_.faceCentres())); + // Clip correction vector to not have min triangle shrink + // by more than minRatio + clipFaceTet + ( + minRatio_, + mesh_.faceCentres(), + faceNormals, + faceCorrection + ); + vectorField faceCentres(mesh_.faceCentres() + faceCorrection); + + if (debug) + { + Pout<< "averageNeighbourFvGeometryScheme::movePoints() :" + << " averageNeighbour weight" + << " max:" << gMax(cellWeight) << " min:" << gMin(cellWeight) + << " average:" << gAverage(cellWeight) << endl; + + // Dump lines from old to new location + const fileName tp(mesh_.time().timePath()); + mkDir(tp); + OBJstream str(tp/"averageNeighbourCellCentres.obj"); + Pout<< "Writing lines from old to new cell centre to " << str.name() + << endl; + forAll(mesh_.cellCentres(), celli) + { + const point& oldCc = mesh_.cellCentres()[celli]; + const point& newCc = cellCentres[celli]; + str.write(linePointRef(oldCc, newCc)); + } + } + if (debug) + { + // Dump lines from old to new location + const fileName tp(mesh_.time().timePath()); + OBJstream str(tp/"averageFaceCentres.obj"); + Pout<< "Writing lines from old to new face centre to " << str.name() + << endl; + forAll(mesh_.faceCentres(), facei) + { + const point& oldFc = mesh_.faceCentres()[facei]; + const point& newFc = faceCentres[facei]; + str.write(linePointRef(oldFc, newFc)); + } + } + + scalarField cellVolumes(mesh_.cellVolumes()); + + // Store on primitiveMesh + //const_cast<fvMesh&>(mesh_).clearGeom(); + const_cast<fvMesh&>(mesh_).primitiveMesh::resetGeometry + ( + std::move(faceCentres), + std::move(faceAreas), + std::move(cellCentres), + std::move(cellVolumes) + ); + } +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvGeometryScheme/averageNeighbour/averageNeighbourFvGeometryScheme.H b/src/finiteVolume/fvMesh/fvGeometryScheme/averageNeighbour/averageNeighbourFvGeometryScheme.H new file mode 100644 index 0000000000000000000000000000000000000000..578179630104007992b325e068f67cdbe1a311b1 --- /dev/null +++ b/src/finiteVolume/fvMesh/fvGeometryScheme/averageNeighbour/averageNeighbourFvGeometryScheme.H @@ -0,0 +1,178 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 3 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, see <http://www.gnu.org/licenses/>. + +Class + Foam::averageNeighbourFvGeometryScheme + +Description + Geometry calculation scheme to minimise non-orthogonality/ + +SourceFiles + averageNeighbourFvGeometryScheme.C + +\*---------------------------------------------------------------------------*/ + +#ifndef averageNeighbourFvGeometryScheme_H +#define averageNeighbourFvGeometryScheme_H + +#include "highAspectRatioFvGeometryScheme.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class primitiveMesh; + +/*---------------------------------------------------------------------------*\ + Class averageNeighbourFvGeometryScheme Declaration +\*---------------------------------------------------------------------------*/ + +class averageNeighbourFvGeometryScheme +: + public highAspectRatioFvGeometryScheme +{ +private: + + //- No copy construct + averageNeighbourFvGeometryScheme + ( + const averageNeighbourFvGeometryScheme& + ) = delete; + + //- No copy assignment + void operator=(const averageNeighbourFvGeometryScheme&) = delete; + + +protected: + + //- Number of averaging iterations + const label nIters_; + + //- Blending between old-iteration cell centres and current average + const scalar relax_; + + //- Clipping for pyramid heights - allowable shrinkage as fraction + // of original + const scalar minRatio_; + + + //- Clip face-centre correction vector if new triangle area + //- would get below min. Return number of clipped faces. + label clipFaceTet + ( + const scalar minRatio, + const vectorField& faceCentres, + const vectorField& faceNormals, + vectorField& faceCorrection + ) const; + + //- Calculate pyramid heights + void makePyrHeights + ( + const pointField& cellCentres, + const vectorField& faceCentres, + const vectorField& faceNormals, + + scalarField& ownHeight, + scalarField& neiHeight + ) const; + + //- Clip correction vector if new pyramid height would get below min. + //- Return number of clipped cells. + label clipPyramids + ( + const pointField& cellCentres, + const vectorField& faceCentres, + const vectorField& faceNormals, + + const scalarField& minOwnHeight, + const scalarField& minNeiHeight, + + vectorField& correction + ) const; + + //- Average neighbouring cell centres to minimise non-ortho + tmp<pointField> averageNeighbourCentres + ( + const pointField& cellCentres, + const vectorField& faceNormals, + const scalarField& faceWeights + ) const; + + tmp<pointField> averageCentres + ( + const pointField& cellCentres, + const pointField& faceCentres, + const vectorField& faceNormals + ) const; + + //- Make weights based on non-orthogonality + void makeNonOrthoWeights + ( + const pointField& cellCentres, + const vectorField& faceNormals, + + scalarField& cosAngles, + scalarField& faceWeights + ) const; + + +public: + + //- Runtime type information + TypeName("averageNeighbour"); + + + // Constructors + + //- Construct from mesh + averageNeighbourFvGeometryScheme + ( + const fvMesh& mesh, + const dictionary& dict + ); + + + //- Destructor + virtual ~averageNeighbourFvGeometryScheme() = default; + + + // Member Functions + + //- Do what is necessary if the mesh has moved + virtual void movePoints(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvGeometryScheme/basic/basicFvGeometryScheme.C b/src/finiteVolume/fvMesh/fvGeometryScheme/basic/basicFvGeometryScheme.C new file mode 100644 index 0000000000000000000000000000000000000000..422f6e9059b932e7f1d8625c0aeed86a948af772 --- /dev/null +++ b/src/finiteVolume/fvMesh/fvGeometryScheme/basic/basicFvGeometryScheme.C @@ -0,0 +1,388 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 3 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, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "basicFvGeometryScheme.H" +#include "addToRunTimeSelectionTable.H" +#include "surfaceFields.H" +#include "volFields.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(basicFvGeometryScheme, 0); + addToRunTimeSelectionTable(fvGeometryScheme, basicFvGeometryScheme, dict); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::basicFvGeometryScheme::basicFvGeometryScheme +( + const fvMesh& mesh, + const dictionary& dict +) +: + fvGeometryScheme(mesh, dict) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::basicFvGeometryScheme::movePoints() +{ + if (debug) + { + Pout<< "basicFvGeometryScheme::movePoints() : " + << "recalculating primitiveMesh centres" << endl; + } + // Use lower level to calculate the geometry + const_cast<fvMesh&>(mesh_).primitiveMesh::updateGeom(); +} + + +Foam::tmp<Foam::surfaceScalarField> Foam::basicFvGeometryScheme::weights() const +{ + if (debug) + { + Pout<< "basicFvGeometryScheme::weights() : " + << "Constructing weighting factors for face interpolation" + << endl; + } + + tmp<surfaceScalarField> tweights + ( + new surfaceScalarField + ( + IOobject + ( + "weights", + mesh_.pointsInstance(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE, + false // Do not register + ), + mesh_, + dimless + ) + ); + surfaceScalarField& weights = tweights.ref(); + weights.setOriented(); + + // Set local references to mesh data + // Note that we should not use fvMesh sliced fields at this point yet + // since this causes a loop when generating weighting factors in + // coupledFvPatchField evaluation phase + const labelUList& owner = mesh_.owner(); + const labelUList& neighbour = mesh_.neighbour(); + + const vectorField& Cf = mesh_.faceCentres(); + const vectorField& C = mesh_.cellCentres(); + const vectorField& Sf = mesh_.faceAreas(); + + // ... and reference to the internal field of the weighting factors + scalarField& w = weights.primitiveFieldRef(); + + forAll(owner, facei) + { + // Note: mag in the dot-product. + // For all valid meshes, the non-orthogonality will be less than + // 90 deg and the dot-product will be positive. For invalid + // meshes (d & s <= 0), this will stabilise the calculation + // but the result will be poor. + scalar SfdOwn = mag(Sf[facei] & (Cf[facei] - C[owner[facei]])); + scalar SfdNei = mag(Sf[facei] & (C[neighbour[facei]] - Cf[facei])); + w[facei] = SfdNei/(SfdOwn + SfdNei); + } + + surfaceScalarField::Boundary& wBf = weights.boundaryFieldRef(); + + forAll(mesh_.boundary(), patchi) + { + mesh_.boundary()[patchi].makeWeights(wBf[patchi]); + } + + if (debug) + { + Pout<< "basicFvGeometryScheme::weights : " + << "Finished constructing weighting factors for face interpolation" + << endl; + } + return tweights; +} + + +Foam::tmp<Foam::surfaceScalarField> +Foam::basicFvGeometryScheme::deltaCoeffs() const +{ + if (debug) + { + Pout<< "basicFvGeometryScheme::deltaCoeffs() : " + << "Constructing differencing factors array for face gradient" + << endl; + } + + // Force the construction of the weighting factors + // needed to make sure deltaCoeffs are calculated for parallel runs. + (void)mesh_.weights(); + + tmp<surfaceScalarField> tdeltaCoeffs + ( + new surfaceScalarField + ( + IOobject + ( + "deltaCoeffs", + mesh_.pointsInstance(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE, + false // Do not register + ), + mesh_, + dimless/dimLength + ) + ); + surfaceScalarField& deltaCoeffs = tdeltaCoeffs.ref(); + deltaCoeffs.setOriented(); + + + // Set local references to mesh data + const volVectorField& C = mesh_.C(); + const labelUList& owner = mesh_.owner(); + const labelUList& neighbour = mesh_.neighbour(); + + forAll(owner, facei) + { + deltaCoeffs[facei] = 1.0/mag(C[neighbour[facei]] - C[owner[facei]]); + } + + surfaceScalarField::Boundary& deltaCoeffsBf = + deltaCoeffs.boundaryFieldRef(); + + forAll(deltaCoeffsBf, patchi) + { + const fvPatch& p = mesh_.boundary()[patchi]; + deltaCoeffsBf[patchi] = 1.0/mag(p.delta()); + + // Optionally correct + p.makeDeltaCoeffs(deltaCoeffsBf[patchi]); + } + + return tdeltaCoeffs; +} + + +Foam::tmp<Foam::surfaceScalarField> +Foam::basicFvGeometryScheme::nonOrthDeltaCoeffs() const +{ + if (debug) + { + Pout<< "basicFvGeometryScheme::nonOrthDeltaCoeffs() : " + << "Constructing differencing factors array for face gradient" + << endl; + } + + // Force the construction of the weighting factors + // needed to make sure deltaCoeffs are calculated for parallel runs. + weights(); + + tmp<surfaceScalarField> tnonOrthDeltaCoeffs + ( + new surfaceScalarField + ( + IOobject + ( + "nonOrthDeltaCoeffs", + mesh_.pointsInstance(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE, + false // Do not register + ), + mesh_, + dimless/dimLength + ) + ); + surfaceScalarField& nonOrthDeltaCoeffs = tnonOrthDeltaCoeffs.ref(); + nonOrthDeltaCoeffs.setOriented(); + + + // Set local references to mesh data + const volVectorField& C = mesh_.C(); + const labelUList& owner = mesh_.owner(); + const labelUList& neighbour = mesh_.neighbour(); + const surfaceVectorField& Sf = mesh_.Sf(); + const surfaceScalarField& magSf = mesh_.magSf(); + + forAll(owner, facei) + { + vector delta = C[neighbour[facei]] - C[owner[facei]]; + vector unitArea = Sf[facei]/magSf[facei]; + + // Standard cell-centre distance form + //NonOrthDeltaCoeffs[facei] = (unitArea & delta)/magSqr(delta); + + // Slightly under-relaxed form + //NonOrthDeltaCoeffs[facei] = 1.0/mag(delta); + + // More under-relaxed form + //NonOrthDeltaCoeffs[facei] = 1.0/(mag(unitArea & delta) + VSMALL); + + // Stabilised form for bad meshes + nonOrthDeltaCoeffs[facei] = 1.0/max(unitArea & delta, 0.05*mag(delta)); + } + + surfaceScalarField::Boundary& nonOrthDeltaCoeffsBf = + nonOrthDeltaCoeffs.boundaryFieldRef(); + + forAll(nonOrthDeltaCoeffsBf, patchi) + { + fvsPatchScalarField& patchDeltaCoeffs = nonOrthDeltaCoeffsBf[patchi]; + + const fvPatch& p = patchDeltaCoeffs.patch(); + + const vectorField patchDeltas(mesh_.boundary()[patchi].delta()); + + forAll(p, patchFacei) + { + vector unitArea = + Sf.boundaryField()[patchi][patchFacei] + /magSf.boundaryField()[patchi][patchFacei]; + + const vector& delta = patchDeltas[patchFacei]; + + patchDeltaCoeffs[patchFacei] = + 1.0/max(unitArea & delta, 0.05*mag(delta)); + } + + // Optionally correct + p.makeNonOrthoDeltaCoeffs(patchDeltaCoeffs); + } + return tnonOrthDeltaCoeffs; +} + + +Foam::tmp<Foam::surfaceVectorField> +Foam::basicFvGeometryScheme::nonOrthCorrectionVectors() const +{ + if (debug) + { + Pout<< "surfaceInterpolation::makeNonOrthCorrectionVectors() : " + << "Constructing non-orthogonal correction vectors" + << endl; + } + + tmp<surfaceVectorField> tnonOrthCorrectionVectors + ( + new surfaceVectorField + ( + IOobject + ( + "nonOrthCorrectionVectors", + mesh_.pointsInstance(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE, + false // Do not register + ), + mesh_, + dimless + ) + ); + surfaceVectorField& corrVecs = tnonOrthCorrectionVectors.ref(); + corrVecs.setOriented(); + + // Set local references to mesh data + const volVectorField& C = mesh_.C(); + const labelUList& owner = mesh_.owner(); + const labelUList& neighbour = mesh_.neighbour(); + const surfaceVectorField& Sf = mesh_.Sf(); + const surfaceScalarField& magSf = mesh_.magSf(); + tmp<surfaceScalarField> tNonOrthDeltaCoeffs(nonOrthDeltaCoeffs()); + const surfaceScalarField& NonOrthDeltaCoeffs = tNonOrthDeltaCoeffs(); + + forAll(owner, facei) + { + vector unitArea = Sf[facei]/magSf[facei]; + vector delta = C[neighbour[facei]] - C[owner[facei]]; + + corrVecs[facei] = unitArea - delta*NonOrthDeltaCoeffs[facei]; + } + + // Boundary correction vectors set to zero for boundary patches + // and calculated consistently with internal corrections for + // coupled patches + + surfaceVectorField::Boundary& corrVecsBf = corrVecs.boundaryFieldRef(); + + forAll(corrVecsBf, patchi) + { + fvsPatchVectorField& patchCorrVecs = corrVecsBf[patchi]; + + const fvPatch& p = patchCorrVecs.patch(); + + if (!patchCorrVecs.coupled()) + { + patchCorrVecs = Zero; + } + else + { + const fvsPatchScalarField& patchNonOrthDeltaCoeffs = + NonOrthDeltaCoeffs.boundaryField()[patchi]; + + const vectorField patchDeltas(mesh_.boundary()[patchi].delta()); + + forAll(p, patchFacei) + { + vector unitArea = + Sf.boundaryField()[patchi][patchFacei] + /magSf.boundaryField()[patchi][patchFacei]; + + const vector& delta = patchDeltas[patchFacei]; + + patchCorrVecs[patchFacei] = + unitArea - delta*patchNonOrthDeltaCoeffs[patchFacei]; + } + } + + // Optionally correct + p.makeNonOrthoCorrVectors(patchCorrVecs); + } + + if (debug) + { + Pout<< "surfaceInterpolation::makeNonOrthCorrectionVectors() : " + << "Finished constructing non-orthogonal correction vectors" + << endl; + } + return tnonOrthCorrectionVectors; +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvGeometryScheme/basic/basicFvGeometryScheme.H b/src/finiteVolume/fvMesh/fvGeometryScheme/basic/basicFvGeometryScheme.H new file mode 100644 index 0000000000000000000000000000000000000000..b69d43e834eeae9d982262b13563cfabc82475a6 --- /dev/null +++ b/src/finiteVolume/fvMesh/fvGeometryScheme/basic/basicFvGeometryScheme.H @@ -0,0 +1,107 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 3 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, see <http://www.gnu.org/licenses/>. + +Class + Foam::basicFvGeometryScheme + +Description + Default geometry calculation scheme. Slight stabilisation for bad meshes. + +SourceFiles + basicFvGeometryScheme.C + +\*---------------------------------------------------------------------------*/ + +#ifndef basicFvGeometryScheme_H +#define basicFvGeometryScheme_H + +#include "fvGeometryScheme.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class basicFvGeometryScheme Declaration +\*---------------------------------------------------------------------------*/ + +class basicFvGeometryScheme +: + public fvGeometryScheme +{ + // Private Member Functions + + //- No copy construct + basicFvGeometryScheme(const basicFvGeometryScheme&) = delete; + + //- No copy assignment + void operator=(const basicFvGeometryScheme&) = delete; + + +public: + + //- Runtime type information + TypeName("basic"); + + + // Constructors + + //- Construct from mesh + basicFvGeometryScheme(const fvMesh& mesh, const dictionary& dict); + + + //- Destructor + virtual ~basicFvGeometryScheme() = default; + + + // Member Functions + + //- Do what is necessary if the mesh has moved + virtual void movePoints(); + + //- Return linear difference weighting factors + virtual tmp<surfaceScalarField> weights() const; + + //- Return cell-centre difference coefficients + virtual tmp<surfaceScalarField> deltaCoeffs() const; + + //- Return non-orthogonal cell-centre difference coefficients + virtual tmp<surfaceScalarField> nonOrthDeltaCoeffs() const; + + //- Return non-orthogonality correction vectors + virtual tmp<surfaceVectorField> nonOrthCorrectionVectors() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvGeometryScheme/fvGeometryScheme/fvGeometryScheme.C b/src/finiteVolume/fvMesh/fvGeometryScheme/fvGeometryScheme/fvGeometryScheme.C new file mode 100644 index 0000000000000000000000000000000000000000..a0eab8501757aeb2b1613a2e255c1a2f7aa36dd5 --- /dev/null +++ b/src/finiteVolume/fvMesh/fvGeometryScheme/fvGeometryScheme/fvGeometryScheme.C @@ -0,0 +1,80 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 3 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, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "fvGeometryScheme.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(fvGeometryScheme, 0); + + defineRunTimeSelectionTable(fvGeometryScheme, dict); +} + + +// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * // + +Foam::tmp<Foam::fvGeometryScheme> +Foam::fvGeometryScheme::New +( + const fvMesh& mesh, + const dictionary& dict, + const word& defaultScheme +) +{ + const entry* ePtr = dict.findEntry("method"); + const word schemeName + ( + ePtr + ? word(ePtr->stream()) + : dict.getOrDefault<word>("type", defaultScheme) + ); + + if (debug) + { + InfoInFunction << "Geometry scheme = " << schemeName << endl; + } + + auto cstrIter = dictConstructorTablePtr_->cfind(schemeName); + + if (!cstrIter.found()) + { + FatalIOErrorInLookup + ( + dict, + "fvGeometryScheme", + schemeName, + *dictConstructorTablePtr_ + ) << exit(FatalIOError); + } + + return cstrIter()(mesh, dict); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvGeometryScheme/fvGeometryScheme/fvGeometryScheme.H b/src/finiteVolume/fvMesh/fvGeometryScheme/fvGeometryScheme/fvGeometryScheme.H new file mode 100644 index 0000000000000000000000000000000000000000..a8a4f0367382aa97bbbd117850265aa6520e5555 --- /dev/null +++ b/src/finiteVolume/fvMesh/fvGeometryScheme/fvGeometryScheme/fvGeometryScheme.H @@ -0,0 +1,164 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 3 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, see <http://www.gnu.org/licenses/>. + +Class + Foam::fvGeometryScheme + +Description + Abstract base class for geometry calculation schemes. + +SourceFiles + fvGeometryScheme.C + +\*---------------------------------------------------------------------------*/ + +#ifndef fvGeometryScheme_H +#define fvGeometryScheme_H + +#include "tmp.H" +#include "surfaceFieldsFwd.H" +#include "typeInfo.H" +#include "runTimeSelectionTables.H" +#include "pointField.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class fvMesh; + +/*---------------------------------------------------------------------------*\ + Class fvGeometryScheme Declaration +\*---------------------------------------------------------------------------*/ + +class fvGeometryScheme +: + public refCount +{ + // Private Member Functions + + //- No copy construct + fvGeometryScheme(const fvGeometryScheme&) = delete; + + //- No copy assignment + void operator=(const fvGeometryScheme&) = delete; + + +protected: + + //- Hold reference to mesh + const fvMesh& mesh_; + + +public: + + //- Runtime type information + TypeName("fvGeometryScheme"); + + + // Declare run-time constructor selection tables + + declareRunTimeSelectionTable + ( + tmp, + fvGeometryScheme, + dict, + ( + const fvMesh& mesh, + const dictionary& dict + ), + (mesh, dict) + ); + + + // Constructors + + //- Construct from mesh + fvGeometryScheme(const fvMesh& mesh, const dictionary& dict) + : + mesh_(mesh) + {} + + + // Selectors + + //- Return new tmp interpolation scheme + static tmp<fvGeometryScheme> New + ( + const fvMesh& mesh, + const dictionary& dict, + const word& defaultScheme + ); + + + //- Destructor + virtual ~fvGeometryScheme() = default; + + + // Member Functions + + //- Return mesh reference + const fvMesh& mesh() const + { + return mesh_; + } + + //- Update basic geometric properties from provided points + virtual void movePoints() + {} + + //- Return linear difference weighting factors + virtual tmp<surfaceScalarField> weights() const = 0; + + //- Return cell-centre difference coefficients + virtual tmp<surfaceScalarField> deltaCoeffs() const = 0; + + //- Return non-orthogonal cell-centre difference coefficients + virtual tmp<surfaceScalarField> nonOrthDeltaCoeffs() const = 0; + + //- Return non-orthogonality correction vectors + virtual tmp<surfaceVectorField> nonOrthCorrectionVectors() const = 0; + + ////- Selector for wall distance method. WIP. Ideally return wall + //// distance or meshObject? + //virtual autoPtr<patchDistMethod> newPatchDistMethod + //( + // const dictionary& dict, + // const labelHashSet& patchIDs, + // const word& defaultPatchDistMethod + //) const = 0; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvGeometryScheme/highAspectRatio/cellAspectRatio.C b/src/finiteVolume/fvMesh/fvGeometryScheme/highAspectRatio/cellAspectRatio.C new file mode 100644 index 0000000000000000000000000000000000000000..0a0f9e27d17137bff050ac2d7a37bcfc9a8f8bdb --- /dev/null +++ b/src/finiteVolume/fvMesh/fvGeometryScheme/highAspectRatio/cellAspectRatio.C @@ -0,0 +1,123 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 3 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, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cellAspectRatio.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(cellAspectRatio, 0); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cellAspectRatio::cellAspectRatio(const polyMesh& mesh) +: + MeshObject<polyMesh, Foam::MoveableMeshObject, cellAspectRatio>(mesh) +{ + calcAspectRatio(); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::cellAspectRatio::~cellAspectRatio() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::cellAspectRatio::calcAspectRatio() +{ + if (debug) + { + InfoInFunction << "Calculating cell aspect ratio" << endl; + } + + const polyMesh& mesh = mesh_; + const pointField& cellCentres = mesh.cellCentres(); + const scalarField& cellVolumes = mesh.cellVolumes(); + const vectorField& faceAreas = mesh.faceAreas(); + const vectorField& faceCentres = mesh.faceCentres(); + const cellList& cells = mesh.cells(); + //const faceList& faces = mesh.faces(); + //const pointField& points = mesh.points(); + + scalarField& aRatio = *this; + aRatio.setSize(mesh.nCells()); + + forAll(cells, celli) + { + const point& cc = cellCentres[celli]; + const cell& cFaces = cells[celli]; + + scalar sumA = Zero; + scalar maxMag = Zero; + + for (const label facei : cFaces) + { + const vector& n = faceAreas[facei]; + + sumA += mag(n); + + //// Max distance from point to cell centre + //const face& f = faces[facei]; + //for (const label pointi : f) + //{ + // const point& pt = points[pointi]; + // const vector d(pt-cc); + // maxMag = max(maxMag, magSqr(d)); + //} + + // Max distance from face centre to cell centre + const point& fc = faceCentres[facei]; + maxMag = max(maxMag, magSqr(fc-cc)); + } + sumA /= cFaces.size(); + + // Local length scale + const scalar length = cellVolumes[celli]/sumA; + + // Max edge length + maxMag = Foam::sqrt(maxMag); + + //aRatio[celli] = Foam::sqrt(4.0/3.0)*maxMag/length; + aRatio[celli] = 2.0*maxMag/length; + } + + if (debug) + { + InfoInFunction << "Calculated cell aspect ratio min:" << gMin(aRatio) + << " max:" << gMax(aRatio) << " average:" << gAverage(aRatio) + << endl; + } +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvGeometryScheme/highAspectRatio/cellAspectRatio.H b/src/finiteVolume/fvMesh/fvGeometryScheme/highAspectRatio/cellAspectRatio.H new file mode 100644 index 0000000000000000000000000000000000000000..ed0dd9ab3e5737b064970991027424c76d7750fc --- /dev/null +++ b/src/finiteVolume/fvMesh/fvGeometryScheme/highAspectRatio/cellAspectRatio.H @@ -0,0 +1,97 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 3 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, see <http://www.gnu.org/licenses/>. + +Class + Foam::cellAspectRatio + +Description + (Rough approximation of) cell aspect ratio + +SourceFiles + cellAspectRatio.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cellAspectRatio_H +#define cellAspectRatio_H + +#include "MeshObject.H" +#include "polyMesh.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cellAspectRatio Declaration +\*---------------------------------------------------------------------------*/ + +class cellAspectRatio +: + public MeshObject<polyMesh, MoveableMeshObject, cellAspectRatio>, + public scalarField +{ + // Private Member Functions + + //- Construct aspect ratio + void calcAspectRatio(); + + +public: + + // Declare name of the class and its debug switch + TypeName("cellAspectRatio"); + + + // Constructors + + //- Construct given an polyMesh + explicit cellAspectRatio(const polyMesh&); + + + //- Destructor + virtual ~cellAspectRatio(); + + + // Member functions + + //- Ignore mesh motion for now + virtual bool movePoints() + { + return false; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvGeometryScheme/highAspectRatio/highAspectRatioFvGeometryScheme.C b/src/finiteVolume/fvMesh/fvGeometryScheme/highAspectRatio/highAspectRatioFvGeometryScheme.C new file mode 100644 index 0000000000000000000000000000000000000000..be94d91b8fdea1b016f9137ddb4cb11f218705c0 --- /dev/null +++ b/src/finiteVolume/fvMesh/fvGeometryScheme/highAspectRatio/highAspectRatioFvGeometryScheme.C @@ -0,0 +1,466 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 3 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, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "highAspectRatioFvGeometryScheme.H" +#include "addToRunTimeSelectionTable.H" +#include "fvMesh.H" +#include "syncTools.H" +#include "cellAspectRatio.H" +#include "emptyPolyPatch.H" +#include "wedgePolyPatch.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(highAspectRatioFvGeometryScheme, 0); + addToRunTimeSelectionTable + ( + fvGeometryScheme, + highAspectRatioFvGeometryScheme, + dict + ); +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +//void Foam::highAspectRatioFvGeometryScheme::cellClosedness +//( +// const vectorField& areas, +// const scalarField& vols, +// const tensorField& cellCoords, +// +// scalarField& aratio +//) const +//{ +// // From primitiveMeshTools::cellClosedness: +// // calculate aspect ratio in given direction +// const labelList& own = mesh_.faceOwner(); +// const labelList& nei = mesh_.faceNeighbour(); +// +// // Loop through cell faces and sum up the face area vectors for each cell. +// // This should be zero in all vector components +// +// vectorField sumMagClosed(mesh_.nCells(), Zero); +// +// forAll(own, facei) +// { +// // Add to owner +// vector& v = sumMagClosed[own[facei]]; +// v += cmptMag(cellCoords[own[facei]] & areas[facei]); +// } +// +// forAll(nei, facei) +// { +// // Subtract from neighbour +// vector& v = sumMagClosed[nei[facei]]; +// v += cmptMag(cellCoords[nei[facei]] & areas[facei]); +// } +// +// // Check the sums +// aratio.setSize(mesh_.nCells()); +// +// forAll(sumMagClosed, celli) +// { +// // Calculate the aspect ration as the maximum of Cartesian component +// // aspect ratio to the total area hydraulic area aspect ratio +// scalar minCmpt = VGREAT; +// scalar maxCmpt = -VGREAT; +// for (direction dir = 0; dir < vector::nComponents; dir++) +// { +// minCmpt = min(minCmpt, sumMagClosed[celli][dir]); +// maxCmpt = max(maxCmpt, sumMagClosed[celli][dir]); +// } +// +// scalar aspectRatio = maxCmpt/(minCmpt + ROOTVSMALL); +// const scalar v = max(ROOTVSMALL, vols[celli]); +// +// aspectRatio = max +// ( +// aspectRatio, +// 1.0/6.0*cmptSum(sumMagClosed[celli])/Foam::pow(v, 2.0/3.0) +// ); +// +// aratio[celli] = aspectRatio; +// } +//} +// +// +//void Foam::highAspectRatioFvGeometryScheme::cellDirections +//( +// tensorField& T, +// vectorField& lambda +//) const +//{ +// // Calculate principal directions in increasing order +// +// T.setSize(mesh_.nCells()); +// lambda.setSize(mesh_.nCells()); +// +// forAll(T, celli) +// { +// tensor J = Zero; +// { +// const List<tetIndices> cellTets +// ( +// polyMeshTetDecomposition::cellTetIndices +// ( +// mesh_, +// celli +// ) +// ); +// triFaceList faces(cellTets.size()); +// forAll(cellTets, cTI) +// { +// faces[cTI] = cellTets[cTI].faceTriIs(mesh_); +// } +// +// scalar m = 0.0; +// vector cM = Zero; +// J = Zero; +// momentOfInertia::massPropertiesShell +// ( +// mesh_.points(), +// faces, +// 1.0, +// m, +// cM, +// J +// ); +// } +// +// lambda[celli] = Foam::eigenValues(J); +// T[celli] = Foam::eigenVectors(J, lambda[celli]); +// } +//} + +void Foam::highAspectRatioFvGeometryScheme::calcAspectRatioWeights +( + scalarField& cellWeight, + scalarField& faceWeight +) const +{ + //scalarField aratio; + //{ + // tensorField principalDirections; + // vectorField lambdas; + // cellDirections(principalDirections, lambdas); + // + // cellClosedness + // ( + // mesh_.faceAreas(), + // mesh_.cellVolumes(), + // principalDirections, + // aratio + // ); + //} + const cellAspectRatio aratio(mesh_); + + // Weighting for correction + // - 0 if aratio < minAspect_ + // - 1 if aratio >= maxAspect_ + + scalar delta(maxAspect_-minAspect_); + if (delta < ROOTVSMALL) + { + delta = SMALL; + } + + cellWeight = + max + ( + min + ( + (aratio-minAspect_)/delta, + 1.0 + ), + 0.0 + ); + + faceWeight.setSize(mesh_.nFaces()); + + for (label facei = 0; facei < mesh_.nInternalFaces(); facei++) + { + const label own = mesh_.faceOwner()[facei]; + const label nei = mesh_.faceNeighbour()[facei]; + faceWeight[facei] = max(cellWeight[own], cellWeight[nei]); + } + scalarField nbrCellWeight; + syncTools::swapBoundaryCellList + ( + mesh_, + cellWeight, + nbrCellWeight + ); + for + ( + label facei = mesh_.nInternalFaces(); + facei < mesh_.nFaces(); + facei++ + ) + { + const label own = mesh_.faceOwner()[facei]; + const label bFacei = facei-mesh_.nInternalFaces(); + faceWeight[facei] = max(cellWeight[own], nbrCellWeight[bFacei]); + } +} + + +void Foam::highAspectRatioFvGeometryScheme::makeAverageCentres +( + const polyMesh& mesh, + const pointField& p, + const pointField& faceAreas, + const scalarField& magFaceAreas, + pointField& faceCentres, + pointField& cellCentres +) +{ + if (debug) + { + Pout<< "highAspectRatioFvGeometryScheme::makeAverageCentres() : " + << "calculating weighted average face/cell centre" << endl; + } + + typedef Vector<solveScalar> solveVector; + + const faceList& fs = mesh.faces(); + + // Start off from primitiveMesh faceCentres (preserved for triangles) + faceCentres.setSize(mesh.nFaces()); + + forAll(fs, facei) + { + const labelList& f = fs[facei]; + const label nPoints = f.size(); + + if (nPoints == 3) + { + faceCentres[facei] = (1.0/3.0)*(p[f[0]] + p[f[1]] + p[f[2]]); + } + else + { + solveScalar sumA = 0.0; + solveVector sumAc = Zero; + + for (label pi = 0; pi < nPoints; pi++) + { + const label nextPi(pi == nPoints-1 ? 0 : pi+1); + const solveVector nextPoint(p[f[nextPi]]); + const solveVector thisPoint(p[f[pi]]); + + const solveVector eMid = 0.5*(thisPoint+nextPoint); + const solveScalar a = mag(nextPoint-thisPoint); + + sumAc += a*eMid; + sumA += a; + } + // This is to deal with zero-area faces. Mark very small faces + // to be detected in e.g. processorPolyPatch. + if (sumA >= ROOTVSMALL) + { + faceCentres[facei] = sumAc/sumA; + } + else + { + // Unweighted average of points + sumAc = Zero; + for (label pi = 0; pi < nPoints; pi++) + { + sumAc += p[f[pi]]; + } + faceCentres[facei] = sumAc/nPoints; + } + } + } + + + cellCentres.setSize(mesh.nCells()); + cellCentres = Zero; + { + const labelList& own = mesh.faceOwner(); + const labelList& nei = mesh.faceNeighbour(); + + Field<solveScalar> cellWeights(mesh.nCells(), Zero); + for (label facei = 0; facei < mesh.nInternalFaces(); facei++) + { + const solveScalar magfA(magFaceAreas[facei]); + const solveVector weightedFc(magfA*faceCentres[facei]); + + // Accumulate area-weighted face-centre + cellCentres[own[facei]] += weightedFc; + cellCentres[nei[facei]] += weightedFc; + + // Accumulate weights + cellWeights[own[facei]] += magfA; + cellWeights[nei[facei]] += magfA; + } + + const polyBoundaryMesh& pbm = mesh.boundaryMesh(); + for (const polyPatch& pp : pbm) + { + if (!isA<emptyPolyPatch>(pp) && !isA<wedgePolyPatch>(pp)) + { + for + ( + label facei = pp.start(); + facei < pp.start()+pp.size(); + facei++ + ) + { + const solveScalar magfA(magFaceAreas[facei]); + const solveVector weightedFc(magfA*faceCentres[facei]); + + cellCentres[own[facei]] += weightedFc; + cellWeights[own[facei]] += magfA; + } + } + } + + forAll(cellCentres, celli) + { + if (mag(cellWeights[celli]) > VSMALL) + { + cellCentres[celli] /= cellWeights[celli]; + } + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::highAspectRatioFvGeometryScheme::highAspectRatioFvGeometryScheme +( + const fvMesh& mesh, + const dictionary& dict +) +: + basicFvGeometryScheme(mesh, dict), + minAspect_(dict.get<scalar>("minAspect")), + maxAspect_(dict.get<scalar>("maxAspect")) +{ + if (maxAspect_ < minAspect_) + { + FatalIOErrorInFunction(dict) + << "minAspect " << minAspect_ + << " has to be less than maxAspect " << maxAspect_ + << exit(FatalIOError); + } + if (minAspect_ < 0 || maxAspect_ < 0) + { + FatalIOErrorInFunction(dict) + << "Illegal aspect ratio : minAspect:" << minAspect_ + << " maxAspect:" << maxAspect_ + << exit(FatalIOError); + } + + // Force local calculation + movePoints(); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::highAspectRatioFvGeometryScheme::movePoints() +{ + if (debug) + { + Pout<< "highAspectRatioFvGeometryScheme::movePoints() : " + << "recalculating primitiveMesh centres" << endl; + } + + if + ( + !mesh_.hasCellCentres() + && !mesh_.hasFaceCentres() + && !mesh_.hasCellVolumes() + && !mesh_.hasFaceAreas() + ) + { + // Use lower level to calculate the geometry + const_cast<fvMesh&>(mesh_).primitiveMesh::updateGeom(); + + pointField avgFaceCentres; + pointField avgCellCentres; + makeAverageCentres + ( + mesh_, + mesh_.points(), + mesh_.faceAreas(), + mag(mesh_.faceAreas()), + avgFaceCentres, + avgCellCentres + ); + + + // Calculate aspectratio weights + // - 0 if aratio < minAspect_ + // - 1 if aratio >= maxAspect_ + scalarField cellWeight, faceWeight; + calcAspectRatioWeights(cellWeight, faceWeight); + + + // Weight with average ones + vectorField faceCentres + ( + (1.0-faceWeight)*mesh_.faceCentres() + + faceWeight*avgFaceCentres + ); + vectorField cellCentres + ( + (1.0-cellWeight)*mesh_.cellCentres() + + cellWeight*avgCellCentres + ); + + + if (debug) + { + Pout<< "highAspectRatioFvGeometryScheme::movePoints() :" + << " highAspectRatio weight" + << " max:" << gMax(cellWeight) << " min:" << gMin(cellWeight) + << " average:" << gAverage(cellWeight) << endl; + } + + vectorField faceAreas(mesh_.faceAreas()); + scalarField cellVolumes(mesh_.cellVolumes()); + + // Store on primitiveMesh + //const_cast<fvMesh&>(mesh_).clearGeom(); + const_cast<fvMesh&>(mesh_).primitiveMesh::resetGeometry + ( + std::move(faceCentres), + std::move(faceAreas), + std::move(cellCentres), + std::move(cellVolumes) + ); + } +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvGeometryScheme/highAspectRatio/highAspectRatioFvGeometryScheme.H b/src/finiteVolume/fvMesh/fvGeometryScheme/highAspectRatio/highAspectRatioFvGeometryScheme.H new file mode 100644 index 0000000000000000000000000000000000000000..1ed2164b4f01cb3c5a7a9090694928847a885e8c --- /dev/null +++ b/src/finiteVolume/fvMesh/fvGeometryScheme/highAspectRatio/highAspectRatioFvGeometryScheme.H @@ -0,0 +1,137 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 3 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, see <http://www.gnu.org/licenses/>. + +Class + Foam::highAspectRatioFvGeometryScheme + +Description + Geometry calculation scheme with automatic stabilisation for high-aspect + ratio cells. + +SourceFiles + highAspectRatioFvGeometryScheme.C + +\*---------------------------------------------------------------------------*/ + +#ifndef highAspectRatioFvGeometryScheme_H +#define highAspectRatioFvGeometryScheme_H + +#include "basicFvGeometryScheme.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class primitiveMesh; +class polyMesh; + +/*---------------------------------------------------------------------------*\ + Class highAspectRatioFvGeometryScheme Declaration +\*---------------------------------------------------------------------------*/ + +class highAspectRatioFvGeometryScheme +: + public basicFvGeometryScheme +{ +protected: + + const scalar minAspect_; + + const scalar maxAspect_; + + + // Protected Member Functions + + //- Calculate cell and face weight. Is 0 for cell < minAspect, 1 for + // cell > maxAspect + void calcAspectRatioWeights + ( + scalarField& cellWeight, + scalarField& faceWeight + ) const; + + //- Helper : calculate (weighted) average face and cell centres + static void makeAverageCentres + ( + const polyMesh& mesh, + const pointField& points, + const pointField& faceAreas, + const scalarField& magFaceAreas, + pointField& faceCentres, + pointField& cellCentres + ); + + +private: + + // Private Member Functions + + //- No copy construct + highAspectRatioFvGeometryScheme + ( + const highAspectRatioFvGeometryScheme& + ) = delete; + + //- No copy assignment + void operator=(const highAspectRatioFvGeometryScheme&) = delete; + + +public: + + //- Runtime type information + TypeName("highAspectRatio"); + + + // Constructors + + //- Construct from mesh + highAspectRatioFvGeometryScheme + ( + const fvMesh& mesh, + const dictionary& dict + ); + + + //- Destructor + virtual ~highAspectRatioFvGeometryScheme() = default; + + + // Member Functions + + //- Do what is necessary if the mesh has moved + virtual void movePoints(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvGeometryScheme/stabilised/stabilisedFvGeometryScheme.C b/src/finiteVolume/fvMesh/fvGeometryScheme/stabilised/stabilisedFvGeometryScheme.C new file mode 100644 index 0000000000000000000000000000000000000000..eaedbb3e47e628ca98d459816859fd229758572f --- /dev/null +++ b/src/finiteVolume/fvMesh/fvGeometryScheme/stabilised/stabilisedFvGeometryScheme.C @@ -0,0 +1,210 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 3 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, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "stabilisedFvGeometryScheme.H" +#include "addToRunTimeSelectionTable.H" +#include "fvMesh.H" +#include "PrecisionAdaptor.H" +#include "primitiveMeshTools.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(stabilisedFvGeometryScheme, 0); + addToRunTimeSelectionTable + ( + fvGeometryScheme, + stabilisedFvGeometryScheme, + dict + ); +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::stabilisedFvGeometryScheme::makeFaceCentresAndAreas +( + const polyMesh& mesh, + const pointField& p, + vectorField& fCtrs, + vectorField& fAreas +) +{ + const faceList& fs = mesh.faces(); + + forAll(fs, facei) + { + const labelList& f = fs[facei]; + label nPoints = f.size(); + + // If the face is a triangle, do a direct calculation for efficiency + // and to avoid round-off error-related problems + if (nPoints == 3) + { + fCtrs[facei] = (1.0/3.0)*(p[f[0]] + p[f[1]] + p[f[2]]); + fAreas[facei] = 0.5*((p[f[1]] - p[f[0]])^(p[f[2]] - p[f[0]])); + } + + // For more complex faces, decompose into triangles + else + { + typedef Vector<solveScalar> solveVector; + + // Compute an estimate of the centre as the average of the points + solveVector fCentre = p[f[0]]; + for (label pi = 1; pi < nPoints; pi++) + { + fCentre += solveVector(p[f[pi]]); + } + fCentre /= nPoints; + + // Compute the face area normal and unit normal by summing up the + // normals of the triangles formed by connecting each edge to the + // point average. + solveVector sumA = Zero; + for (label pi = 0; pi < nPoints; pi++) + { + const label nextPi(pi == nPoints-1 ? 0 : pi+1); + const solveVector nextPoint(p[f[nextPi]]); + const solveVector thisPoint(p[f[pi]]); + + const solveVector a = + (nextPoint - thisPoint)^(fCentre - thisPoint); + + sumA += a; + } + const solveVector sumAHat = normalised(sumA); + + // Compute the area-weighted sum of the triangle centres. Note use + // the triangle area projected in the direction of the face normal + // as the weight, *not* the triangle area magnitude. Only the + // former makes the calculation independent of the initial estimate. + solveScalar sumAn = 0.0; + solveVector sumAnc = Zero; + for (label pi = 0; pi < nPoints; pi++) + { + const label nextPi(pi == nPoints-1 ? 0 : pi+1); + const solveVector nextPoint(p[f[nextPi]]); + const solveVector thisPoint(p[f[pi]]); + + const solveVector c = thisPoint + nextPoint + fCentre; + const solveVector a = + (nextPoint - thisPoint)^(fCentre - thisPoint); + + const scalar an = a & sumAHat; + + sumAn += an; + sumAnc += an*c; + } + + // Complete calculating centres and areas. If the face is too small + // for the sums to be reliably divided then just set the centre to + // the initial estimate. + if (sumAn > ROOTVSMALL) + { + fCtrs[facei] = (1.0/3.0)*sumAnc/sumAn; + } + else + { + fCtrs[facei] = fCentre; + } + fAreas[facei] = 0.5*sumA; + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::stabilisedFvGeometryScheme::stabilisedFvGeometryScheme +( + const fvMesh& mesh, + const dictionary& dict +) +: + basicFvGeometryScheme(mesh, dict) +{ + // Force local calculation + movePoints(); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::stabilisedFvGeometryScheme::movePoints() +{ + if (debug) + { + Pout<< "stabilisedFvGeometryScheme::movePoints() : " + << "recalculating primitiveMesh centres" << endl; + } + + if + ( + !mesh_.hasCellCentres() + && !mesh_.hasFaceCentres() + && !mesh_.hasCellVolumes() + && !mesh_.hasFaceAreas() + ) + { + vectorField faceCentres(mesh_.nFaces()); + vectorField faceAreas(mesh_.nFaces()); + + makeFaceCentresAndAreas + ( + mesh_, + mesh_.points(), + faceCentres, + faceAreas + ); + + vectorField cellCentres(mesh_.nCells()); + scalarField cellVolumes(mesh_.nCells()); + + primitiveMeshTools::makeCellCentresAndVols + ( + mesh_, + faceCentres, + faceAreas, + cellCentres, + cellVolumes + ); + + const_cast<fvMesh&>(mesh_).primitiveMesh::resetGeometry + ( + std::move(faceCentres), + std::move(faceAreas), + std::move(cellCentres), + std::move(cellVolumes) + ); + } +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvGeometryScheme/stabilised/stabilisedFvGeometryScheme.H b/src/finiteVolume/fvMesh/fvGeometryScheme/stabilised/stabilisedFvGeometryScheme.H new file mode 100644 index 0000000000000000000000000000000000000000..c367ecf9b188cec160cece3f5cbcc5aa7ab84a7e --- /dev/null +++ b/src/finiteVolume/fvMesh/fvGeometryScheme/stabilised/stabilisedFvGeometryScheme.H @@ -0,0 +1,126 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 3 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, see <http://www.gnu.org/licenses/>. + +Class + Foam::stabilisedFvGeometryScheme + +Description + Geometry calculation scheme that implements face geometry calculation + using normal-component-of-area weighted triangle contributions. + + This implements the Foundation 'Corrected face-centre calculations' + as a separate geometry scheme. Only implements the primitiveMesh parts, + not the individual face calculation. + +SourceFiles + stabilisedFvGeometryScheme.C + +\*---------------------------------------------------------------------------*/ + +#ifndef stabilisedFvGeometryScheme_H +#define stabilisedFvGeometryScheme_H + +#include "basicFvGeometryScheme.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class primitiveMesh; +class polyMesh; + +/*---------------------------------------------------------------------------*\ + Class stabilisedFvGeometryScheme Declaration +\*---------------------------------------------------------------------------*/ + +class stabilisedFvGeometryScheme +: + public basicFvGeometryScheme +{ +protected: + + // Protected Member Functions + + //- Calculate face area and centre weighted using pyramid height + static void makeFaceCentresAndAreas + ( + const polyMesh& mesh, + const pointField& p, + vectorField& fCtrs, + vectorField& fAreas + ); + + +private: + + // Private Member Functions + + //- No copy construct + stabilisedFvGeometryScheme + ( + const stabilisedFvGeometryScheme& + ) = delete; + + //- No copy assignment + void operator=(const stabilisedFvGeometryScheme&) = delete; + + +public: + + //- Runtime type information + TypeName("stabilised"); + + + // Constructors + + //- Construct from mesh + stabilisedFvGeometryScheme + ( + const fvMesh& mesh, + const dictionary& dict + ); + + + //- Destructor + virtual ~stabilisedFvGeometryScheme() = default; + + + // Member Functions + + //- Do what is necessary if the mesh has moved + virtual void movePoints(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvMesh.C b/src/finiteVolume/fvMesh/fvMesh.C index e02ae63dccb3177dc8a6766dc2b9f2187453afe9..57de821d382fd4cf2b90e8f374a136726ef7c717 100644 --- a/src/finiteVolume/fvMesh/fvMesh.C +++ b/src/finiteVolume/fvMesh/fvMesh.C @@ -240,11 +240,11 @@ void Foam::fvMesh::clearOut() // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::fvMesh::fvMesh(const IOobject& io) +Foam::fvMesh::fvMesh(const IOobject& io, const bool doInit) : - polyMesh(io), - surfaceInterpolation(*this), + polyMesh(io, doInit), fvSchemes(static_cast<const objectRegistry&>(*this)), + surfaceInterpolation(*this), fvSolution(static_cast<const objectRegistry&>(*this)), data(static_cast<const objectRegistry&>(*this)), boundary_(*this, boundaryMesh()), @@ -261,6 +261,25 @@ Foam::fvMesh::fvMesh(const IOobject& io) { DebugInFunction << "Constructing fvMesh from IOobject" << endl; + if (doInit) + { + fvMesh::init(false); // do not initialise lower levels + } +} + + +bool Foam::fvMesh::init(const bool doInit) +{ + if (doInit) + { + // Construct basic geometry calculation engine. Note: do before + // doing anything with primitiveMesh::cellCentres etc. + (void)geometry(); + + // Intialise my data + polyMesh::init(doInit); + } + // Check the existence of the cell volumes and read if present // and set the storage of V00 if (fileHandler().isFile(time().timePath()/dbDir()/"V0")) @@ -322,6 +341,7 @@ Foam::fvMesh::fvMesh(const IOobject& io) moving(true); } + return false; } @@ -344,11 +364,11 @@ Foam::fvMesh::fvMesh std::move(allNeighbour), syncPar ), - surfaceInterpolation(*this), fvSchemes(static_cast<const objectRegistry&>(*this)), + surfaceInterpolation(*this), fvSolution(static_cast<const objectRegistry&>(*this)), data(static_cast<const objectRegistry&>(*this)), - boundary_(*this, boundaryMesh()), + boundary_(*this), lduPtr_(nullptr), curTimeIndex_(time().timeIndex()), VPtr_(nullptr), @@ -381,8 +401,8 @@ Foam::fvMesh::fvMesh std::move(cells), syncPar ), - surfaceInterpolation(*this), fvSchemes(static_cast<const objectRegistry&>(*this)), + surfaceInterpolation(*this), fvSolution(static_cast<const objectRegistry&>(*this)), data(static_cast<const objectRegistry&>(*this)), boundary_(*this), @@ -407,6 +427,108 @@ Foam::fvMesh::fvMesh(const IOobject& io, const zero, const bool syncPar) {} +Foam::fvMesh::fvMesh +( + const IOobject& io, + const fvMesh& baseMesh, + pointField&& points, + faceList&& faces, + labelList&& allOwner, + labelList&& allNeighbour, + const bool syncPar +) +: + polyMesh + ( + io, + std::move(points), + std::move(faces), + std::move(allOwner), + std::move(allNeighbour), + syncPar + ), + fvSchemes + ( + static_cast<const objectRegistry&>(*this), + static_cast<const fvSchemes&>(baseMesh) + ), + surfaceInterpolation(*this), + fvSolution + ( + static_cast<const objectRegistry&>(*this), + static_cast<const fvSolution&>(baseMesh) + ), + data + ( + static_cast<const objectRegistry&>(*this), + static_cast<const data&>(baseMesh) + ), + boundary_(*this), + lduPtr_(nullptr), + curTimeIndex_(time().timeIndex()), + VPtr_(nullptr), + V0Ptr_(nullptr), + V00Ptr_(nullptr), + SfPtr_(nullptr), + magSfPtr_(nullptr), + CPtr_(nullptr), + CfPtr_(nullptr), + phiPtr_(nullptr) +{ + DebugInFunction << "Constructing fvMesh as copy and primitives" << endl; +} + + +Foam::fvMesh::fvMesh +( + const IOobject& io, + const fvMesh& baseMesh, + pointField&& points, + faceList&& faces, + cellList&& cells, + const bool syncPar +) +: + polyMesh + ( + io, + std::move(points), + std::move(faces), + std::move(cells), + syncPar + ), + fvSchemes + ( + static_cast<const objectRegistry&>(*this), + static_cast<const fvSchemes&>(baseMesh) + ), + surfaceInterpolation(*this), + fvSolution + ( + static_cast<const objectRegistry&>(*this), + static_cast<const fvSolution&>(baseMesh) + ), + data + ( + static_cast<const objectRegistry&>(*this), + static_cast<const data&>(baseMesh) + ), + boundary_(*this), + lduPtr_(nullptr), + curTimeIndex_(time().timeIndex()), + VPtr_(nullptr), + V0Ptr_(nullptr), + V00Ptr_(nullptr), + SfPtr_(nullptr), + magSfPtr_(nullptr), + CPtr_(nullptr), + CfPtr_(nullptr), + phiPtr_(nullptr) +{ + DebugInFunction << "Constructing fvMesh as copy and primitives" << endl; +} + + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::fvMesh::~fvMesh() @@ -804,6 +926,13 @@ Foam::tmp<Foam::scalarField> Foam::fvMesh::movePoints(const pointField& p) } +void Foam::fvMesh::updateGeom() +{ + // Let surfaceInterpolation handle geometry calculation + surfaceInterpolation::updateGeom(); +} + + void Foam::fvMesh::updateMesh(const mapPolyMesh& mpm) { DebugInFunction << endl; diff --git a/src/finiteVolume/fvMesh/fvMesh.H b/src/finiteVolume/fvMesh/fvMesh.H index 0e35ef9f9d2a4da19d29e39bfedc28a33c41f9fb..728111bc241d3faedb6380a6b16f1dcbea43ac25 100644 --- a/src/finiteVolume/fvMesh/fvMesh.H +++ b/src/finiteVolume/fvMesh/fvMesh.H @@ -77,7 +77,6 @@ class volMesh; template<class Type> class fvMatrix; - /*---------------------------------------------------------------------------*\ Class fvMesh Declaration \*---------------------------------------------------------------------------*/ @@ -86,8 +85,8 @@ class fvMesh : public polyMesh, public lduMesh, - public surfaceInterpolation, public fvSchemes, + public surfaceInterpolation, // needs input from fvSchemes public fvSolution, public data { @@ -98,7 +97,6 @@ protected: //- Boundary mesh fvBoundaryMesh boundary_; - // Demand-driven data mutable fvMeshLduAddressing* lduPtr_; @@ -186,7 +184,7 @@ public: // Constructors //- Construct from IOobject - explicit fvMesh(const IOobject& io); + explicit fvMesh(const IOobject& io, const bool doInit=true); //- Construct from IOobject or as zero-sized mesh // Boundary is added using addFvPatches() member function @@ -215,6 +213,32 @@ public: const bool syncPar = true ); + //- Construct as copy (for dictionaries) and components without + // boundary. Boundary is added using addFvPatches() member function + fvMesh + ( + const IOobject& io, + const fvMesh& baseMesh, + pointField&& points, + faceList&& faces, + labelList&& allOwner, + labelList&& allNeighbour, + const bool syncPar = true + ); + + //- Construct as copy (for dictionaries) without boundary from cells + // rather than owner/neighbour. Boundary is added using addFvPatches() + // member function + fvMesh + ( + const IOobject& io, + const fvMesh& baseMesh, + pointField&& points, + faceList&& faces, + cellList&& cells, + const bool syncPar = true + ); + //- Destructor virtual ~fvMesh(); @@ -224,6 +248,9 @@ public: // Helpers + //- Initialise all non-demand-driven data + virtual bool init(const bool doInit); + //- Add boundary patches. Constructor helper void addFvPatches ( @@ -438,6 +465,10 @@ public: //- Move points, returns volumes swept by faces in motion virtual tmp<scalarField> movePoints(const pointField&); + //- Update all geometric data. This gets redirected up from + // primitiveMesh level + virtual void updateGeom(); + //- Map all fields in time using given map. virtual void mapFields(const mapPolyMesh& mpm); diff --git a/src/finiteVolume/fvMesh/fvPatches/fvPatch/fvPatch.H b/src/finiteVolume/fvMesh/fvPatches/fvPatch/fvPatch.H index 3a04adfb38f06e0dec75600fbe38a75b4d2082a9..92870d06b17aba590efd0e6abd0afee065c3aec3 100644 --- a/src/finiteVolume/fvMesh/fvPatches/fvPatch/fvPatch.H +++ b/src/finiteVolume/fvMesh/fvPatches/fvPatch/fvPatch.H @@ -74,7 +74,16 @@ class fvPatch const fvBoundaryMesh& boundaryMesh_; -protected: + // Private Member Functions + + //- No copy construct + fvPatch(const fvPatch&) = delete; + + //- No copy assignment + void operator=(const fvPatch&) = delete; + + +public: // Protected Member Functions @@ -96,11 +105,6 @@ protected: //- Correct patches after moving points virtual void movePoints(); - //- No copy construct - fvPatch(const fvPatch&) = delete; - - //- No copy assignment - void operator=(const fvPatch&) = delete; public: diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolation/surfaceInterpolation.C b/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolation/surfaceInterpolation.C index 7642933971866680ca7687b0ba82604db92cf956..e4f516980ea0b5357f59bc16c98e9cb3903177c8 100644 --- a/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolation/surfaceInterpolation.C +++ b/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolation/surfaceInterpolation.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2017 OpenCFD Ltd. + Copyright (C) 2017-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,11 +29,12 @@ Description \*---------------------------------------------------------------------------*/ +#include "surfaceInterpolation.H" #include "fvMesh.H" #include "volFields.H" #include "surfaceFields.H" -#include "demandDrivenData.H" #include "coupledFvPatch.H" +#include "basicFvGeometryScheme.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -47,10 +48,10 @@ namespace Foam void Foam::surfaceInterpolation::clearOut() { - deleteDemandDrivenData(weights_); - deleteDemandDrivenData(deltaCoeffs_); - deleteDemandDrivenData(nonOrthDeltaCoeffs_); - deleteDemandDrivenData(nonOrthCorrectionVectors_); + weights_.clear(); + deltaCoeffs_.clear(); + nonOrthDeltaCoeffs_.clear(); + nonOrthCorrectionVectors_.clear(); } @@ -76,358 +77,107 @@ Foam::surfaceInterpolation::~surfaceInterpolation() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -const Foam::surfaceScalarField& Foam::surfaceInterpolation::weights() const +const Foam::fvGeometryScheme& Foam::surfaceInterpolation::geometry() const { - if (!weights_) + if (!geometryPtr_.valid()) { - makeWeights(); + geometryPtr_ = fvGeometryScheme::New + ( + mesh_, + mesh_.schemesDict().subOrEmptyDict("geometry"), + basicFvGeometryScheme::typeName + ); } - return (*weights_); + return geometryPtr_(); } -const Foam::surfaceScalarField& Foam::surfaceInterpolation::deltaCoeffs() const +void Foam::surfaceInterpolation::geometry(tmp<fvGeometryScheme>& schemePtr) { - if (!deltaCoeffs_) - { - makeDeltaCoeffs(); - } - - return (*deltaCoeffs_); + geometryPtr_ = schemePtr; } -const Foam::surfaceScalarField& -Foam::surfaceInterpolation::nonOrthDeltaCoeffs() const +const Foam::surfaceScalarField& Foam::surfaceInterpolation::weights() const { - if (!nonOrthDeltaCoeffs_) + if (!weights_.valid()) { - makeNonOrthDeltaCoeffs(); + weights_.set(geometry().weights().ptr()); } - return (*nonOrthDeltaCoeffs_); + return weights_(); } -const Foam::surfaceVectorField& -Foam::surfaceInterpolation::nonOrthCorrectionVectors() const +const Foam::surfaceScalarField& Foam::surfaceInterpolation::deltaCoeffs() const { - if (!nonOrthCorrectionVectors_) + if (!deltaCoeffs_.valid()) { - makeNonOrthCorrectionVectors(); + deltaCoeffs_.set(geometry().deltaCoeffs().ptr()); } - return (*nonOrthCorrectionVectors_); + return deltaCoeffs_(); } -bool Foam::surfaceInterpolation::movePoints() -{ - deleteDemandDrivenData(weights_); - deleteDemandDrivenData(deltaCoeffs_); - deleteDemandDrivenData(nonOrthDeltaCoeffs_); - deleteDemandDrivenData(nonOrthCorrectionVectors_); - - return true; -} - - -void Foam::surfaceInterpolation::makeWeights() const +const Foam::surfaceScalarField& +Foam::surfaceInterpolation::nonOrthDeltaCoeffs() const { - if (debug) + if (!nonOrthDeltaCoeffs_.valid()) { - Pout<< "surfaceInterpolation::makeWeights() : " - << "Constructing weighting factors for face interpolation" - << endl; - } - - weights_ = new surfaceScalarField - ( - IOobject - ( - "weights", - mesh_.pointsInstance(), - mesh_, - IOobject::NO_READ, - IOobject::NO_WRITE, - false // Do not register - ), - mesh_, - dimless - ); - surfaceScalarField& weights = *weights_; - weights.setOriented(); - - // Set local references to mesh data - // Note that we should not use fvMesh sliced fields at this point yet - // since this causes a loop when generating weighting factors in - // coupledFvPatchField evaluation phase - const labelUList& owner = mesh_.owner(); - const labelUList& neighbour = mesh_.neighbour(); - - const vectorField& Cf = mesh_.faceCentres(); - const vectorField& C = mesh_.cellCentres(); - const vectorField& Sf = mesh_.faceAreas(); - - // ... and reference to the internal field of the weighting factors - scalarField& w = weights.primitiveFieldRef(); - forAll(owner, facei) - { - // Note: mag in the dot-product. - // For all valid meshes, the non-orthogonality will be less than - // 90 deg and the dot-product will be positive. For invalid - // meshes (d & s <= 0), this will stabilise the calculation - // but the result will be poor. - scalar SfdOwn = mag(Sf[facei] & (Cf[facei] - C[owner[facei]])); - scalar SfdNei = mag(Sf[facei] & (C[neighbour[facei]] - Cf[facei])); - w[facei] = SfdNei/(SfdOwn + SfdNei); + nonOrthDeltaCoeffs_.set(geometry().nonOrthDeltaCoeffs().ptr()); } - surfaceScalarField::Boundary& wBf = weights.boundaryFieldRef(); - - forAll(mesh_.boundary(), patchi) - { - mesh_.boundary()[patchi].makeWeights(wBf[patchi]); - } - - if (debug) - { - Pout<< "surfaceInterpolation::makeWeights() : " - << "Finished constructing weighting factors for face interpolation" - << endl; - } + return nonOrthDeltaCoeffs_(); } -void Foam::surfaceInterpolation::makeDeltaCoeffs() const +const Foam::surfaceVectorField& +Foam::surfaceInterpolation::nonOrthCorrectionVectors() const { - if (debug) + if (!nonOrthCorrectionVectors_.valid()) { - Pout<< "surfaceInterpolation::makeDeltaCoeffs() : " - << "Constructing differencing factors array for face gradient" - << endl; - } - - // Force the construction of the weighting factors - // needed to make sure deltaCoeffs are calculated for parallel runs. - weights(); - - deltaCoeffs_ = new surfaceScalarField - ( - IOobject + nonOrthCorrectionVectors_.set ( - "deltaCoeffs", - mesh_.pointsInstance(), - mesh_, - IOobject::NO_READ, - IOobject::NO_WRITE, - false // Do not register - ), - mesh_, - dimless/dimLength - ); - surfaceScalarField& deltaCoeffs = *deltaCoeffs_; - deltaCoeffs.setOriented(); - - - // Set local references to mesh data - const volVectorField& C = mesh_.C(); - const labelUList& owner = mesh_.owner(); - const labelUList& neighbour = mesh_.neighbour(); - - forAll(owner, facei) - { - deltaCoeffs[facei] = 1.0/mag(C[neighbour[facei]] - C[owner[facei]]); + geometry().nonOrthCorrectionVectors().ptr() + ); } - surfaceScalarField::Boundary& deltaCoeffsBf = - deltaCoeffs.boundaryFieldRef(); - - forAll(deltaCoeffsBf, patchi) - { - const fvPatch& p = mesh_.boundary()[patchi]; - deltaCoeffsBf[patchi] = 1.0/mag(p.delta()); - - // Optionally correct - p.makeDeltaCoeffs(deltaCoeffsBf[patchi]); - } + return nonOrthCorrectionVectors_(); } -void Foam::surfaceInterpolation::makeNonOrthDeltaCoeffs() const +bool Foam::surfaceInterpolation::movePoints() { if (debug) { - Pout<< "surfaceInterpolation::makeNonOrthDeltaCoeffs() : " - << "Constructing differencing factors array for face gradient" + Pout<< "surfaceInterpolation::movePoints() : " + << "Updating geometric properties using the fvGeometryScheme" << endl; } - // Force the construction of the weighting factors - // needed to make sure deltaCoeffs are calculated for parallel runs. - weights(); - - nonOrthDeltaCoeffs_ = new surfaceScalarField - ( - IOobject - ( - "nonOrthDeltaCoeffs", - mesh_.pointsInstance(), - mesh_, - IOobject::NO_READ, - IOobject::NO_WRITE, - false // Do not register - ), - mesh_, - dimless/dimLength - ); - surfaceScalarField& nonOrthDeltaCoeffs = *nonOrthDeltaCoeffs_; - nonOrthDeltaCoeffs.setOriented(); - - - // Set local references to mesh data - const volVectorField& C = mesh_.C(); - const labelUList& owner = mesh_.owner(); - const labelUList& neighbour = mesh_.neighbour(); - const surfaceVectorField& Sf = mesh_.Sf(); - const surfaceScalarField& magSf = mesh_.magSf(); - - forAll(owner, facei) - { - vector delta = C[neighbour[facei]] - C[owner[facei]]; - vector unitArea = Sf[facei]/magSf[facei]; + // Do any primitive geometry calculation + const_cast<fvGeometryScheme&>(geometry()).movePoints(); - // Standard cell-centre distance form - //NonOrthDeltaCoeffs[facei] = (unitArea & delta)/magSqr(delta); + weights_.clear(); + deltaCoeffs_.clear(); + nonOrthDeltaCoeffs_.clear(); + nonOrthCorrectionVectors_.clear(); - // Slightly under-relaxed form - //NonOrthDeltaCoeffs[facei] = 1.0/mag(delta); - - // More under-relaxed form - //NonOrthDeltaCoeffs[facei] = 1.0/(mag(unitArea & delta) + VSMALL); - - // Stabilised form for bad meshes - nonOrthDeltaCoeffs[facei] = 1.0/max(unitArea & delta, 0.05*mag(delta)); - } - - surfaceScalarField::Boundary& nonOrthDeltaCoeffsBf = - nonOrthDeltaCoeffs.boundaryFieldRef(); - - forAll(nonOrthDeltaCoeffsBf, patchi) - { - fvsPatchScalarField& patchDeltaCoeffs = nonOrthDeltaCoeffsBf[patchi]; - - const fvPatch& p = patchDeltaCoeffs.patch(); - - const vectorField patchDeltas(mesh_.boundary()[patchi].delta()); - - forAll(p, patchFacei) - { - vector unitArea = - Sf.boundaryField()[patchi][patchFacei] - /magSf.boundaryField()[patchi][patchFacei]; - - const vector& delta = patchDeltas[patchFacei]; - - patchDeltaCoeffs[patchFacei] = - 1.0/max(unitArea & delta, 0.05*mag(delta)); - } - - // Optionally correct - p.makeNonOrthoDeltaCoeffs(patchDeltaCoeffs); - } + return true; } -void Foam::surfaceInterpolation::makeNonOrthCorrectionVectors() const +void Foam::surfaceInterpolation::updateGeom() { if (debug) { - Pout<< "surfaceInterpolation::makeNonOrthCorrectionVectors() : " - << "Constructing non-orthogonal correction vectors" - << endl; - } - - nonOrthCorrectionVectors_ = new surfaceVectorField - ( - IOobject - ( - "nonOrthCorrectionVectors", - mesh_.pointsInstance(), - mesh_, - IOobject::NO_READ, - IOobject::NO_WRITE, - false // Do not register - ), - mesh_, - dimless - ); - surfaceVectorField& corrVecs = *nonOrthCorrectionVectors_; - corrVecs.setOriented(); - - // Set local references to mesh data - const volVectorField& C = mesh_.C(); - const labelUList& owner = mesh_.owner(); - const labelUList& neighbour = mesh_.neighbour(); - const surfaceVectorField& Sf = mesh_.Sf(); - const surfaceScalarField& magSf = mesh_.magSf(); - const surfaceScalarField& NonOrthDeltaCoeffs = nonOrthDeltaCoeffs(); - - forAll(owner, facei) - { - vector unitArea = Sf[facei]/magSf[facei]; - vector delta = C[neighbour[facei]] - C[owner[facei]]; - - corrVecs[facei] = unitArea - delta*NonOrthDeltaCoeffs[facei]; + Pout<< "surfaceInterpolation::updateGeom() : " + << "Updating geometric properties" << endl; } - // Boundary correction vectors set to zero for boundary patches - // and calculated consistently with internal corrections for - // coupled patches - - surfaceVectorField::Boundary& corrVecsBf = corrVecs.boundaryFieldRef(); - - forAll(corrVecsBf, patchi) - { - fvsPatchVectorField& patchCorrVecs = corrVecsBf[patchi]; - - const fvPatch& p = patchCorrVecs.patch(); - - if (!patchCorrVecs.coupled()) - { - patchCorrVecs = Zero; - } - else - { - const fvsPatchScalarField& patchNonOrthDeltaCoeffs = - NonOrthDeltaCoeffs.boundaryField()[patchi]; - - const vectorField patchDeltas(mesh_.boundary()[patchi].delta()); - - forAll(p, patchFacei) - { - vector unitArea = - Sf.boundaryField()[patchi][patchFacei] - /magSf.boundaryField()[patchi][patchFacei]; - - const vector& delta = patchDeltas[patchFacei]; - - patchCorrVecs[patchFacei] = - unitArea - delta*patchNonOrthDeltaCoeffs[patchFacei]; - } - } - - // Optionally correct - p.makeNonOrthoCorrVectors(patchCorrVecs); - } - - if (debug) - { - Pout<< "surfaceInterpolation::makeNonOrthCorrectionVectors() : " - << "Finished constructing non-orthogonal correction vectors" - << endl; - } + const_cast<fvGeometryScheme&>(geometry()).movePoints(); } diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolation/surfaceInterpolation.H b/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolation/surfaceInterpolation.H index e5776d74b2e7a9315f88c93d2db32cba39b21569..5f83411a19bc3e18c6d81ad26cbf26ea5f79b10f 100644 --- a/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolation/surfaceInterpolation.H +++ b/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolation/surfaceInterpolation.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -48,8 +49,11 @@ SourceFiles namespace Foam { +class fvMesh; +class fvGeometryScheme; + /*---------------------------------------------------------------------------*\ - Class surfaceInterpolation Declaration + Class surfaceInterpolation Declaration \*---------------------------------------------------------------------------*/ class surfaceInterpolation @@ -59,34 +63,23 @@ class surfaceInterpolation // Reference to fvMesh const fvMesh& mesh_; + // Demand-driven data + //- Geometry calculation + mutable tmp<fvGeometryScheme> geometryPtr_; + //- Linear difference weighting factors - mutable surfaceScalarField* weights_; + mutable autoPtr<surfaceScalarField> weights_; //- Cell-centre difference coefficients - mutable surfaceScalarField* deltaCoeffs_; + mutable autoPtr<surfaceScalarField> deltaCoeffs_; //- Non-orthogonal cell-centre difference coefficients - mutable surfaceScalarField* nonOrthDeltaCoeffs_; + mutable autoPtr<surfaceScalarField> nonOrthDeltaCoeffs_; //- Non-orthogonality correction vectors - mutable surfaceVectorField* nonOrthCorrectionVectors_; - - - // Private Member Functions - - //- Construct central-differencing weighting factors - void makeWeights() const; - - //- Construct face-gradient difference factors - void makeDeltaCoeffs() const; - - //- Construct face-gradient difference factors - void makeNonOrthDeltaCoeffs() const; - - //- Construct non-orthogonality correction vectors - void makeNonOrthCorrectionVectors() const; + mutable autoPtr<surfaceVectorField> nonOrthCorrectionVectors_; protected: @@ -112,26 +105,35 @@ public: //- Destructor - ~surfaceInterpolation(); + virtual ~surfaceInterpolation(); // Member functions + //- Return reference to geometry calculation scheme + virtual const fvGeometryScheme& geometry() const; + + //- Set geometry calculation scheme + void geometry(tmp<fvGeometryScheme>&); + //- Return reference to linear difference weighting factors - const surfaceScalarField& weights() const; + virtual const surfaceScalarField& weights() const; //- Return reference to cell-centre difference coefficients - const surfaceScalarField& deltaCoeffs() const; + virtual const surfaceScalarField& deltaCoeffs() const; //- Return reference to non-orthogonal cell-centre difference // coefficients - const surfaceScalarField& nonOrthDeltaCoeffs() const; + virtual const surfaceScalarField& nonOrthDeltaCoeffs() const; //- Return reference to non-orthogonality correction vectors - const surfaceVectorField& nonOrthCorrectionVectors() const; + virtual const surfaceVectorField& nonOrthCorrectionVectors() const; //- Do what is necessary if the mesh has moved - bool movePoints(); + virtual bool movePoints(); + + //- Update all geometric data + virtual void updateGeom(); }; diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/layerParameters/layerParameters.C b/src/mesh/snappyHexMesh/snappyHexMeshDriver/layerParameters/layerParameters.C index 6459337f47a3c0981e8657d1b30e5a60547a1c63..29dccf452532b733f73221f6a27fb835d126a049 100644 --- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/layerParameters/layerParameters.C +++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/layerParameters/layerParameters.C @@ -35,6 +35,20 @@ License // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // +const Foam::Enum +< + Foam::layerParameters::thicknessModelType +> +Foam::layerParameters::thicknessModelTypeNames_ +({ + { thicknessModelType::FIRST_AND_TOTAL, "firstAndOverall" }, + { thicknessModelType::FIRST_AND_EXPANSION, "firstAndExpansion" }, + { thicknessModelType::FINAL_AND_TOTAL, "finalAndOverall" }, + { thicknessModelType::FINAL_AND_EXPANSION, "finalAndExpansion" }, + { thicknessModelType::TOTAL_AND_EXPANSION, "overallAndExpansion" }, + { thicknessModelType::FIRST_AND_RELATIVE_FINAL, "firstAndRelativeFinal" }, +}); + const Foam::scalar Foam::layerParameters::defaultConcaveAngle = 90; @@ -44,7 +58,7 @@ Foam::scalar Foam::layerParameters::layerExpansionRatio ( const label n, const scalar totalOverFirst -) const +) { if (n <= 1) { @@ -66,11 +80,11 @@ Foam::scalar Foam::layerParameters::layerExpansionRatio if (totalOverFirst < n) { minR = 0.0; - maxR = pow(totalOverFirst/n, 1/(n-1)); + maxR = pow(totalOverFirst/n, scalar(1)/(n-1)); } else { - minR = pow(totalOverFirst/n, 1/(n-1)); + minR = pow(totalOverFirst/n, scalar(1)/(n-1)); maxR = totalOverFirst/(n - 1); } @@ -94,6 +108,253 @@ Foam::scalar Foam::layerParameters::layerExpansionRatio } +void Foam::layerParameters::readLayerParameters +( + const bool verbose, + const dictionary& dict, + const thicknessModelType& spec, + scalar& firstLayerThickness, + scalar& finalLayerThickness, + scalar& thickness, + scalar& expansionRatio +) +{ + // Now we have determined the layer-specification read the actual fields + switch (spec) + { + case FIRST_AND_TOTAL: + if (verbose) + { + Info<< "Layer specification as" << nl + << "- first layer thickness ('firstLayerThickness')" << nl + << "- overall thickness ('thickness')" << endl; + } + firstLayerThickness = readScalar + ( + dict.lookup("firstLayerThickness") + ); + thickness = readScalar(dict.lookup("thickness")); + break; + + case FIRST_AND_EXPANSION: + if (verbose) + { + Info<< "Layer specification as" << nl + << "- first layer thickness ('firstLayerThickness')" << nl + << "- expansion ratio ('expansionRatio')" << endl; + } + firstLayerThickness = readScalar + ( + dict.lookup("firstLayerThickness") + ); + expansionRatio = readScalar(dict.lookup("expansionRatio")); + break; + + case FINAL_AND_TOTAL: + if (verbose) + { + Info<< "Layer specification as" << nl + << "- final layer thickness ('finalLayerThickness')" << nl + << "- overall thickness ('thickness')" << endl; + } + finalLayerThickness = readScalar + ( + dict.lookup("finalLayerThickness") + ); + thickness = readScalar(dict.lookup("thickness")); + break; + + case FINAL_AND_EXPANSION: + if (verbose) + { + Info<< "Layer specification as" << nl + << "- final layer thickness ('finalLayerThickness')" << nl + << "- expansion ratio ('expansionRatio')" << endl; + } + finalLayerThickness = readScalar + ( + dict.lookup("finalLayerThickness") + ); + expansionRatio = readScalar(dict.lookup("expansionRatio")); + break; + + case TOTAL_AND_EXPANSION: + if (verbose) + { + Info<< "Layer specification as" << nl + << "- overall thickness ('thickness')" << nl + << "- expansion ratio ('expansionRatio')" << endl; + } + thickness = readScalar(dict.lookup("thickness")); + expansionRatio = readScalar(dict.lookup("expansionRatio")); + break; + + case FIRST_AND_RELATIVE_FINAL: + if (verbose) + { + Info<< "Layer specification as" << nl + << "- absolute first layer thickness" + << " ('firstLayerThickness')" + << nl + << "- and final layer thickness" + << " ('finalLayerThickness')" << nl + << endl; + } + firstLayerThickness = readScalar + ( + dict.lookup("firstLayerThickness") + ); + finalLayerThickness = readScalar + ( + dict.lookup("finalLayerThickness") + ); + break; + + default: + FatalIOErrorIn + ( + "layerParameters::layerParameters(..)", + dict + ) << "problem." << exit(FatalIOError); + break; + } +} + + +void Foam::layerParameters::calculateLayerParameters +( + const thicknessModelType& spec, + const label nLayers, + scalar& firstThickness, + scalar& finalThickness, + scalar& thickness, + scalar& expansionRatio +) +{ + // Calculate the non-read parameters + switch (spec) + { + case FIRST_AND_TOTAL: + expansionRatio = layerExpansionRatio + ( + spec, + nLayers, + firstThickness, + VGREAT, + thickness, //totalThickness + VGREAT //expansionRatio + ); + finalThickness = + thickness + *finalLayerThicknessRatio(nLayers, expansionRatio); + + break; + + case FIRST_AND_EXPANSION: + thickness = layerThickness + ( + spec, + nLayers, + firstThickness, //firstThickness + VGREAT, //finalThickness + VGREAT, //totalThickness + expansionRatio //expansionRatio + ); + finalThickness = + thickness + *finalLayerThicknessRatio(nLayers, expansionRatio); + + break; + + case FINAL_AND_TOTAL: + firstThickness = firstLayerThickness + ( + spec, + nLayers, + VGREAT, //firstThickness + VGREAT, //finalThickness + thickness, //totalThickness + VGREAT //expansionRatio + ); + expansionRatio = layerExpansionRatio + ( + spec, + nLayers, + VGREAT, //firstThickness + finalThickness, //finalThickness + thickness, //totalThickness + VGREAT //expansionRatio + ); + + break; + + case FINAL_AND_EXPANSION: + firstThickness = firstLayerThickness + ( + spec, + nLayers, + VGREAT, //firstThickness + finalThickness, //finalThickness + VGREAT, //thickness + expansionRatio //expansionRatio + ); + thickness = layerThickness + ( + spec, + nLayers, + VGREAT, //firstThickness + finalThickness, //finalThickness + VGREAT, //totalThickness + expansionRatio //expansionRatio + ); + break; + + case TOTAL_AND_EXPANSION: + firstThickness = firstLayerThickness + ( + spec, + nLayers, + VGREAT, //firstThickness + finalThickness, //finalThickness + VGREAT, //thickness + expansionRatio //expansionRatio + ); + finalThickness = + thickness + *finalLayerThicknessRatio(nLayers, expansionRatio); + + break; + + case FIRST_AND_RELATIVE_FINAL: + thickness = layerThickness + ( + spec, + nLayers, + firstThickness, //firstThickness + finalThickness, //finalThickness + VGREAT, //totalThickness + VGREAT //expansionRatio + ); + expansionRatio = layerExpansionRatio + ( + spec, + nLayers, + firstThickness, //firstThickness + finalThickness, //finalThickness + VGREAT, //totalThickness + VGREAT //expansionRatio + ); + + break; + + default: + FatalErrorInFunction << "Illegal thicknessModel " << spec + << exit(FatalError); + break; + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::layerParameters::layerParameters @@ -105,10 +366,13 @@ Foam::layerParameters::layerParameters : dict_(dict), dryRun_(dryRun), - relativeSizes_(meshRefinement::get<bool>(dict, "relativeSizes", dryRun)), - additionalReporting_(dict.getOrDefault("additionalReporting", false)), - layerSpec_(ILLEGAL), numLayers_(boundaryMesh.size(), -1), + relativeSizes_ + ( + boundaryMesh.size(), + meshRefinement::get<bool>(dict, "relativeSizes", dryRun) + ), + layerModels_(boundaryMesh.size(), FIRST_AND_TOTAL), firstLayerThickness_(boundaryMesh.size(), -123), finalLayerThickness_(boundaryMesh.size(), -123), thickness_(boundaryMesh.size(), -123), @@ -142,6 +406,7 @@ Foam::layerParameters::layerParameters ), nLayerIter_(meshRefinement::get<label>(dict, "nLayerIter", dryRun)), nRelaxedIter_(labelMax), + additionalReporting_(dict.getOrDefault("additionalReporting", false)), meshShrinker_ ( dict.getOrDefault @@ -153,100 +418,112 @@ Foam::layerParameters::layerParameters { // Detect layer specification mode - label nSpec = 0; - - bool haveFirst = dict.found("firstLayerThickness"); - if (haveFirst) - { - firstLayerThickness_ = scalarField - ( - boundaryMesh.size(), - dict.get<scalar>("firstLayerThickness") - ); - nSpec++; - } - bool haveFinal = dict.found("finalLayerThickness"); - if (haveFinal) + word spec; + if (dict.readIfPresent("thicknessModel", spec)) { - finalLayerThickness_ = scalarField - ( - boundaryMesh.size(), - dict.get<scalar>("finalLayerThickness") - ); - nSpec++; + layerModels_ = thicknessModelTypeNames_[spec]; } - bool haveTotal = dict.found("thickness"); - if (haveTotal) - { - thickness_ = scalarField - ( - boundaryMesh.size(), - dict.get<scalar>("thickness") - ); - nSpec++; - } - bool haveExp = dict.found("expansionRatio"); - if (haveExp) + else { - expansionRatio_ = scalarField - ( - boundaryMesh.size(), - dict.get<scalar>("expansionRatio") - ); - nSpec++; - } + // Count number of specifications + label nSpec = 0; + bool haveFirst = dict.found("firstLayerThickness"); + if (haveFirst) + { + nSpec++; + } + bool haveFinal = dict.found("finalLayerThickness"); + if (haveFinal) + { + nSpec++; + } + bool haveTotal = dict.found("thickness"); + if (haveTotal) + { + nSpec++; + } + bool haveExp = dict.found("expansionRatio"); + if (haveExp) + { + nSpec++; + } - if (haveFirst && haveTotal) - { - layerSpec_ = FIRST_AND_TOTAL; - Info<< "Layer thickness specified as first layer and overall thickness." - << endl; - } - else if (haveFirst && haveExp) - { - layerSpec_ = FIRST_AND_EXPANSION; - Info<< "Layer thickness specified as first layer and expansion ratio." - << endl; - } - else if (haveFinal && haveTotal) - { - layerSpec_ = FINAL_AND_TOTAL; - Info<< "Layer thickness specified as final layer and overall thickness." - << endl; - } - else if (haveFinal && haveExp) - { - layerSpec_ = FINAL_AND_EXPANSION; - Info<< "Layer thickness specified as final layer and expansion ratio." - << endl; - } - else if (haveTotal && haveExp) - { - layerSpec_ = TOTAL_AND_EXPANSION; - Info<< "Layer thickness specified as overall thickness" - << " and expansion ratio." << endl; + if (nSpec == 2 && haveFirst && haveTotal) + { + layerModels_ = FIRST_AND_TOTAL; + //Info<< "Layer thickness specified as first layer" + // << " and overall thickness." << endl; + } + else if (nSpec == 2 && haveFirst && haveExp) + { + layerModels_ = FIRST_AND_EXPANSION; + //Info<< "Layer thickness specified as first layer" + // << " and expansion ratio." << endl; + } + else if (nSpec == 2 && haveFinal && haveTotal) + { + layerModels_ = FINAL_AND_TOTAL; + //Info<< "Layer thickness specified as final layer" + // << " and overall thickness." << endl; + } + else if (nSpec == 2 && haveFinal && haveExp) + { + layerModels_ = FINAL_AND_EXPANSION; + //Info<< "Layer thickness specified as final layer" + // << " and expansion ratio." << endl; + } + else if (nSpec == 2 && haveTotal && haveExp) + { + layerModels_ = TOTAL_AND_EXPANSION; + //Info<< "Layer thickness specified as overall thickness" + // << " and expansion ratio." << endl; + } + else if (nSpec == 2 && haveFirst && haveFinal) + { + layerModels_ = FIRST_AND_RELATIVE_FINAL; + //Info<< "Layer thickness specified as absolute first and" + // << " relative final layer ratio." << endl; + } + else + { + FatalIOErrorInFunction(dict) + << "Over- or underspecified layer thickness." + << " Please specify" << nl + << " first layer thickness ('firstLayerThickness')" + << " and overall thickness ('thickness') or" << nl + << " first layer thickness ('firstLayerThickness')" + << " and expansion ratio ('expansionRatio') or" << nl + << " final layer thickness ('finalLayerThickness')" + << " and expansion ratio ('expansionRatio') or" << nl + << " final layer thickness ('finalLayerThickness')" + << " and overall thickness ('thickness') or" << nl + << " overall thickness ('thickness')" + << " and expansion ratio ('expansionRatio'" + << exit(FatalIOError); + } } - if (layerSpec_ == ILLEGAL || nSpec != 2) - { - FatalIOErrorInFunction(dict) - << "Over- or underspecified layer thickness." - << " Please specify" << nl - << " first layer thickness ('firstLayerThickness')" - << " and overall thickness ('thickness') or" << nl - << " first layer thickness ('firstLayerThickness')" - << " and expansion ratio ('expansionRatio') or" << nl - << " final layer thickness ('finalLayerThickness')" - << " and expansion ratio ('expansionRatio') or" << nl - << " final layer thickness ('finalLayerThickness')" - << " and overall thickness ('thickness') or" << nl - << " overall thickness ('thickness')" - << " and expansion ratio ('expansionRatio'" - << exit(FatalIOError); - } - + // Now we have determined the layer-specification read the actual fields + scalar firstThickness; + scalar finalThickness; + scalar thickness; + scalar expansionRatio; + readLayerParameters + ( + true, // verbose + dict, + layerModels_[0], // spec + firstThickness, + finalThickness, + thickness, + expansionRatio + ); + firstLayerThickness_ = firstThickness; + finalLayerThickness_ = finalThickness; + thickness_ = thickness; + expansionRatio_ = expansionRatio; dict.readIfPresent("nRelaxedIter", nRelaxedIter_); @@ -293,88 +570,147 @@ Foam::layerParameters::layerParameters numLayers_[patchi] = layerDict.get<label>("nSurfaceLayers"); - switch (layerSpec_) + word spec; + if (layerDict.readIfPresent("thicknessModel", spec)) + { + // If the thickness model is explicitly specified + // we want full specification of all parameters + layerModels_[patchi] = thicknessModelTypeNames_[spec]; + readLayerParameters + ( + false, // verbose + layerDict, + layerModels_[patchi], // spec + firstLayerThickness_[patchi], + finalLayerThickness_[patchi], + thickness_[patchi], + expansionRatio_[patchi] + ); + minThickness_[patchi] = readScalar + ( + layerDict.lookup("minThickness") + ); + } + else { - case FIRST_AND_TOTAL: - layerDict.readIfPresent - ( - "firstLayerThickness", - firstLayerThickness_[patchi] - ); - layerDict.readIfPresent - ( - "thickness", - thickness_[patchi] - ); - break; - - case FIRST_AND_EXPANSION: - layerDict.readIfPresent - ( - "firstLayerThickness", - firstLayerThickness_[patchi] - ); - layerDict.readIfPresent - ( - "expansionRatio", - expansionRatio_[patchi] - ); - break; - - case FINAL_AND_TOTAL: - layerDict.readIfPresent - ( - "finalLayerThickness", - finalLayerThickness_[patchi] - ); - layerDict.readIfPresent - ( - "thickness", - thickness_[patchi] - ); - break; - - case FINAL_AND_EXPANSION: - layerDict.readIfPresent - ( - "finalLayerThickness", - finalLayerThickness_[patchi] - ); - layerDict.readIfPresent - ( - "expansionRatio", - expansionRatio_[patchi] - ); - break; - - case TOTAL_AND_EXPANSION: - layerDict.readIfPresent - ( - "thickness", - thickness_[patchi] - ); - layerDict.readIfPresent - ( - "expansionRatio", - expansionRatio_[patchi] - ); - break; - - default: - FatalIOErrorInFunction(dict) - << "problem." << exit(FatalIOError); - break; + // Optional override of thickness parameters + switch (layerModels_[patchi]) + { + case FIRST_AND_TOTAL: + layerDict.readIfPresent + ( + "firstLayerThickness", + firstLayerThickness_[patchi] + ); + layerDict.readIfPresent + ( + "thickness", + thickness_[patchi] + ); + break; + + case FIRST_AND_EXPANSION: + layerDict.readIfPresent + ( + "firstLayerThickness", + firstLayerThickness_[patchi] + ); + layerDict.readIfPresent + ( + "expansionRatio", + expansionRatio_[patchi] + ); + break; + + case FINAL_AND_TOTAL: + layerDict.readIfPresent + ( + "finalLayerThickness", + finalLayerThickness_[patchi] + ); + layerDict.readIfPresent + ( + "thickness", + thickness_[patchi] + ); + break; + + case FINAL_AND_EXPANSION: + layerDict.readIfPresent + ( + "finalLayerThickness", + finalLayerThickness_[patchi] + ); + layerDict.readIfPresent + ( + "expansionRatio", + expansionRatio_[patchi] + ); + break; + + case TOTAL_AND_EXPANSION: + layerDict.readIfPresent + ( + "thickness", + thickness_[patchi] + ); + layerDict.readIfPresent + ( + "expansionRatio", + expansionRatio_[patchi] + ); + break; + + case FIRST_AND_RELATIVE_FINAL: + layerDict.readIfPresent + ( + "firstLayerThickness", + firstLayerThickness_[patchi] + ); + layerDict.readIfPresent + ( + "finalLayerThickness", + finalLayerThickness_[patchi] + ); + break; + + default: + FatalIOErrorInFunction(dict) + << "problem." << exit(FatalIOError); + break; + } + + layerDict.readIfPresent + ( + "minThickness", + minThickness_[patchi] + ); } layerDict.readIfPresent ( - "minThickness", - minThickness_[patchi] + "relativeSizes", + relativeSizes_[patchi] ); } } } } + + + forAll(numLayers_, patchi) + { + // Calculate the remaining parameters + calculateLayerParameters + ( + layerModels_[patchi], + numLayers_[patchi], + firstLayerThickness_[patchi], + finalLayerThickness_[patchi], + thickness_[patchi], + expansionRatio_[patchi] + ); + } } @@ -382,14 +718,15 @@ Foam::layerParameters::layerParameters Foam::scalar Foam::layerParameters::layerThickness ( + const thicknessModelType layerSpec, const label nLayers, - const scalar firstLayerThickess, - const scalar finalLayerThickess, + const scalar firstLayerThickness, + const scalar finalLayerThickness, const scalar totalThickness, const scalar expansionRatio -) const +) { - switch (layerSpec_) + switch (layerSpec) { case FIRST_AND_TOTAL: case FINAL_AND_TOTAL: @@ -403,11 +740,11 @@ Foam::scalar Foam::layerParameters::layerThickness { if (mag(expansionRatio-1) < SMALL) { - return firstLayerThickess * nLayers; + return firstLayerThickness * nLayers; } else { - return firstLayerThickess + return firstLayerThickness *(1.0 - pow(expansionRatio, nLayers)) /(1.0 - expansionRatio); } @@ -418,22 +755,54 @@ Foam::scalar Foam::layerParameters::layerThickness { if (mag(expansionRatio-1) < SMALL) { - return finalLayerThickess * nLayers; + return finalLayerThickness * nLayers; } else { scalar invExpansion = 1.0 / expansionRatio; - return finalLayerThickess + return finalLayerThickness *(1.0 - pow(invExpansion, nLayers)) /(1.0 - invExpansion); } } break; + case FIRST_AND_RELATIVE_FINAL: + { + if (mag(expansionRatio-1) < SMALL) + { + return firstLayerThickness * nLayers; + } + else + { + scalar ratio = layerExpansionRatio + ( + layerSpec, + nLayers, + firstLayerThickness, + finalLayerThickness, + totalThickness, + expansionRatio + ); + + if (mag(ratio-1) < SMALL) + { + return firstLayerThickness * nLayers; + } + else + { + return firstLayerThickness * + (1.0 - pow(ratio, nLayers)) + / (1.0 - ratio); + } + } + } + break; + default: { FatalErrorInFunction - << exit(FatalError); + << layerSpec << exit(FatalError); return -VGREAT; } } @@ -442,14 +811,15 @@ Foam::scalar Foam::layerParameters::layerThickness Foam::scalar Foam::layerParameters::layerExpansionRatio ( + const thicknessModelType layerSpec, const label nLayers, - const scalar firstLayerThickess, - const scalar finalLayerThickess, + const scalar firstLayerThickness, + const scalar finalLayerThickness, const scalar totalThickness, const scalar expansionRatio -) const +) { - switch (layerSpec_) + switch (layerSpec) { case FIRST_AND_EXPANSION: case FINAL_AND_EXPANSION: @@ -461,23 +831,58 @@ Foam::scalar Foam::layerParameters::layerExpansionRatio case FIRST_AND_TOTAL: { - return layerExpansionRatio - ( - nLayers, - totalThickness/firstLayerThickess - ); + if (firstLayerThickness < SMALL) + { + // Do what? + return 1; + } + else + { + return layerExpansionRatio + ( + nLayers, + totalThickness/firstLayerThickness + ); + } } break; case FINAL_AND_TOTAL: { - return - 1.0 - /layerExpansionRatio + if (finalLayerThickness < SMALL) + { + // Do what? + return 1; + } + else + { + return + 1.0 + / layerExpansionRatio + ( + nLayers, + totalThickness/finalLayerThickness + ); + } + } + break; + + case FIRST_AND_RELATIVE_FINAL: + { + if (firstLayerThickness < SMALL || nLayers <= 1) + { + return 1.0; + } + else + { + // Note: at this point the finalLayerThickness is already + // absolute + return pow ( - nLayers, - totalThickness/finalLayerThickess + finalLayerThickness/firstLayerThickness, + 1.0/(nLayers-1) ); + } } break; @@ -493,24 +898,34 @@ Foam::scalar Foam::layerParameters::layerExpansionRatio Foam::scalar Foam::layerParameters::firstLayerThickness ( + const thicknessModelType layerSpec, const label nLayers, - const scalar firstLayerThickess, - const scalar finalLayerThickess, + const scalar firstLayerThickness, + const scalar finalLayerThickness, const scalar totalThickness, const scalar expansionRatio -) const +) { - switch (layerSpec_) + switch (layerSpec) { case FIRST_AND_EXPANSION: case FIRST_AND_TOTAL: + case FIRST_AND_RELATIVE_FINAL: { - return firstLayerThickess; + return firstLayerThickness; } case FINAL_AND_EXPANSION: { - return finalLayerThickess*pow(1.0/expansionRatio, nLayers-1); + if (expansionRatio < SMALL) + { + // Do what? + return 0.0; + } + else + { + return finalLayerThickness*pow(1.0/expansionRatio, nLayers-1); + } } break; @@ -518,13 +933,14 @@ Foam::scalar Foam::layerParameters::firstLayerThickness { scalar r = layerExpansionRatio ( + layerSpec, nLayers, - firstLayerThickess, - finalLayerThickess, + firstLayerThickness, + finalLayerThickness, totalThickness, expansionRatio ); - return finalLayerThickess/pow(r, nLayers-1); + return finalLayerThickness/pow(r, nLayers-1); } break; @@ -554,7 +970,7 @@ Foam::scalar Foam::layerParameters::finalLayerThicknessRatio ( const label nLayers, const scalar expansionRatio -) const +) { if (nLayers > 0) { diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/layerParameters/layerParameters.H b/src/mesh/snappyHexMesh/snappyHexMeshDriver/layerParameters/layerParameters.H index 4bc2f1622fc7e0765bede0c81c3493f409e4b649..3c8778a6de9137fb619bf6a999913dcceb9d57d9 100644 --- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/layerParameters/layerParameters.H +++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/layerParameters/layerParameters.H @@ -41,6 +41,7 @@ SourceFiles #include "scalarField.H" #include "labelList.H" #include "Switch.H" +#include "Enum.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -67,14 +68,14 @@ public: // - final and total thickness specified // - final and expansion ratio specified // - total thickness and expansion ratio specified - enum layerSpecification + enum thicknessModelType { - ILLEGAL, FIRST_AND_TOTAL, FIRST_AND_EXPANSION, FINAL_AND_TOTAL, FINAL_AND_EXPANSION, - TOTAL_AND_EXPANSION + TOTAL_AND_EXPANSION, + FIRST_AND_RELATIVE_FINAL }; @@ -85,6 +86,9 @@ private: //- Default angle for faces to be concave static const scalar defaultConcaveAngle; + //- thicknessModelType names + static const Enum<thicknessModelType> thicknessModelTypeNames_; + // Private Data @@ -93,28 +97,25 @@ private: //- In dry-run mode? const bool dryRun_; - //- Are sizes relative to local cell size - bool relativeSizes_; - - //- Any additional reporting - bool additionalReporting_; - // Per patch (not region!) information - //- How thickness is specified. - layerSpecification layerSpec_; - //- How many layers to add. labelList numLayers_; - scalarField firstLayerThickness_; + //- Are sizes relative to local cell size + boolList relativeSizes_; - scalarField finalLayerThickness_; + //- How thickness is specified. + List<thicknessModelType> layerModels_; - scalarField thickness_; + scalarField firstLayerThickness_; - scalarField expansionRatio_; + scalarField finalLayerThickness_; + + scalarField thickness_; + + scalarField expansionRatio_; //- Minimum total thickness scalarField minThickness_; @@ -136,6 +137,9 @@ private: label nRelaxedIter_; + //- Any additional reporting + bool additionalReporting_; + word meshShrinker_; @@ -143,11 +147,33 @@ private: //- Calculate expansion ratio from overall size v.s. thickness of // first layer. - scalar layerExpansionRatio + static scalar layerExpansionRatio ( const label n, const scalar totalOverFirst - ) const; + ); + + //- Read parameters according to thickness model + static void readLayerParameters + ( + const bool verbose, + const dictionary&, + const thicknessModelType& spec, + scalar& firstLayerThickness, + scalar& finalLayerThickness, + scalar& thickness, + scalar& expansionRatio + ); + + void calculateLayerParameters + ( + const thicknessModelType& spec, + const label nLayers, + scalar& firstLayerThickness, + scalar& finalLayerThickness, + scalar& thickness, + scalar& expansionRatio + ); //- No copy construct layerParameters(const layerParameters&) = delete; @@ -191,15 +217,15 @@ public: //- Are size parameters relative to inner cell size or // absolute distances. - bool relativeSizes() const + const boolList& relativeSizes() const { return relativeSizes_; } - //- Any additional reporting requested? - bool additionalReporting() const + //- Specification of layer thickness + const List<thicknessModelType>& layerModels() const { - return additionalReporting_; + return layerModels_; } // Expansion factor for layer mesh @@ -296,6 +322,12 @@ public: return nBufferCellsNoExtrude_; } + //- Any additional reporting requested? + bool additionalReporting() const + { + return additionalReporting_; + } + //- Type of mesh shrinker const word& meshShrinker() const { @@ -306,45 +338,48 @@ public: // Helper //- Determine overall thickness. Uses two of the four parameters - // according to the layerSpecification - scalar layerThickness + // according to the thicknessModel + static scalar layerThickness ( + const thicknessModelType, const label nLayers, - const scalar firstLayerThickess, - const scalar finalLayerThickess, + const scalar firstLayerThickness, + const scalar finalLayerThickness, const scalar totalThickness, const scalar expansionRatio - ) const; + ); //- Determine expansion ratio. Uses two of the four parameters - // according to the layerSpecification - scalar layerExpansionRatio + // according to the thicknessModel + static scalar layerExpansionRatio ( + const thicknessModelType, const label nLayers, - const scalar firstLayerThickess, - const scalar finalLayerThickess, + const scalar firstLayerThickness, + const scalar finalLayerThickness, const scalar totalThickness, const scalar expansionRatio - ) const; + ); //- Determine first layer (near-wall) thickness. Uses two of the - // four parameters according to the layerSpecification - scalar firstLayerThickness + // four parameters according to the thicknessModel + static scalar firstLayerThickness ( + const thicknessModelType, const label nLayers, - const scalar firstLayerThickess, - const scalar finalLayerThickess, + const scalar firstLayerThickness, + const scalar finalLayerThickness, const scalar totalThickness, const scalar expansionRatio - ) const; + ); //- Determine ratio of final layer thickness to // overall layer thickness - scalar finalLayerThicknessRatio + static scalar finalLayerThicknessRatio ( const label nLayers, const scalar expansionRatio - ) const; + ); }; diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.C b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.C index c383960c0627b1d6317658c9c18525861359c937..bd65f209fd91496960d62e2708f5cf53017458b6 100644 --- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.C +++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.C @@ -820,6 +820,7 @@ void Foam::snappyLayerDriver::handleWarpedFaces ( const indirectPrimitivePatch& pp, const scalar faceRatio, + const boolList& relativeSizes, const scalar edge0Len, const labelList& cellLevel, pointField& patchDisp, @@ -828,6 +829,7 @@ void Foam::snappyLayerDriver::handleWarpedFaces ) const { const fvMesh& mesh = meshRefiner_.mesh(); + const polyBoundaryMesh& patches = mesh.boundaryMesh(); Info<< nl << "Handling cells with warped patch faces ..." << nl; @@ -838,16 +840,19 @@ void Foam::snappyLayerDriver::handleWarpedFaces forAll(pp, i) { const face& f = pp[i]; + label faceI = pp.addressing()[i]; + label patchI = patches.patchID()[faceI-mesh.nInternalFaces()]; - if (f.size() > 3) - { - label facei = pp.addressing()[i]; + // It is hard to calculate some length scale if not in relative + // mode so disable this check. - label ownLevel = cellLevel[mesh.faceOwner()[facei]]; + if (relativeSizes[patchI] && f.size() > 3) + { + label ownLevel = cellLevel[mesh.faceOwner()[faceI]]; scalar edgeLen = edge0Len/(1<<ownLevel); // Normal distance to face centre plane - const point& fc = mesh.faceCentres()[facei]; + const point& fc = mesh.faceCentres()[faceI]; const vector& fn = pp.faceNormals()[i]; scalarField vProj(f.size()); @@ -1412,10 +1417,14 @@ void Foam::snappyLayerDriver::calculateLayerThickness minThickness.setSize(pp.nPoints()); minThickness = GREAT; - forAll(patchIDs, i) - { - label patchi = patchIDs[i]; + thickness.setSize(pp.nPoints()); + thickness = GREAT; + expansionRatio.setSize(pp.nPoints()); + expansionRatio = GREAT; + + for (const label patchi : patchIDs) + { const labelList& meshPoints = patches[patchi].meshPoints(); forAll(meshPoints, patchPointi) @@ -1495,32 +1504,11 @@ void Foam::snappyLayerDriver::calculateLayerThickness // Now the thicknesses are set according to the minimum of connected // patches. + // Determine per point the max cell level of connected cells + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Rework relative thickness into absolute - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // by multiplying with the internal cell size. - - if (layerParams.relativeSizes()) + labelList maxPointLevel(pp.nPoints(), labelMin); { - if - ( - min(layerParams.minThickness()) < 0 - || max(layerParams.minThickness()) > 2 - ) - { - FatalErrorInFunction - << "Thickness should be factor of local undistorted cell size." - << " Valid values are [0..2]." << nl - << " minThickness:" << layerParams.minThickness() - << 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]]]; @@ -1541,45 +1529,150 @@ void Foam::snappyLayerDriver::calculateLayerThickness maxEqOp<label>(), labelMin // null value ); + } + + + // Rework relative thickness into absolute + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // by multiplying with the internal cell size. + // Note that we cannot loop over the patches since then points on + // multiple patches would get multiplied with edgeLen twice .. + { + // Multiplication factor for relative sizes + scalarField edgeLen(pp.nPoints(), GREAT); + + labelList spec(pp.nPoints(), layerParameters::FIRST_AND_TOTAL); + bitSet isRelativePoint(mesh.nPoints()); - forAll(maxPointLevel, pointi) + for (const label patchi : patchIDs) { - // Find undistorted edge size for this level. - scalar edgeLen = edge0Len/(1<<maxPointLevel[pointi]); - firstLayerThickness[pointi] *= edgeLen; - finalLayerThickness[pointi] *= edgeLen; - totalThickness[pointi] *= edgeLen; - minThickness[pointi] *= edgeLen; - } - } + const labelList& meshPoints = patches[patchi].meshPoints(); + const layerParameters::thicknessModelType patchSpec = + layerParams.layerModels()[patchi]; + const bool relSize = layerParams.relativeSizes()[patchi]; + for (const label meshPointi : meshPoints) + { + const label ppPointi = pp.meshPointMap()[meshPointi]; + // Note: who wins if different specs? - // Rework thickness parameters into overall thickness - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Calculate undistorted edge size for this level. + edgeLen[ppPointi] = min + ( + edgeLen[ppPointi], + edge0Len/(1<<maxPointLevel[ppPointi]) + ); + spec[ppPointi] = max(spec[ppPointi], patchSpec); + isRelativePoint[meshPointi] = + isRelativePoint[meshPointi] + || relSize; + } + } - forAll(firstLayerThickness, pointi) - { - thickness[pointi] = layerParams.layerThickness + syncTools::syncPointList ( - patchNLayers[pointi], - firstLayerThickness[pointi], - finalLayerThickness[pointi], - totalThickness[pointi], - expRatio[pointi] + mesh, + pp.meshPoints(), + edgeLen, + minEqOp<scalar>(), + GREAT // null value ); - - expansionRatio[pointi] = layerParams.layerExpansionRatio + syncTools::syncPointList ( - patchNLayers[pointi], - firstLayerThickness[pointi], - finalLayerThickness[pointi], - totalThickness[pointi], - expRatio[pointi] + mesh, + pp.meshPoints(), + spec, + maxEqOp<label>(), + label(layerParameters::FIRST_AND_TOTAL) // null value + ); + syncTools::syncPointList + ( + mesh, + isRelativePoint, + orEqOp<unsigned int>(), + 0 ); + + + + + forAll(pp.meshPoints(), pointi) + { + const label meshPointi = pp.meshPoints()[pointi]; + const layerParameters::thicknessModelType pointSpec = + static_cast<layerParameters::thicknessModelType>(spec[pointi]); + + if (pointSpec == layerParameters::FIRST_AND_RELATIVE_FINAL) + { + // This overrules the relative sizes flag for + // first (always absolute) and final (always relative) + finalLayerThickness[pointi] *= edgeLen[pointi]; + if (isRelativePoint[meshPointi]) + { + totalThickness[pointi] *= edgeLen[pointi]; + minThickness[pointi] *= edgeLen[pointi]; + } + } + else if (isRelativePoint[meshPointi]) + { + firstLayerThickness[pointi] *= edgeLen[pointi]; + finalLayerThickness[pointi] *= edgeLen[pointi]; + totalThickness[pointi] *= edgeLen[pointi]; + minThickness[pointi] *= edgeLen[pointi]; + } + + thickness[pointi] = min + ( + thickness[pointi], + layerParameters::layerThickness + ( + pointSpec, + patchNLayers[pointi], + firstLayerThickness[pointi], + finalLayerThickness[pointi], + totalThickness[pointi], + expRatio[pointi] + ) + ); + expansionRatio[pointi] = min + ( + expansionRatio[pointi], + layerParameters::layerExpansionRatio + ( + pointSpec, + patchNLayers[pointi], + firstLayerThickness[pointi], + finalLayerThickness[pointi], + totalThickness[pointi], + expRatio[pointi] + ) + ); + } } + // Synchronise the determined thicknes. Note that this should not be + // necessary since the inputs to the calls to layerThickness, + // layerExpansionRatio above are already parallel consistent + + syncTools::syncPointList + ( + mesh, + pp.meshPoints(), + thickness, + minEqOp<scalar>(), + GREAT // null value + ); + syncTools::syncPointList + ( + mesh, + pp.meshPoints(), + expansionRatio, + minEqOp<scalar>(), + GREAT // null value + ); + //Info<< "calculateLayerThickness : min:" << gMin(thickness) // << " max:" << gMax(thickness) << endl; @@ -1614,6 +1707,8 @@ void Foam::snappyLayerDriver::calculateLayerThickness label patchi = patchIDs[i]; const labelList& meshPoints = patches[patchi].meshPoints(); + const layerParameters::thicknessModelType spec = + layerParams.layerModels()[patchi]; scalar sumThickness = 0; scalar sumNearWallThickness = 0; @@ -1629,6 +1724,7 @@ void Foam::snappyLayerDriver::calculateLayerThickness sumThickness += thickness[ppPointi]; sumNearWallThickness += layerParams.firstLayerThickness ( + spec, patchNLayers[ppPointi], firstLayerThickness[ppPointi], finalLayerThickness[ppPointi], @@ -1806,6 +1902,8 @@ void Foam::snappyLayerDriver::getPatchDisplacement const indirectPrimitivePatch& pp, const scalarField& thickness, const scalarField& minThickness, + const scalarField& expansionRatio, + pointField& patchDisp, labelList& patchNLayers, List<extrudeMode>& extrudeStatus @@ -1836,6 +1934,98 @@ void Foam::snappyLayerDriver::getPatchDisplacement label nExtrudeRemove = 0; +////XXXXXXXX +// { +// OBJstream twoStr +// ( +// mesh.time().path() +// / "twoFacePoints_" +// + meshRefiner_.timeName() +// + ".obj" +// ); +// OBJstream multiStr +// ( +// mesh.time().path() +// / "multiFacePoints_" +// + meshRefiner_.timeName() +// + ".obj" +// ); +// Pout<< "Writing points inbetween two faces on same cell to " +// << twoStr.name() << endl; +// Pout<< "Writing points inbetween three or more faces on same cell to " +// << multiStr.name() << endl; +// // Check whether inbetween patch faces on same cell +// Map<labelList> cellToFaces; +// forAll(pointNormals, patchPointi) +// { +// const labelList& pFaces = pointFaces[patchPointi]; +// +// cellToFaces.clear(); +// forAll(pFaces, pFacei) +// { +// const label patchFacei = pFaces[pFacei]; +// const label meshFacei = pp.addressing()[patchFacei]; +// const label celli = mesh.faceOwner()[meshFacei]; +// Map<labelList>::iterator faceFnd = cellToFaces.find(celli); +// if (faceFnd.found()) +// { +// labelList& faces = faceFnd(); +// if (!faces.found(patchFacei)) +// { +// faces.append(patchFacei); +// } +// } +// else +// { +// cellToFaces.insert(celli, labelList(1, patchFacei)); +// } +// } +// +// forAllConstIter(Map<labelList>, cellToFaces, iter) +// { +// if (iter().size() == 2) +// { +// twoStr.write(pp.localPoints()[patchPointi]); +// } +// else if (iter().size() > 2) +// { +// multiStr.write(pp.localPoints()[patchPointi]); +// +// const scalar ratio = +// layerParameters::finalLayerThicknessRatio +// ( +// patchNLayers[patchPointi], +// expansionRatio[patchPointi] +// ); +// // Get thickness of cell next to bulk +// const vector finalDisp +// ( +// ratio*patchDisp[patchPointi] +// ); +// +// //Pout<< "** point:" << pp.localPoints()[patchPointi] +// // << " on cell:" << iter.key() +// // << " faces:" << iter() +// // << " displacement was:" << patchDisp[patchPointi] +// // << " ratio:" << ratio +// // << " finalDispl:" << finalDisp; +// +// // Half this thickness +// patchDisp[patchPointi] -= 0.8*finalDisp; +// +// //Pout<< " new displacement:" +// // << patchDisp[patchPointi] << endl; +// } +// } +// } +// +// Pout<< "Written " << multiStr.nVertices() +// << " points inbetween three or more faces on same cell to " +// << multiStr.name() << endl; +// } +////XXXXXXXX + + // Check if no extrude possible. forAll(pointNormals, patchPointi) { @@ -3724,7 +3914,7 @@ void Foam::snappyLayerDriver::addLayers // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // It is hard to calculate some length scale if not in relative // mode so disable this check. - if (layerParams.relativeSizes()) + if (!layerParams.relativeSizes().found(false)) { // Undistorted edge length const scalar edge0Len = @@ -3735,6 +3925,7 @@ void Foam::snappyLayerDriver::addLayers ( *pp, layerParams.maxFaceThicknessRatio(), + layerParams.relativeSizes(), edge0Len, cellLevel, @@ -3948,6 +4139,8 @@ void Foam::snappyLayerDriver::addLayers *pp, thickness, minThickness, + expansionRatio, + patchDisp, patchNLayers, extrudeStatus @@ -4077,7 +4270,7 @@ void Foam::snappyLayerDriver::addLayers forAll(nPatchPointLayers, i) { - scalar ratio = layerParams.finalLayerThicknessRatio + scalar ratio = layerParameters::finalLayerThicknessRatio ( nPatchPointLayers[i], expansionRatio[i] @@ -4133,7 +4326,7 @@ void Foam::snappyLayerDriver::addLayers mesh.name(), static_cast<polyMesh&>(mesh).instance(), mesh.time(), // register with runTime - IOobject::NO_READ, + IOobject::READ_IF_PRESENT, // read fv* if present static_cast<polyMesh&>(mesh).writeOpt() ), // io params from original mesh but new name mesh, // original mesh diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.H b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.H index 5d837c88c779d27df966bdabc547956ff91659c5..453cd5554b3af6342f6fd6a6514203ed4834b675 100644 --- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.H +++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.H @@ -235,6 +235,7 @@ private: ( const indirectPrimitivePatch& pp, const scalar faceRatio, + const boolList& relativeSizes, const scalar edge0Len, const labelList& cellLevel, pointField& patchDisp, @@ -328,6 +329,8 @@ private: const indirectPrimitivePatch& pp, const scalarField& thickness, const scalarField& minThickness, + const scalarField& expansionRatio, + pointField& patchDisp, labelList& patchNLayers, List<extrudeMode>& extrudeStatus diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.C b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.C index 374827f252ae295fa277fa2652ac0b238e1213a6..f15f7fb3c952d108ac372f419756f82fd3be8e6c 100644 --- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.C +++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.C @@ -1476,6 +1476,261 @@ Foam::label Foam::snappyRefineDriver::refinementInterfaceRefine return iter; } +bool Foam::snappyRefineDriver::usesHigherLevel +( + const labelUList& boundaryPointLevel, + const labelUList& f, + const label cLevel +) const +{ + for (const label pointi : f) + { + if (boundaryPointLevel[pointi] > cLevel) + { + return true; + } + } + return false; +} + + +Foam::label Foam::snappyRefineDriver::boundaryRefinementInterfaceRefine +( + const refinementParameters& refineParams, + const label maxIter +) +{ + if (refineParams.minRefineCells() == -1) + { + // Special setting to be able to restart shm on meshes with inconsistent + // cellLevel/pointLevel + return 0; + } + + if (dryRun_) + { + return 0; + } + + addProfiling(interface, "snappyHexMesh::refine::transition"); + const fvMesh& mesh = meshRefiner_.mesh(); + + label iter = 0; + + if (refineParams.interfaceRefine()) + { + for (;iter < maxIter; iter++) + { + Info<< nl + << "Boundary refinement iteration " << iter << nl + << "-------------------------------" << nl + << endl; + + const labelList& surfaceIndex = meshRefiner_.surfaceIndex(); + const hexRef8& cutter = meshRefiner_.meshCutter(); + const labelList& cellLevel = cutter.cellLevel(); + const faceList& faces = mesh.faces(); + const cellList& cells = mesh.cells(); + + + // Determine cells to refine + // ~~~~~~~~~~~~~~~~~~~~~~~~~ + + // Point/face on boundary + bitSet isBoundaryPoint(mesh.nPoints()); + bitSet isBoundaryFace(mesh.nFaces()); + { + forAll(surfaceIndex, facei) + { + if (surfaceIndex[facei] != -1) + { + isBoundaryFace.set(facei); + isBoundaryPoint.set(faces[facei]); + } + } + const labelList meshPatchIDs(meshRefiner_.meshedPatches()); + for (const label patchi : meshPatchIDs) + { + const polyPatch& pp = mesh.boundaryMesh()[patchi]; + forAll(pp, i) + { + isBoundaryFace.set(pp.start()+i); + isBoundaryPoint.set(pp[i]); + } + } + + syncTools::syncPointList + ( + mesh, + isBoundaryPoint, + orEqOp<unsigned int>(), + 0 + ); + } + + // Mark max boundary face level onto boundary points. All points + // not on a boundary face stay 0. + labelList boundaryPointLevel(mesh.nPoints(), 0); + { + forAll(cells, celli) + { + const cell& cFaces = cells[celli]; + const label cLevel = cellLevel[celli]; + + for (const label facei : cFaces) + { + if (isBoundaryFace(facei)) + { + const face& f = faces[facei]; + for (const label pointi : f) + { + boundaryPointLevel[pointi] = + max + ( + boundaryPointLevel[pointi], + cLevel + ); + } + } + } + } + + syncTools::syncPointList + ( + mesh, + boundaryPointLevel, + maxEqOp<label>(), + 0 + ); + } + + + // Detect cells with a point but not face on the boundary + labelList candidateCells; + { + const cellList& cells = mesh.cells(); + + cellSet candidateCellSet + ( + mesh, + "candidateCells", + cells.size()/100 + ); + + forAll(cells, celli) + { + const cell& cFaces = cells[celli]; + const label cLevel = cellLevel[celli]; + + bool isBoundaryCell = false; + for (const label facei : cFaces) + { + if (isBoundaryFace(facei)) + { + isBoundaryCell = true; + break; + } + } + + if (!isBoundaryCell) + { + for (const label facei : cFaces) + { + const face& f = mesh.faces()[facei]; + if (usesHigherLevel(boundaryPointLevel, f, cLevel)) + { + candidateCellSet.insert(celli); + break; + } + } + } + } + if (debug&meshRefinement::MESH) + { + Pout<< "Dumping " << candidateCellSet.size() + << " cells to cellSet candidateCellSet." << endl; + candidateCellSet.instance() = meshRefiner_.timeName(); + candidateCellSet.write(); + } + candidateCells = candidateCellSet.toc(); + } + + labelList cellsToRefine + ( + meshRefiner_.meshCutter().consistentRefinement + ( + candidateCells, + true + ) + ); + Info<< "Determined cells to refine in = " + << mesh.time().cpuTimeIncrement() << " s" << endl; + + + label nCellsToRefine = cellsToRefine.size(); + reduce(nCellsToRefine, sumOp<label>()); + + Info<< "Selected for refinement : " << nCellsToRefine + << " cells (out of " << mesh.globalData().nTotalCells() + << ')' << endl; + + // Stop when no cells to refine. After a few iterations check if too + // few cells + if + ( + nCellsToRefine == 0 + // || ( + // iter >= 1 + // && nCellsToRefine <= refineParams.minRefineCells() + // ) + ) + { + Info<< "Stopping refining since too few cells selected." + << nl << endl; + break; + } + + + if (debug) + { + const_cast<Time&>(mesh.time())++; + } + + + if + ( + returnReduce + ( + (mesh.nCells() >= refineParams.maxLocalCells()), + orOp<bool>() + ) + ) + { + meshRefiner_.balanceAndRefine + ( + "boundary cell refinement iteration " + name(iter), + decomposer_, + distributor_, + cellsToRefine, + refineParams.maxLoadUnbalance() + ); + } + else + { + meshRefiner_.refineAndBalance + ( + "boundary cell refinement iteration " + name(iter), + decomposer_, + distributor_, + cellsToRefine, + refineParams.maxLoadUnbalance() + ); + } + } + } + return iter; +} + void Foam::snappyRefineDriver::removeInsideCells ( @@ -3195,6 +3450,18 @@ void Foam::snappyRefineDriver::doRefine motionDict ); + + //- Commented out for now since causes zoning errors (sigsegv) on + // case with faceZones. TBD. + //// Refine any cells are point/edge connected to the boundary and have a + //// lower refinement level than the neighbouring cells + //boundaryRefinementInterfaceRefine + //( + // refineParams, + // 10 // maxIter + //); + + // Mesh is at its finest. Do optional zoning (cellZones and faceZones) wordPairHashTable zonesToFaceZone; zonify(refineParams, zonesToFaceZone); diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.H b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.H index 787190069e9f0dedbfb82f4f0ac928d3cf9d82a5..26f1a320cffe7e8d8f991ec49e0eadbead327df7 100644 --- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.H +++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.H @@ -165,6 +165,21 @@ class snappyRefineDriver const label maxIter ); + //- Helper: see if any element in f has higher level than cLevel + bool usesHigherLevel + ( + const labelUList& boundaryPointLevel, + const labelUList& f, + const label cLevel + ) const; + + //- Refine cells with a point/edge but not face on the boundary + label boundaryRefinementInterfaceRefine + ( + const refinementParameters& refineParams, + const label maxIter + ); + //- Remove all cells within intersected region void removeInsideCells ( diff --git a/src/meshTools/polyTopoChange/polyTopoChange.H b/src/meshTools/polyTopoChange/polyTopoChange.H index 613f6d398f3bafb16e051d0ca40b2d44c46da63d..00fd3603b3ec65586d574ea609c2469f648ec1f2 100644 --- a/src/meshTools/polyTopoChange/polyTopoChange.H +++ b/src/meshTools/polyTopoChange/polyTopoChange.H @@ -617,7 +617,8 @@ public: const bool orderPoints = false ); - //- Create new mesh with old mesh patches + //- Create new mesh with old mesh patches. Additional dictionaries + // (fv* etc) read according to IO flags template<class Type> autoPtr<mapPolyMesh> makeMesh ( diff --git a/src/meshTools/polyTopoChange/polyTopoChangeTemplates.C b/src/meshTools/polyTopoChange/polyTopoChangeTemplates.C index 9989d54f2af5bafd9b9ac471ad152255ac66f1c7..8f02476777549b578335b1ada263ffa5d2143d55 100644 --- a/src/meshTools/polyTopoChange/polyTopoChangeTemplates.C +++ b/src/meshTools/polyTopoChange/polyTopoChangeTemplates.C @@ -182,14 +182,14 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh // Create the mesh // ~~~~~~~~~~~~~~~ - IOobject noReadIO(io); - noReadIO.readOpt() = IOobject::NO_READ; - noReadIO.writeOpt() = IOobject::AUTO_WRITE; + //IOobject noReadIO(io); + //noReadIO.readOpt() = IOobject::NO_READ; + //noReadIO.writeOpt() = IOobject::AUTO_WRITE; newMeshPtr.reset ( new Type ( - noReadIO, + io, //noReadIO std::move(newPoints), std::move(faces_), std::move(faceOwner_), diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/Allclean b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/Allclean new file mode 100755 index 0000000000000000000000000000000000000000..1e0a8525559d9ac73e3009393aeaec0be4836929 --- /dev/null +++ b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/Allclean @@ -0,0 +1,9 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions +#------------------------------------------------------------------------------ + +cleanCase0 +rm -rf constant/extendedFeatureEdgeMesh + +#------------------------------------------------------------------------------ diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/Allrun b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/Allrun new file mode 100755 index 0000000000000000000000000000000000000000..539592d552178414db89032a29ed45056079ae20 --- /dev/null +++ b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/Allrun @@ -0,0 +1,22 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions +#------------------------------------------------------------------------------ + +runApplication blockMesh +runApplication surfaceFeatureExtract + +mkdir -p 0 + +# Run with basic +foamDictionary -entry geometry.type -set basic system/fvSchemes +runApplication -s basic snappyHexMesh +runApplication -s basic checkMesh -writeAllFields +foamListTimes -rm + +# Run with highAspectRatio +foamDictionary -entry geometry.type -set highAspectRatio system/fvSchemes +runApplication -s highAspectRatio snappyHexMesh +runApplication -s highAspectRatio checkMesh -writeAllFields + +#------------------------------------------------------------------------------ diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/transportProperties b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/transportProperties new file mode 100644 index 0000000000000000000000000000000000000000..60041417e7ace7e44613ec90089a1ff649222aef --- /dev/null +++ b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/transportProperties @@ -0,0 +1,32 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object transportProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Air temperature at standard atmospheric pressure = 540 R = 300 K +// See README.md +// c = 347.336 [m/s] +// Ma = UInf/c = 0.15 +// UInf = 52.1004 [m/s] +// ReChord = 6e6 (per chord) +// Chord = 1 [m] +// ReChord = UInf*Chord/nuFluid +// nuFluid = UInf*Chord/ReChord = 8.6834e-06 [m2/s] + +transportModel Newtonian; + +nu 8.6834e-06; + + +// ************************************************************************* // diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/triSurface/aerofoil.curvature b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/triSurface/aerofoil.curvature new file mode 100644 index 0000000000000000000000000000000000000000..e2fa245cdcd9bcdbaa872a00bcbbd7c2e46e0bb3 Binary files /dev/null and b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/triSurface/aerofoil.curvature differ diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/triSurface/aerofoil.eMesh b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/triSurface/aerofoil.eMesh new file mode 100644 index 0000000000000000000000000000000000000000..bf37d53d469ad9eae98e770a4cc51a0fe69f74d8 Binary files /dev/null and b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/triSurface/aerofoil.eMesh differ diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/triSurface/aerofoil.stl b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/triSurface/aerofoil.stl new file mode 100644 index 0000000000000000000000000000000000000000..0a53c45b7737a0e2513ebdb414da22765ffb1615 --- /dev/null +++ b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/triSurface/aerofoil.stl @@ -0,0 +1,3586 @@ +solid PART_3 + facet normal 1.611197192e-01 0.000000000e+00 -9.869348692e-01 + outer loop + vertex 9.838551561e-02 0.000000000e+00 4.628967360e-02 + vertex 1.063121234e-01 -1.000000000e+00 4.758371321e-02 + vertex 9.838551561e-02 -1.000000000e+00 4.628967360e-02 + endloop + endfacet + facet normal 1.741405608e-01 0.000000000e+00 -9.847208056e-01 + outer loop + vertex 9.092487459e-02 0.000000000e+00 4.497031464e-02 + vertex 9.838551561e-02 0.000000000e+00 4.628967360e-02 + vertex 9.838551561e-02 -1.000000000e+00 4.628967360e-02 + endloop + endfacet + facet normal 1.611197192e-01 0.000000000e+00 -9.869348692e-01 + outer loop + vertex 9.838551561e-02 0.000000000e+00 4.628967360e-02 + vertex 1.063121234e-01 0.000000000e+00 4.758371321e-02 + vertex 1.063121234e-01 -1.000000000e+00 4.758371321e-02 + endloop + endfacet + facet normal 1.741405608e-01 0.000000000e+00 -9.847208056e-01 + outer loop + vertex 9.092487459e-02 0.000000000e+00 4.497031464e-02 + vertex 9.838551561e-02 -1.000000000e+00 4.628967360e-02 + vertex 9.092487459e-02 -1.000000000e+00 4.497031464e-02 + endloop + endfacet + facet normal 1.485035906e-01 0.000000000e+00 -9.889118685e-01 + outer loop + vertex 1.063121234e-01 0.000000000e+00 4.758371321e-02 + vertex 1.147220645e-01 -1.000000000e+00 4.884662297e-02 + vertex 1.063121234e-01 -1.000000000e+00 4.758371321e-02 + endloop + endfacet + facet normal 1.875881539e-01 0.000000000e+00 -9.822477714e-01 + outer loop + vertex 8.391230599e-02 0.000000000e+00 4.363106518e-02 + vertex 9.092487459e-02 0.000000000e+00 4.497031464e-02 + vertex 9.092487459e-02 -1.000000000e+00 4.497031464e-02 + endloop + endfacet + facet normal 1.485035906e-01 0.000000000e+00 -9.889118685e-01 + outer loop + vertex 1.063121234e-01 0.000000000e+00 4.758371321e-02 + vertex 1.147220645e-01 0.000000000e+00 4.884662297e-02 + vertex 1.147220645e-01 -1.000000000e+00 4.884662297e-02 + endloop + endfacet + facet normal 1.875881539e-01 0.000000000e+00 -9.822477714e-01 + outer loop + vertex 8.391230599e-02 0.000000000e+00 4.363106518e-02 + vertex 9.092487459e-02 -1.000000000e+00 4.497031464e-02 + vertex 8.391230599e-02 -1.000000000e+00 4.363106518e-02 + endloop + endfacet + facet normal 1.362723604e-01 0.000000000e+00 -9.906714106e-01 + outer loop + vertex 1.147220645e-01 0.000000000e+00 4.884662297e-02 + vertex 1.236319622e-01 -1.000000000e+00 5.007222894e-02 + vertex 1.147220645e-01 -1.000000000e+00 4.884662297e-02 + endloop + endfacet + facet normal 2.014869252e-01 0.000000000e+00 -9.794912041e-01 + outer loop + vertex 7.732958127e-02 0.000000000e+00 4.227696118e-02 + vertex 8.391230599e-02 0.000000000e+00 4.363106518e-02 + vertex 8.391230599e-02 -1.000000000e+00 4.363106518e-02 + endloop + endfacet + facet normal 1.362723604e-01 0.000000000e+00 -9.906714106e-01 + outer loop + vertex 1.147220645e-01 0.000000000e+00 4.884662297e-02 + vertex 1.236319622e-01 0.000000000e+00 5.007222894e-02 + vertex 1.236319622e-01 -1.000000000e+00 5.007222894e-02 + endloop + endfacet + facet normal 2.014869252e-01 0.000000000e+00 -9.794912041e-01 + outer loop + vertex 7.732958127e-02 0.000000000e+00 4.227696118e-02 + vertex 8.391230599e-02 -1.000000000e+00 4.363106518e-02 + vertex 7.732958127e-02 -1.000000000e+00 4.227696118e-02 + endloop + endfacet + facet normal 1.244087695e-01 0.000000000e+00 -9.922310508e-01 + outer loop + vertex 1.236319622e-01 0.000000000e+00 5.007222894e-02 + vertex 1.330574640e-01 -1.000000000e+00 5.125402534e-02 + vertex 1.236319622e-01 -1.000000000e+00 5.007222894e-02 + endloop + endfacet + facet normal 2.158634372e-01 0.000000000e+00 -9.764235641e-01 + outer loop + vertex 7.115831020e-02 0.000000000e+00 4.091264365e-02 + vertex 7.732958127e-02 0.000000000e+00 4.227696118e-02 + vertex 7.732958127e-02 -1.000000000e+00 4.227696118e-02 + endloop + endfacet + facet normal 1.244087695e-01 0.000000000e+00 -9.922310508e-01 + outer loop + vertex 1.236319622e-01 0.000000000e+00 5.007222894e-02 + vertex 1.330574640e-01 0.000000000e+00 5.125402534e-02 + vertex 1.330574640e-01 -1.000000000e+00 5.125402534e-02 + endloop + endfacet + facet normal 2.158634372e-01 0.000000000e+00 -9.764235641e-01 + outer loop + vertex 7.115831020e-02 0.000000000e+00 4.091264365e-02 + vertex 7.732958127e-02 -1.000000000e+00 4.227696118e-02 + vertex 7.115831020e-02 -1.000000000e+00 4.091264365e-02 + endloop + endfacet + facet normal 1.128977803e-01 0.000000000e+00 -9.936066079e-01 + outer loop + vertex 1.330574640e-01 0.000000000e+00 5.125402534e-02 + vertex 1.430129884e-01 -1.000000000e+00 5.238521408e-02 + vertex 1.330574640e-01 -1.000000000e+00 5.125402534e-02 + endloop + endfacet + facet normal 2.307462575e-01 0.000000000e+00 -9.730139591e-01 + outer loop + vertex 6.538009589e-02 0.000000000e+00 3.954236390e-02 + vertex 7.115831020e-02 0.000000000e+00 4.091264365e-02 + vertex 7.115831020e-02 -1.000000000e+00 4.091264365e-02 + endloop + endfacet + facet normal 1.128977803e-01 0.000000000e+00 -9.936066079e-01 + outer loop + vertex 1.330574640e-01 0.000000000e+00 5.125402534e-02 + vertex 1.430129884e-01 0.000000000e+00 5.238521408e-02 + vertex 1.430129884e-01 -1.000000000e+00 5.238521408e-02 + endloop + endfacet + facet normal 2.307462575e-01 0.000000000e+00 -9.730139591e-01 + outer loop + vertex 6.538009589e-02 0.000000000e+00 3.954236390e-02 + vertex 7.115831020e-02 -1.000000000e+00 4.091264365e-02 + vertex 6.538009589e-02 -1.000000000e+00 3.954236390e-02 + endloop + endfacet + facet normal 1.017268987e-01 0.000000000e+00 -9.948123633e-01 + outer loop + vertex 1.430129884e-01 0.000000000e+00 5.238521408e-02 + vertex 1.535114574e-01 -1.000000000e+00 5.345875993e-02 + vertex 1.430129884e-01 -1.000000000e+00 5.238521408e-02 + endloop + endfacet + facet normal 2.461659993e-01 0.000000000e+00 -9.692276826e-01 + outer loop + vertex 5.997667081e-02 0.000000000e+00 3.816999334e-02 + vertex 6.538009589e-02 0.000000000e+00 3.954236390e-02 + vertex 6.538009589e-02 -1.000000000e+00 3.954236390e-02 + endloop + endfacet + facet normal 1.017268987e-01 0.000000000e+00 -9.948123633e-01 + outer loop + vertex 1.430129884e-01 0.000000000e+00 5.238521408e-02 + vertex 1.535114574e-01 0.000000000e+00 5.345875993e-02 + vertex 1.535114574e-01 -1.000000000e+00 5.345875993e-02 + endloop + endfacet + facet normal 2.461659993e-01 0.000000000e+00 -9.692276826e-01 + outer loop + vertex 5.997667081e-02 0.000000000e+00 3.816999334e-02 + vertex 6.538009589e-02 -1.000000000e+00 3.954236390e-02 + vertex 5.997667081e-02 -1.000000000e+00 3.816999334e-02 + endloop + endfacet + facet normal 9.088575017e-02 0.000000000e+00 -9.958613259e-01 + outer loop + vertex 1.535114574e-01 0.000000000e+00 5.345875993e-02 + vertex 1.645640139e-01 -1.000000000e+00 5.446745448e-02 + vertex 1.535114574e-01 -1.000000000e+00 5.345875993e-02 + endloop + endfacet + facet normal 2.621544324e-01 0.000000000e+00 -9.650259341e-01 + outer loop + vertex 5.493000570e-02 0.000000000e+00 3.679903989e-02 + vertex 5.997667081e-02 0.000000000e+00 3.816999334e-02 + vertex 5.997667081e-02 -1.000000000e+00 3.816999334e-02 + endloop + endfacet + facet normal 9.088575017e-02 0.000000000e+00 -9.958613259e-01 + outer loop + vertex 1.535114574e-01 0.000000000e+00 5.345875993e-02 + vertex 1.645640139e-01 0.000000000e+00 5.446745448e-02 + vertex 1.645640139e-01 -1.000000000e+00 5.446745448e-02 + endloop + endfacet + facet normal 2.621544324e-01 0.000000000e+00 -9.650259341e-01 + outer loop + vertex 5.493000570e-02 0.000000000e+00 3.679903989e-02 + vertex 5.997667081e-02 -1.000000000e+00 3.816999334e-02 + vertex 5.493000570e-02 -1.000000000e+00 3.679903989e-02 + endloop + endfacet + facet normal 8.036637189e-02 0.000000000e+00 -9.967653918e-01 + outer loop + vertex 1.645640139e-01 0.000000000e+00 5.446745448e-02 + vertex 1.761797308e-01 -1.000000000e+00 5.540399685e-02 + vertex 1.645640139e-01 -1.000000000e+00 5.446745448e-02 + endloop + endfacet + facet normal 2.787448045e-01 0.000000000e+00 -9.603652087e-01 + outer loop + vertex 5.022241269e-02 0.000000000e+00 3.543266689e-02 + vertex 5.493000570e-02 0.000000000e+00 3.679903989e-02 + vertex 5.493000570e-02 -1.000000000e+00 3.679903989e-02 + endloop + endfacet + facet normal 8.036637189e-02 0.000000000e+00 -9.967653918e-01 + outer loop + vertex 1.645640139e-01 0.000000000e+00 5.446745448e-02 + vertex 1.761797308e-01 0.000000000e+00 5.540399685e-02 + vertex 1.761797308e-01 -1.000000000e+00 5.540399685e-02 + endloop + endfacet + facet normal 2.787448045e-01 0.000000000e+00 -9.603652087e-01 + outer loop + vertex 5.022241269e-02 0.000000000e+00 3.543266689e-02 + vertex 5.493000570e-02 -1.000000000e+00 3.679903989e-02 + vertex 5.022241269e-02 -1.000000000e+00 3.543266689e-02 + endloop + endfacet + facet normal 7.016267427e-02 0.000000000e+00 -9.975355628e-01 + outer loop + vertex 1.761797308e-01 0.000000000e+00 5.540399685e-02 + vertex 1.883653127e-01 -1.000000000e+00 5.626108210e-02 + vertex 1.761797308e-01 -1.000000000e+00 5.540399685e-02 + endloop + endfacet + facet normal 2.959717921e-01 0.000000000e+00 -9.551966804e-01 + outer loop + vertex 4.583663031e-02 0.000000000e+00 3.407371340e-02 + vertex 5.022241269e-02 0.000000000e+00 3.543266689e-02 + vertex 5.022241269e-02 -1.000000000e+00 3.543266689e-02 + endloop + endfacet + facet normal 7.016267427e-02 0.000000000e+00 -9.975355628e-01 + outer loop + vertex 1.761797308e-01 0.000000000e+00 5.540399685e-02 + vertex 1.883653127e-01 0.000000000e+00 5.626108210e-02 + vertex 1.883653127e-01 -1.000000000e+00 5.626108210e-02 + endloop + endfacet + facet normal 2.959717921e-01 0.000000000e+00 -9.551966804e-01 + outer loop + vertex 4.583663031e-02 0.000000000e+00 3.407371340e-02 + vertex 5.022241269e-02 -1.000000000e+00 3.543266689e-02 + vertex 4.583663031e-02 -1.000000000e+00 3.407371340e-02 + endloop + endfacet + facet normal 6.027064398e-02 0.000000000e+00 -9.981820723e-01 + outer loop + vertex 1.883653127e-01 0.000000000e+00 5.626108210e-02 + vertex 2.011247989e-01 -1.000000000e+00 5.703150512e-02 + vertex 1.883653127e-01 -1.000000000e+00 5.626108210e-02 + endloop + endfacet + facet normal 3.138686541e-01 0.000000000e+00 -9.494664122e-01 + outer loop + vertex 4.175587667e-02 0.000000000e+00 3.272472344e-02 + vertex 4.583663031e-02 0.000000000e+00 3.407371340e-02 + vertex 4.583663031e-02 -1.000000000e+00 3.407371340e-02 + endloop + endfacet + facet normal 6.027064398e-02 0.000000000e+00 -9.981820723e-01 + outer loop + vertex 1.883653127e-01 0.000000000e+00 5.626108210e-02 + vertex 2.011247989e-01 0.000000000e+00 5.703150512e-02 + vertex 2.011247989e-01 -1.000000000e+00 5.703150512e-02 + endloop + endfacet + facet normal 3.138686541e-01 0.000000000e+00 -9.494664122e-01 + outer loop + vertex 4.175587667e-02 0.000000000e+00 3.272472344e-02 + vertex 4.583663031e-02 -1.000000000e+00 3.407371340e-02 + vertex 4.175587667e-02 -1.000000000e+00 3.272472344e-02 + endloop + endfacet + facet normal 5.068799969e-02 0.000000000e+00 -9.987145371e-01 + outer loop + vertex 2.011247989e-01 0.000000000e+00 5.703150512e-02 + vertex 2.144592713e-01 -1.000000000e+00 5.770827282e-02 + vertex 2.011247989e-01 -1.000000000e+00 5.703150512e-02 + endloop + endfacet + facet normal 3.324693170e-01 0.000000000e+00 -9.431140723e-01 + outer loop + vertex 3.796391187e-02 0.000000000e+00 3.138796897e-02 + vertex 4.175587667e-02 0.000000000e+00 3.272472344e-02 + vertex 4.175587667e-02 -1.000000000e+00 3.272472344e-02 + endloop + endfacet + facet normal 5.068799969e-02 0.000000000e+00 -9.987145371e-01 + outer loop + vertex 2.011247989e-01 0.000000000e+00 5.703150512e-02 + vertex 2.144592713e-01 0.000000000e+00 5.770827282e-02 + vertex 2.144592713e-01 -1.000000000e+00 5.770827282e-02 + endloop + endfacet + facet normal 3.324693170e-01 0.000000000e+00 -9.431140723e-01 + outer loop + vertex 3.796391187e-02 0.000000000e+00 3.138796897e-02 + vertex 4.175587667e-02 -1.000000000e+00 3.272472344e-02 + vertex 3.796391187e-02 -1.000000000e+00 3.138796897e-02 + endloop + endfacet + facet normal 4.141384771e-02 0.000000000e+00 -9.991420786e-01 + outer loop + vertex 2.144592713e-01 0.000000000e+00 5.770827282e-02 + vertex 2.283665750e-01 -1.000000000e+00 5.828472232e-02 + vertex 2.144592713e-01 -1.000000000e+00 5.770827282e-02 + endloop + endfacet + facet normal 3.518081088e-01 0.000000000e+00 -9.360721417e-01 + outer loop + vertex 3.444508613e-02 0.000000000e+00 3.006547323e-02 + vertex 3.796391187e-02 0.000000000e+00 3.138796897e-02 + vertex 3.796391187e-02 -1.000000000e+00 3.138796897e-02 + endloop + endfacet + facet normal 4.141384771e-02 0.000000000e+00 -9.991420786e-01 + outer loop + vertex 2.144592713e-01 0.000000000e+00 5.770827282e-02 + vertex 2.283665750e-01 0.000000000e+00 5.828472232e-02 + vertex 2.283665750e-01 -1.000000000e+00 5.828472232e-02 + endloop + endfacet + facet normal 3.518081088e-01 0.000000000e+00 -9.360721417e-01 + outer loop + vertex 3.444508613e-02 0.000000000e+00 3.006547323e-02 + vertex 3.796391187e-02 -1.000000000e+00 3.138796897e-02 + vertex 3.444508613e-02 -1.000000000e+00 3.006547323e-02 + endloop + endfacet + facet normal 3.244852317e-02 0.000000000e+00 -9.994734080e-01 + outer loop + vertex 2.283665750e-01 0.000000000e+00 5.828472232e-02 + vertex 2.428410589e-01 -1.000000000e+00 5.875464541e-02 + vertex 2.283665750e-01 -1.000000000e+00 5.828472232e-02 + endloop + endfacet + facet normal 3.719109324e-01 0.000000000e+00 -9.282684193e-01 + outer loop + vertex 3.118433506e-02 0.000000000e+00 2.875905264e-02 + vertex 3.444508613e-02 0.000000000e+00 3.006547323e-02 + vertex 3.444508613e-02 -1.000000000e+00 3.006547323e-02 + endloop + endfacet + facet normal 3.244852317e-02 0.000000000e+00 -9.994734080e-01 + outer loop + vertex 2.283665750e-01 0.000000000e+00 5.828472232e-02 + vertex 2.428410589e-01 0.000000000e+00 5.875464541e-02 + vertex 2.428410589e-01 -1.000000000e+00 5.875464541e-02 + endloop + endfacet + facet normal 3.719109324e-01 0.000000000e+00 -9.282684193e-01 + outer loop + vertex 3.118433506e-02 0.000000000e+00 2.875905264e-02 + vertex 3.444508613e-02 -1.000000000e+00 3.006547323e-02 + vertex 3.118433506e-02 -1.000000000e+00 2.875905264e-02 + endloop + endfacet + facet normal 2.379353806e-02 0.000000000e+00 -9.997168937e-01 + outer loop + vertex 2.428410589e-01 0.000000000e+00 5.875464541e-02 + vertex 2.578733449e-01 -1.000000000e+00 5.911241796e-02 + vertex 2.428410589e-01 -1.000000000e+00 5.875464541e-02 + endloop + endfacet + facet normal 3.928074751e-01 0.000000000e+00 -9.196207302e-01 + outer loop + vertex 2.816723853e-02 0.000000000e+00 2.747032781e-02 + vertex 3.118433506e-02 0.000000000e+00 2.875905264e-02 + vertex 3.118433506e-02 -1.000000000e+00 2.875905264e-02 + endloop + endfacet + facet normal 2.379353806e-02 0.000000000e+00 -9.997168937e-01 + outer loop + vertex 2.428410589e-01 0.000000000e+00 5.875464541e-02 + vertex 2.578733449e-01 0.000000000e+00 5.911241796e-02 + vertex 2.578733449e-01 -1.000000000e+00 5.911241796e-02 + endloop + endfacet + facet normal 3.928074751e-01 0.000000000e+00 -9.196207302e-01 + outer loop + vertex 2.816723853e-02 0.000000000e+00 2.747032781e-02 + vertex 3.118433506e-02 -1.000000000e+00 2.875905264e-02 + vertex 2.816723853e-02 -1.000000000e+00 2.747032781e-02 + endloop + endfacet + facet normal 1.545062239e-02 0.000000000e+00 -9.998806320e-01 + outer loop + vertex 2.578733449e-01 0.000000000e+00 5.911241796e-02 + vertex 2.734501317e-01 -1.000000000e+00 5.935311774e-02 + vertex 2.578733449e-01 -1.000000000e+00 5.911241796e-02 + endloop + endfacet + facet normal 4.145162520e-01 0.000000000e+00 -9.100419094e-01 + outer loop + vertex 2.537999933e-02 0.000000000e+00 2.620076436e-02 + vertex 2.816723853e-02 0.000000000e+00 2.747032781e-02 + vertex 2.816723853e-02 -1.000000000e+00 2.747032781e-02 + endloop + endfacet + facet normal 1.545062239e-02 0.000000000e+00 -9.998806320e-01 + outer loop + vertex 2.578733449e-01 0.000000000e+00 5.911241796e-02 + vertex 2.734501317e-01 0.000000000e+00 5.935311774e-02 + vertex 2.734501317e-01 -1.000000000e+00 5.935311774e-02 + endloop + endfacet + facet normal 4.145162520e-01 0.000000000e+00 -9.100419094e-01 + outer loop + vertex 2.537999933e-02 0.000000000e+00 2.620076436e-02 + vertex 2.816723853e-02 -1.000000000e+00 2.747032781e-02 + vertex 2.537999933e-02 -1.000000000e+00 2.620076436e-02 + endloop + endfacet + facet normal 7.422430169e-03 0.000000000e+00 -9.999724534e-01 + outer loop + vertex 2.734501317e-01 0.000000000e+00 5.935311774e-02 + vertex 2.895540445e-01 -1.000000000e+00 5.947265121e-02 + vertex 2.734501317e-01 -1.000000000e+00 5.935311774e-02 + endloop + endfacet + facet normal 4.370466301e-01 0.000000000e+00 -8.994388490e-01 + outer loop + vertex 2.280943840e-02 0.000000000e+00 2.495170224e-02 + vertex 2.537999933e-02 0.000000000e+00 2.620076436e-02 + vertex 2.537999933e-02 -1.000000000e+00 2.620076436e-02 + endloop + endfacet + facet normal 7.422430169e-03 0.000000000e+00 -9.999724534e-01 + outer loop + vertex 2.734501317e-01 0.000000000e+00 5.935311774e-02 + vertex 2.895540445e-01 0.000000000e+00 5.947265121e-02 + vertex 2.895540445e-01 -1.000000000e+00 5.947265121e-02 + endloop + endfacet + facet normal 4.370466301e-01 0.000000000e+00 -8.994388490e-01 + outer loop + vertex 2.280943840e-02 0.000000000e+00 2.495170224e-02 + vertex 2.537999933e-02 -1.000000000e+00 2.620076436e-02 + vertex 2.280943840e-02 -1.000000000e+00 2.495170224e-02 + endloop + endfacet + facet normal -2.891886740e-04 -0.000000000e+00 -9.999999582e-01 + outer loop + vertex 2.895540445e-01 0.000000000e+00 5.947265121e-02 + vertex 3.061635346e-01 -1.000000000e+00 5.946784793e-02 + vertex 2.895540445e-01 -1.000000000e+00 5.947265121e-02 + endloop + endfacet + facet normal 4.604106449e-01 0.000000000e+00 -8.877060539e-01 + outer loop + vertex 2.044303685e-02 0.000000000e+00 2.372436301e-02 + vertex 2.280943840e-02 0.000000000e+00 2.495170224e-02 + vertex 2.280943840e-02 -1.000000000e+00 2.495170224e-02 + endloop + endfacet + facet normal -2.891886740e-04 0.000000000e+00 -9.999999582e-01 + outer loop + vertex 2.895540445e-01 0.000000000e+00 5.947265121e-02 + vertex 3.061635346e-01 0.000000000e+00 5.946784793e-02 + vertex 3.061635346e-01 -1.000000000e+00 5.946784793e-02 + endloop + endfacet + facet normal 4.604106449e-01 0.000000000e+00 -8.877060539e-01 + outer loop + vertex 2.044303685e-02 0.000000000e+00 2.372436301e-02 + vertex 2.280943840e-02 -1.000000000e+00 2.495170224e-02 + vertex 2.044303685e-02 -1.000000000e+00 2.372436301e-02 + endloop + endfacet + facet normal -7.682172093e-03 -0.000000000e+00 -9.999704917e-01 + outer loop + vertex 3.061635346e-01 0.000000000e+00 5.946784793e-02 + vertex 3.232528391e-01 -1.000000000e+00 5.933656108e-02 + vertex 3.061635346e-01 -1.000000000e+00 5.946784793e-02 + endloop + endfacet + facet normal 4.845921893e-01 0.000000000e+00 -8.747401958e-01 + outer loop + vertex 1.826885694e-02 0.000000000e+00 2.251990184e-02 + vertex 2.044303685e-02 0.000000000e+00 2.372436301e-02 + vertex 2.044303685e-02 -1.000000000e+00 2.372436301e-02 + endloop + endfacet + facet normal -7.682172093e-03 0.000000000e+00 -9.999704917e-01 + outer loop + vertex 3.061635346e-01 0.000000000e+00 5.946784793e-02 + vertex 3.232528391e-01 0.000000000e+00 5.933656108e-02 + vertex 3.232528391e-01 -1.000000000e+00 5.933656108e-02 + endloop + endfacet + facet normal 4.845921893e-01 0.000000000e+00 -8.747401958e-01 + outer loop + vertex 1.826885694e-02 0.000000000e+00 2.251990184e-02 + vertex 2.044303685e-02 -1.000000000e+00 2.372436301e-02 + vertex 1.826885694e-02 -1.000000000e+00 2.251990184e-02 + endloop + endfacet + facet normal -1.475500706e-02 -0.000000000e+00 -9.998911390e-01 + outer loop + vertex 3.232528391e-01 0.000000000e+00 5.933656108e-02 + vertex 3.407920053e-01 -1.000000000e+00 5.907774238e-02 + vertex 3.232528391e-01 -1.000000000e+00 5.933656108e-02 + endloop + endfacet + facet normal 5.095572007e-01 0.000000000e+00 -8.604367840e-01 + outer loop + vertex 1.627551729e-02 0.000000000e+00 2.133943095e-02 + vertex 1.826885694e-02 0.000000000e+00 2.251990184e-02 + vertex 1.826885694e-02 -1.000000000e+00 2.251990184e-02 + endloop + endfacet + facet normal -1.475500706e-02 0.000000000e+00 -9.998911390e-01 + outer loop + vertex 3.232528391e-01 0.000000000e+00 5.933656108e-02 + vertex 3.407920053e-01 0.000000000e+00 5.907774238e-02 + vertex 3.407920053e-01 -1.000000000e+00 5.907774238e-02 + endloop + endfacet + facet normal 5.095572007e-01 0.000000000e+00 -8.604367840e-01 + outer loop + vertex 1.627551729e-02 0.000000000e+00 2.133943095e-02 + vertex 1.826885694e-02 -1.000000000e+00 2.251990184e-02 + vertex 1.627551729e-02 -1.000000000e+00 2.133943095e-02 + endloop + endfacet + facet normal -2.150774975e-02 -0.000000000e+00 -9.997686816e-01 + outer loop + vertex 3.407920053e-01 0.000000000e+00 5.907774238e-02 + vertex 3.587469844e-01 -1.000000000e+00 5.869148183e-02 + vertex 3.407920053e-01 -1.000000000e+00 5.907774238e-02 + endloop + endfacet + facet normal 5.352628388e-01 0.000000000e+00 -8.446855589e-01 + outer loop + vertex 1.445220177e-02 0.000000000e+00 2.018402699e-02 + vertex 1.627551729e-02 0.000000000e+00 2.133943095e-02 + vertex 1.627551729e-02 -1.000000000e+00 2.133943095e-02 + endloop + endfacet + facet normal -2.150774975e-02 0.000000000e+00 -9.997686816e-01 + outer loop + vertex 3.407920053e-01 0.000000000e+00 5.907774238e-02 + vertex 3.587469844e-01 0.000000000e+00 5.869148183e-02 + vertex 3.587469844e-01 -1.000000000e+00 5.869148183e-02 + endloop + endfacet + facet normal 5.352628388e-01 0.000000000e+00 -8.446855589e-01 + outer loop + vertex 1.445220177e-02 0.000000000e+00 2.018402699e-02 + vertex 1.627551729e-02 -1.000000000e+00 2.133943095e-02 + vertex 1.445220177e-02 -1.000000000e+00 2.018402699e-02 + endloop + endfacet + facet normal -2.794110893e-02 -0.000000000e+00 -9.996095710e-01 + outer loop + vertex 3.587469844e-01 0.000000000e+00 5.869148183e-02 + vertex 3.770797979e-01 -1.000000000e+00 5.817904262e-02 + vertex 3.587469844e-01 -1.000000000e+00 5.869148183e-02 + endloop + endfacet + facet normal 5.616747199e-01 0.000000000e+00 -8.273581504e-01 + outer loop + vertex 1.278871775e-02 0.000000000e+00 1.905472535e-02 + vertex 1.445220177e-02 0.000000000e+00 2.018402699e-02 + vertex 1.445220177e-02 -1.000000000e+00 2.018402699e-02 + endloop + endfacet + facet normal -2.794110893e-02 0.000000000e+00 -9.996095710e-01 + outer loop + vertex 3.587469844e-01 0.000000000e+00 5.869148183e-02 + vertex 3.770797979e-01 0.000000000e+00 5.817904262e-02 + vertex 3.770797979e-01 -1.000000000e+00 5.817904262e-02 + endloop + endfacet + facet normal 5.616747199e-01 0.000000000e+00 -8.273581504e-01 + outer loop + vertex 1.278871775e-02 0.000000000e+00 1.905472535e-02 + vertex 1.445220177e-02 -1.000000000e+00 2.018402699e-02 + vertex 1.278871775e-02 -1.000000000e+00 1.905472535e-02 + endloop + endfacet + facet normal -3.405749389e-02 -0.000000000e+00 -9.994198753e-01 + outer loop + vertex 3.770797979e-01 0.000000000e+00 5.817904262e-02 + vertex 3.957487780e-01 -1.000000000e+00 5.754285488e-02 + vertex 3.770797979e-01 -1.000000000e+00 5.817904262e-02 + endloop + endfacet + facet normal 5.886358783e-01 0.000000000e+00 -8.083982946e-01 + outer loop + vertex 1.127516041e-02 0.000000000e+00 1.795262733e-02 + vertex 1.278871775e-02 0.000000000e+00 1.905472535e-02 + vertex 1.278871775e-02 -1.000000000e+00 1.905472535e-02 + endloop + endfacet + facet normal -3.405749389e-02 0.000000000e+00 -9.994198753e-01 + outer loop + vertex 3.770797979e-01 0.000000000e+00 5.817904262e-02 + vertex 3.957487780e-01 0.000000000e+00 5.754285488e-02 + vertex 3.957487780e-01 -1.000000000e+00 5.754285488e-02 + endloop + endfacet + facet normal 5.886358783e-01 0.000000000e+00 -8.083982946e-01 + outer loop + vertex 1.127516041e-02 0.000000000e+00 1.795262733e-02 + vertex 1.278871775e-02 -1.000000000e+00 1.905472535e-02 + vertex 1.127516041e-02 -1.000000000e+00 1.795262733e-02 + endloop + endfacet + facet normal -3.986080756e-02 -0.000000000e+00 -9.992052422e-01 + outer loop + vertex 3.957487780e-01 0.000000000e+00 5.754285488e-02 + vertex 4.147088805e-01 -1.000000000e+00 5.678648875e-02 + vertex 3.957487780e-01 -1.000000000e+00 5.754285488e-02 + endloop + endfacet + facet normal 6.160902106e-01 0.000000000e+00 -7.876756010e-01 + outer loop + vertex 9.902279365e-03 0.000000000e+00 1.687881145e-02 + vertex 1.127516041e-02 0.000000000e+00 1.795262733e-02 + vertex 1.127516041e-02 -1.000000000e+00 1.795262733e-02 + endloop + endfacet + facet normal -3.986080756e-02 0.000000000e+00 -9.992052422e-01 + outer loop + vertex 3.957487780e-01 0.000000000e+00 5.754285488e-02 + vertex 4.147088805e-01 0.000000000e+00 5.678648875e-02 + vertex 4.147088805e-01 -1.000000000e+00 5.678648875e-02 + endloop + endfacet + facet normal -3.986080756e-02 2.371970670e-310 -9.992052422e-01 + outer loop + vertex 9.902279365e-03 0.000000000e+00 1.687881145e-02 + vertex 1.127516041e-02 -1.000000000e+00 1.795262733e-02 + vertex 9.902279365e-03 -1.000000000e+00 1.687881145e-02 + endloop + endfacet + facet normal -4.535657593e-02 -0.000000000e+00 -9.989708609e-01 + outer loop + vertex 4.147088805e-01 0.000000000e+00 5.678648875e-02 + vertex 4.339120676e-01 -1.000000000e+00 5.591460065e-02 + vertex 4.147088805e-01 -1.000000000e+00 5.678648875e-02 + endloop + endfacet + facet normal 6.438398167e-01 0.000000000e+00 -7.651603038e-01 + outer loop + vertex 8.660977829e-03 0.000000000e+00 1.583432528e-02 + vertex 9.902279365e-03 0.000000000e+00 1.687881145e-02 + vertex 9.902279365e-03 -1.000000000e+00 1.687881145e-02 + endloop + endfacet + facet normal -4.535657593e-02 0.000000000e+00 -9.989708609e-01 + outer loop + vertex 4.147088805e-01 0.000000000e+00 5.678648875e-02 + vertex 4.339120676e-01 0.000000000e+00 5.591460065e-02 + vertex 4.339120676e-01 -1.000000000e+00 5.591460065e-02 + endloop + endfacet + facet normal -4.535657593e-02 2.371970670e-310 -9.989708609e-01 + outer loop + vertex 8.660977829e-03 0.000000000e+00 1.583432528e-02 + vertex 9.902279365e-03 -1.000000000e+00 1.687881145e-02 + vertex 8.660977829e-03 -1.000000000e+00 1.583432528e-02 + endloop + endfacet + facet normal -5.055209308e-02 -0.000000000e+00 -9.987214256e-01 + outer loop + vertex 4.339120676e-01 0.000000000e+00 5.591460065e-02 + vertex 4.533077537e-01 -1.000000000e+00 5.493285288e-02 + vertex 4.339120676e-01 -1.000000000e+00 5.591460065e-02 + endloop + endfacet + facet normal 6.717137430e-01 0.000000000e+00 -7.408108041e-01 + outer loop + vertex 7.542786567e-03 0.000000000e+00 1.482043019e-02 + vertex 8.660977829e-03 0.000000000e+00 1.583432528e-02 + vertex 8.660977829e-03 -1.000000000e+00 1.583432528e-02 + endloop + endfacet + facet normal -5.055209308e-02 0.000000000e+00 -9.987214256e-01 + outer loop + vertex 4.339120676e-01 0.000000000e+00 5.591460065e-02 + vertex 4.533077537e-01 0.000000000e+00 5.493285288e-02 + vertex 4.533077537e-01 -1.000000000e+00 5.493285288e-02 + endloop + endfacet + facet normal -5.055209308e-02 2.371970670e-310 -9.987214256e-01 + outer loop + vertex 7.542786567e-03 0.000000000e+00 1.482043019e-02 + vertex 8.660977829e-03 -1.000000000e+00 1.583432528e-02 + vertex 7.542786567e-03 -1.000000000e+00 1.482043019e-02 + endloop + endfacet + facet normal -5.545626925e-02 -0.000000000e+00 -9.984611170e-01 + outer loop + vertex 4.533077537e-01 0.000000000e+00 5.493285288e-02 + vertex 4.728433083e-01 -1.000000000e+00 5.384781416e-02 + vertex 4.533077537e-01 -1.000000000e+00 5.493285288e-02 + endloop + endfacet + facet normal 6.995209056e-01 0.000000000e+00 -7.146121344e-01 + outer loop + vertex 6.539262457e-03 0.000000000e+00 1.383809857e-02 + vertex 7.542786567e-03 0.000000000e+00 1.482043019e-02 + vertex 7.542786567e-03 -1.000000000e+00 1.482043019e-02 + endloop + endfacet + facet normal -5.545626925e-02 0.000000000e+00 -9.984611170e-01 + outer loop + vertex 4.533077537e-01 0.000000000e+00 5.493285288e-02 + vertex 4.728433083e-01 0.000000000e+00 5.384781416e-02 + vertex 4.728433083e-01 -1.000000000e+00 5.384781416e-02 + endloop + endfacet + facet normal -5.545626925e-02 2.371970670e-310 -9.984611170e-01 + outer loop + vertex 6.539262457e-03 0.000000000e+00 1.383809857e-02 + vertex 7.542786567e-03 -1.000000000e+00 1.482043019e-02 + vertex 6.539262457e-03 -1.000000000e+00 1.383809857e-02 + endloop + endfacet + facet normal -6.007958990e-02 -0.000000000e+00 -9.981935899e-01 + outer loop + vertex 4.728433083e-01 0.000000000e+00 5.384781416e-02 + vertex 4.924646039e-01 -1.000000000e+00 5.266684144e-02 + vertex 4.728433083e-01 -1.000000000e+00 5.384781416e-02 + endloop + endfacet + facet normal 7.270093594e-01 0.000000000e+00 -6.866275492e-01 + outer loop + vertex 5.642485232e-03 0.000000000e+00 1.288858025e-02 + vertex 6.539262457e-03 0.000000000e+00 1.383809857e-02 + vertex 6.539262457e-03 -1.000000000e+00 1.383809857e-02 + endloop + endfacet + facet normal -6.007958990e-02 0.000000000e+00 -9.981935899e-01 + outer loop + vertex 4.728433083e-01 0.000000000e+00 5.384781416e-02 + vertex 4.924646039e-01 0.000000000e+00 5.266684144e-02 + vertex 4.924646039e-01 -1.000000000e+00 5.266684144e-02 + endloop + endfacet + facet normal -6.007958990e-02 2.371970670e-310 -9.981935899e-01 + outer loop + vertex 5.642485232e-03 0.000000000e+00 1.288858025e-02 + vertex 6.539262457e-03 -1.000000000e+00 1.383809857e-02 + vertex 5.642485232e-03 -1.000000000e+00 1.288858025e-02 + endloop + endfacet + facet normal -6.443395190e-02 -0.000000000e+00 -9.979219738e-01 + outer loop + vertex 4.924646039e-01 0.000000000e+00 5.266684144e-02 + vertex 5.121166001e-01 -1.000000000e+00 5.139794887e-02 + vertex 4.924646039e-01 -1.000000000e+00 5.266684144e-02 + endloop + endfacet + facet normal 7.539426229e-01 0.000000000e+00 -6.569402723e-01 + outer loop + vertex 4.844550254e-03 0.000000000e+00 1.197282396e-02 + vertex 5.642485232e-03 0.000000000e+00 1.288858025e-02 + vertex 5.642485232e-03 -1.000000000e+00 1.288858025e-02 + endloop + endfacet + facet normal -6.443395190e-02 0.000000000e+00 -9.979219738e-01 + outer loop + vertex 4.924646039e-01 0.000000000e+00 5.266684144e-02 + vertex 5.121166001e-01 0.000000000e+00 5.139794887e-02 + vertex 5.121166001e-01 -1.000000000e+00 5.139794887e-02 + endloop + endfacet + facet normal -6.443395190e-02 2.371970670e-310 -9.979219738e-01 + outer loop + vertex 4.844550254e-03 0.000000000e+00 1.197282396e-02 + vertex 5.642485232e-03 -1.000000000e+00 1.288858025e-02 + vertex 4.844550254e-03 -1.000000000e+00 1.197282396e-02 + endloop + endfacet + facet normal -6.853246021e-02 -0.000000000e+00 -9.976488871e-01 + outer loop + vertex 5.121166001e-01 0.000000000e+00 5.139794887e-02 + vertex 5.317439474e-01 -1.000000000e+00 5.004966851e-02 + vertex 5.121166001e-01 -1.000000000e+00 5.139794887e-02 + endloop + endfacet + facet normal 7.800621896e-01 0.000000000e+00 -6.257019901e-01 + outer loop + vertex 4.137967065e-03 0.000000000e+00 1.109192724e-02 + vertex 4.844550254e-03 0.000000000e+00 1.197282396e-02 + vertex 4.844550254e-03 -1.000000000e+00 1.197282396e-02 + endloop + endfacet + facet normal -6.853246021e-02 0.000000000e+00 -9.976488871e-01 + outer loop + vertex 5.121166001e-01 0.000000000e+00 5.139794887e-02 + vertex 5.317439474e-01 0.000000000e+00 5.004966851e-02 + vertex 5.317439474e-01 -1.000000000e+00 5.004966851e-02 + endloop + endfacet + facet normal -6.853246021e-02 2.371970670e-310 -9.976488871e-01 + outer loop + vertex 4.137967065e-03 0.000000000e+00 1.109192724e-02 + vertex 4.844550254e-03 -1.000000000e+00 1.197282396e-02 + vertex 4.137967065e-03 -1.000000000e+00 1.109192724e-02 + endloop + endfacet + facet normal -7.238916428e-02 -0.000000000e+00 -9.973764630e-01 + outer loop + vertex 5.317439474e-01 0.000000000e+00 5.004966851e-02 + vertex 5.512916003e-01 -1.000000000e+00 4.863090809e-02 + vertex 5.317439474e-01 -1.000000000e+00 5.004966851e-02 + endloop + endfacet + facet normal 8.051203121e-01 0.000000000e+00 -5.931115266e-01 + outer loop + vertex 3.515319859e-03 0.000000000e+00 1.024671367e-02 + vertex 4.137967065e-03 0.000000000e+00 1.109192724e-02 + vertex 4.137967065e-03 -1.000000000e+00 1.109192724e-02 + endloop + endfacet + facet normal -7.238916428e-02 0.000000000e+00 -9.973764630e-01 + outer loop + vertex 5.317439474e-01 0.000000000e+00 5.004966851e-02 + vertex 5.512916003e-01 0.000000000e+00 4.863090809e-02 + vertex 5.512916003e-01 -1.000000000e+00 4.863090809e-02 + endloop + endfacet + facet normal -7.238916428e-02 2.371970670e-310 -9.973764630e-01 + outer loop + vertex 3.515319859e-03 0.000000000e+00 1.024671367e-02 + vertex 4.137967065e-03 -1.000000000e+00 1.109192724e-02 + vertex 3.515319859e-03 -1.000000000e+00 1.024671367e-02 + endloop + endfacet + facet normal -7.601881370e-02 -0.000000000e+00 -9.971063835e-01 + outer loop + vertex 5.512916003e-01 0.000000000e+00 4.863090809e-02 + vertex 5.707054232e-01 -1.000000000e+00 4.715080947e-02 + vertex 5.512916003e-01 -1.000000000e+00 4.863090809e-02 + endloop + endfacet + facet normal 8.288852628e-01 0.000000000e+00 -5.594186457e-01 + outer loop + vertex 2.969441608e-03 0.000000000e+00 9.437891077e-03 + vertex 3.515319859e-03 0.000000000e+00 1.024671367e-02 + vertex 3.515319859e-03 -1.000000000e+00 1.024671367e-02 + endloop + endfacet + facet normal -7.601881370e-02 0.000000000e+00 -9.971063835e-01 + outer loop + vertex 5.512916003e-01 0.000000000e+00 4.863090809e-02 + vertex 5.707054232e-01 0.000000000e+00 4.715080947e-02 + vertex 5.707054232e-01 -1.000000000e+00 4.715080947e-02 + endloop + endfacet + facet normal -7.601881370e-02 2.371970670e-310 -9.971063835e-01 + outer loop + vertex 2.969441608e-03 0.000000000e+00 9.437891077e-03 + vertex 3.515319859e-03 -1.000000000e+00 1.024671367e-02 + vertex 2.969441608e-03 -1.000000000e+00 9.437891077e-03 + endloop + endfacet + facet normal -7.943655855e-02 -0.000000000e+00 -9.968399235e-01 + outer loop + vertex 5.707054232e-01 0.000000000e+00 4.715080947e-02 + vertex 5.899327757e-01 -1.000000000e+00 4.561861289e-02 + vertex 5.707054232e-01 -1.000000000e+00 4.715080947e-02 + endloop + endfacet + facet normal 8.511610130e-01 0.000000000e+00 -5.249046866e-01 + outer loop + vertex 2.493434235e-03 0.000000000e+00 8.666019672e-03 + vertex 2.969441608e-03 0.000000000e+00 9.437891077e-03 + vertex 2.969441608e-03 -1.000000000e+00 9.437891077e-03 + endloop + endfacet + facet normal -7.943655855e-02 0.000000000e+00 -9.968399235e-01 + outer loop + vertex 5.707054232e-01 0.000000000e+00 4.715080947e-02 + vertex 5.899327757e-01 0.000000000e+00 4.561861289e-02 + vertex 5.899327757e-01 -1.000000000e+00 4.561861289e-02 + endloop + endfacet + facet normal -7.943655855e-02 2.371970670e-310 -9.968399235e-01 + outer loop + vertex 2.493434235e-03 0.000000000e+00 8.666019672e-03 + vertex 2.969441608e-03 -1.000000000e+00 9.437891077e-03 + vertex 2.493434235e-03 -1.000000000e+00 8.666019672e-03 + endloop + endfacet + facet normal -8.265766256e-02 -0.000000000e+00 -9.965780004e-01 + outer loop + vertex 5.899327757e-01 0.000000000e+00 4.561861289e-02 + vertex 6.089230652e-01 -1.000000000e+00 4.404353002e-02 + vertex 5.899327757e-01 -1.000000000e+00 4.561861289e-02 + endloop + endfacet + facet normal 8.717854146e-01 0.000000000e+00 -4.898879371e-01 + outer loop + vertex 2.080623294e-03 0.000000000e+00 7.931397466e-03 + vertex 2.493434235e-03 0.000000000e+00 8.666019672e-03 + vertex 2.493434235e-03 -1.000000000e+00 8.666019672e-03 + endloop + endfacet + facet normal -8.265766256e-02 0.000000000e+00 -9.965780004e-01 + outer loop + vertex 5.899327757e-01 0.000000000e+00 4.561861289e-02 + vertex 6.089230652e-01 0.000000000e+00 4.404353002e-02 + vertex 6.089230652e-01 -1.000000000e+00 4.404353002e-02 + endloop + endfacet + facet normal -8.265766256e-02 2.371970670e-310 -9.965780004e-01 + outer loop + vertex 2.080623294e-03 0.000000000e+00 7.931397466e-03 + vertex 2.493434235e-03 -1.000000000e+00 8.666019672e-03 + vertex 2.080623294e-03 -1.000000000e+00 7.931397466e-03 + endloop + endfacet + facet normal -8.569722467e-02 -0.000000000e+00 -9.963212262e-01 + outer loop + vertex 6.089230652e-01 0.000000000e+00 4.404353002e-02 + vertex 6.276282526e-01 -1.000000000e+00 4.243462859e-02 + vertex 6.089230652e-01 -1.000000000e+00 4.404353002e-02 + endloop + endfacet + facet normal 8.906458568e-01 0.000000000e+00 -4.546976554e-01 + outer loop + vertex 1.724623064e-03 0.000000000e+00 7.234076671e-03 + vertex 2.080623294e-03 0.000000000e+00 7.931397466e-03 + vertex 2.080623294e-03 -1.000000000e+00 7.931397466e-03 + endloop + endfacet + facet normal -8.569722467e-02 0.000000000e+00 -9.963212262e-01 + outer loop + vertex 6.089230652e-01 0.000000000e+00 4.404353002e-02 + vertex 6.276282526e-01 0.000000000e+00 4.243462859e-02 + vertex 6.276282526e-01 -1.000000000e+00 4.243462859e-02 + endloop + endfacet + facet normal -8.569722467e-02 2.371970670e-310 -9.963212262e-01 + outer loop + vertex 1.724623064e-03 0.000000000e+00 7.234076671e-03 + vertex 2.080623294e-03 -1.000000000e+00 7.931397466e-03 + vertex 1.724623064e-03 -1.000000000e+00 7.234076671e-03 + endloop + endfacet + facet normal -8.856992168e-02 -0.000000000e+00 -9.960699619e-01 + outer loop + vertex 6.276282526e-01 0.000000000e+00 4.243462859e-02 + vertex 6.460033026e-01 -1.000000000e+00 4.080073057e-02 + vertex 6.276282526e-01 -1.000000000e+00 4.243462859e-02 + endloop + endfacet + facet normal 9.076819810e-01 0.000000000e+00 -4.196586963e-01 + outer loop + vertex 1.419377891e-03 0.000000000e+00 6.573860296e-03 + vertex 1.724623064e-03 0.000000000e+00 7.234076671e-03 + vertex 1.724623064e-03 -1.000000000e+00 7.234076671e-03 + endloop + endfacet + facet normal -8.856992168e-02 0.000000000e+00 -9.960699619e-01 + outer loop + vertex 6.276282526e-01 0.000000000e+00 4.243462859e-02 + vertex 6.460033026e-01 0.000000000e+00 4.080073057e-02 + vertex 6.460033026e-01 -1.000000000e+00 4.080073057e-02 + endloop + endfacet + facet normal -8.856992168e-02 2.371970670e-310 -9.960699619e-01 + outer loop + vertex 1.419377891e-03 0.000000000e+00 6.573860296e-03 + vertex 1.724623064e-03 -1.000000000e+00 7.234076671e-03 + vertex 1.419377891e-03 -1.000000000e+00 6.573860296e-03 + endloop + endfacet + facet normal -9.128978719e-02 -0.000000000e+00 -9.958243694e-01 + outer loop + vertex 6.460033026e-01 0.000000000e+00 4.080073057e-02 + vertex 6.640065698e-01 -1.000000000e+00 3.915032465e-02 + vertex 6.460033026e-01 -1.000000000e+00 4.080073057e-02 + endloop + endfacet + facet normal 9.228834274e-01 0.000000000e+00 -3.850794457e-01 + outer loop + vertex 1.159193086e-03 0.000000000e+00 5.950300022e-03 + vertex 1.419377891e-03 0.000000000e+00 6.573860296e-03 + vertex 1.419377891e-03 -1.000000000e+00 6.573860296e-03 + endloop + endfacet + facet normal -9.128978719e-02 0.000000000e+00 -9.958243694e-01 + outer loop + vertex 6.460033026e-01 0.000000000e+00 4.080073057e-02 + vertex 6.640065698e-01 0.000000000e+00 3.915032465e-02 + vertex 6.640065698e-01 -1.000000000e+00 3.915032465e-02 + endloop + endfacet + facet normal -9.128978719e-02 2.371970670e-310 -9.958243694e-01 + outer loop + vertex 1.159193086e-03 0.000000000e+00 5.950300022e-03 + vertex 1.419377891e-03 -1.000000000e+00 6.573860296e-03 + vertex 1.159193086e-03 -1.000000000e+00 5.950300022e-03 + endloop + endfacet + facet normal -9.387001982e-02 -0.000000000e+00 -9.955844612e-01 + outer loop + vertex 6.640065698e-01 0.000000000e+00 3.915032465e-02 + vertex 6.816001146e-01 -1.000000000e+00 3.749149362e-02 + vertex 6.640065698e-01 -1.000000000e+00 3.915032465e-02 + endloop + endfacet + facet normal 9.362860169e-01 0.000000000e+00 -3.512385153e-01 + outer loop + vertex 9.387642340e-04 0.000000000e+00 5.362709417e-03 + vertex 1.159193086e-03 0.000000000e+00 5.950300022e-03 + vertex 1.159193086e-03 -1.000000000e+00 5.950300022e-03 + endloop + endfacet + facet normal -9.387001982e-02 0.000000000e+00 -9.955844612e-01 + outer loop + vertex 6.640065698e-01 0.000000000e+00 3.915032465e-02 + vertex 6.816001146e-01 0.000000000e+00 3.749149362e-02 + vertex 6.816001146e-01 -1.000000000e+00 3.749149362e-02 + endloop + endfacet + facet normal -9.387001982e-02 2.371970670e-310 -9.955844612e-01 + outer loop + vertex 9.387642340e-04 0.000000000e+00 5.362709417e-03 + vertex 1.159193086e-03 -1.000000000e+00 5.950300022e-03 + vertex 9.387642340e-04 -1.000000000e+00 5.362709417e-03 + endloop + endfacet + facet normal -9.632283502e-02 -0.000000000e+00 -9.953501452e-01 + outer loop + vertex 6.816001146e-01 0.000000000e+00 3.749149362e-02 + vertex 6.987499446e-01 -1.000000000e+00 3.583185630e-02 + vertex 6.816001146e-01 -1.000000000e+00 3.749149362e-02 + endloop + endfacet + facet normal 9.479615149e-01 0.000000000e+00 -3.183849341e-01 + outer loop + vertex 7.531893325e-04 0.000000000e+00 4.810177416e-03 + vertex 9.387642340e-04 0.000000000e+00 5.362709417e-03 + vertex 9.387642340e-04 -1.000000000e+00 5.362709417e-03 + endloop + endfacet + facet normal -9.632283502e-02 0.000000000e+00 -9.953501452e-01 + outer loop + vertex 6.816001146e-01 0.000000000e+00 3.749149362e-02 + vertex 6.987499446e-01 0.000000000e+00 3.583185630e-02 + vertex 6.987499446e-01 -1.000000000e+00 3.583185630e-02 + endloop + endfacet + facet normal -9.632283502e-02 2.371970670e-310 -9.953501452e-01 + outer loop + vertex 7.531893325e-04 0.000000000e+00 4.810177416e-03 + vertex 9.387642340e-04 -1.000000000e+00 5.362709417e-03 + vertex 7.531893325e-04 -1.000000000e+00 4.810177416e-03 + endloop + endfacet + facet normal -9.865936682e-02 -0.000000000e+00 -9.951212636e-01 + outer loop + vertex 6.987499446e-01 0.000000000e+00 3.583185630e-02 + vertex 7.154261826e-01 -1.000000000e+00 3.417852304e-02 + vertex 6.987499446e-01 -1.000000000e+00 3.583185630e-02 + endloop + endfacet + facet normal 9.580156776e-01 0.000000000e+00 -2.867158202e-01 + outer loop + vertex 5.979922706e-04 0.000000000e+00 4.291610920e-03 + vertex 7.531893325e-04 0.000000000e+00 4.810177416e-03 + vertex 7.531893325e-04 -1.000000000e+00 4.810177416e-03 + endloop + endfacet + facet normal -9.865936682e-02 0.000000000e+00 -9.951212636e-01 + outer loop + vertex 6.987499446e-01 0.000000000e+00 3.583185630e-02 + vertex 7.154261826e-01 0.000000000e+00 3.417852304e-02 + vertex 7.154261826e-01 -1.000000000e+00 3.417852304e-02 + endloop + endfacet + facet normal -9.865936682e-02 2.371970670e-310 -9.951212636e-01 + outer loop + vertex 5.979922706e-04 0.000000000e+00 4.291610920e-03 + vertex 7.531893325e-04 -1.000000000e+00 4.810177416e-03 + vertex 5.979922706e-04 -1.000000000e+00 4.291610920e-03 + endloop + endfacet + facet normal -1.008896020e-01 -0.000000000e+00 -9.948976270e-01 + outer loop + vertex 7.154261826e-01 0.000000000e+00 3.417852304e-02 + vertex 7.316031585e-01 -1.000000000e+00 3.253806414e-02 + vertex 7.154261826e-01 -1.000000000e+00 3.417852304e-02 + endloop + endfacet + facet normal 9.665775405e-01 0.000000000e+00 -2.563744493e-01 + outer loop + vertex 4.691284474e-04 0.000000000e+00 3.805771252e-03 + vertex 5.979922706e-04 0.000000000e+00 4.291610920e-03 + vertex 5.979922706e-04 -1.000000000e+00 4.291610920e-03 + endloop + endfacet + facet normal -1.008896020e-01 0.000000000e+00 -9.948976270e-01 + outer loop + vertex 7.154261826e-01 0.000000000e+00 3.417852304e-02 + vertex 7.316031585e-01 0.000000000e+00 3.253806414e-02 + vertex 7.316031585e-01 -1.000000000e+00 3.253806414e-02 + endloop + endfacet + facet normal -1.008896020e-01 2.371970670e-310 -9.948976270e-01 + outer loop + vertex 4.691284474e-04 0.000000000e+00 3.805771252e-03 + vertex 5.979922706e-04 -1.000000000e+00 4.291610920e-03 + vertex 4.691284474e-04 -1.000000000e+00 3.805771252e-03 + endloop + endfacet + facet normal -1.030223709e-01 -0.000000000e+00 -9.946790392e-01 + outer loop + vertex 7.316031585e-01 0.000000000e+00 3.253806414e-02 + vertex 7.472594329e-01 -1.000000000e+00 3.091648931e-02 + vertex 7.316031585e-01 -1.000000000e+00 3.253806414e-02 + endloop + endfacet + facet normal 9.737803899e-01 0.000000000e+00 -2.274901146e-01 + outer loop + vertex 3.629542983e-04 0.000000000e+00 3.351288627e-03 + vertex 4.691284474e-04 0.000000000e+00 3.805771252e-03 + vertex 4.691284474e-04 -1.000000000e+00 3.805771252e-03 + endloop + endfacet + facet normal -1.030223709e-01 0.000000000e+00 -9.946790392e-01 + outer loop + vertex 7.316031585e-01 0.000000000e+00 3.253806414e-02 + vertex 7.472594329e-01 0.000000000e+00 3.091648931e-02 + vertex 7.472594329e-01 -1.000000000e+00 3.091648931e-02 + endloop + endfacet + facet normal -1.030223709e-01 2.371970670e-310 -9.946790392e-01 + outer loop + vertex 3.629542983e-04 0.000000000e+00 3.351288627e-03 + vertex 4.691284474e-04 -1.000000000e+00 3.805771252e-03 + vertex 3.629542983e-04 -1.000000000e+00 3.351288627e-03 + endloop + endfacet + facet normal -1.050653526e-01 -0.000000000e+00 -9.944653195e-01 + outer loop + vertex 7.472594329e-01 0.000000000e+00 3.091648931e-02 + vertex 7.623777525e-01 -1.000000000e+00 2.931923745e-02 + vertex 7.472594329e-01 -1.000000000e+00 3.091648931e-02 + endloop + endfacet + facet normal 9.797717540e-01 0.000000000e+00 -2.001182400e-01 + outer loop + vertex 2.762360161e-04 0.000000000e+00 2.926719016e-03 + vertex 3.629542983e-04 0.000000000e+00 3.351288627e-03 + vertex 3.629542983e-04 -1.000000000e+00 3.351288627e-03 + endloop + endfacet + facet normal -1.050653526e-01 0.000000000e+00 -9.944653195e-01 + outer loop + vertex 7.472594329e-01 0.000000000e+00 3.091648931e-02 + vertex 7.623777525e-01 0.000000000e+00 2.931923745e-02 + vertex 7.623777525e-01 -1.000000000e+00 2.931923745e-02 + endloop + endfacet + facet normal -1.050653526e-01 2.371970670e-310 -9.944653195e-01 + outer loop + vertex 2.762360161e-04 0.000000000e+00 2.926719016e-03 + vertex 3.629542983e-04 -1.000000000e+00 3.351288627e-03 + vertex 2.762360161e-04 -1.000000000e+00 2.926719016e-03 + endloop + endfacet + facet normal -1.070251372e-01 -0.000000000e+00 -9.942563150e-01 + outer loop + vertex 7.623777525e-01 0.000000000e+00 2.931923745e-02 + vertex 7.769449477e-01 -1.000000000e+00 2.775117492e-02 + vertex 7.623777525e-01 -1.000000000e+00 2.931923745e-02 + endloop + endfacet + facet normal 9.846931504e-01 0.000000000e+00 -1.742968721e-01 + outer loop + vertex 2.061140380e-04 0.000000000e+00 2.530563705e-03 + vertex 2.762360161e-04 0.000000000e+00 2.926719016e-03 + vertex 2.762360161e-04 -1.000000000e+00 2.926719016e-03 + endloop + endfacet + facet normal -1.070251372e-01 0.000000000e+00 -9.942563150e-01 + outer loop + vertex 7.623777525e-01 0.000000000e+00 2.931923745e-02 + vertex 7.769449477e-01 0.000000000e+00 2.775117492e-02 + vertex 7.769449477e-01 -1.000000000e+00 2.775117492e-02 + endloop + endfacet + facet normal -1.070251372e-01 2.371970670e-310 -9.942563150e-01 + outer loop + vertex 2.061140380e-04 0.000000000e+00 2.530563705e-03 + vertex 2.762360161e-04 -1.000000000e+00 2.926719016e-03 + vertex 2.061140380e-04 -1.000000000e+00 2.530563705e-03 + endloop + endfacet + facet normal -1.089072894e-01 -0.000000000e+00 -9.940519113e-01 + outer loop + vertex 7.769449477e-01 0.000000000e+00 2.775117492e-02 + vertex 7.909517772e-01 -1.000000000e+00 2.621660131e-02 + vertex 7.769449477e-01 -1.000000000e+00 2.775117492e-02 + endloop + endfacet + facet normal 9.886812308e-01 0.000000000e+00 -1.500314095e-01 + outer loop + vertex 1.500786146e-04 0.000000000e+00 2.161299885e-03 + vertex 2.061140380e-04 0.000000000e+00 2.530563705e-03 + vertex 2.061140380e-04 -1.000000000e+00 2.530563705e-03 + endloop + endfacet + facet normal -1.089072894e-01 0.000000000e+00 -9.940519113e-01 + outer loop + vertex 7.769449477e-01 0.000000000e+00 2.775117492e-02 + vertex 7.909517772e-01 0.000000000e+00 2.621660131e-02 + vertex 7.909517772e-01 -1.000000000e+00 2.621660131e-02 + endloop + endfacet + facet normal -1.089072894e-01 2.371970670e-310 -9.940519113e-01 + outer loop + vertex 1.500786146e-04 0.000000000e+00 2.161299885e-03 + vertex 2.061140380e-04 -1.000000000e+00 2.530563705e-03 + vertex 1.500786146e-04 -1.000000000e+00 2.161299885e-03 + endloop + endfacet + facet normal -1.107164486e-01 -0.000000000e+00 -9.938520353e-01 + outer loop + vertex 7.909517772e-01 0.000000000e+00 2.621660131e-02 + vertex 8.043927285e-01 -1.000000000e+00 2.471926132e-02 + vertex 7.909517772e-01 -1.000000000e+00 2.621660131e-02 + endloop + endfacet + facet normal 9.918637954e-01 0.000000000e+00 -1.273036187e-01 + outer loop + vertex 1.059404071e-04 0.000000000e+00 1.817404791e-03 + vertex 1.500786146e-04 0.000000000e+00 2.161299885e-03 + vertex 1.500786146e-04 -1.000000000e+00 2.161299885e-03 + endloop + endfacet + facet normal -1.107164486e-01 0.000000000e+00 -9.938520353e-01 + outer loop + vertex 7.909517772e-01 0.000000000e+00 2.621660131e-02 + vertex 8.043927285e-01 0.000000000e+00 2.471926132e-02 + vertex 8.043927285e-01 -1.000000000e+00 2.471926132e-02 + endloop + endfacet + facet normal -1.107164486e-01 2.371970670e-310 -9.938520353e-01 + outer loop + vertex 1.059404071e-04 0.000000000e+00 1.817404791e-03 + vertex 1.500786146e-04 -1.000000000e+00 2.161299885e-03 + vertex 1.059404071e-04 -1.000000000e+00 1.817404791e-03 + endloop + endfacet + facet normal -1.124564291e-01 -0.000000000e+00 -9.936566568e-01 + outer loop + vertex 8.043927285e-01 0.000000000e+00 2.471926132e-02 + vertex 8.172657826e-01 -1.000000000e+00 2.326236201e-02 + vertex 8.043927285e-01 -1.000000000e+00 2.471926132e-02 + endloop + endfacet + facet normal 9.943589292e-01 0.000000000e+00 -1.060675252e-01 + outer loop + vertex 7.180327325e-05 0.000000000e+00 1.497376923e-03 + vertex 1.059404071e-04 0.000000000e+00 1.817404791e-03 + vertex 1.059404071e-04 -1.000000000e+00 1.817404791e-03 + endloop + endfacet + facet normal -1.124564291e-01 0.000000000e+00 -9.936566568e-01 + outer loop + vertex 8.043927285e-01 0.000000000e+00 2.471926132e-02 + vertex 8.172657826e-01 0.000000000e+00 2.326236201e-02 + vertex 8.172657826e-01 -1.000000000e+00 2.326236201e-02 + endloop + endfacet + facet normal -1.124564291e-01 2.371970670e-310 -9.936566568e-01 + outer loop + vertex 7.180327325e-05 0.000000000e+00 1.497376923e-03 + vertex 1.059404071e-04 -1.000000000e+00 1.817404791e-03 + vertex 7.180327325e-05 -1.000000000e+00 1.497376923e-03 + endloop + endfacet + facet normal -1.141303372e-01 -0.000000000e+00 -9.934657851e-01 + outer loop + vertex 8.172657826e-01 0.000000000e+00 2.326236201e-02 + vertex 8.295721518e-01 -1.000000000e+00 2.184859409e-02 + vertex 8.172657826e-01 -1.000000000e+00 2.326236201e-02 + endloop + endfacet + facet normal 9.962713608e-01 0.000000000e+00 -8.627500005e-02 + outer loop + vertex 4.602934243e-05 0.000000000e+00 1.199749232e-03 + vertex 7.180327325e-05 0.000000000e+00 1.497376923e-03 + vertex 7.180327325e-05 -1.000000000e+00 1.497376923e-03 + endloop + endfacet + facet normal -1.141303372e-01 0.000000000e+00 -9.934657851e-01 + outer loop + vertex 8.172657826e-01 0.000000000e+00 2.326236201e-02 + vertex 8.295721518e-01 0.000000000e+00 2.184859409e-02 + vertex 8.295721518e-01 -1.000000000e+00 2.184859409e-02 + endloop + endfacet + facet normal -1.141303372e-01 2.371970670e-310 -9.934657851e-01 + outer loop + vertex 4.602934243e-05 0.000000000e+00 1.199749232e-03 + vertex 7.180327325e-05 -1.000000000e+00 1.497376923e-03 + vertex 4.602934243e-05 -1.000000000e+00 1.199749232e-03 + endloop + endfacet + facet normal -1.157406790e-01 -0.000000000e+00 -9.932794648e-01 + outer loop + vertex 8.295721518e-01 0.000000000e+00 2.184859409e-02 + vertex 8.413159970e-01 -1.000000000e+00 2.048015683e-02 + vertex 8.295721518e-01 -1.000000000e+00 2.184859409e-02 + endloop + endfacet + facet normal 9.976948642e-01 0.000000000e+00 -6.785984115e-02 + outer loop + vertex 2.721275946e-05 0.000000000e+00 9.231024272e-04 + vertex 4.602934243e-05 0.000000000e+00 1.199749232e-03 + vertex 4.602934243e-05 -1.000000000e+00 1.199749232e-03 + endloop + endfacet + facet normal -1.157406790e-01 0.000000000e+00 -9.932794648e-01 + outer loop + vertex 8.295721518e-01 0.000000000e+00 2.184859409e-02 + vertex 8.413159970e-01 0.000000000e+00 2.048015683e-02 + vertex 8.413159970e-01 -1.000000000e+00 2.048015683e-02 + endloop + endfacet + facet normal -1.157406790e-01 2.371970670e-310 -9.932794648e-01 + outer loop + vertex 2.721275946e-05 0.000000000e+00 9.231024272e-04 + vertex 4.602934243e-05 -1.000000000e+00 1.199749232e-03 + vertex 2.721275946e-05 -1.000000000e+00 9.231024272e-04 + endloop + endfacet + facet normal -1.172894744e-01 -0.000000000e+00 -9.930977692e-01 + outer loop + vertex 8.413159970e-01 0.000000000e+00 2.048015683e-02 + vertex 8.525041347e-01 -1.000000000e+00 1.915878564e-02 + vertex 8.413159970e-01 -1.000000000e+00 2.048015683e-02 + endloop + endfacet + facet normal 9.987111802e-01 0.000000000e+00 -5.075409788e-02 + outer loop + vertex 1.415062741e-05 0.000000000e+00 6.660729881e-04 + vertex 2.721275946e-05 0.000000000e+00 9.231024272e-04 + vertex 2.721275946e-05 -1.000000000e+00 9.231024272e-04 + endloop + endfacet + facet normal -1.172894744e-01 0.000000000e+00 -9.930977692e-01 + outer loop + vertex 8.413159970e-01 0.000000000e+00 2.048015683e-02 + vertex 8.525041347e-01 0.000000000e+00 1.915878564e-02 + vertex 8.525041347e-01 -1.000000000e+00 1.915878564e-02 + endloop + endfacet + facet normal -1.172894744e-01 2.371970670e-310 -9.930977692e-01 + outer loop + vertex 1.415062741e-05 0.000000000e+00 6.660729881e-04 + vertex 2.721275946e-05 -1.000000000e+00 9.231024272e-04 + vertex 1.415062741e-05 -1.000000000e+00 6.660729881e-04 + endloop + endfacet + facet normal -1.187783598e-01 -0.000000000e+00 -9.929207930e-01 + outer loop + vertex 8.525041347e-01 0.000000000e+00 1.915878564e-02 + vertex 8.631457375e-01 -1.000000000e+00 1.788578165e-02 + vertex 8.525041347e-01 -1.000000000e+00 1.915878564e-02 + endloop + endfacet + facet normal 9.993914177e-01 0.000000000e+00 -3.488257686e-02 + outer loop + vertex 5.818606344e-06 0.000000000e+00 4.273592491e-04 + vertex 1.415062741e-05 0.000000000e+00 6.660729881e-04 + vertex 1.415062741e-05 -1.000000000e+00 6.660729881e-04 + endloop + endfacet + facet normal -1.187783598e-01 0.000000000e+00 -9.929207930e-01 + outer loop + vertex 8.525041347e-01 0.000000000e+00 1.915878564e-02 + vertex 8.631457375e-01 0.000000000e+00 1.788578165e-02 + vertex 8.631457375e-01 -1.000000000e+00 1.788578165e-02 + endloop + endfacet + facet normal -1.187783598e-01 2.371970670e-310 -9.929207930e-01 + outer loop + vertex 5.818606344e-06 0.000000000e+00 4.273592491e-04 + vertex 1.415062741e-05 -1.000000000e+00 6.660729881e-04 + vertex 5.818606344e-06 -1.000000000e+00 4.273592491e-04 + endloop + endfacet + facet normal -1.202086835e-01 -0.000000000e+00 -9.927486451e-01 + outer loop + vertex 8.631457375e-01 0.000000000e+00 1.788578165e-02 + vertex 8.732520369e-01 -1.000000000e+00 1.666204294e-02 + vertex 8.631457375e-01 -1.000000000e+00 1.788578165e-02 + endloop + endfacet + facet normal 9.997965274e-01 0.000000000e+00 -2.017185708e-02 + outer loop + vertex 1.346916910e-06 0.000000000e+00 2.057247437e-04 + vertex 5.818606344e-06 0.000000000e+00 4.273592491e-04 + vertex 5.818606344e-06 -1.000000000e+00 4.273592491e-04 + endloop + endfacet + facet normal -1.202086835e-01 0.000000000e+00 -9.927486451e-01 + outer loop + vertex 8.631457375e-01 0.000000000e+00 1.788578165e-02 + vertex 8.732520369e-01 0.000000000e+00 1.666204294e-02 + vertex 8.732520369e-01 -1.000000000e+00 1.666204294e-02 + endloop + endfacet + facet normal -1.202086835e-01 2.371970670e-310 -9.927486451e-01 + outer loop + vertex 1.346916910e-06 0.000000000e+00 2.057247437e-04 + vertex 5.818606344e-06 -1.000000000e+00 4.273592491e-04 + vertex 1.346916910e-06 -1.000000000e+00 2.057247437e-04 + endloop + endfacet + facet normal -1.215815886e-01 -0.000000000e+00 -9.925814412e-01 + outer loop + vertex 8.732520369e-01 0.000000000e+00 1.666204294e-02 + vertex 8.828360321e-01 -1.000000000e+00 1.548809660e-02 + vertex 8.732520369e-01 -1.000000000e+00 1.666204294e-02 + endloop + endfacet + facet normal 9.999785679e-01 0.000000000e+00 -6.547039596e-03 + outer loop + vertex 0.000000000e+00 0.000000000e+00 0.000000000e+00 + vertex 1.346916910e-06 0.000000000e+00 2.057247437e-04 + vertex 1.346916910e-06 -1.000000000e+00 2.057247437e-04 + endloop + endfacet + facet normal -1.215815886e-01 0.000000000e+00 -9.925814412e-01 + outer loop + vertex 8.732520369e-01 0.000000000e+00 1.666204294e-02 + vertex 8.828360321e-01 0.000000000e+00 1.548809660e-02 + vertex 8.828360321e-01 -1.000000000e+00 1.548809660e-02 + endloop + endfacet + facet normal -1.215815886e-01 2.371970670e-310 -9.925814412e-01 + outer loop + vertex 0.000000000e+00 0.000000000e+00 0.000000000e+00 + vertex 1.346916910e-06 -1.000000000e+00 2.057247437e-04 + vertex 0.000000000e+00 -1.000000000e+00 0.000000000e+00 + endloop + endfacet + facet normal -1.228980857e-01 -0.000000000e+00 -9.924192967e-01 + outer loop + vertex 8.828360321e-01 0.000000000e+00 1.548809660e-02 + vertex 8.919122088e-01 -1.000000000e+00 1.436413141e-02 + vertex 8.828360321e-01 -1.000000000e+00 1.548809660e-02 + endloop + endfacet + facet normal 9.999785679e-01 0.000000000e+00 6.547039596e-03 + outer loop + vertex 1.346916910e-06 0.000000000e+00 -2.057247437e-04 + vertex 0.000000000e+00 0.000000000e+00 0.000000000e+00 + vertex 0.000000000e+00 -1.000000000e+00 0.000000000e+00 + endloop + endfacet + facet normal -1.228980857e-01 0.000000000e+00 -9.924192967e-01 + outer loop + vertex 8.828360321e-01 0.000000000e+00 1.548809660e-02 + vertex 8.919122088e-01 0.000000000e+00 1.436413141e-02 + vertex 8.919122088e-01 -1.000000000e+00 1.436413141e-02 + endloop + endfacet + facet normal -1.228980857e-01 2.371970670e-310 -9.924192967e-01 + outer loop + vertex 1.346916910e-06 0.000000000e+00 -2.057247437e-04 + vertex 0.000000000e+00 -1.000000000e+00 0.000000000e+00 + vertex 1.346916910e-06 -1.000000000e+00 -2.057247437e-04 + endloop + endfacet + facet normal -1.241591156e-01 -0.000000000e+00 -9.922623212e-01 + outer loop + vertex 8.919122088e-01 0.000000000e+00 1.436413141e-02 + vertex 9.004962735e-01 -1.000000000e+00 1.329003048e-02 + vertex 8.919122088e-01 -1.000000000e+00 1.436413141e-02 + endloop + endfacet + facet normal 9.997965274e-01 0.000000000e+00 2.017185708e-02 + outer loop + vertex 5.818606344e-06 0.000000000e+00 -4.273592491e-04 + vertex 1.346916910e-06 0.000000000e+00 -2.057247437e-04 + vertex 1.346916910e-06 -1.000000000e+00 -2.057247437e-04 + endloop + endfacet + facet normal -1.241591156e-01 0.000000000e+00 -9.922623212e-01 + outer loop + vertex 8.919122088e-01 0.000000000e+00 1.436413141e-02 + vertex 9.004962735e-01 0.000000000e+00 1.329003048e-02 + vertex 9.004962735e-01 -1.000000000e+00 1.329003048e-02 + endloop + endfacet + facet normal -1.241591156e-01 2.371970670e-310 -9.922623212e-01 + outer loop + vertex 5.818606344e-06 0.000000000e+00 -4.273592491e-04 + vertex 1.346916910e-06 -1.000000000e+00 -2.057247437e-04 + vertex 5.818606344e-06 -1.000000000e+00 -4.273592491e-04 + endloop + endfacet + facet normal -1.253655965e-01 -0.000000000e+00 -9.921106124e-01 + outer loop + vertex 9.004962735e-01 0.000000000e+00 1.329003048e-02 + vertex 9.086049032e-01 -1.000000000e+00 1.226540359e-02 + vertex 9.004962735e-01 -1.000000000e+00 1.329003048e-02 + endloop + endfacet + facet normal 9.993914177e-01 0.000000000e+00 3.488257686e-02 + outer loop + vertex 1.415062741e-05 0.000000000e+00 -6.660729881e-04 + vertex 5.818606344e-06 0.000000000e+00 -4.273592491e-04 + vertex 5.818606344e-06 -1.000000000e+00 -4.273592491e-04 + endloop + endfacet + facet normal -1.253655965e-01 0.000000000e+00 -9.921106124e-01 + outer loop + vertex 9.004962735e-01 0.000000000e+00 1.329003048e-02 + vertex 9.086049032e-01 0.000000000e+00 1.226540359e-02 + vertex 9.086049032e-01 -1.000000000e+00 1.226540359e-02 + endloop + endfacet + facet normal -1.253655965e-01 2.371970670e-310 -9.921106124e-01 + outer loop + vertex 1.415062741e-05 0.000000000e+00 -6.660729881e-04 + vertex 5.818606344e-06 -1.000000000e+00 -4.273592491e-04 + vertex 1.415062741e-05 -1.000000000e+00 -6.660729881e-04 + endloop + endfacet + facet normal -1.265184621e-01 -0.000000000e+00 -9.919642528e-01 + outer loop + vertex 9.086049032e-01 0.000000000e+00 1.226540359e-02 + vertex 9.162555145e-01 -1.000000000e+00 1.128961886e-02 + vertex 9.086049032e-01 -1.000000000e+00 1.226540359e-02 + endloop + endfacet + facet normal 9.987111802e-01 0.000000000e+00 5.075409787e-02 + outer loop + vertex 2.721275946e-05 0.000000000e+00 -9.231024272e-04 + vertex 1.415062741e-05 0.000000000e+00 -6.660729881e-04 + vertex 1.415062741e-05 -1.000000000e+00 -6.660729881e-04 + endloop + endfacet + facet normal -1.265184621e-01 0.000000000e+00 -9.919642528e-01 + outer loop + vertex 9.086049032e-01 0.000000000e+00 1.226540359e-02 + vertex 9.162555145e-01 0.000000000e+00 1.128961886e-02 + vertex 9.162555145e-01 -1.000000000e+00 1.128961886e-02 + endloop + endfacet + facet normal -1.265184621e-01 2.371970670e-310 -9.919642528e-01 + outer loop + vertex 2.721275946e-05 0.000000000e+00 -9.231024272e-04 + vertex 1.415062741e-05 -1.000000000e+00 -6.660729881e-04 + vertex 2.721275946e-05 -1.000000000e+00 -9.231024272e-04 + endloop + endfacet + facet normal -1.276186911e-01 -0.000000000e+00 -9.918233057e-01 + outer loop + vertex 9.162555145e-01 0.000000000e+00 1.128961886e-02 + vertex 9.234660518e-01 -1.000000000e+00 1.036183331e-02 + vertex 9.162555145e-01 -1.000000000e+00 1.128961886e-02 + endloop + endfacet + facet normal 9.976948642e-01 0.000000000e+00 6.785984114e-02 + outer loop + vertex 4.602934243e-05 0.000000000e+00 -1.199749232e-03 + vertex 2.721275946e-05 0.000000000e+00 -9.231024272e-04 + vertex 2.721275946e-05 -1.000000000e+00 -9.231024272e-04 + endloop + endfacet + facet normal -1.276186911e-01 0.000000000e+00 -9.918233057e-01 + outer loop + vertex 9.162555145e-01 0.000000000e+00 1.128961886e-02 + vertex 9.234660518e-01 0.000000000e+00 1.036183331e-02 + vertex 9.234660518e-01 -1.000000000e+00 1.036183331e-02 + endloop + endfacet + facet normal -1.276186911e-01 2.371970670e-310 -9.918233057e-01 + outer loop + vertex 4.602934243e-05 0.000000000e+00 -1.199749232e-03 + vertex 2.721275946e-05 -1.000000000e+00 -9.231024272e-04 + vertex 4.602934243e-05 -1.000000000e+00 -1.199749232e-03 + endloop + endfacet + facet normal -1.286673255e-01 -0.000000000e+00 -9.916878134e-01 + outer loop + vertex 9.234660518e-01 0.000000000e+00 1.036183331e-02 + vertex 9.302547963e-01 -1.000000000e+00 9.481022247e-03 + vertex 9.234660518e-01 -1.000000000e+00 1.036183331e-02 + endloop + endfacet + facet normal 9.962713608e-01 0.000000000e+00 8.627500005e-02 + outer loop + vertex 7.180327325e-05 0.000000000e+00 -1.497376923e-03 + vertex 4.602934243e-05 0.000000000e+00 -1.199749232e-03 + vertex 4.602934243e-05 -1.000000000e+00 -1.199749232e-03 + endloop + endfacet + facet normal -1.286673255e-01 0.000000000e+00 -9.916878134e-01 + outer loop + vertex 9.234660518e-01 0.000000000e+00 1.036183331e-02 + vertex 9.302547963e-01 0.000000000e+00 9.481022247e-03 + vertex 9.302547963e-01 -1.000000000e+00 9.481022247e-03 + endloop + endfacet + facet normal -1.286673255e-01 2.371970670e-310 -9.916878134e-01 + outer loop + vertex 7.180327325e-05 0.000000000e+00 -1.497376923e-03 + vertex 4.602934243e-05 -1.000000000e+00 -1.199749232e-03 + vertex 7.180327325e-05 -1.000000000e+00 -1.497376923e-03 + endloop + endfacet + facet normal -1.296654827e-01 -0.000000000e+00 -9.915577959e-01 + outer loop + vertex 9.302547963e-01 0.000000000e+00 9.481022247e-03 + vertex 9.366401952e-01 -1.000000000e+00 8.646007049e-03 + vertex 9.302547963e-01 -1.000000000e+00 9.481022247e-03 + endloop + endfacet + facet normal 9.943589292e-01 0.000000000e+00 1.060675252e-01 + outer loop + vertex 1.059404071e-04 0.000000000e+00 -1.817404791e-03 + vertex 7.180327325e-05 0.000000000e+00 -1.497376923e-03 + vertex 7.180327325e-05 -1.000000000e+00 -1.497376923e-03 + endloop + endfacet + facet normal -1.296654827e-01 0.000000000e+00 -9.915577959e-01 + outer loop + vertex 9.302547963e-01 0.000000000e+00 9.481022247e-03 + vertex 9.366401952e-01 0.000000000e+00 8.646007049e-03 + vertex 9.366401952e-01 -1.000000000e+00 8.646007049e-03 + endloop + endfacet + facet normal -1.296654827e-01 2.371970670e-310 -9.915577959e-01 + outer loop + vertex 1.059404071e-04 0.000000000e+00 -1.817404791e-03 + vertex 7.180327325e-05 -1.000000000e+00 -1.497376923e-03 + vertex 1.059404071e-04 -1.000000000e+00 -1.817404791e-03 + endloop + endfacet + facet normal -1.306143609e-01 -0.000000000e+00 -9.914332498e-01 + outer loop + vertex 9.366401952e-01 0.000000000e+00 8.646007049e-03 + vertex 9.426407106e-01 -1.000000000e+00 7.855481327e-03 + vertex 9.366401952e-01 -1.000000000e+00 8.646007049e-03 + endloop + endfacet + facet normal 9.918637954e-01 0.000000000e+00 1.273036187e-01 + outer loop + vertex 1.500786146e-04 0.000000000e+00 -2.161299885e-03 + vertex 1.059404071e-04 0.000000000e+00 -1.817404791e-03 + vertex 1.059404071e-04 -1.000000000e+00 -1.817404791e-03 + endloop + endfacet + facet normal -1.306143609e-01 0.000000000e+00 -9.914332498e-01 + outer loop + vertex 9.366401952e-01 0.000000000e+00 8.646007049e-03 + vertex 9.426407106e-01 0.000000000e+00 7.855481327e-03 + vertex 9.426407106e-01 -1.000000000e+00 7.855481327e-03 + endloop + endfacet + facet normal -1.306143609e-01 2.371970670e-310 -9.914332498e-01 + outer loop + vertex 1.500786146e-04 0.000000000e+00 -2.161299885e-03 + vertex 1.059404071e-04 -1.000000000e+00 -1.817404791e-03 + vertex 1.500786146e-04 -1.000000000e+00 -2.161299885e-03 + endloop + endfacet + facet normal -1.315152389e-01 -0.000000000e+00 -9.913141490e-01 + outer loop + vertex 9.426407106e-01 0.000000000e+00 7.855481327e-03 + vertex 9.482746880e-01 -1.000000000e+00 7.108035235e-03 + vertex 9.426407106e-01 -1.000000000e+00 7.855481327e-03 + endloop + endfacet + facet normal 9.886812308e-01 0.000000000e+00 1.500314095e-01 + outer loop + vertex 2.061140379e-04 0.000000000e+00 -2.530563705e-03 + vertex 1.500786146e-04 0.000000000e+00 -2.161299885e-03 + vertex 1.500786146e-04 -1.000000000e+00 -2.161299885e-03 + endloop + endfacet + facet normal -1.315152389e-01 0.000000000e+00 -9.913141490e-01 + outer loop + vertex 9.426407106e-01 0.000000000e+00 7.855481327e-03 + vertex 9.482746880e-01 0.000000000e+00 7.108035235e-03 + vertex 9.482746880e-01 -1.000000000e+00 7.108035235e-03 + endloop + endfacet + facet normal -1.315152389e-01 2.371970670e-310 -9.913141490e-01 + outer loop + vertex 2.061140379e-04 0.000000000e+00 -2.530563705e-03 + vertex 1.500786146e-04 -1.000000000e+00 -2.161299885e-03 + vertex 2.061140379e-04 -1.000000000e+00 -2.530563705e-03 + endloop + endfacet + facet normal -1.323694742e-01 -0.000000000e+00 -9.912004451e-01 + outer loop + vertex 9.482746880e-01 0.000000000e+00 7.108035235e-03 + vertex 9.535602429e-01 -1.000000000e+00 6.402177880e-03 + vertex 9.482746880e-01 -1.000000000e+00 7.108035235e-03 + endloop + endfacet + facet normal 9.846931504e-01 0.000000000e+00 1.742968721e-01 + outer loop + vertex 2.762360161e-04 0.000000000e+00 -2.926719016e-03 + vertex 2.061140379e-04 0.000000000e+00 -2.530563705e-03 + vertex 2.061140379e-04 -1.000000000e+00 -2.530563705e-03 + endloop + endfacet + facet normal -1.323694742e-01 0.000000000e+00 -9.912004451e-01 + outer loop + vertex 9.482746880e-01 0.000000000e+00 7.108035235e-03 + vertex 9.535602429e-01 0.000000000e+00 6.402177880e-03 + vertex 9.535602429e-01 -1.000000000e+00 6.402177880e-03 + endloop + endfacet + facet normal -1.323694742e-01 2.371970670e-310 -9.912004451e-01 + outer loop + vertex 2.762360161e-04 0.000000000e+00 -2.926719016e-03 + vertex 2.061140379e-04 -1.000000000e+00 -2.530563705e-03 + vertex 2.762360161e-04 -1.000000000e+00 -2.926719016e-03 + endloop + endfacet + facet normal -1.331784915e-01 -0.000000000e+00 -9.910920691e-01 + outer loop + vertex 9.535602429e-01 0.000000000e+00 6.402177880e-03 + vertex 9.585151646e-01 -1.000000000e+00 5.736357801e-03 + vertex 9.535602429e-01 -1.000000000e+00 6.402177880e-03 + endloop + endfacet + facet normal 9.797717541e-01 0.000000000e+00 2.001182400e-01 + outer loop + vertex 3.629542982e-04 0.000000000e+00 -3.351288627e-03 + vertex 2.762360161e-04 0.000000000e+00 -2.926719016e-03 + vertex 2.762360161e-04 -1.000000000e+00 -2.926719016e-03 + endloop + endfacet + facet normal -1.331784915e-01 0.000000000e+00 -9.910920691e-01 + outer loop + vertex 9.535602429e-01 0.000000000e+00 6.402177880e-03 + vertex 9.585151646e-01 0.000000000e+00 5.736357801e-03 + vertex 9.585151646e-01 -1.000000000e+00 5.736357801e-03 + endloop + endfacet + facet normal -1.331784915e-01 2.371970670e-310 -9.910920691e-01 + outer loop + vertex 3.629542982e-04 0.000000000e+00 -3.351288627e-03 + vertex 2.762360161e-04 -1.000000000e+00 -2.926719016e-03 + vertex 3.629542982e-04 -1.000000000e+00 -3.351288627e-03 + endloop + endfacet + facet normal -1.339437802e-01 -0.000000000e+00 -9.909889322e-01 + outer loop + vertex 9.585151646e-01 0.000000000e+00 5.736357801e-03 + vertex 9.631568360e-01 -1.000000000e+00 5.108981458e-03 + vertex 9.585151646e-01 -1.000000000e+00 5.736357801e-03 + endloop + endfacet + facet normal 9.737803899e-01 0.000000000e+00 2.274901146e-01 + outer loop + vertex 4.691284474e-04 0.000000000e+00 -3.805771252e-03 + vertex 3.629542982e-04 0.000000000e+00 -3.351288627e-03 + vertex 3.629542982e-04 -1.000000000e+00 -3.351288627e-03 + endloop + endfacet + facet normal -1.339437802e-01 0.000000000e+00 -9.909889322e-01 + outer loop + vertex 9.585151646e-01 0.000000000e+00 5.736357801e-03 + vertex 9.631568360e-01 0.000000000e+00 5.108981458e-03 + vertex 9.631568360e-01 -1.000000000e+00 5.108981458e-03 + endloop + endfacet + facet normal -1.339437802e-01 2.371970670e-310 -9.909889322e-01 + outer loop + vertex 4.691284474e-04 0.000000000e+00 -3.805771252e-03 + vertex 3.629542982e-04 -1.000000000e+00 -3.351288627e-03 + vertex 4.691284474e-04 -1.000000000e+00 -3.805771252e-03 + endloop + endfacet + facet normal -1.346668767e-01 -0.000000000e+00 -9.908909286e-01 + outer loop + vertex 9.631568360e-01 0.000000000e+00 5.108981458e-03 + vertex 9.675021678e-01 -1.000000000e+00 4.518429822e-03 + vertex 9.631568360e-01 -1.000000000e+00 5.108981458e-03 + endloop + endfacet + facet normal 9.665775405e-01 0.000000000e+00 2.563744493e-01 + outer loop + vertex 5.979922705e-04 0.000000000e+00 -4.291610919e-03 + vertex 4.691284474e-04 0.000000000e+00 -3.805771252e-03 + vertex 4.691284474e-04 -1.000000000e+00 -3.805771252e-03 + endloop + endfacet + facet normal -1.346668767e-01 0.000000000e+00 -9.908909286e-01 + outer loop + vertex 9.631568360e-01 0.000000000e+00 5.108981458e-03 + vertex 9.675021678e-01 0.000000000e+00 4.518429822e-03 + vertex 9.675021678e-01 -1.000000000e+00 4.518429822e-03 + endloop + endfacet + facet normal -1.346668767e-01 2.371970670e-310 -9.908909286e-01 + outer loop + vertex 5.979922705e-04 0.000000000e+00 -4.291610919e-03 + vertex 4.691284474e-04 -1.000000000e+00 -3.805771252e-03 + vertex 5.979922705e-04 -1.000000000e+00 -4.291610919e-03 + endloop + endfacet + facet normal -1.353493602e-01 -0.000000000e+00 -9.907979364e-01 + outer loop + vertex 9.675021678e-01 0.000000000e+00 4.518429822e-03 + vertex 9.715675461e-01 -1.000000000e+00 3.963073045e-03 + vertex 9.675021678e-01 -1.000000000e+00 4.518429822e-03 + endloop + endfacet + facet normal 9.580156776e-01 0.000000000e+00 2.867158202e-01 + outer loop + vertex 7.531893325e-04 0.000000000e+00 -4.810177416e-03 + vertex 5.979922705e-04 0.000000000e+00 -4.291610919e-03 + vertex 5.979922705e-04 -1.000000000e+00 -4.291610919e-03 + endloop + endfacet + facet normal -1.353493602e-01 0.000000000e+00 -9.907979364e-01 + outer loop + vertex 9.675021678e-01 0.000000000e+00 4.518429822e-03 + vertex 9.715675461e-01 0.000000000e+00 3.963073045e-03 + vertex 9.715675461e-01 -1.000000000e+00 3.963073045e-03 + endloop + endfacet + facet normal -1.353493602e-01 2.371970670e-310 -9.907979364e-01 + outer loop + vertex 7.531893325e-04 0.000000000e+00 -4.810177416e-03 + vertex 5.979922705e-04 -1.000000000e+00 -4.291610919e-03 + vertex 7.531893325e-04 -1.000000000e+00 -4.810177416e-03 + endloop + endfacet + facet normal -1.359928360e-01 -0.000000000e+00 -9.907098206e-01 + outer loop + vertex 9.715675461e-01 0.000000000e+00 3.963073045e-03 + vertex 9.753687917e-01 -1.000000000e+00 3.441283350e-03 + vertex 9.715675461e-01 -1.000000000e+00 3.963073045e-03 + endloop + endfacet + facet normal 9.479615149e-01 0.000000000e+00 3.183849341e-01 + outer loop + vertex 9.387642339e-04 0.000000000e+00 -5.362709417e-03 + vertex 7.531893325e-04 0.000000000e+00 -4.810177416e-03 + vertex 7.531893325e-04 -1.000000000e+00 -4.810177416e-03 + endloop + endfacet + facet normal -1.359928360e-01 0.000000000e+00 -9.907098206e-01 + outer loop + vertex 9.715675461e-01 0.000000000e+00 3.963073045e-03 + vertex 9.753687917e-01 0.000000000e+00 3.441283350e-03 + vertex 9.753687917e-01 -1.000000000e+00 3.441283350e-03 + endloop + endfacet + facet normal -1.359928360e-01 2.371970670e-310 -9.907098206e-01 + outer loop + vertex 9.387642339e-04 0.000000000e+00 -5.362709417e-03 + vertex 7.531893325e-04 -1.000000000e+00 -4.810177416e-03 + vertex 9.387642339e-04 -1.000000000e+00 -5.362709417e-03 + endloop + endfacet + facet normal -1.365989258e-01 -0.000000000e+00 -9.906264349e-01 + outer loop + vertex 9.753687917e-01 0.000000000e+00 3.441283350e-03 + vertex 9.789211303e-01 -1.000000000e+00 2.951446198e-03 + vertex 9.753687917e-01 -1.000000000e+00 3.441283350e-03 + endloop + endfacet + facet normal 9.362860169e-01 0.000000000e+00 3.512385152e-01 + outer loop + vertex 1.159193086e-03 0.000000000e+00 -5.950300022e-03 + vertex 9.387642339e-04 0.000000000e+00 -5.362709417e-03 + vertex 9.387642339e-04 -1.000000000e+00 -5.362709417e-03 + endloop + endfacet + facet normal -1.365989258e-01 0.000000000e+00 -9.906264349e-01 + outer loop + vertex 9.753687917e-01 0.000000000e+00 3.441283350e-03 + vertex 9.789211303e-01 0.000000000e+00 2.951446198e-03 + vertex 9.789211303e-01 -1.000000000e+00 2.951446198e-03 + endloop + endfacet + facet normal -1.365989258e-01 2.371970670e-310 -9.906264349e-01 + outer loop + vertex 1.159193086e-03 0.000000000e+00 -5.950300022e-03 + vertex 9.387642339e-04 -1.000000000e+00 -5.362709417e-03 + vertex 1.159193086e-03 -1.000000000e+00 -5.950300022e-03 + endloop + endfacet + facet normal -1.371692595e-01 -0.000000000e+00 -9.905476234e-01 + outer loop + vertex 9.789211303e-01 0.000000000e+00 2.951446198e-03 + vertex 9.822391712e-01 -1.000000000e+00 2.491969835e-03 + vertex 9.789211303e-01 -1.000000000e+00 2.951446198e-03 + endloop + endfacet + facet normal 9.228834274e-01 0.000000000e+00 3.850794457e-01 + outer loop + vertex 1.419377891e-03 0.000000000e+00 -6.573860296e-03 + vertex 1.159193086e-03 0.000000000e+00 -5.950300022e-03 + vertex 1.159193086e-03 -1.000000000e+00 -5.950300022e-03 + endloop + endfacet + facet normal -1.371692595e-01 0.000000000e+00 -9.905476234e-01 + outer loop + vertex 9.789211303e-01 0.000000000e+00 2.951446198e-03 + vertex 9.822391712e-01 0.000000000e+00 2.491969835e-03 + vertex 9.822391712e-01 -1.000000000e+00 2.491969835e-03 + endloop + endfacet + facet normal -1.371692595e-01 2.371970670e-310 -9.905476234e-01 + outer loop + vertex 1.419377891e-03 0.000000000e+00 -6.573860296e-03 + vertex 1.159193086e-03 -1.000000000e+00 -5.950300022e-03 + vertex 1.419377891e-03 -1.000000000e+00 -6.573860296e-03 + endloop + endfacet + facet normal -1.377054593e-01 -0.000000000e+00 -9.904732235e-01 + outer loop + vertex 9.822391712e-01 0.000000000e+00 2.491969835e-03 + vertex 9.853368953e-01 -1.000000000e+00 2.061293362e-03 + vertex 9.822391712e-01 -1.000000000e+00 2.491969835e-03 + endloop + endfacet + facet normal 9.076819810e-01 0.000000000e+00 4.196586963e-01 + outer loop + vertex 1.724623064e-03 0.000000000e+00 -7.234076671e-03 + vertex 1.419377891e-03 0.000000000e+00 -6.573860296e-03 + vertex 1.419377891e-03 -1.000000000e+00 -6.573860296e-03 + endloop + endfacet + facet normal -1.377054593e-01 0.000000000e+00 -9.904732235e-01 + outer loop + vertex 9.822391712e-01 0.000000000e+00 2.491969835e-03 + vertex 9.853368953e-01 0.000000000e+00 2.061293362e-03 + vertex 9.853368953e-01 -1.000000000e+00 2.061293362e-03 + endloop + endfacet + facet normal -1.377054593e-01 2.371970670e-310 -9.904732235e-01 + outer loop + vertex 1.724623064e-03 0.000000000e+00 -7.234076671e-03 + vertex 1.419377891e-03 -1.000000000e+00 -6.573860296e-03 + vertex 1.724623064e-03 -1.000000000e+00 -7.234076671e-03 + endloop + endfacet + facet normal -1.382091374e-01 -0.000000000e+00 -9.904030666e-01 + outer loop + vertex 9.853368953e-01 0.000000000e+00 2.061293362e-03 + vertex 9.882276488e-01 -1.000000000e+00 1.657893416e-03 + vertex 9.853368953e-01 -1.000000000e+00 2.061293362e-03 + endloop + endfacet + facet normal 8.906458568e-01 0.000000000e+00 4.546976554e-01 + outer loop + vertex 2.080623294e-03 0.000000000e+00 -7.931397466e-03 + vertex 1.724623064e-03 0.000000000e+00 -7.234076671e-03 + vertex 1.724623064e-03 -1.000000000e+00 -7.234076671e-03 + endloop + endfacet + facet normal -1.382091374e-01 0.000000000e+00 -9.904030666e-01 + outer loop + vertex 9.853368953e-01 0.000000000e+00 2.061293362e-03 + vertex 9.882276488e-01 0.000000000e+00 1.657893416e-03 + vertex 9.882276488e-01 -1.000000000e+00 1.657893416e-03 + endloop + endfacet + facet normal -1.382091374e-01 2.371970670e-310 -9.904030666e-01 + outer loop + vertex 2.080623294e-03 0.000000000e+00 -7.931397466e-03 + vertex 1.724623064e-03 -1.000000000e+00 -7.234076671e-03 + vertex 2.080623294e-03 -1.000000000e+00 -7.931397466e-03 + endloop + endfacet + facet normal -1.386818826e-01 -0.000000000e+00 -9.903369807e-01 + outer loop + vertex 9.882276488e-01 0.000000000e+00 1.657893416e-03 + vertex 9.909241438e-01 -1.000000000e+00 1.280289614e-03 + vertex 9.882276488e-01 -1.000000000e+00 1.657893416e-03 + endloop + endfacet + facet normal 8.717854146e-01 0.000000000e+00 4.898879371e-01 + outer loop + vertex 2.493434235e-03 0.000000000e+00 -8.666019672e-03 + vertex 2.080623294e-03 0.000000000e+00 -7.931397466e-03 + vertex 2.080623294e-03 -1.000000000e+00 -7.931397466e-03 + endloop + endfacet + facet normal -1.386818826e-01 0.000000000e+00 -9.903369807e-01 + outer loop + vertex 9.882276488e-01 0.000000000e+00 1.657893416e-03 + vertex 9.909241438e-01 0.000000000e+00 1.280289614e-03 + vertex 9.909241438e-01 -1.000000000e+00 1.280289614e-03 + endloop + endfacet + facet normal -1.386818826e-01 2.371970670e-310 -9.903369807e-01 + outer loop + vertex 2.493434235e-03 0.000000000e+00 -8.666019672e-03 + vertex 2.080623294e-03 -1.000000000e+00 -7.931397466e-03 + vertex 2.493434235e-03 -1.000000000e+00 -8.666019672e-03 + endloop + endfacet + facet normal -1.391252567e-01 -0.000000000e+00 -9.902747916e-01 + outer loop + vertex 9.909241438e-01 0.000000000e+00 1.280289614e-03 + vertex 9.934384638e-01 -1.000000000e+00 9.270488597e-04 + vertex 9.909241438e-01 -1.000000000e+00 1.280289614e-03 + endloop + endfacet + facet normal 8.511610130e-01 0.000000000e+00 5.249046866e-01 + outer loop + vertex 2.969441608e-03 0.000000000e+00 -9.437891077e-03 + vertex 2.493434235e-03 0.000000000e+00 -8.666019672e-03 + vertex 2.493434235e-03 -1.000000000e+00 -8.666019672e-03 + endloop + endfacet + facet normal -1.391252567e-01 0.000000000e+00 -9.902747916e-01 + outer loop + vertex 9.909241438e-01 0.000000000e+00 1.280289614e-03 + vertex 9.934384638e-01 0.000000000e+00 9.270488597e-04 + vertex 9.934384638e-01 -1.000000000e+00 9.270488597e-04 + endloop + endfacet + facet normal -1.391252567e-01 2.371970670e-310 -9.902747916e-01 + outer loop + vertex 2.969441608e-03 0.000000000e+00 -9.437891077e-03 + vertex 2.493434235e-03 -1.000000000e+00 -8.666019672e-03 + vertex 2.969441608e-03 -1.000000000e+00 -9.437891077e-03 + endloop + endfacet + facet normal -1.395407809e-01 -0.000000000e+00 -9.902163251e-01 + outer loop + vertex 9.934384638e-01 0.000000000e+00 9.270488597e-04 + vertex 9.957820729e-01 -1.000000000e+00 5.967886532e-04 + vertex 9.934384638e-01 -1.000000000e+00 9.270488597e-04 + endloop + endfacet + facet normal 8.288852628e-01 0.000000000e+00 5.594186456e-01 + outer loop + vertex 3.515319859e-03 0.000000000e+00 -1.024671367e-02 + vertex 2.969441608e-03 0.000000000e+00 -9.437891077e-03 + vertex 2.969441608e-03 -1.000000000e+00 -9.437891077e-03 + endloop + endfacet + facet normal -1.395407809e-01 0.000000000e+00 -9.902163251e-01 + outer loop + vertex 9.934384638e-01 0.000000000e+00 9.270488597e-04 + vertex 9.957820729e-01 0.000000000e+00 5.967886532e-04 + vertex 9.957820729e-01 -1.000000000e+00 5.967886532e-04 + endloop + endfacet + facet normal -1.395407809e-01 2.371970670e-310 -9.902163251e-01 + outer loop + vertex 3.515319859e-03 0.000000000e+00 -1.024671367e-02 + vertex 2.969441608e-03 -1.000000000e+00 -9.437891077e-03 + vertex 3.515319859e-03 -1.000000000e+00 -1.024671367e-02 + endloop + endfacet + facet normal -1.399299448e-01 -0.000000000e+00 -9.901614063e-01 + outer loop + vertex 9.957820729e-01 0.000000000e+00 5.967886532e-04 + vertex 9.979658291e-01 -1.000000000e+00 2.881794857e-04 + vertex 9.957820729e-01 -1.000000000e+00 5.967886532e-04 + endloop + endfacet + facet normal 8.051203121e-01 0.000000000e+00 5.931115266e-01 + outer loop + vertex 4.137967065e-03 0.000000000e+00 -1.109192724e-02 + vertex 3.515319859e-03 0.000000000e+00 -1.024671367e-02 + vertex 3.515319859e-03 -1.000000000e+00 -1.024671367e-02 + endloop + endfacet + facet normal -1.399299448e-01 0.000000000e+00 -9.901614063e-01 + outer loop + vertex 9.957820729e-01 0.000000000e+00 5.967886532e-04 + vertex 9.979658291e-01 0.000000000e+00 2.881794857e-04 + vertex 9.979658291e-01 -1.000000000e+00 2.881794857e-04 + endloop + endfacet + facet normal -1.399299448e-01 2.371970670e-310 -9.901614063e-01 + outer loop + vertex 4.137967065e-03 0.000000000e+00 -1.109192724e-02 + vertex 3.515319859e-03 -1.000000000e+00 -1.024671367e-02 + vertex 4.137967065e-03 -1.000000000e+00 -1.109192724e-02 + endloop + endfacet + facet normal -1.402431081e-01 -0.000000000e+00 -9.901170994e-01 + outer loop + vertex 9.979658291e-01 0.000000000e+00 2.881794857e-04 + vertex 1.000000000e+00 -1.000000000e+00 5.352202629e-08 + vertex 9.979658291e-01 -1.000000000e+00 2.881794857e-04 + endloop + endfacet + facet normal 7.800621896e-01 0.000000000e+00 6.257019901e-01 + outer loop + vertex 4.844550254e-03 0.000000000e+00 -1.197282396e-02 + vertex 4.137967065e-03 0.000000000e+00 -1.109192724e-02 + vertex 4.137967065e-03 -1.000000000e+00 -1.109192724e-02 + endloop + endfacet + facet normal -1.410780652e-01 -1.732624298e-06 -9.899984745e-01 + outer loop + vertex 9.979658291e-01 0.000000000e+00 2.881794857e-04 + vertex 1.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 1.000000000e+00 -1.000000000e+00 5.352202629e-08 + endloop + endfacet + facet normal -1.410780652e-01 2.371970670e-310 -9.899984745e-01 + outer loop + vertex 4.844550254e-03 0.000000000e+00 -1.197282396e-02 + vertex 4.137967065e-03 -1.000000000e+00 -1.109192724e-02 + vertex 4.844550254e-03 -1.000000000e+00 -1.197282396e-02 + endloop + endfacet + facet normal 7.539426229e-01 0.000000000e+00 6.569402723e-01 + outer loop + vertex 5.642485232e-03 0.000000000e+00 -1.288858025e-02 + vertex 4.844550254e-03 0.000000000e+00 -1.197282396e-02 + vertex 4.844550254e-03 -1.000000000e+00 -1.197282396e-02 + endloop + endfacet + facet normal 7.539426229e-01 2.371970670e-310 6.569402723e-01 + outer loop + vertex 5.642485232e-03 0.000000000e+00 -1.288858025e-02 + vertex 4.844550254e-03 -1.000000000e+00 -1.197282396e-02 + vertex 5.642485232e-03 -1.000000000e+00 -1.288858025e-02 + endloop + endfacet + facet normal 7.270093594e-01 0.000000000e+00 6.866275492e-01 + outer loop + vertex 6.539262457e-03 0.000000000e+00 -1.383809857e-02 + vertex 5.642485232e-03 0.000000000e+00 -1.288858025e-02 + vertex 5.642485232e-03 -1.000000000e+00 -1.288858025e-02 + endloop + endfacet + facet normal 7.270093594e-01 2.371970670e-310 6.866275492e-01 + outer loop + vertex 6.539262457e-03 0.000000000e+00 -1.383809857e-02 + vertex 5.642485232e-03 -1.000000000e+00 -1.288858025e-02 + vertex 6.539262457e-03 -1.000000000e+00 -1.383809857e-02 + endloop + endfacet + facet normal 6.995209056e-01 0.000000000e+00 7.146121344e-01 + outer loop + vertex 7.542786567e-03 0.000000000e+00 -1.482043019e-02 + vertex 6.539262457e-03 0.000000000e+00 -1.383809857e-02 + vertex 6.539262457e-03 -1.000000000e+00 -1.383809857e-02 + endloop + endfacet + facet normal 6.995209056e-01 2.371970670e-310 7.146121344e-01 + outer loop + vertex 7.542786567e-03 0.000000000e+00 -1.482043019e-02 + vertex 6.539262457e-03 -1.000000000e+00 -1.383809857e-02 + vertex 7.542786567e-03 -1.000000000e+00 -1.482043019e-02 + endloop + endfacet + facet normal 6.717137430e-01 0.000000000e+00 7.408108041e-01 + outer loop + vertex 8.660977829e-03 0.000000000e+00 -1.583432528e-02 + vertex 7.542786567e-03 0.000000000e+00 -1.482043019e-02 + vertex 7.542786567e-03 -1.000000000e+00 -1.482043019e-02 + endloop + endfacet + facet normal 6.717137430e-01 2.371970670e-310 7.408108041e-01 + outer loop + vertex 8.660977829e-03 0.000000000e+00 -1.583432528e-02 + vertex 7.542786567e-03 -1.000000000e+00 -1.482043019e-02 + vertex 8.660977829e-03 -1.000000000e+00 -1.583432528e-02 + endloop + endfacet + facet normal 6.438398167e-01 0.000000000e+00 7.651603038e-01 + outer loop + vertex 9.902279364e-03 0.000000000e+00 -1.687881145e-02 + vertex 8.660977829e-03 0.000000000e+00 -1.583432528e-02 + vertex 8.660977829e-03 -1.000000000e+00 -1.583432528e-02 + endloop + endfacet + facet normal 6.438398167e-01 2.371970670e-310 7.651603038e-01 + outer loop + vertex 9.902279364e-03 0.000000000e+00 -1.687881145e-02 + vertex 8.660977829e-03 -1.000000000e+00 -1.583432528e-02 + vertex 9.902279364e-03 -1.000000000e+00 -1.687881145e-02 + endloop + endfacet + facet normal 6.160902106e-01 0.000000000e+00 7.876756010e-01 + outer loop + vertex 1.127516041e-02 0.000000000e+00 -1.795262733e-02 + vertex 9.902279364e-03 0.000000000e+00 -1.687881145e-02 + vertex 9.902279364e-03 -1.000000000e+00 -1.687881145e-02 + endloop + endfacet + facet normal 6.160902106e-01 2.371970670e-310 7.876756010e-01 + outer loop + vertex 1.127516041e-02 0.000000000e+00 -1.795262733e-02 + vertex 9.902279364e-03 -1.000000000e+00 -1.687881145e-02 + vertex 1.127516041e-02 -1.000000000e+00 -1.795262733e-02 + endloop + endfacet + facet normal 5.886358783e-01 0.000000000e+00 8.083982946e-01 + outer loop + vertex 1.278871775e-02 0.000000000e+00 -1.905472535e-02 + vertex 1.127516041e-02 0.000000000e+00 -1.795262733e-02 + vertex 1.127516041e-02 -1.000000000e+00 -1.795262733e-02 + endloop + endfacet + facet normal 5.886358783e-01 0.000000000e+00 8.083982946e-01 + outer loop + vertex 1.278871775e-02 0.000000000e+00 -1.905472535e-02 + vertex 1.127516041e-02 -1.000000000e+00 -1.795262733e-02 + vertex 1.278871775e-02 -1.000000000e+00 -1.905472535e-02 + endloop + endfacet + facet normal 5.616747199e-01 0.000000000e+00 8.273581504e-01 + outer loop + vertex 1.445220177e-02 0.000000000e+00 -2.018402699e-02 + vertex 1.278871775e-02 0.000000000e+00 -1.905472535e-02 + vertex 1.278871775e-02 -1.000000000e+00 -1.905472535e-02 + endloop + endfacet + facet normal 5.616747199e-01 0.000000000e+00 8.273581504e-01 + outer loop + vertex 1.445220177e-02 0.000000000e+00 -2.018402699e-02 + vertex 1.278871775e-02 -1.000000000e+00 -1.905472535e-02 + vertex 1.445220177e-02 -1.000000000e+00 -2.018402699e-02 + endloop + endfacet + facet normal 5.352628389e-01 0.000000000e+00 8.446855589e-01 + outer loop + vertex 1.627551729e-02 0.000000000e+00 -2.133943095e-02 + vertex 1.445220177e-02 0.000000000e+00 -2.018402699e-02 + vertex 1.445220177e-02 -1.000000000e+00 -2.018402699e-02 + endloop + endfacet + facet normal 5.352628389e-01 0.000000000e+00 8.446855589e-01 + outer loop + vertex 1.627551729e-02 0.000000000e+00 -2.133943095e-02 + vertex 1.445220177e-02 -1.000000000e+00 -2.018402699e-02 + vertex 1.627551729e-02 -1.000000000e+00 -2.133943095e-02 + endloop + endfacet + facet normal 5.095572007e-01 0.000000000e+00 8.604367840e-01 + outer loop + vertex 1.826885694e-02 0.000000000e+00 -2.251990184e-02 + vertex 1.627551729e-02 0.000000000e+00 -2.133943095e-02 + vertex 1.627551729e-02 -1.000000000e+00 -2.133943095e-02 + endloop + endfacet + facet normal 5.095572007e-01 0.000000000e+00 8.604367840e-01 + outer loop + vertex 1.826885694e-02 0.000000000e+00 -2.251990184e-02 + vertex 1.627551729e-02 -1.000000000e+00 -2.133943095e-02 + vertex 1.826885694e-02 -1.000000000e+00 -2.251990184e-02 + endloop + endfacet + facet normal 4.845921893e-01 0.000000000e+00 8.747401957e-01 + outer loop + vertex 2.044303685e-02 0.000000000e+00 -2.372436301e-02 + vertex 1.826885694e-02 0.000000000e+00 -2.251990184e-02 + vertex 1.826885694e-02 -1.000000000e+00 -2.251990184e-02 + endloop + endfacet + facet normal 4.845921893e-01 0.000000000e+00 8.747401957e-01 + outer loop + vertex 2.044303685e-02 0.000000000e+00 -2.372436301e-02 + vertex 1.826885694e-02 -1.000000000e+00 -2.251990184e-02 + vertex 2.044303685e-02 -1.000000000e+00 -2.372436301e-02 + endloop + endfacet + facet normal 4.604106449e-01 0.000000000e+00 8.877060539e-01 + outer loop + vertex 2.280943840e-02 0.000000000e+00 -2.495170224e-02 + vertex 2.044303685e-02 0.000000000e+00 -2.372436301e-02 + vertex 2.044303685e-02 -1.000000000e+00 -2.372436301e-02 + endloop + endfacet + facet normal 4.604106449e-01 0.000000000e+00 8.877060539e-01 + outer loop + vertex 2.280943840e-02 0.000000000e+00 -2.495170224e-02 + vertex 2.044303685e-02 -1.000000000e+00 -2.372436301e-02 + vertex 2.280943840e-02 -1.000000000e+00 -2.495170224e-02 + endloop + endfacet + facet normal 4.370466301e-01 0.000000000e+00 8.994388490e-01 + outer loop + vertex 2.537999933e-02 0.000000000e+00 -2.620076436e-02 + vertex 2.280943840e-02 0.000000000e+00 -2.495170224e-02 + vertex 2.280943840e-02 -1.000000000e+00 -2.495170224e-02 + endloop + endfacet + facet normal 4.370466301e-01 0.000000000e+00 8.994388490e-01 + outer loop + vertex 2.537999933e-02 0.000000000e+00 -2.620076436e-02 + vertex 2.280943840e-02 -1.000000000e+00 -2.495170224e-02 + vertex 2.537999933e-02 -1.000000000e+00 -2.620076436e-02 + endloop + endfacet + facet normal 4.145162520e-01 0.000000000e+00 9.100419094e-01 + outer loop + vertex 2.816723853e-02 0.000000000e+00 -2.747032781e-02 + vertex 2.537999933e-02 0.000000000e+00 -2.620076436e-02 + vertex 2.537999933e-02 -1.000000000e+00 -2.620076436e-02 + endloop + endfacet + facet normal 4.145162520e-01 0.000000000e+00 9.100419094e-01 + outer loop + vertex 2.816723853e-02 0.000000000e+00 -2.747032781e-02 + vertex 2.537999933e-02 -1.000000000e+00 -2.620076436e-02 + vertex 2.816723853e-02 -1.000000000e+00 -2.747032781e-02 + endloop + endfacet + facet normal 3.928074751e-01 0.000000000e+00 9.196207302e-01 + outer loop + vertex 3.118433506e-02 0.000000000e+00 -2.875905264e-02 + vertex 2.816723853e-02 0.000000000e+00 -2.747032781e-02 + vertex 2.816723853e-02 -1.000000000e+00 -2.747032781e-02 + endloop + endfacet + facet normal 3.928074751e-01 0.000000000e+00 9.196207302e-01 + outer loop + vertex 3.118433506e-02 0.000000000e+00 -2.875905264e-02 + vertex 2.816723853e-02 -1.000000000e+00 -2.747032781e-02 + vertex 3.118433506e-02 -1.000000000e+00 -2.875905264e-02 + endloop + endfacet + facet normal 3.719109324e-01 0.000000000e+00 9.282684193e-01 + outer loop + vertex 3.444508613e-02 0.000000000e+00 -3.006547322e-02 + vertex 3.118433506e-02 0.000000000e+00 -2.875905264e-02 + vertex 3.118433506e-02 -1.000000000e+00 -2.875905264e-02 + endloop + endfacet + facet normal 3.719109324e-01 0.000000000e+00 9.282684193e-01 + outer loop + vertex 3.444508613e-02 0.000000000e+00 -3.006547322e-02 + vertex 3.118433506e-02 -1.000000000e+00 -2.875905264e-02 + vertex 3.444508613e-02 -1.000000000e+00 -3.006547322e-02 + endloop + endfacet + facet normal 3.518081089e-01 0.000000000e+00 9.360721417e-01 + outer loop + vertex 3.796391187e-02 0.000000000e+00 -3.138796897e-02 + vertex 3.444508613e-02 0.000000000e+00 -3.006547322e-02 + vertex 3.444508613e-02 -1.000000000e+00 -3.006547322e-02 + endloop + endfacet + facet normal 3.518081089e-01 0.000000000e+00 9.360721417e-01 + outer loop + vertex 3.796391187e-02 0.000000000e+00 -3.138796897e-02 + vertex 3.444508613e-02 -1.000000000e+00 -3.006547322e-02 + vertex 3.796391187e-02 -1.000000000e+00 -3.138796897e-02 + endloop + endfacet + facet normal 3.324693170e-01 0.000000000e+00 9.431140722e-01 + outer loop + vertex 4.175587666e-02 0.000000000e+00 -3.272472344e-02 + vertex 3.796391187e-02 0.000000000e+00 -3.138796897e-02 + vertex 3.796391187e-02 -1.000000000e+00 -3.138796897e-02 + endloop + endfacet + facet normal 3.324693170e-01 0.000000000e+00 9.431140722e-01 + outer loop + vertex 4.175587666e-02 0.000000000e+00 -3.272472344e-02 + vertex 3.796391187e-02 -1.000000000e+00 -3.138796897e-02 + vertex 4.175587666e-02 -1.000000000e+00 -3.272472344e-02 + endloop + endfacet + facet normal 3.138686541e-01 0.000000000e+00 9.494664122e-01 + outer loop + vertex 4.583663031e-02 0.000000000e+00 -3.407371339e-02 + vertex 4.175587666e-02 0.000000000e+00 -3.272472344e-02 + vertex 4.175587666e-02 -1.000000000e+00 -3.272472344e-02 + endloop + endfacet + facet normal 3.138686541e-01 0.000000000e+00 9.494664122e-01 + outer loop + vertex 4.583663031e-02 0.000000000e+00 -3.407371339e-02 + vertex 4.175587666e-02 -1.000000000e+00 -3.272472344e-02 + vertex 4.583663031e-02 -1.000000000e+00 -3.407371339e-02 + endloop + endfacet + facet normal 2.959717921e-01 0.000000000e+00 9.551966804e-01 + outer loop + vertex 5.022241269e-02 0.000000000e+00 -3.543266689e-02 + vertex 4.583663031e-02 0.000000000e+00 -3.407371339e-02 + vertex 4.583663031e-02 -1.000000000e+00 -3.407371339e-02 + endloop + endfacet + facet normal 2.959717921e-01 0.000000000e+00 9.551966804e-01 + outer loop + vertex 5.022241269e-02 0.000000000e+00 -3.543266689e-02 + vertex 4.583663031e-02 -1.000000000e+00 -3.407371339e-02 + vertex 5.022241269e-02 -1.000000000e+00 -3.543266689e-02 + endloop + endfacet + facet normal 2.787448045e-01 0.000000000e+00 9.603652086e-01 + outer loop + vertex 5.493000570e-02 0.000000000e+00 -3.679903989e-02 + vertex 5.022241269e-02 0.000000000e+00 -3.543266689e-02 + vertex 5.022241269e-02 -1.000000000e+00 -3.543266689e-02 + endloop + endfacet + facet normal 2.787448045e-01 0.000000000e+00 9.603652086e-01 + outer loop + vertex 5.493000570e-02 0.000000000e+00 -3.679903989e-02 + vertex 5.022241269e-02 -1.000000000e+00 -3.543266689e-02 + vertex 5.493000570e-02 -1.000000000e+00 -3.679903989e-02 + endloop + endfacet + facet normal 2.621544324e-01 0.000000000e+00 9.650259341e-01 + outer loop + vertex 5.997667081e-02 0.000000000e+00 -3.816999334e-02 + vertex 5.493000570e-02 0.000000000e+00 -3.679903989e-02 + vertex 5.493000570e-02 -1.000000000e+00 -3.679903989e-02 + endloop + endfacet + facet normal 2.621544324e-01 0.000000000e+00 9.650259341e-01 + outer loop + vertex 5.997667081e-02 0.000000000e+00 -3.816999334e-02 + vertex 5.493000570e-02 -1.000000000e+00 -3.679903989e-02 + vertex 5.997667081e-02 -1.000000000e+00 -3.816999334e-02 + endloop + endfacet + facet normal 2.461659993e-01 0.000000000e+00 9.692276826e-01 + outer loop + vertex 6.538009589e-02 0.000000000e+00 -3.954236389e-02 + vertex 5.997667081e-02 0.000000000e+00 -3.816999334e-02 + vertex 5.997667081e-02 -1.000000000e+00 -3.816999334e-02 + endloop + endfacet + facet normal 2.461659993e-01 0.000000000e+00 9.692276826e-01 + outer loop + vertex 6.538009589e-02 0.000000000e+00 -3.954236389e-02 + vertex 5.997667081e-02 -1.000000000e+00 -3.816999334e-02 + vertex 6.538009589e-02 -1.000000000e+00 -3.954236389e-02 + endloop + endfacet + facet normal 2.307462575e-01 0.000000000e+00 9.730139591e-01 + outer loop + vertex 7.115831019e-02 0.000000000e+00 -4.091264365e-02 + vertex 6.538009589e-02 0.000000000e+00 -3.954236389e-02 + vertex 6.538009589e-02 -1.000000000e+00 -3.954236389e-02 + endloop + endfacet + facet normal 2.307462575e-01 0.000000000e+00 9.730139591e-01 + outer loop + vertex 7.115831019e-02 0.000000000e+00 -4.091264365e-02 + vertex 6.538009589e-02 -1.000000000e+00 -3.954236389e-02 + vertex 7.115831019e-02 -1.000000000e+00 -4.091264365e-02 + endloop + endfacet + facet normal 2.158634372e-01 0.000000000e+00 9.764235641e-01 + outer loop + vertex 7.732958127e-02 0.000000000e+00 -4.227696118e-02 + vertex 7.115831019e-02 0.000000000e+00 -4.091264365e-02 + vertex 7.115831019e-02 -1.000000000e+00 -4.091264365e-02 + endloop + endfacet + facet normal 2.158634372e-01 0.000000000e+00 9.764235641e-01 + outer loop + vertex 7.732958127e-02 0.000000000e+00 -4.227696118e-02 + vertex 7.115831019e-02 -1.000000000e+00 -4.091264365e-02 + vertex 7.732958127e-02 -1.000000000e+00 -4.227696118e-02 + endloop + endfacet + facet normal 2.014869252e-01 0.000000000e+00 9.794912041e-01 + outer loop + vertex 8.391230598e-02 0.000000000e+00 -4.363106518e-02 + vertex 7.732958127e-02 0.000000000e+00 -4.227696118e-02 + vertex 7.732958127e-02 -1.000000000e+00 -4.227696118e-02 + endloop + endfacet + facet normal 2.014869252e-01 0.000000000e+00 9.794912041e-01 + outer loop + vertex 8.391230598e-02 0.000000000e+00 -4.363106518e-02 + vertex 7.732958127e-02 -1.000000000e+00 -4.227696118e-02 + vertex 8.391230598e-02 -1.000000000e+00 -4.363106518e-02 + endloop + endfacet + facet normal 1.875881539e-01 0.000000000e+00 9.822477714e-01 + outer loop + vertex 9.092487458e-02 0.000000000e+00 -4.497031464e-02 + vertex 8.391230598e-02 0.000000000e+00 -4.363106518e-02 + vertex 8.391230598e-02 -1.000000000e+00 -4.363106518e-02 + endloop + endfacet + facet normal 1.875881539e-01 0.000000000e+00 9.822477714e-01 + outer loop + vertex 9.092487458e-02 0.000000000e+00 -4.497031464e-02 + vertex 8.391230598e-02 -1.000000000e+00 -4.363106518e-02 + vertex 9.092487458e-02 -1.000000000e+00 -4.497031464e-02 + endloop + endfacet + facet normal 1.741405608e-01 0.000000000e+00 9.847208056e-01 + outer loop + vertex 9.838551560e-02 0.000000000e+00 -4.628967359e-02 + vertex 9.092487458e-02 0.000000000e+00 -4.497031464e-02 + vertex 9.092487458e-02 -1.000000000e+00 -4.497031464e-02 + endloop + endfacet + facet normal 1.741405608e-01 0.000000000e+00 9.847208056e-01 + outer loop + vertex 9.838551560e-02 0.000000000e+00 -4.628967359e-02 + vertex 9.092487458e-02 -1.000000000e+00 -4.497031464e-02 + vertex 9.838551560e-02 -1.000000000e+00 -4.628967359e-02 + endloop + endfacet + facet normal 1.611197192e-01 0.000000000e+00 9.869348692e-01 + outer loop + vertex 1.063121234e-01 0.000000000e+00 -4.758371321e-02 + vertex 9.838551560e-02 0.000000000e+00 -4.628967359e-02 + vertex 9.838551560e-02 -1.000000000e+00 -4.628967359e-02 + endloop + endfacet + facet normal 1.611197192e-01 0.000000000e+00 9.869348692e-01 + outer loop + vertex 1.063121234e-01 0.000000000e+00 -4.758371321e-02 + vertex 9.838551560e-02 -1.000000000e+00 -4.628967359e-02 + vertex 1.063121234e-01 -1.000000000e+00 -4.758371321e-02 + endloop + endfacet + facet normal 1.485035906e-01 0.000000000e+00 9.889118685e-01 + outer loop + vertex 1.147220645e-01 0.000000000e+00 -4.884662297e-02 + vertex 1.063121234e-01 0.000000000e+00 -4.758371321e-02 + vertex 1.063121234e-01 -1.000000000e+00 -4.758371321e-02 + endloop + endfacet + facet normal 1.485035906e-01 0.000000000e+00 9.889118685e-01 + outer loop + vertex 1.147220645e-01 0.000000000e+00 -4.884662297e-02 + vertex 1.063121234e-01 -1.000000000e+00 -4.758371321e-02 + vertex 1.147220645e-01 -1.000000000e+00 -4.884662297e-02 + endloop + endfacet + facet normal 1.362723604e-01 0.000000000e+00 9.906714106e-01 + outer loop + vertex 1.236319622e-01 0.000000000e+00 -5.007222894e-02 + vertex 1.147220645e-01 0.000000000e+00 -4.884662297e-02 + vertex 1.147220645e-01 -1.000000000e+00 -4.884662297e-02 + endloop + endfacet + facet normal 1.362723604e-01 0.000000000e+00 9.906714106e-01 + outer loop + vertex 1.236319622e-01 0.000000000e+00 -5.007222894e-02 + vertex 1.147220645e-01 -1.000000000e+00 -4.884662297e-02 + vertex 1.236319622e-01 -1.000000000e+00 -5.007222894e-02 + endloop + endfacet + facet normal 1.244087695e-01 0.000000000e+00 9.922310508e-01 + outer loop + vertex 1.330574640e-01 0.000000000e+00 -5.125402534e-02 + vertex 1.236319622e-01 0.000000000e+00 -5.007222894e-02 + vertex 1.236319622e-01 -1.000000000e+00 -5.007222894e-02 + endloop + endfacet + facet normal 1.244087695e-01 0.000000000e+00 9.922310508e-01 + outer loop + vertex 1.330574640e-01 0.000000000e+00 -5.125402534e-02 + vertex 1.236319622e-01 -1.000000000e+00 -5.007222894e-02 + vertex 1.330574640e-01 -1.000000000e+00 -5.125402534e-02 + endloop + endfacet + facet normal 1.128977803e-01 0.000000000e+00 9.936066079e-01 + outer loop + vertex 1.430129884e-01 0.000000000e+00 -5.238521408e-02 + vertex 1.330574640e-01 0.000000000e+00 -5.125402534e-02 + vertex 1.330574640e-01 -1.000000000e+00 -5.125402534e-02 + endloop + endfacet + facet normal 1.128977803e-01 0.000000000e+00 9.936066079e-01 + outer loop + vertex 1.430129884e-01 0.000000000e+00 -5.238521408e-02 + vertex 1.330574640e-01 -1.000000000e+00 -5.125402534e-02 + vertex 1.430129884e-01 -1.000000000e+00 -5.238521408e-02 + endloop + endfacet + facet normal 1.017268987e-01 0.000000000e+00 9.948123633e-01 + outer loop + vertex 1.535114574e-01 0.000000000e+00 -5.345875993e-02 + vertex 1.430129884e-01 0.000000000e+00 -5.238521408e-02 + vertex 1.430129884e-01 -1.000000000e+00 -5.238521408e-02 + endloop + endfacet + facet normal 1.017268987e-01 0.000000000e+00 9.948123633e-01 + outer loop + vertex 1.535114574e-01 0.000000000e+00 -5.345875993e-02 + vertex 1.430129884e-01 -1.000000000e+00 -5.238521408e-02 + vertex 1.535114574e-01 -1.000000000e+00 -5.345875993e-02 + endloop + endfacet + facet normal 9.088575018e-02 0.000000000e+00 9.958613259e-01 + outer loop + vertex 1.645640139e-01 0.000000000e+00 -5.446745448e-02 + vertex 1.535114574e-01 0.000000000e+00 -5.345875993e-02 + vertex 1.535114574e-01 -1.000000000e+00 -5.345875993e-02 + endloop + endfacet + facet normal 9.088575018e-02 0.000000000e+00 9.958613259e-01 + outer loop + vertex 1.645640139e-01 0.000000000e+00 -5.446745448e-02 + vertex 1.535114574e-01 -1.000000000e+00 -5.345875993e-02 + vertex 1.645640139e-01 -1.000000000e+00 -5.446745448e-02 + endloop + endfacet + facet normal 8.036637190e-02 0.000000000e+00 9.967653918e-01 + outer loop + vertex 1.761797308e-01 0.000000000e+00 -5.540399685e-02 + vertex 1.645640139e-01 0.000000000e+00 -5.446745448e-02 + vertex 1.645640139e-01 -1.000000000e+00 -5.446745448e-02 + endloop + endfacet + facet normal 8.036637190e-02 0.000000000e+00 9.967653918e-01 + outer loop + vertex 1.761797308e-01 0.000000000e+00 -5.540399685e-02 + vertex 1.645640139e-01 -1.000000000e+00 -5.446745448e-02 + vertex 1.761797308e-01 -1.000000000e+00 -5.540399685e-02 + endloop + endfacet + facet normal 7.016267428e-02 0.000000000e+00 9.975355628e-01 + outer loop + vertex 1.883653127e-01 0.000000000e+00 -5.626108210e-02 + vertex 1.761797308e-01 0.000000000e+00 -5.540399685e-02 + vertex 1.761797308e-01 -1.000000000e+00 -5.540399685e-02 + endloop + endfacet + facet normal 7.016267428e-02 0.000000000e+00 9.975355628e-01 + outer loop + vertex 1.883653127e-01 0.000000000e+00 -5.626108210e-02 + vertex 1.761797308e-01 -1.000000000e+00 -5.540399685e-02 + vertex 1.883653127e-01 -1.000000000e+00 -5.626108210e-02 + endloop + endfacet + facet normal 6.027064399e-02 0.000000000e+00 9.981820723e-01 + outer loop + vertex 2.011247989e-01 0.000000000e+00 -5.703150512e-02 + vertex 1.883653127e-01 0.000000000e+00 -5.626108210e-02 + vertex 1.883653127e-01 -1.000000000e+00 -5.626108210e-02 + endloop + endfacet + facet normal 6.027064399e-02 0.000000000e+00 9.981820723e-01 + outer loop + vertex 2.011247989e-01 0.000000000e+00 -5.703150512e-02 + vertex 1.883653127e-01 -1.000000000e+00 -5.626108210e-02 + vertex 2.011247989e-01 -1.000000000e+00 -5.703150512e-02 + endloop + endfacet + facet normal 5.068799970e-02 0.000000000e+00 9.987145371e-01 + outer loop + vertex 2.144592713e-01 0.000000000e+00 -5.770827282e-02 + vertex 2.011247989e-01 0.000000000e+00 -5.703150512e-02 + vertex 2.011247989e-01 -1.000000000e+00 -5.703150512e-02 + endloop + endfacet + facet normal 5.068799970e-02 0.000000000e+00 9.987145371e-01 + outer loop + vertex 2.144592713e-01 0.000000000e+00 -5.770827282e-02 + vertex 2.011247989e-01 -1.000000000e+00 -5.703150512e-02 + vertex 2.144592713e-01 -1.000000000e+00 -5.770827282e-02 + endloop + endfacet + facet normal 4.141384771e-02 0.000000000e+00 9.991420786e-01 + outer loop + vertex 2.283665750e-01 0.000000000e+00 -5.828472232e-02 + vertex 2.144592713e-01 0.000000000e+00 -5.770827282e-02 + vertex 2.144592713e-01 -1.000000000e+00 -5.770827282e-02 + endloop + endfacet + facet normal 4.141384771e-02 0.000000000e+00 9.991420786e-01 + outer loop + vertex 2.283665750e-01 0.000000000e+00 -5.828472232e-02 + vertex 2.144592713e-01 -1.000000000e+00 -5.770827282e-02 + vertex 2.283665750e-01 -1.000000000e+00 -5.828472232e-02 + endloop + endfacet + facet normal 3.244852317e-02 0.000000000e+00 9.994734080e-01 + outer loop + vertex 2.428410589e-01 0.000000000e+00 -5.875464540e-02 + vertex 2.283665750e-01 0.000000000e+00 -5.828472232e-02 + vertex 2.283665750e-01 -1.000000000e+00 -5.828472232e-02 + endloop + endfacet + facet normal 3.244852317e-02 0.000000000e+00 9.994734080e-01 + outer loop + vertex 2.428410589e-01 0.000000000e+00 -5.875464540e-02 + vertex 2.283665750e-01 -1.000000000e+00 -5.828472232e-02 + vertex 2.428410589e-01 -1.000000000e+00 -5.875464540e-02 + endloop + endfacet + facet normal 2.379353806e-02 0.000000000e+00 9.997168937e-01 + outer loop + vertex 2.578733448e-01 0.000000000e+00 -5.911241796e-02 + vertex 2.428410589e-01 0.000000000e+00 -5.875464540e-02 + vertex 2.428410589e-01 -1.000000000e+00 -5.875464540e-02 + endloop + endfacet + facet normal 2.379353806e-02 0.000000000e+00 9.997168937e-01 + outer loop + vertex 2.578733448e-01 0.000000000e+00 -5.911241796e-02 + vertex 2.428410589e-01 -1.000000000e+00 -5.875464540e-02 + vertex 2.578733448e-01 -1.000000000e+00 -5.911241796e-02 + endloop + endfacet + facet normal 1.545062240e-02 0.000000000e+00 9.998806320e-01 + outer loop + vertex 2.734501317e-01 0.000000000e+00 -5.935311774e-02 + vertex 2.578733448e-01 0.000000000e+00 -5.911241796e-02 + vertex 2.578733448e-01 -1.000000000e+00 -5.911241796e-02 + endloop + endfacet + facet normal 1.545062240e-02 0.000000000e+00 9.998806320e-01 + outer loop + vertex 2.734501317e-01 0.000000000e+00 -5.935311774e-02 + vertex 2.578733448e-01 -1.000000000e+00 -5.911241796e-02 + vertex 2.734501317e-01 -1.000000000e+00 -5.935311774e-02 + endloop + endfacet + facet normal 7.422430173e-03 0.000000000e+00 9.999724534e-01 + outer loop + vertex 2.895540445e-01 0.000000000e+00 -5.947265121e-02 + vertex 2.734501317e-01 0.000000000e+00 -5.935311774e-02 + vertex 2.734501317e-01 -1.000000000e+00 -5.935311774e-02 + endloop + endfacet + facet normal 7.422430173e-03 0.000000000e+00 9.999724534e-01 + outer loop + vertex 2.895540445e-01 0.000000000e+00 -5.947265121e-02 + vertex 2.734501317e-01 -1.000000000e+00 -5.935311774e-02 + vertex 2.895540445e-01 -1.000000000e+00 -5.947265121e-02 + endloop + endfacet + facet normal -2.891886697e-04 0.000000000e+00 9.999999582e-01 + outer loop + vertex 3.061635346e-01 0.000000000e+00 -5.946784793e-02 + vertex 2.895540445e-01 0.000000000e+00 -5.947265121e-02 + vertex 2.895540445e-01 -1.000000000e+00 -5.947265121e-02 + endloop + endfacet + facet normal -2.891886697e-04 0.000000000e+00 9.999999582e-01 + outer loop + vertex 3.061635346e-01 0.000000000e+00 -5.946784793e-02 + vertex 2.895540445e-01 -1.000000000e+00 -5.947265121e-02 + vertex 3.061635346e-01 -1.000000000e+00 -5.946784793e-02 + endloop + endfacet + facet normal -7.682172089e-03 0.000000000e+00 9.999704917e-01 + outer loop + vertex 3.232528391e-01 0.000000000e+00 -5.933656108e-02 + vertex 3.061635346e-01 0.000000000e+00 -5.946784793e-02 + vertex 3.061635346e-01 -1.000000000e+00 -5.946784793e-02 + endloop + endfacet + facet normal -7.682172089e-03 0.000000000e+00 9.999704917e-01 + outer loop + vertex 3.232528391e-01 0.000000000e+00 -5.933656108e-02 + vertex 3.061635346e-01 -1.000000000e+00 -5.946784793e-02 + vertex 3.232528391e-01 -1.000000000e+00 -5.933656108e-02 + endloop + endfacet + facet normal -1.475500706e-02 0.000000000e+00 9.998911390e-01 + outer loop + vertex 3.407920053e-01 0.000000000e+00 -5.907774238e-02 + vertex 3.232528391e-01 0.000000000e+00 -5.933656108e-02 + vertex 3.232528391e-01 -1.000000000e+00 -5.933656108e-02 + endloop + endfacet + facet normal -1.475500706e-02 0.000000000e+00 9.998911390e-01 + outer loop + vertex 3.407920053e-01 0.000000000e+00 -5.907774238e-02 + vertex 3.232528391e-01 -1.000000000e+00 -5.933656108e-02 + vertex 3.407920053e-01 -1.000000000e+00 -5.907774238e-02 + endloop + endfacet + facet normal -2.150774974e-02 0.000000000e+00 9.997686816e-01 + outer loop + vertex 3.587469844e-01 0.000000000e+00 -5.869148183e-02 + vertex 3.407920053e-01 0.000000000e+00 -5.907774238e-02 + vertex 3.407920053e-01 -1.000000000e+00 -5.907774238e-02 + endloop + endfacet + facet normal -2.150774974e-02 0.000000000e+00 9.997686816e-01 + outer loop + vertex 3.587469844e-01 0.000000000e+00 -5.869148183e-02 + vertex 3.407920053e-01 -1.000000000e+00 -5.907774238e-02 + vertex 3.587469844e-01 -1.000000000e+00 -5.869148183e-02 + endloop + endfacet + facet normal -2.794110892e-02 0.000000000e+00 9.996095710e-01 + outer loop + vertex 3.770797979e-01 0.000000000e+00 -5.817904262e-02 + vertex 3.587469844e-01 0.000000000e+00 -5.869148183e-02 + vertex 3.587469844e-01 -1.000000000e+00 -5.869148183e-02 + endloop + endfacet + facet normal -2.794110892e-02 0.000000000e+00 9.996095710e-01 + outer loop + vertex 3.770797979e-01 0.000000000e+00 -5.817904262e-02 + vertex 3.587469844e-01 -1.000000000e+00 -5.869148183e-02 + vertex 3.770797979e-01 -1.000000000e+00 -5.817904262e-02 + endloop + endfacet + facet normal -3.405749389e-02 0.000000000e+00 9.994198753e-01 + outer loop + vertex 3.957487780e-01 0.000000000e+00 -5.754285488e-02 + vertex 3.770797979e-01 0.000000000e+00 -5.817904262e-02 + vertex 3.770797979e-01 -1.000000000e+00 -5.817904262e-02 + endloop + endfacet + facet normal -3.405749389e-02 0.000000000e+00 9.994198753e-01 + outer loop + vertex 3.957487780e-01 0.000000000e+00 -5.754285488e-02 + vertex 3.770797979e-01 -1.000000000e+00 -5.817904262e-02 + vertex 3.957487780e-01 -1.000000000e+00 -5.754285488e-02 + endloop + endfacet + facet normal -3.986080756e-02 0.000000000e+00 9.992052422e-01 + outer loop + vertex 4.147088805e-01 0.000000000e+00 -5.678648875e-02 + vertex 3.957487780e-01 0.000000000e+00 -5.754285488e-02 + vertex 3.957487780e-01 -1.000000000e+00 -5.754285488e-02 + endloop + endfacet + facet normal -3.986080756e-02 0.000000000e+00 9.992052422e-01 + outer loop + vertex 4.147088805e-01 0.000000000e+00 -5.678648875e-02 + vertex 3.957487780e-01 -1.000000000e+00 -5.754285488e-02 + vertex 4.147088805e-01 -1.000000000e+00 -5.678648875e-02 + endloop + endfacet + facet normal -4.535657593e-02 0.000000000e+00 9.989708609e-01 + outer loop + vertex 4.339120676e-01 0.000000000e+00 -5.591460065e-02 + vertex 4.147088805e-01 0.000000000e+00 -5.678648875e-02 + vertex 4.147088805e-01 -1.000000000e+00 -5.678648875e-02 + endloop + endfacet + facet normal -4.535657593e-02 0.000000000e+00 9.989708609e-01 + outer loop + vertex 4.339120676e-01 0.000000000e+00 -5.591460065e-02 + vertex 4.147088805e-01 -1.000000000e+00 -5.678648875e-02 + vertex 4.339120676e-01 -1.000000000e+00 -5.591460065e-02 + endloop + endfacet + facet normal -5.055209307e-02 0.000000000e+00 9.987214256e-01 + outer loop + vertex 4.533077537e-01 0.000000000e+00 -5.493285288e-02 + vertex 4.339120676e-01 0.000000000e+00 -5.591460065e-02 + vertex 4.339120676e-01 -1.000000000e+00 -5.591460065e-02 + endloop + endfacet + facet normal -5.055209307e-02 0.000000000e+00 9.987214256e-01 + outer loop + vertex 4.533077537e-01 0.000000000e+00 -5.493285288e-02 + vertex 4.339120676e-01 -1.000000000e+00 -5.591460065e-02 + vertex 4.533077537e-01 -1.000000000e+00 -5.493285288e-02 + endloop + endfacet + facet normal -5.545626925e-02 0.000000000e+00 9.984611170e-01 + outer loop + vertex 4.728433082e-01 0.000000000e+00 -5.384781416e-02 + vertex 4.533077537e-01 0.000000000e+00 -5.493285288e-02 + vertex 4.533077537e-01 -1.000000000e+00 -5.493285288e-02 + endloop + endfacet + facet normal -5.545626925e-02 0.000000000e+00 9.984611170e-01 + outer loop + vertex 4.728433082e-01 0.000000000e+00 -5.384781416e-02 + vertex 4.533077537e-01 -1.000000000e+00 -5.493285288e-02 + vertex 4.728433082e-01 -1.000000000e+00 -5.384781416e-02 + endloop + endfacet + facet normal -6.007958990e-02 0.000000000e+00 9.981935899e-01 + outer loop + vertex 4.924646039e-01 0.000000000e+00 -5.266684144e-02 + vertex 4.728433082e-01 0.000000000e+00 -5.384781416e-02 + vertex 4.728433082e-01 -1.000000000e+00 -5.384781416e-02 + endloop + endfacet + facet normal -6.007958990e-02 0.000000000e+00 9.981935899e-01 + outer loop + vertex 4.924646039e-01 0.000000000e+00 -5.266684144e-02 + vertex 4.728433082e-01 -1.000000000e+00 -5.384781416e-02 + vertex 4.924646039e-01 -1.000000000e+00 -5.266684144e-02 + endloop + endfacet + facet normal -6.443395190e-02 0.000000000e+00 9.979219738e-01 + outer loop + vertex 5.121166001e-01 0.000000000e+00 -5.139794887e-02 + vertex 4.924646039e-01 0.000000000e+00 -5.266684144e-02 + vertex 4.924646039e-01 -1.000000000e+00 -5.266684144e-02 + endloop + endfacet + facet normal -6.443395190e-02 0.000000000e+00 9.979219738e-01 + outer loop + vertex 5.121166001e-01 0.000000000e+00 -5.139794887e-02 + vertex 4.924646039e-01 -1.000000000e+00 -5.266684144e-02 + vertex 5.121166001e-01 -1.000000000e+00 -5.139794887e-02 + endloop + endfacet + facet normal -6.853246021e-02 0.000000000e+00 9.976488871e-01 + outer loop + vertex 5.317439474e-01 0.000000000e+00 -5.004966851e-02 + vertex 5.121166001e-01 0.000000000e+00 -5.139794887e-02 + vertex 5.121166001e-01 -1.000000000e+00 -5.139794887e-02 + endloop + endfacet + facet normal -6.853246021e-02 0.000000000e+00 9.976488871e-01 + outer loop + vertex 5.317439474e-01 0.000000000e+00 -5.004966851e-02 + vertex 5.121166001e-01 -1.000000000e+00 -5.139794887e-02 + vertex 5.317439474e-01 -1.000000000e+00 -5.004966851e-02 + endloop + endfacet + facet normal -7.238916428e-02 0.000000000e+00 9.973764630e-01 + outer loop + vertex 5.512916003e-01 0.000000000e+00 -4.863090809e-02 + vertex 5.317439474e-01 0.000000000e+00 -5.004966851e-02 + vertex 5.317439474e-01 -1.000000000e+00 -5.004966851e-02 + endloop + endfacet + facet normal -7.238916428e-02 0.000000000e+00 9.973764630e-01 + outer loop + vertex 5.512916003e-01 0.000000000e+00 -4.863090809e-02 + vertex 5.317439474e-01 -1.000000000e+00 -5.004966851e-02 + vertex 5.512916003e-01 -1.000000000e+00 -4.863090809e-02 + endloop + endfacet + facet normal -7.601881370e-02 0.000000000e+00 9.971063835e-01 + outer loop + vertex 5.707054231e-01 0.000000000e+00 -4.715080947e-02 + vertex 5.512916003e-01 0.000000000e+00 -4.863090809e-02 + vertex 5.512916003e-01 -1.000000000e+00 -4.863090809e-02 + endloop + endfacet + facet normal -7.601881370e-02 0.000000000e+00 9.971063835e-01 + outer loop + vertex 5.707054231e-01 0.000000000e+00 -4.715080947e-02 + vertex 5.512916003e-01 -1.000000000e+00 -4.863090809e-02 + vertex 5.707054231e-01 -1.000000000e+00 -4.715080947e-02 + endloop + endfacet + facet normal -7.943655855e-02 0.000000000e+00 9.968399235e-01 + outer loop + vertex 5.899327757e-01 0.000000000e+00 -4.561861289e-02 + vertex 5.707054231e-01 0.000000000e+00 -4.715080947e-02 + vertex 5.707054231e-01 -1.000000000e+00 -4.715080947e-02 + endloop + endfacet + facet normal -7.943655855e-02 0.000000000e+00 9.968399235e-01 + outer loop + vertex 5.899327757e-01 0.000000000e+00 -4.561861289e-02 + vertex 5.707054231e-01 -1.000000000e+00 -4.715080947e-02 + vertex 5.899327757e-01 -1.000000000e+00 -4.561861289e-02 + endloop + endfacet + facet normal -8.265766256e-02 0.000000000e+00 9.965780004e-01 + outer loop + vertex 6.089230652e-01 0.000000000e+00 -4.404353002e-02 + vertex 5.899327757e-01 0.000000000e+00 -4.561861289e-02 + vertex 5.899327757e-01 -1.000000000e+00 -4.561861289e-02 + endloop + endfacet + facet normal -8.265766256e-02 0.000000000e+00 9.965780004e-01 + outer loop + vertex 6.089230652e-01 0.000000000e+00 -4.404353002e-02 + vertex 5.899327757e-01 -1.000000000e+00 -4.561861289e-02 + vertex 6.089230652e-01 -1.000000000e+00 -4.404353002e-02 + endloop + endfacet + facet normal -8.569722467e-02 0.000000000e+00 9.963212262e-01 + outer loop + vertex 6.276282526e-01 0.000000000e+00 -4.243462859e-02 + vertex 6.089230652e-01 0.000000000e+00 -4.404353002e-02 + vertex 6.089230652e-01 -1.000000000e+00 -4.404353002e-02 + endloop + endfacet + facet normal -8.569722467e-02 0.000000000e+00 9.963212262e-01 + outer loop + vertex 6.276282526e-01 0.000000000e+00 -4.243462859e-02 + vertex 6.089230652e-01 -1.000000000e+00 -4.404353002e-02 + vertex 6.276282526e-01 -1.000000000e+00 -4.243462859e-02 + endloop + endfacet + facet normal -8.856992167e-02 0.000000000e+00 9.960699619e-01 + outer loop + vertex 6.460033026e-01 0.000000000e+00 -4.080073057e-02 + vertex 6.276282526e-01 0.000000000e+00 -4.243462859e-02 + vertex 6.276282526e-01 -1.000000000e+00 -4.243462859e-02 + endloop + endfacet + facet normal -8.856992167e-02 0.000000000e+00 9.960699619e-01 + outer loop + vertex 6.460033026e-01 0.000000000e+00 -4.080073057e-02 + vertex 6.276282526e-01 -1.000000000e+00 -4.243462859e-02 + vertex 6.460033026e-01 -1.000000000e+00 -4.080073057e-02 + endloop + endfacet + facet normal -9.128978719e-02 0.000000000e+00 9.958243694e-01 + outer loop + vertex 6.640065698e-01 0.000000000e+00 -3.915032465e-02 + vertex 6.460033026e-01 0.000000000e+00 -4.080073057e-02 + vertex 6.460033026e-01 -1.000000000e+00 -4.080073057e-02 + endloop + endfacet + facet normal -9.128978719e-02 0.000000000e+00 9.958243694e-01 + outer loop + vertex 6.640065698e-01 0.000000000e+00 -3.915032465e-02 + vertex 6.460033026e-01 -1.000000000e+00 -4.080073057e-02 + vertex 6.640065698e-01 -1.000000000e+00 -3.915032465e-02 + endloop + endfacet + facet normal -9.387001982e-02 0.000000000e+00 9.955844612e-01 + outer loop + vertex 6.816001146e-01 0.000000000e+00 -3.749149362e-02 + vertex 6.640065698e-01 0.000000000e+00 -3.915032465e-02 + vertex 6.640065698e-01 -1.000000000e+00 -3.915032465e-02 + endloop + endfacet + facet normal -9.387001982e-02 0.000000000e+00 9.955844612e-01 + outer loop + vertex 6.816001146e-01 0.000000000e+00 -3.749149362e-02 + vertex 6.640065698e-01 -1.000000000e+00 -3.915032465e-02 + vertex 6.816001146e-01 -1.000000000e+00 -3.749149362e-02 + endloop + endfacet + facet normal -9.632283502e-02 0.000000000e+00 9.953501452e-01 + outer loop + vertex 6.987499446e-01 0.000000000e+00 -3.583185630e-02 + vertex 6.816001146e-01 0.000000000e+00 -3.749149362e-02 + vertex 6.816001146e-01 -1.000000000e+00 -3.749149362e-02 + endloop + endfacet + facet normal -9.632283502e-02 0.000000000e+00 9.953501452e-01 + outer loop + vertex 6.987499446e-01 0.000000000e+00 -3.583185630e-02 + vertex 6.816001146e-01 -1.000000000e+00 -3.749149362e-02 + vertex 6.987499446e-01 -1.000000000e+00 -3.583185630e-02 + endloop + endfacet + facet normal -9.865936682e-02 0.000000000e+00 9.951212636e-01 + outer loop + vertex 7.154261825e-01 0.000000000e+00 -3.417852305e-02 + vertex 6.987499446e-01 0.000000000e+00 -3.583185630e-02 + vertex 6.987499446e-01 -1.000000000e+00 -3.583185630e-02 + endloop + endfacet + facet normal -9.865936682e-02 0.000000000e+00 9.951212636e-01 + outer loop + vertex 7.154261825e-01 0.000000000e+00 -3.417852305e-02 + vertex 6.987499446e-01 -1.000000000e+00 -3.583185630e-02 + vertex 7.154261825e-01 -1.000000000e+00 -3.417852305e-02 + endloop + endfacet + facet normal -1.008896020e-01 0.000000000e+00 9.948976270e-01 + outer loop + vertex 7.316031585e-01 0.000000000e+00 -3.253806414e-02 + vertex 7.154261825e-01 0.000000000e+00 -3.417852305e-02 + vertex 7.154261825e-01 -1.000000000e+00 -3.417852305e-02 + endloop + endfacet + facet normal -1.008896020e-01 0.000000000e+00 9.948976270e-01 + outer loop + vertex 7.316031585e-01 0.000000000e+00 -3.253806414e-02 + vertex 7.154261825e-01 -1.000000000e+00 -3.417852305e-02 + vertex 7.316031585e-01 -1.000000000e+00 -3.253806414e-02 + endloop + endfacet + facet normal -1.030223709e-01 0.000000000e+00 9.946790392e-01 + outer loop + vertex 7.472594329e-01 0.000000000e+00 -3.091648931e-02 + vertex 7.316031585e-01 0.000000000e+00 -3.253806414e-02 + vertex 7.316031585e-01 -1.000000000e+00 -3.253806414e-02 + endloop + endfacet + facet normal -1.030223709e-01 0.000000000e+00 9.946790392e-01 + outer loop + vertex 7.472594329e-01 0.000000000e+00 -3.091648931e-02 + vertex 7.316031585e-01 -1.000000000e+00 -3.253806414e-02 + vertex 7.472594329e-01 -1.000000000e+00 -3.091648931e-02 + endloop + endfacet + facet normal -1.050653526e-01 0.000000000e+00 9.944653195e-01 + outer loop + vertex 7.623777525e-01 0.000000000e+00 -2.931923745e-02 + vertex 7.472594329e-01 0.000000000e+00 -3.091648931e-02 + vertex 7.472594329e-01 -1.000000000e+00 -3.091648931e-02 + endloop + endfacet + facet normal -1.050653526e-01 0.000000000e+00 9.944653195e-01 + outer loop + vertex 7.623777525e-01 0.000000000e+00 -2.931923745e-02 + vertex 7.472594329e-01 -1.000000000e+00 -3.091648931e-02 + vertex 7.623777525e-01 -1.000000000e+00 -2.931923745e-02 + endloop + endfacet + facet normal -1.070251372e-01 0.000000000e+00 9.942563150e-01 + outer loop + vertex 7.769449477e-01 0.000000000e+00 -2.775117492e-02 + vertex 7.623777525e-01 0.000000000e+00 -2.931923745e-02 + vertex 7.623777525e-01 -1.000000000e+00 -2.931923745e-02 + endloop + endfacet + facet normal -1.070251372e-01 0.000000000e+00 9.942563150e-01 + outer loop + vertex 7.769449477e-01 0.000000000e+00 -2.775117492e-02 + vertex 7.623777525e-01 -1.000000000e+00 -2.931923745e-02 + vertex 7.769449477e-01 -1.000000000e+00 -2.775117492e-02 + endloop + endfacet + facet normal -1.089072893e-01 0.000000000e+00 9.940519113e-01 + outer loop + vertex 7.909517772e-01 0.000000000e+00 -2.621660131e-02 + vertex 7.769449477e-01 0.000000000e+00 -2.775117492e-02 + vertex 7.769449477e-01 -1.000000000e+00 -2.775117492e-02 + endloop + endfacet + facet normal -1.089072893e-01 0.000000000e+00 9.940519113e-01 + outer loop + vertex 7.909517772e-01 0.000000000e+00 -2.621660131e-02 + vertex 7.769449477e-01 -1.000000000e+00 -2.775117492e-02 + vertex 7.909517772e-01 -1.000000000e+00 -2.621660131e-02 + endloop + endfacet + facet normal -1.107164486e-01 0.000000000e+00 9.938520353e-01 + outer loop + vertex 8.043927285e-01 0.000000000e+00 -2.471926133e-02 + vertex 7.909517772e-01 0.000000000e+00 -2.621660131e-02 + vertex 7.909517772e-01 -1.000000000e+00 -2.621660131e-02 + endloop + endfacet + facet normal -1.107164486e-01 0.000000000e+00 9.938520353e-01 + outer loop + vertex 8.043927285e-01 0.000000000e+00 -2.471926133e-02 + vertex 7.909517772e-01 -1.000000000e+00 -2.621660131e-02 + vertex 8.043927285e-01 -1.000000000e+00 -2.471926133e-02 + endloop + endfacet + facet normal -1.124564291e-01 0.000000000e+00 9.936566568e-01 + outer loop + vertex 8.172657826e-01 0.000000000e+00 -2.326236201e-02 + vertex 8.043927285e-01 0.000000000e+00 -2.471926133e-02 + vertex 8.043927285e-01 -1.000000000e+00 -2.471926133e-02 + endloop + endfacet + facet normal -1.124564291e-01 0.000000000e+00 9.936566568e-01 + outer loop + vertex 8.172657826e-01 0.000000000e+00 -2.326236201e-02 + vertex 8.043927285e-01 -1.000000000e+00 -2.471926133e-02 + vertex 8.172657826e-01 -1.000000000e+00 -2.326236201e-02 + endloop + endfacet + facet normal -1.141303372e-01 0.000000000e+00 9.934657851e-01 + outer loop + vertex 8.295721518e-01 0.000000000e+00 -2.184859409e-02 + vertex 8.172657826e-01 0.000000000e+00 -2.326236201e-02 + vertex 8.172657826e-01 -1.000000000e+00 -2.326236201e-02 + endloop + endfacet + facet normal -1.141303372e-01 0.000000000e+00 9.934657851e-01 + outer loop + vertex 8.295721518e-01 0.000000000e+00 -2.184859409e-02 + vertex 8.172657826e-01 -1.000000000e+00 -2.326236201e-02 + vertex 8.295721518e-01 -1.000000000e+00 -2.184859409e-02 + endloop + endfacet + facet normal -1.157406790e-01 0.000000000e+00 9.932794648e-01 + outer loop + vertex 8.413159970e-01 0.000000000e+00 -2.048015684e-02 + vertex 8.295721518e-01 0.000000000e+00 -2.184859409e-02 + vertex 8.295721518e-01 -1.000000000e+00 -2.184859409e-02 + endloop + endfacet + facet normal -1.157406790e-01 0.000000000e+00 9.932794648e-01 + outer loop + vertex 8.413159970e-01 0.000000000e+00 -2.048015684e-02 + vertex 8.295721518e-01 -1.000000000e+00 -2.184859409e-02 + vertex 8.413159970e-01 -1.000000000e+00 -2.048015684e-02 + endloop + endfacet + facet normal -1.172894744e-01 0.000000000e+00 9.930977692e-01 + outer loop + vertex 8.525041347e-01 0.000000000e+00 -1.915878564e-02 + vertex 8.413159970e-01 0.000000000e+00 -2.048015684e-02 + vertex 8.413159970e-01 -1.000000000e+00 -2.048015684e-02 + endloop + endfacet + facet normal -1.172894744e-01 0.000000000e+00 9.930977692e-01 + outer loop + vertex 8.525041347e-01 0.000000000e+00 -1.915878564e-02 + vertex 8.413159970e-01 -1.000000000e+00 -2.048015684e-02 + vertex 8.525041347e-01 -1.000000000e+00 -1.915878564e-02 + endloop + endfacet + facet normal -1.187783598e-01 0.000000000e+00 9.929207930e-01 + outer loop + vertex 8.631457375e-01 0.000000000e+00 -1.788578165e-02 + vertex 8.525041347e-01 0.000000000e+00 -1.915878564e-02 + vertex 8.525041347e-01 -1.000000000e+00 -1.915878564e-02 + endloop + endfacet + facet normal -1.187783598e-01 0.000000000e+00 9.929207930e-01 + outer loop + vertex 8.631457375e-01 0.000000000e+00 -1.788578165e-02 + vertex 8.525041347e-01 -1.000000000e+00 -1.915878564e-02 + vertex 8.631457375e-01 -1.000000000e+00 -1.788578165e-02 + endloop + endfacet + facet normal -1.202086835e-01 0.000000000e+00 9.927486451e-01 + outer loop + vertex 8.732520369e-01 0.000000000e+00 -1.666204294e-02 + vertex 8.631457375e-01 0.000000000e+00 -1.788578165e-02 + vertex 8.631457375e-01 -1.000000000e+00 -1.788578165e-02 + endloop + endfacet + facet normal -1.202086835e-01 0.000000000e+00 9.927486451e-01 + outer loop + vertex 8.732520369e-01 0.000000000e+00 -1.666204294e-02 + vertex 8.631457375e-01 -1.000000000e+00 -1.788578165e-02 + vertex 8.732520369e-01 -1.000000000e+00 -1.666204294e-02 + endloop + endfacet + facet normal -1.215815886e-01 0.000000000e+00 9.925814412e-01 + outer loop + vertex 8.828360320e-01 0.000000000e+00 -1.548809660e-02 + vertex 8.732520369e-01 0.000000000e+00 -1.666204294e-02 + vertex 8.732520369e-01 -1.000000000e+00 -1.666204294e-02 + endloop + endfacet + facet normal -1.215815886e-01 0.000000000e+00 9.925814412e-01 + outer loop + vertex 8.828360320e-01 0.000000000e+00 -1.548809660e-02 + vertex 8.732520369e-01 -1.000000000e+00 -1.666204294e-02 + vertex 8.828360320e-01 -1.000000000e+00 -1.548809660e-02 + endloop + endfacet + facet normal -1.228980857e-01 0.000000000e+00 9.924192967e-01 + outer loop + vertex 8.919122088e-01 0.000000000e+00 -1.436413141e-02 + vertex 8.828360320e-01 0.000000000e+00 -1.548809660e-02 + vertex 8.828360320e-01 -1.000000000e+00 -1.548809660e-02 + endloop + endfacet + facet normal -1.228980857e-01 0.000000000e+00 9.924192967e-01 + outer loop + vertex 8.919122088e-01 0.000000000e+00 -1.436413141e-02 + vertex 8.828360320e-01 -1.000000000e+00 -1.548809660e-02 + vertex 8.919122088e-01 -1.000000000e+00 -1.436413141e-02 + endloop + endfacet + facet normal -1.241591156e-01 0.000000000e+00 9.922623212e-01 + outer loop + vertex 9.004962735e-01 0.000000000e+00 -1.329003048e-02 + vertex 8.919122088e-01 0.000000000e+00 -1.436413141e-02 + vertex 8.919122088e-01 -1.000000000e+00 -1.436413141e-02 + endloop + endfacet + facet normal -1.241591156e-01 0.000000000e+00 9.922623212e-01 + outer loop + vertex 9.004962735e-01 0.000000000e+00 -1.329003048e-02 + vertex 8.919122088e-01 -1.000000000e+00 -1.436413141e-02 + vertex 9.004962735e-01 -1.000000000e+00 -1.329003048e-02 + endloop + endfacet + facet normal -1.253655965e-01 0.000000000e+00 9.921106124e-01 + outer loop + vertex 9.086049032e-01 0.000000000e+00 -1.226540359e-02 + vertex 9.004962735e-01 0.000000000e+00 -1.329003048e-02 + vertex 9.004962735e-01 -1.000000000e+00 -1.329003048e-02 + endloop + endfacet + facet normal -1.253655965e-01 0.000000000e+00 9.921106124e-01 + outer loop + vertex 9.086049032e-01 0.000000000e+00 -1.226540359e-02 + vertex 9.004962735e-01 -1.000000000e+00 -1.329003048e-02 + vertex 9.086049032e-01 -1.000000000e+00 -1.226540359e-02 + endloop + endfacet + facet normal -1.265184621e-01 0.000000000e+00 9.919642528e-01 + outer loop + vertex 9.162555145e-01 0.000000000e+00 -1.128961886e-02 + vertex 9.086049032e-01 0.000000000e+00 -1.226540359e-02 + vertex 9.086049032e-01 -1.000000000e+00 -1.226540359e-02 + endloop + endfacet + facet normal -1.265184621e-01 0.000000000e+00 9.919642528e-01 + outer loop + vertex 9.162555145e-01 0.000000000e+00 -1.128961886e-02 + vertex 9.086049032e-01 -1.000000000e+00 -1.226540359e-02 + vertex 9.162555145e-01 -1.000000000e+00 -1.128961886e-02 + endloop + endfacet + facet normal -1.276186911e-01 0.000000000e+00 9.918233057e-01 + outer loop + vertex 9.234660518e-01 0.000000000e+00 -1.036183331e-02 + vertex 9.162555145e-01 0.000000000e+00 -1.128961886e-02 + vertex 9.162555145e-01 -1.000000000e+00 -1.128961886e-02 + endloop + endfacet + facet normal -1.276186911e-01 0.000000000e+00 9.918233057e-01 + outer loop + vertex 9.234660518e-01 0.000000000e+00 -1.036183331e-02 + vertex 9.162555145e-01 -1.000000000e+00 -1.128961886e-02 + vertex 9.234660518e-01 -1.000000000e+00 -1.036183331e-02 + endloop + endfacet + facet normal -1.286673255e-01 0.000000000e+00 9.916878134e-01 + outer loop + vertex 9.302547963e-01 0.000000000e+00 -9.481022247e-03 + vertex 9.234660518e-01 0.000000000e+00 -1.036183331e-02 + vertex 9.234660518e-01 -1.000000000e+00 -1.036183331e-02 + endloop + endfacet + facet normal -1.286673255e-01 0.000000000e+00 9.916878134e-01 + outer loop + vertex 9.302547963e-01 0.000000000e+00 -9.481022247e-03 + vertex 9.234660518e-01 -1.000000000e+00 -1.036183331e-02 + vertex 9.302547963e-01 -1.000000000e+00 -9.481022247e-03 + endloop + endfacet + facet normal -1.296654827e-01 0.000000000e+00 9.915577959e-01 + outer loop + vertex 9.366401952e-01 0.000000000e+00 -8.646007049e-03 + vertex 9.302547963e-01 0.000000000e+00 -9.481022247e-03 + vertex 9.302547963e-01 -1.000000000e+00 -9.481022247e-03 + endloop + endfacet + facet normal -1.296654827e-01 0.000000000e+00 9.915577959e-01 + outer loop + vertex 9.366401952e-01 0.000000000e+00 -8.646007049e-03 + vertex 9.302547963e-01 -1.000000000e+00 -9.481022247e-03 + vertex 9.366401952e-01 -1.000000000e+00 -8.646007049e-03 + endloop + endfacet + facet normal -1.306143609e-01 0.000000000e+00 9.914332498e-01 + outer loop + vertex 9.426407106e-01 0.000000000e+00 -7.855481327e-03 + vertex 9.366401952e-01 0.000000000e+00 -8.646007049e-03 + vertex 9.366401952e-01 -1.000000000e+00 -8.646007049e-03 + endloop + endfacet + facet normal -1.306143609e-01 0.000000000e+00 9.914332498e-01 + outer loop + vertex 9.426407106e-01 0.000000000e+00 -7.855481327e-03 + vertex 9.366401952e-01 -1.000000000e+00 -8.646007049e-03 + vertex 9.426407106e-01 -1.000000000e+00 -7.855481327e-03 + endloop + endfacet + facet normal -1.315152389e-01 0.000000000e+00 9.913141490e-01 + outer loop + vertex 9.482746880e-01 0.000000000e+00 -7.108035235e-03 + vertex 9.426407106e-01 0.000000000e+00 -7.855481327e-03 + vertex 9.426407106e-01 -1.000000000e+00 -7.855481327e-03 + endloop + endfacet + facet normal -1.315152389e-01 0.000000000e+00 9.913141490e-01 + outer loop + vertex 9.482746880e-01 0.000000000e+00 -7.108035235e-03 + vertex 9.426407106e-01 -1.000000000e+00 -7.855481327e-03 + vertex 9.482746880e-01 -1.000000000e+00 -7.108035235e-03 + endloop + endfacet + facet normal -1.323694742e-01 0.000000000e+00 9.912004451e-01 + outer loop + vertex 9.535602429e-01 0.000000000e+00 -6.402177880e-03 + vertex 9.482746880e-01 0.000000000e+00 -7.108035235e-03 + vertex 9.482746880e-01 -1.000000000e+00 -7.108035235e-03 + endloop + endfacet + facet normal -1.323694742e-01 0.000000000e+00 9.912004451e-01 + outer loop + vertex 9.535602429e-01 0.000000000e+00 -6.402177880e-03 + vertex 9.482746880e-01 -1.000000000e+00 -7.108035235e-03 + vertex 9.535602429e-01 -1.000000000e+00 -6.402177880e-03 + endloop + endfacet + facet normal -1.331784915e-01 0.000000000e+00 9.910920691e-01 + outer loop + vertex 9.585151646e-01 0.000000000e+00 -5.736357801e-03 + vertex 9.535602429e-01 0.000000000e+00 -6.402177880e-03 + vertex 9.535602429e-01 -1.000000000e+00 -6.402177880e-03 + endloop + endfacet + facet normal -1.331784915e-01 0.000000000e+00 9.910920691e-01 + outer loop + vertex 9.585151646e-01 0.000000000e+00 -5.736357801e-03 + vertex 9.535602429e-01 -1.000000000e+00 -6.402177880e-03 + vertex 9.585151646e-01 -1.000000000e+00 -5.736357801e-03 + endloop + endfacet + facet normal -1.339437802e-01 0.000000000e+00 9.909889322e-01 + outer loop + vertex 9.631568360e-01 0.000000000e+00 -5.108981459e-03 + vertex 9.585151646e-01 0.000000000e+00 -5.736357801e-03 + vertex 9.585151646e-01 -1.000000000e+00 -5.736357801e-03 + endloop + endfacet + facet normal -1.339437802e-01 0.000000000e+00 9.909889322e-01 + outer loop + vertex 9.631568360e-01 0.000000000e+00 -5.108981459e-03 + vertex 9.585151646e-01 -1.000000000e+00 -5.736357801e-03 + vertex 9.631568360e-01 -1.000000000e+00 -5.108981459e-03 + endloop + endfacet + facet normal -1.346668767e-01 0.000000000e+00 9.908909286e-01 + outer loop + vertex 9.675021678e-01 0.000000000e+00 -4.518429822e-03 + vertex 9.631568360e-01 0.000000000e+00 -5.108981459e-03 + vertex 9.631568360e-01 -1.000000000e+00 -5.108981459e-03 + endloop + endfacet + facet normal -1.346668767e-01 0.000000000e+00 9.908909286e-01 + outer loop + vertex 9.675021678e-01 0.000000000e+00 -4.518429822e-03 + vertex 9.631568360e-01 -1.000000000e+00 -5.108981459e-03 + vertex 9.675021678e-01 -1.000000000e+00 -4.518429822e-03 + endloop + endfacet + facet normal -1.353493602e-01 0.000000000e+00 9.907979364e-01 + outer loop + vertex 9.715675461e-01 0.000000000e+00 -3.963073045e-03 + vertex 9.675021678e-01 0.000000000e+00 -4.518429822e-03 + vertex 9.675021678e-01 -1.000000000e+00 -4.518429822e-03 + endloop + endfacet + facet normal -1.353493602e-01 0.000000000e+00 9.907979364e-01 + outer loop + vertex 9.715675461e-01 0.000000000e+00 -3.963073045e-03 + vertex 9.675021678e-01 -1.000000000e+00 -4.518429822e-03 + vertex 9.715675461e-01 -1.000000000e+00 -3.963073045e-03 + endloop + endfacet + facet normal -1.359928360e-01 0.000000000e+00 9.907098206e-01 + outer loop + vertex 9.753687917e-01 0.000000000e+00 -3.441283350e-03 + vertex 9.715675461e-01 0.000000000e+00 -3.963073045e-03 + vertex 9.715675461e-01 -1.000000000e+00 -3.963073045e-03 + endloop + endfacet + facet normal -1.359928360e-01 0.000000000e+00 9.907098206e-01 + outer loop + vertex 9.753687917e-01 0.000000000e+00 -3.441283350e-03 + vertex 9.715675461e-01 -1.000000000e+00 -3.963073045e-03 + vertex 9.753687917e-01 -1.000000000e+00 -3.441283350e-03 + endloop + endfacet + facet normal -1.365989258e-01 0.000000000e+00 9.906264349e-01 + outer loop + vertex 9.789211303e-01 0.000000000e+00 -2.951446198e-03 + vertex 9.753687917e-01 0.000000000e+00 -3.441283350e-03 + vertex 9.753687917e-01 -1.000000000e+00 -3.441283350e-03 + endloop + endfacet + facet normal -1.365989258e-01 0.000000000e+00 9.906264349e-01 + outer loop + vertex 9.789211303e-01 0.000000000e+00 -2.951446198e-03 + vertex 9.753687917e-01 -1.000000000e+00 -3.441283350e-03 + vertex 9.789211303e-01 -1.000000000e+00 -2.951446198e-03 + endloop + endfacet + facet normal -1.371692595e-01 0.000000000e+00 9.905476234e-01 + outer loop + vertex 9.822391712e-01 0.000000000e+00 -2.491969835e-03 + vertex 9.789211303e-01 0.000000000e+00 -2.951446198e-03 + vertex 9.789211303e-01 -1.000000000e+00 -2.951446198e-03 + endloop + endfacet + facet normal -1.371692595e-01 0.000000000e+00 9.905476234e-01 + outer loop + vertex 9.822391712e-01 0.000000000e+00 -2.491969835e-03 + vertex 9.789211303e-01 -1.000000000e+00 -2.951446198e-03 + vertex 9.822391712e-01 -1.000000000e+00 -2.491969835e-03 + endloop + endfacet + facet normal -1.377054593e-01 0.000000000e+00 9.904732235e-01 + outer loop + vertex 9.853368953e-01 0.000000000e+00 -2.061293362e-03 + vertex 9.822391712e-01 0.000000000e+00 -2.491969835e-03 + vertex 9.822391712e-01 -1.000000000e+00 -2.491969835e-03 + endloop + endfacet + facet normal -1.377054593e-01 0.000000000e+00 9.904732235e-01 + outer loop + vertex 9.853368953e-01 0.000000000e+00 -2.061293362e-03 + vertex 9.822391712e-01 -1.000000000e+00 -2.491969835e-03 + vertex 9.853368953e-01 -1.000000000e+00 -2.061293362e-03 + endloop + endfacet + facet normal -1.382091374e-01 0.000000000e+00 9.904030666e-01 + outer loop + vertex 9.882276488e-01 0.000000000e+00 -1.657893416e-03 + vertex 9.853368953e-01 0.000000000e+00 -2.061293362e-03 + vertex 9.853368953e-01 -1.000000000e+00 -2.061293362e-03 + endloop + endfacet + facet normal -1.382091374e-01 0.000000000e+00 9.904030666e-01 + outer loop + vertex 9.882276488e-01 0.000000000e+00 -1.657893416e-03 + vertex 9.853368953e-01 -1.000000000e+00 -2.061293362e-03 + vertex 9.882276488e-01 -1.000000000e+00 -1.657893416e-03 + endloop + endfacet + facet normal -1.386818826e-01 0.000000000e+00 9.903369807e-01 + outer loop + vertex 9.909241438e-01 0.000000000e+00 -1.280289614e-03 + vertex 9.882276488e-01 0.000000000e+00 -1.657893416e-03 + vertex 9.882276488e-01 -1.000000000e+00 -1.657893416e-03 + endloop + endfacet + facet normal -1.386818826e-01 0.000000000e+00 9.903369807e-01 + outer loop + vertex 9.909241438e-01 0.000000000e+00 -1.280289614e-03 + vertex 9.882276488e-01 -1.000000000e+00 -1.657893416e-03 + vertex 9.909241438e-01 -1.000000000e+00 -1.280289614e-03 + endloop + endfacet + facet normal -1.391252567e-01 0.000000000e+00 9.902747916e-01 + outer loop + vertex 9.934384638e-01 0.000000000e+00 -9.270488597e-04 + vertex 9.909241438e-01 0.000000000e+00 -1.280289614e-03 + vertex 9.909241438e-01 -1.000000000e+00 -1.280289614e-03 + endloop + endfacet + facet normal -1.391252567e-01 0.000000000e+00 9.902747916e-01 + outer loop + vertex 9.934384638e-01 0.000000000e+00 -9.270488597e-04 + vertex 9.909241438e-01 -1.000000000e+00 -1.280289614e-03 + vertex 9.934384638e-01 -1.000000000e+00 -9.270488597e-04 + endloop + endfacet + facet normal -1.395407809e-01 0.000000000e+00 9.902163251e-01 + outer loop + vertex 9.957820729e-01 0.000000000e+00 -5.967886533e-04 + vertex 9.934384638e-01 0.000000000e+00 -9.270488597e-04 + vertex 9.934384638e-01 -1.000000000e+00 -9.270488597e-04 + endloop + endfacet + facet normal -1.395407809e-01 0.000000000e+00 9.902163251e-01 + outer loop + vertex 9.957820729e-01 0.000000000e+00 -5.967886533e-04 + vertex 9.934384638e-01 -1.000000000e+00 -9.270488597e-04 + vertex 9.957820729e-01 -1.000000000e+00 -5.967886533e-04 + endloop + endfacet + facet normal -1.399299448e-01 0.000000000e+00 9.901614063e-01 + outer loop + vertex 9.979658291e-01 0.000000000e+00 -2.881794857e-04 + vertex 9.957820729e-01 0.000000000e+00 -5.967886533e-04 + vertex 9.957820729e-01 -1.000000000e+00 -5.967886533e-04 + endloop + endfacet + facet normal -1.399299448e-01 0.000000000e+00 9.901614063e-01 + outer loop + vertex 9.979658291e-01 0.000000000e+00 -2.881794857e-04 + vertex 9.957820729e-01 -1.000000000e+00 -5.967886533e-04 + vertex 9.979658291e-01 -1.000000000e+00 -2.881794857e-04 + endloop + endfacet + facet normal -1.394420768e-01 0.000000000e+00 9.902302294e-01 + outer loop + vertex 1.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 9.979658291e-01 0.000000000e+00 -2.881794857e-04 + vertex 9.979658291e-01 -1.000000000e+00 -2.881794857e-04 + endloop + endfacet + facet normal -1.402941857e-01 1.767921997e-06 9.901098633e-01 + outer loop + vertex 1.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 9.979658291e-01 -1.000000000e+00 -2.881794857e-04 + vertex 1.000000000e+00 -1.000000000e+00 5.352202629e-08 + endloop + endfacet +endsolid diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/triSurface/internalFace.stl b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/triSurface/internalFace.stl new file mode 100644 index 0000000000000000000000000000000000000000..b55bf09361c6212e7b2f8f50737095e61e3fe190 --- /dev/null +++ b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/constant/triSurface/internalFace.stl @@ -0,0 +1,72 @@ +solid PART_6 + facet normal -0.000000000e+00 -1.767905329e-06 -1.000000000e+00 + outer loop + vertex 2.000000000e+00 -1.000000000e+00 5.352202629e-08 + vertex 1.000000000e+00 -1.000000000e+00 5.352202629e-08 + vertex 1.000000125e+00 0.000000000e+00 -1.714383303e-06 + endloop + endfacet + facet normal -2.117582368e-22 -1.767905329e-06 -1.000000000e+00 + outer loop + vertex 1.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 2.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 2.000000000e+00 -1.000000000e+00 5.352202629e-08 + endloop + endfacet + facet normal -0.000000000e+00 -1.767905329e-06 -1.000000000e+00 + outer loop + vertex 3.000000000e+00 -1.000000000e+00 5.352202629e-08 + vertex 2.000000000e+00 -1.000000000e+00 5.352202629e-08 + vertex 2.000000125e+00 0.000000000e+00 -1.714383303e-06 + endloop + endfacet + facet normal 2.117582368e-22 -1.767905329e-06 -1.000000000e+00 + outer loop + vertex 2.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 3.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 3.000000000e+00 -1.000000000e+00 5.352202629e-08 + endloop + endfacet + facet normal -0.000000000e+00 -1.767905329e-06 -1.000000000e+00 + outer loop + vertex 4.000000000e+00 -1.000000000e+00 5.352202629e-08 + vertex 3.000000000e+00 -1.000000000e+00 5.352202629e-08 + vertex 3.000000125e+00 0.000000000e+00 -1.714383303e-06 + endloop + endfacet + facet normal 0.000000000e+00 -1.767905329e-06 -1.000000000e+00 + outer loop + vertex 3.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 4.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 4.000000000e+00 -1.000000000e+00 5.352202629e-08 + endloop + endfacet + facet normal 2.117582368e-22 -1.767905329e-06 -1.000000000e+00 + outer loop + vertex 5.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 6.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 6.000000000e+00 -1.000000000e+00 5.352202629e-08 + endloop + endfacet + facet normal 0.000000000e+00 -1.767905329e-06 -1.000000000e+00 + outer loop + vertex 5.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 6.000000000e+00 -1.000000000e+00 5.352202629e-08 + vertex 5.000000000e+00 -1.000000000e+00 5.352202629e-08 + endloop + endfacet + facet normal -2.117582368e-22 -1.767905329e-06 -1.000000000e+00 + outer loop + vertex 4.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 5.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 5.000000000e+00 -1.000000000e+00 5.352202629e-08 + endloop + endfacet + facet normal 0.000000000e+00 -1.767905329e-06 -1.000000000e+00 + outer loop + vertex 4.000000000e+00 -1.000000000e+00 5.352202629e-08 + vertex 4.000000125e+00 0.000000000e+00 -1.714383303e-06 + vertex 5.000000000e+00 -1.000000000e+00 5.352202629e-08 + endloop + endfacet +endsolid diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/blockMeshDict b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/blockMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..c3e1035399d618211b5a79a285bb73d138858511 --- /dev/null +++ b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/blockMeshDict @@ -0,0 +1,56 @@ +/*--------------------------------*- 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 dictionary; + object blockMeshDict; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +convertToMeters 1; + +vertices +( + (-1 -1 -1) + ( 2 -1 -1) + ( 2 0 -1) + (-1 0 -1) + (-1 -1 1) + ( 2 -1 1) + ( 2 0 1) + (-1 0 1) +); + +blocks +( +// hex (0 1 2 3 4 5 6 7) (15 10 10) simpleGrading (1 1 1) + hex (0 1 2 3 4 5 6 7) (15 5 10) simpleGrading (1 1 1) +); + +edges +(); +boundary +( + airFlow + { + type patch; + faces + ( + (3 7 6 2) + (1 5 4 0) //back + (2 6 5 1) //outlet + (0 4 7 3) //inlet + (0 3 2 1) //lowerWall + (4 5 6 7) //upperWall + ); + } + +); diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/controlDict b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/controlDict new file mode 100644 index 0000000000000000000000000000000000000000..85986fc7d44762f6965daa830898a1a96c1172d3 --- /dev/null +++ b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/controlDict @@ -0,0 +1,55 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +//DebugSwitches +//{ +// fvGeometryScheme 1; +// highAspectRatio 1; +// basic 1; +//} + +application simpleFoam; + +startFrom startTime; + +startTime 0; + +stopAt endTime; + +endTime 15000; + +deltaT 1; + +writeControl timeStep; + +writeInterval 5000; + +purgeWrite 2; + +writeFormat binary; + +writePrecision 15; + +writeCompression off; + +timeFormat general; + +timePrecision 8; + +runTimeModifiable false; + + +// ************************************************************************* // diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/fvSchemes b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/fvSchemes new file mode 100644 index 0000000000000000000000000000000000000000..5e852737745eb11e5f1d6fec8bdfa89bad29a75a --- /dev/null +++ b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/fvSchemes @@ -0,0 +1,73 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +FoamFile +{ + version 2; + format ascii; + class dictionary; + object fvSchemes; +} + +ddtSchemes +{ + default steadyState; +} + +gradSchemes +{ + default Gauss linear; + grad(p) Gauss linear; + unlimitedGrad(U) Gauss linear; +} + +divSchemes +{ + default none; + div(phi,U) bounded Gauss linearUpwindV unlimitedGrad(U); + turbulence bounded Gauss limitedLinear 1; + div(phi,k) bounded Gauss limitedLinear 1; + div(phi,omega) bounded Gauss limitedLinear 1; + div(phi,nuTilda) bounded Gauss limitedLinear 1; + div(phi,epsilon) bounded Gauss limitedLinear 1; + div(phi,phit) bounded Gauss limitedLinear 1; + div(phi,f) bounded Gauss limitedLinear 1; + div(phi,gammaInt) bounded Gauss linearUpwind grad; + div(phi,ReThetat) bounded Gauss linearUpwind grad; + div((nuEff*dev2(T(grad(U))))) Gauss linear; +} + +laplacianSchemes +{ + default Gauss linear limited corrected 0.33; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default limited corrected 0.33; +} + +wallDist +{ + method meshWave; +} + +geometry +{ + type highAspectRatio; + minAspect 10; + maxAspect 100; +} + + +// ************************************************************************* // diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/fvSolution b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/fvSolution new file mode 100644 index 0000000000000000000000000000000000000000..4ad470198b34489e3261f05d2ca99335509e0aa4 --- /dev/null +++ b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/fvSolution @@ -0,0 +1,71 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + p + { + solver GAMG; + smoother GaussSeidel; + tolerance 1e-06; + relTol 0.1; + } + + "(U|k|omega|nuTilda|gammaInt|ReThetat)" + { + solver smoothSolver; + smoother symGaussSeidel; + tolerance 1e-08; + relTol 0.1; + maxIter 50; + } + + "(epsilon|phit)" + { + solver PBiCGStab; + preconditioner DILU; + tolerance 1e-8; + relTol 0; + } + + f + { + solver PBiCGStab; + preconditioner DIC; + tolerance 1e-8; + relTol 0; + } +} + +SIMPLE +{ + nNonOrthogonalCorrectors 0; + consistent true; +} + +relaxationFactors +{ + equations + { + ".*" 0.9; + "(gammaInt|ReThetat|k|nuTilda)" 0.8; + "(phit|f)" 0.7; + epsilon 0.5; + } +} + + +// ************************************************************************* // diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/meshQualityDict b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/meshQualityDict new file mode 100644 index 0000000000000000000000000000000000000000..467ab8ac82937ce7051e579e719d3951b21dc248 --- /dev/null +++ b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/meshQualityDict @@ -0,0 +1,78 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object meshQualityDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +//- Maximum non-orthogonality allowed. Set to 180 to disable. +maxNonOrtho 65; + +//- Max skewness allowed. Set to <0 to disable. +maxBoundarySkewness 20; +maxInternalSkewness 4; + +//- Max concaveness allowed. Is angle (in degrees) below which concavity +// is allowed. 0 is straight face, <0 would be convex face. +// Set to 180 to disable. +maxConcave 80; + +//- Minimum pyramid volume. Is absolute volume of cell pyramid. +// Set to a sensible fraction of the smallest cell volume expected. +// Set to very negative number (e.g. -1E30) to disable. +minVol 1e-13; + +//- Minimum quality of the tet formed by the face-centre +// and variable base point minimum decomposition triangles and +// the cell centre. Set to very negative number (e.g. -1E30) to +// disable. +// <0 = inside out tet, +// 0 = flat tet +// 1 = regular tet +minTetQuality 1e-15; + +//- Minimum face area. Set to <0 to disable. +minArea -1; + +//- Minimum face twist. Set to <-1 to disable. dot product of face normal +// (itself the average of the triangle normals) +// and face centre triangles normal +minTwist 0.02; + +//- Minimum normalised cell determinant. This is the determinant of all +// the areas of internal faces. It is a measure of how much of the +// outside area of the cell is to other cells. The idea is that if all +// outside faces of the cell are 'floating' (zeroGradient) the +// 'fixedness' of the cell is determined by the area of the internal faces. +// 1 = hex, <= 0 = folded or flattened illegal cell +minDeterminant 0.001; + +//- Relative position of face in relation to cell centres (0.5 for orthogonal +// mesh) (0 -> 0.5) +minFaceWeight 0.05; + +//- Volume ratio of neighbouring cells (0 -> 1) +minVolRatio 0.01; + +//- Per triangle normal compared to that of preceding triangle. Must be >0 +// for Fluent compatibility +minTriangleTwist -1; + + +//- If >0 : preserve cells with all points on the surface if the +// resulting volume after snapping (by approximation) is larger than +// minVolCollapseRatio times old volume (i.e. not collapsed to flat cell). +// If <0 : delete always. +//minVolCollapseRatio 0.1; + + +// ************************************************************************* // diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/snappyHexMeshDict b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/snappyHexMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..dd4c92631e3eb6d32b42b29836cf45e5e0f09c3b --- /dev/null +++ b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/snappyHexMeshDict @@ -0,0 +1,753 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object snappyHexMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Which of the steps to run +castellatedMesh true; +snap true; +addLayers true; + + +// Optional: single region surfaces get patch names according to +// surface only. Multi-region surfaces get patch name +// surface "_ "region. Default is true +// singleRegionName false; + +// Optional: avoid patch-face merging. Allows mesh to be used for +// refinement/unrefinement +// mergePatchFaces false; // default true + +// Optional: preserve all generated patches. Default is to remove +// zero-sized patches. +// keepPatches true; + + +// Geometry. Definition of all surfaces. All surfaces are of class +// searchableSurface. +// Surfaces are used +// - to specify refinement for any mesh cell intersecting it +// - to specify refinement for any mesh cell inside/outside/near +// - to 'snap' the mesh boundary to the surface +geometry +{ + refinement1 + { + type searchableBox; + min (-1 -2 -1); + max ( 1 2 1); + } +/* + // Shell for directional refinement + wakeBox + { + type searchableBox; + min (1.5 1 -0.5); + max (3.5 2 0.5); + } +*/ + internalFace.stl { name internalFace; type triSurfaceMesh;} + + aerofoil.stl + { + name aerofoil; + type triSurfaceMesh; + + //tolerance 1E-5; // optional:non-default tolerance on intersections + //maxTreeDepth 10; // optional:depth of octree. Decrease only in case + // of memory limitations. + + // Per region the patchname. If not provided will be <surface>_<region>. + // Note: this name cannot be used to identity this region in any + // other part of this dictionary; it is only a name + // for the combination of surface+region (which is only used + // when creating patches) +// regions +// { +// secondSolid +// { +// name mySecondPatch; +// } +// } + } + +/* + sphere2 + { + type searchableSphere; + centre (1.5 1.5 1.5); + radius 1.03; + } +*/ +}; + + +// Settings for the castellatedMesh generation. +castellatedMeshControls +{ + + // Refinement parameters + // ~~~~~~~~~~~~~~~~~~~~~ + + // If local number of cells is >= maxLocalCells on any processor + // switches from from refinement followed by balancing + // (current method) to (weighted) balancing before refinement. + maxLocalCells 1000000; + + // Overall cell limit (approximately). Refinement will stop immediately + // upon reaching this number so a refinement level might not complete. + // Note that this is the number of cells before removing the part which + // is not 'visible' from the keepPoint. The final number of cells might + // actually be a lot less. + maxGlobalCells 20000000; + + // The surface refinement loop might spend lots of iterations refining just + // a few cells. This setting will cause refinement to stop if + // <= minRefinementCells cells are selected for refinement. Note: it will + // at least do one iteration unless + // a: the number of cells to refine is 0 + // b: minRefinementCells = -1. This is a special value indicating + // no refinement. + minRefinementCells 0; + + // Allow a certain level of imbalance during refining + // (since balancing is quite expensive) + // Expressed as fraction of perfect balance (= overall number of cells / + // nProcs). 0=balance always. + maxLoadUnbalance 0.10; + + // Number of buffer layers between different levels. + // 1 means normal 2:1 refinement restriction, larger means slower + // refinement. + nCellsBetweenLevels 4; + + + // Explicit feature edge refinement + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // Specifies a level for any cell intersected by explicitly provided + // edges. + // This is a featureEdgeMesh, read from constant/triSurface for now. + // Specify 'levels' in the same way as the 'distance' mode in the + // refinementRegions (see below). The old specification + // level 2; + // is equivalent to + // levels ((0 2)); + + features + ( + { + file "aerofoil.eMesh"; + level 0; // Have level 2 for all cells intersected + // // by feature. + // levels ((0.1 2)); // Have level 2 for all cells within + // // 0.1 of feature. + } + ); + + + // Surface based refinement + // ~~~~~~~~~~~~~~~~~~~~~~~~ + + // Specifies two levels for every surface. The first is the minimum level, + // every cell intersecting a surface gets refined up to the minimum level. + // The second level is the maximum level. Cells that 'see' multiple + // intersections where the intersections make an + // angle > resolveFeatureAngle get refined up to the maximum level. + + refinementSurfaces + { + internalFace { level (0 0); faceZone internalFace; }//faceType baffle;} + aerofoil + { + // Surface-wise min and max refinement level + level (2 2); + + + + + //- Optional increment (on top of max level) in small gaps + //gapLevelIncrement 2; + + //- Optional angle to detect small-large cell situation + // perpendicular to the surface. Is the angle of face w.r.t. + // the local surface normal. Use on flat(ish) surfaces only. + // Otherwise leave out or set to negative number. + //perpendicularAngle 10; + + //- Optional faceZone and (for closed surface) cellZone with + // how to select the cells that are in the cellZone + // (inside / outside / specified insidePoint) + // The orientation of the faceZone is + // - if on cellZone(s) : point out of (minimum) cellZone + // - if freestanding : oriented according to surface + + //faceZone sphere; + //cellZone sphere; + //cellZoneInside inside; // outside/insidePoint + //insidePoint (1 1 1); // if (cellZoneInside == insidePoint) + + //- Optional specification of what to do with faceZone faces: + // internal : keep them as internal faces (default) + // baffle : create baffles from them. This gives more + // freedom in mesh motion + // boundary : create free-standing boundary faces (baffles + // but without the shared points) + //faceType baffle; + } + } + + // Feature angle: + // - used if min and max refinement level of a surface differ + // - used if feature snapping (see snapControls below) is used + resolveFeatureAngle 30; + + //- Optional increment (on top of max level) in small gaps + //gapLevelIncrement 2; + + + // Planar angle: + // - used to determine if surface normals + // are roughly the same or opposite. Used + // - in proximity refinement + // - to decide when to merge free-standing baffles + // (if e.g. running in surfaceSimplify mode set this to 180 to + // merge all baffles) + // - in snapping to avoid snapping to nearest on 'wrong' side + // of thin gap + // + // If not specified same as resolveFeatureAngle + planarAngle 30; + + + // Region-wise refinement + // ~~~~~~~~~~~~~~~~~~~~~~ + + // Specifies refinement level for cells in relation to a surface. One of + // three modes + // - distance. 'levels' specifies per distance to the surface the + // wanted refinement level. The distances need to be specified in + // increasing order. + // - inside. 'levels' is only one entry and only the level is used. All + // cells inside the surface get refined up to the level. The surface + // needs to be closed for this to be possible. + // - outside. Same but cells outside. + + refinementRegions + { +// refinement1 +// { +// mode inside; +// levels ((1.0 1)); +// } +/* + //sphere.stl + //{ + // mode inside; + // levels ((1.0 4)); + // // Optional override of uniform refinement level such + // // that in small gaps we're getting more cells. + // // The specification is + // // - numGapCells : minimum number of cells in the gap + // // (usually >3; lower than this might not + // // resolve correctly) + // // - minLevel : min refinement level at which to kick in + // // - maxLevel : upper refinement level (to avoid refinement + // // continuing on a single extraneous feature) + // // All three settings can be overridden on a surface by + // // surface basis in the refinementSurfaces section. + // gapLevel (<numGapCells> <minLevel> <maxlevel>); + // // Optional: when doing the gapLevel refinement directly remove + // // based on orientation w.r.t. gap. This limits the + // // amount of cells before doing the 'locationInMesh' + // // cell selection. Default is 'mixed' i.e. keep cells + // // whilst doing the gap-level refinement. + // //gapMode inside; // inside/outside/mixed + //} + + //wakeBox + //{ + // mode inside; + // // Dummy base level + // levels ((10000 0)); + // + // // Optional directional refinement (after all other refinement) + // // Directional refinement + // // for all cells according to 'mode' ('inside' or 'outside'; + // // 'distance' not supported) and within certain range. E.g. + // // - for all cells with level 2-5 + // // - do one split in x direction + // levelIncrement (2 5 (1 0 0)); + // + // // Note + // // - ignores 'levels' and gap* settings. + // // - the cellLevel/pointLevels files are no longer consistent + // // with the mesh, the resulting mesh is no longer compatible + // // with e.g. dynamic refinement/unrefinement. + // // - cellLevel will include any directional refinement + // // (i.e. it will be the maximum of all three directions) + //} + + //wakeBox + //{ + // mode inside; + // // Dummy base level + // levels ((10000 0)); + // + // // Optional directional refinement (after all other refinement) + // // Directional refinement + // // for all cells according to 'mode' ('inside' or 'outside'; + // // 'distance' not supported) and within certain range. E.g. + // // - for all cells with level 2-5 + // // - do one split in x direction + // levelIncrement (2 5 (1 0 0)); + // + // // Note + // // - ignores 'levels' and gap* settings. + // // - the cellLevel/pointLevels files are no longer consistent + // // with the mesh, the resulting mesh is no longer compatible + // // with e.g. dynamic refinement/unrefinement. + // // - cellLevel will include any directional refinement + // // (i.e. it will be the maximum of all three directions) + // + // // Optional directional expansion-ratio smoothing (after all + // // refinement). This will try to smooth out edge/cell size jumps + // // Specify smoothing direction and number of iterations + // smoothDirection (1 0 0); + // // Smoothing of expansion ratio + // nSmoothExpansion 100; + // // Smoothing of positions + // nSmoothPosition 100; + //} +*/ + } + + + + // Optionally limit refinement in geometric region. This limits all + // refinement (from features, refinementSurfaces, refinementRegions) + // in a given geometric region. The syntax is exactly the same as for the + // refinementRegions; the cell level now specifies the upper limit + // for any cell. (a special setting is cell level -1 which will remove + // any cells inside the region). Note that it does not override the + // refinement constraints given by the nCellsBetweenLevels setting. + limitRegions + { + } + + + // Mesh selection + // ~~~~~~~~~~~~~~ + + // After refinement patches get added for all refinementSurfaces and + // all cells intersecting the surfaces get put into these patches. The + // section reachable from the location(s)InMesh is kept. + // NOTE: This point should never be on a face, always inside a cell, even + // after refinement. + // + // There are two different ways of specifying the regions to keep: + // 1. a single locationInMesh. This is the unzoned part of the mesh. + // All the 'zoned' surfaces are marked as such + // in the refinementSurfaces with the faceZone and cellZone keywords. + // It is illegal to have the locationInMesh inside a surface for which + // a cellZone is specified. + // + // or + // + // 2. multiple locationsInMesh, with per location the name of the cellZone. + // This uses walking to determine zones and automatically creates + // faceZones on the outside of cellZones. The special name 'none' is + // used to indicate the unzoned/background part of the mesh. + + + // Ad 1. Specify a single location and how to treat faces inbetween + // cellZones + locationInMesh (-0.457 -0.5 0.43); + + // Whether any faceZones (as specified in the refinementSurfaces) + // are only on the boundary of corresponding cellZones. + // Not used if there are no faceZones. The behaviour has changed + // with respect to previous versions: + // true : all intersections with surface are put in faceZone + // (same behaviour as before) + // false : depending on the type of surface intersected: + // - if intersecting surface has faceZone only (so no cellZone) + // leave in faceZone (so behave as if set to true) (= changed + // behaviour) + // - if intersecting surface has faceZone and cellZone + // remove if inbetween same cellZone or if on boundary + // (same behaviour as before) + allowFreeStandingZoneFaces true; + + + + // 2. Specify multiple locations with optional cellZones for the + // regions (use cellZone "none" to specify the unzoned cells) + // FaceZones are automatically constructed from the + // names of the cellZones: <cellZoneA> _to_ <cellZoneB> + // where the cellZoneA is the lowest numbered cellZone (non-cellZone + // cells are in a special region called "none" which is always + // last). + + + + + // Optional locations that should not be reachable from + // location(s)InMesh +// locationsOutsideMesh ((100 100 100)); + + // Optional: do not remove cells likely to give snapping problems + // handleSnapProblems false; + + // Optional: switch off topological test for cells to-be-squashed + // and use geometric test instead + //useTopologicalSnapDetection false; + + // Optional: do not refine surface cells with opposite faces of + // differing refinement levels + //interfaceRefine false; + + // Optional: use an erosion instead of region assignment to allocate + // left-over cells to the background region (i.e. make cellZones + // consistent with the intersections of the surface). + // Erosion is specified as a number of erosion iterations. + // Erosion has less chance of bleeding and changing the zone + // for a complete region. + //nCellZoneErodeIter 2; +} + +// Settings for the snapping. +snapControls +{ + // Number of patch smoothing iterations before finding correspondence + // to surface + nSmoothPatch 3; + + // Optional: number of smoothing iterations for internal points on + // refinement interfaces. This will reduce non-orthogonality on + // refinement interfaces. + //nSmoothInternal $nSmoothPatch; + + // Maximum relative distance for points to be attracted by surface. + // True distance is this factor times local maximum edge length. + tolerance 1.0; + + // Number of mesh displacement relaxation iterations. + nSolveIter 30; + + // Maximum number of snapping relaxation iterations. Should stop + // before upon reaching a correct mesh. + nRelaxIter 5; + + // (wip) disable snapping to opposite near surfaces (revert to 22x + // behaviour) + // detectNearSurfacesSnap false; + + + // Feature snapping + + // Number of feature edge snapping iterations. + // Leave out altogether to disable. + nFeatureSnapIter 10; + + // Detect (geometric only) features by sampling the surface + // (default=false). + implicitFeatureSnap false; + + // Use castellatedMeshControls::features (default = true) + explicitFeatureSnap true; + + // Detect features between multiple surfaces + // (only for explicitFeatureSnap, default = false) + multiRegionFeatureSnap false; + + + //- When to run face splitting (never at first iteration, always + // at last iteration). Is interval. Default -1 (disabled) + //nFaceSplitInterval 5; + + + // (wip) Optional for explicit feature snapping: + //- Detect baffle edges. Default is true. + //detectBaffles false; + //- On any faces where points are on multiple regions (see + // multiRegionFeatureSnap) have the other points follow these points + // instead of having their own independent movement, i.e. have snapping + // to multi-region edges/points take priority. This might aid snapping + // to sharp edges that are also region edges. The default is false. + //releasePoints true; + //- Walk along feature edges, adding missing ones. Default is true. + //stringFeatures false; + //- If diagonal attraction also attract other face points. Default is + // false + //avoidDiagonal true; + //- When splitting what concave faces to leave intact. Default is 45 + // degrees. + //concaveAngle 30; + //- When splitting the minimum area ratio of faces. If face split + // causes ratio of area less than this do not split. Default is 0.3 + //minAreaRatio 0.3; + //- Attract points only to the surface they originate from. Default + // false. This can improve snapping of intersecting surfaces. + strictRegionSnap true; +} + +// Settings for the layer addition. +addLayersControls +{ + // Are the thickness parameters below relative to the undistorted + // size of the refined cell outside layer (true) or absolute sizes (false). + relativeSizes true; + + // Layer thickness specification. This can be specified in one of following + // ways: + // - expansionRatio and finalLayerThickness (cell nearest internal mesh) + // - expansionRatio and firstLayerThickness (cell on surface) + // - overall thickness and firstLayerThickness + // - overall thickness and finalLayerThickness + // - overall thickness and expansionRatio + // + // Note: the mode thus selected is global, i.e. one cannot override the + // mode on a per-patch basis (only the values can be overridden) + + // Expansion factor for layer mesh + expansionRatio 1.5; + + // Wanted thickness of the layer furthest away from the wall. + // If relativeSizes this is relative to undistorted size of cell + // outside layer. + finalLayerThickness 0.3; + + // Wanted thickness of the layer next to the wall. + // If relativeSizes this is relative to undistorted size of cell + // outside layer. + //firstLayerThickness 0.3; + + // Wanted overall thickness of layers. + // If relativeSizes this is relative to undistorted size of cell + // outside layer. + //thickness 0.5 + + + // Minimum overall thickness of total layers. If for any reason layer + // cannot be above minThickness do not add layer. + // If relativeSizes this is relative to undistorted size of cell + // outside layer.. + minThickness 0.1; + + + // Per final patch or faceZone (so not geometry!) the layer information + // Note: This behaviour changed after 21x. Any non-mentioned patches + // now slide unless: + // - nSurfaceLayers is explicitly mentioned to be 0. + // - angle to nearest surface < slipFeatureAngle (see below) + layers + { + "internalFace.*" {nSurfaceLayers 20; } + aerofoil + { + nSurfaceLayers 20; + + } + } + + // If points get not extruded do nGrow layers of connected faces that are + // also not grown. This helps convergence of the layer addition process + // close to features. + // Note: changed(corrected) w.r.t 1.7.x! (didn't do anything in 1.7.x) + nGrow -1; + + // Advanced settings + + + // Static analysis of starting mesh + + // When not to extrude surface. 0 is flat surface, 90 is when two faces + // are perpendicular. Note: was not working correctly < 1806 + featureAngle 180; + + // When to merge patch faces. Default is featureAngle. Useful when + // featureAngle is large. + //mergePatchFacesAngle 45; + + // Stop layer growth on highly warped cells + maxFaceThicknessRatio 1000;//0.5; + + + // Patch displacement + + // Number of smoothing iterations of surface normals + nSmoothSurfaceNormals 1; + + // Smooth layer thickness over surface patches + nSmoothThickness 10; + + + + // Choice of mesh shrinking algorithm + + // Optional mesh shrinking algorithm (default is displacementMedialAxis) + // The displacementMotionSolver is a wrapper around the displacement + // motion solvers. It needs specification of the solver to use and + // its control dictionary. + //meshShrinker displacementMotionSolver; + //solver displacementLaplacian; + //displacementLaplacianCoeffs + //{ + // diffusivity quadratic inverseDistance + // ( + // sphere.stl_firstSolid + // maxY + // ); + //} + // Note that e.g. displacementLaplacian needs entries in + // fvSchemes, fvSolution. Also specify a minIter > 1 when solving + // cellDisplacement since otherwise solution might not be sufficiently + // accurate on points. + + + // Medial axis analysis (for use with default displacementMedialAxis) + + // Angle used to pick up medial axis points + // Note: changed(corrected) w.r.t 1.7.x! 90 degrees corresponds to 130 + // in 1.7.x. + minMedialAxisAngle 90; + + // Reduce layer growth where ratio thickness to medial + // distance is large + maxThicknessToMedialRatio 0.3; + + // Number of smoothing iterations of interior mesh movement direction + nSmoothNormals 3; + + // Optional: limit the number of steps walking away from the surface. + // Default is unlimited. + //nMedialAxisIter 10; + + // Optional: smooth displacement after medial axis determination. + // default is 0. + //nSmoothDisplacement 90; + + // (wip)Optional: do not extrude any point where + // (false) : all surrounding faces are not fully extruded + // (true) : all surrounding points are not extruded + // Default is false. + //detectExtrusionIsland true; + + // Optional: do not extrude around sharp edges if both faces are not + // fully extruded i.e. if one of the faces on either side would + // become a wedge. + // Default is 0.5*featureAngle. Set to -180 always attempt extrusion + //layerTerminationAngle 25; + + // Optional: disable shrinking of edges that have one (or two) points + // on an extruded patch. + // Default is false to enable single/two cell thick channels to still + // have layers. In <=1806 this was true by default. On larger gaps it + // should have no effect. + //disableWallEdges true; + + // Optional: at non-patched sides allow mesh to slip if extrusion + // direction makes angle larger than slipFeatureAngle. Default is + // 0.5*featureAngle. + slipFeatureAngle 10; + + // Maximum number of snapping relaxation iterations. Should stop + // before upon reaching a correct mesh. + nRelaxIter 5; + + + // Mesh shrinking + + // Create buffer region for new layer terminations, i.e. gradually + // step down number of layers. Set to <0 to terminate layer in one go. + nBufferCellsNoExtrude 0; + + // Overall max number of layer addition iterations. The mesher will + // exit if it reaches this number of iterations; possibly with an + // illegal mesh. + nLayerIter 50; + + // Max number of iterations after which relaxed meshQuality controls + // get used. Up to nRelaxedIter it uses the settings in + // meshQualityControls, + // after nRelaxedIter it uses the values in + // meshQualityControls::relaxed. + nRelaxedIter 0; + + // Additional reporting: if there are just a few faces where there + // are mesh errors (after adding the layers) print their face centres. + // This helps in tracking down problematic mesh areas. + //additionalReporting true; +} + +// Generic mesh quality settings. At any undoable phase these determine +// where to undo. +meshQualityControls +{ + // Specify mesh quality constraints in separate dictionary so can + // be reused (e.g. checkMesh -meshQuality) + #include "meshQualityDict" + + minDeterminant 1e-8; + + // 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; + minTetQuality -1e30; + minTwist -1; + } + + + // Advanced + + // Number of error distribution iterations + nSmoothScale 4; + // amount to scale back displacement at error points + errorReduction 0.75; +} + +// Advanced + +//// Debug flags +//debugFlags +//( +// mesh // write intermediate meshes +// intersections // write current mesh intersections as .obj files +// featureSeeds // write information about explicit feature edge +// // refinement +// attraction // write attraction as .obj files +// layerInfo // write information about layers +//); +// +//// Write flags +//writeFlags +//( +// scalarLevels // write volScalarField with cellLevel for postprocessing +// layerSets // write cellSets, faceSets of faces in layer +// layerFields // write volScalarField for layer coverage +//); + + +//// Format for writing lines. E.g. leak path. Default is vtk format. +//setFormat ensight; + +// Merge tolerance. Is fraction of overall bounding box of initial mesh. +// Note: the write tolerance needs to be higher than this. +mergeTolerance 1e-6; + +// ************************************************************************* // diff --git a/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/surfaceFeatureExtractDict b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/surfaceFeatureExtractDict new file mode 100644 index 0000000000000000000000000000000000000000..12cc383824cdd466c19891b2ab54c9ea554f50e3 --- /dev/null +++ b/tutorials/mesh/snappyHexMesh/airfoilWithLayers/system/surfaceFeatureExtractDict @@ -0,0 +1,47 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object surfaceFeatureExtractDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +aerofoil.stl +{ + // Extract raw features (none | extractFromFile | extractFromSurface) + extractionMethod extractFromSurface; + + // Mark edges whose adjacent surface normals are at an angle less + // than includedAngle as features + // - 0 : selects no edges + // - 180: selects all edges + includedAngle 120; + +curvature true; + // Do not mark region edges + geometricTestOnly yes; + + // Generate additional intersection features (none | self | region) + intersectionMethod none; + + // Tolerance for surface intersections + // tolerance 1e-3; + +// Output options: + + // Write features to obj format for postprocessing + writeObj yes; +} + + + + +// ************************************************************************* //