diff --git a/applications/solvers/combustion/dieselEngineFoam/Make/options b/applications/solvers/combustion/dieselEngineFoam/Make/options index d0a572b86fe75a654e87f7729063cd71d4d88e1b..9a4524781991ee2dda50e905632a3fc35a8be60a 100644 --- a/applications/solvers/combustion/dieselEngineFoam/Make/options +++ b/applications/solvers/combustion/dieselEngineFoam/Make/options @@ -2,6 +2,7 @@ EXE_INC = \ -I../engineFoam \ -I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/dieselSpray/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/liquids/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/liquidMixture/lnInclude \ @@ -24,6 +25,7 @@ EXE_LIBS = \ -lreactionThermophysicalModels \ -lfiniteVolume \ -llagrangian \ + -lmeshTools \ -ldieselSpray \ -lliquids \ -lliquidMixture \ diff --git a/applications/solvers/combustion/dieselFoam/Make/options b/applications/solvers/combustion/dieselFoam/Make/options index 9096934c2dd4fafb86625f17eb348a8c26f5fde8..3b1786aa08b6821b38799bebcace1e7560c5eb31 100644 --- a/applications/solvers/combustion/dieselFoam/Make/options +++ b/applications/solvers/combustion/dieselFoam/Make/options @@ -3,6 +3,7 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/dieselSpray/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/liquids/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/liquidMixture/lnInclude \ @@ -21,6 +22,7 @@ EXE_LIBS = \ -lcompressibleLESModels \ -lreactionThermophysicalModels \ -llagrangian \ + -lmeshTools \ -ldieselSpray \ -lliquids \ -lliquidMixture \ diff --git a/applications/solvers/discreteMethods/dsmc/dsmcFoam/Make/options b/applications/solvers/discreteMethods/dsmc/dsmcFoam/Make/options index bc99834af6ea732c365d0b07940f997e1c6cedfe..62520c19b0ea4fb400f41c1327a7ebcb243309f0 100644 --- a/applications/solvers/discreteMethods/dsmc/dsmcFoam/Make/options +++ b/applications/solvers/discreteMethods/dsmc/dsmcFoam/Make/options @@ -9,4 +9,3 @@ EXE_LIBS = \ -lfiniteVolume \ -llagrangian \ -ldsmc - diff --git a/applications/solvers/lagrangian/incompressibleUncoupledKinematicParcelDyMFoam/Make/files b/applications/solvers/lagrangian/incompressibleUncoupledKinematicParcelDyMFoam/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..e233a549b844fd65145120df55ecc29952c772a1 --- /dev/null +++ b/applications/solvers/lagrangian/incompressibleUncoupledKinematicParcelDyMFoam/Make/files @@ -0,0 +1,3 @@ +incompressibleUncoupledKinematicParcelDyMFoam.C + +EXE = $(FOAM_APPBIN)/incompressibleUncoupledKinematicParcelDyMFoam diff --git a/applications/solvers/lagrangian/incompressibleUncoupledKinematicParcelDyMFoam/Make/options b/applications/solvers/lagrangian/incompressibleUncoupledKinematicParcelDyMFoam/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..3c4206dc24a7aa2bad9124f943e263402bf7821d --- /dev/null +++ b/applications/solvers/lagrangian/incompressibleUncoupledKinematicParcelDyMFoam/Make/options @@ -0,0 +1,33 @@ +EXE_INC = \ + -I$(LIB_SRC)/lagrangian/basic/lnInclude \ + -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \ + -I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \ + -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ + -I$(LIB_SRC)/thermophysicalModels/reactionThermo/lnInclude \ + -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \ + -I$(LIB_SRC)/turbulenceModels/incompressible/turbulenceModel \ + -I$(LIB_SRC)/transportModels \ + -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/surfaceFilmModels/lnInclude \ + -I$(LIB_SRC)/dynamicMesh/lnInclude \ + -I$(LIB_SRC)/dynamicFvMesh/lnInclude + + +EXE_LIBS = \ + -llagrangian \ + -llagrangianIntermediate \ + -lthermophysicalFunctions \ + -lbasicThermophysicalModels \ + -lspecie \ + -lradiation \ + -lincompressibleRASModels \ + -lincompressibleLESModels \ + -lincompressibleTransportModels \ + -lfiniteVolume \ + -lmeshTools \ + -lsurfaceFilmModels \ + -ldynamicMesh \ + -ldynamicFvMesh \ + -ltopoChangerFvMesh diff --git a/applications/solvers/lagrangian/incompressibleUncoupledKinematicParcelDyMFoam/createFields.H b/applications/solvers/lagrangian/incompressibleUncoupledKinematicParcelDyMFoam/createFields.H new file mode 100644 index 0000000000000000000000000000000000000000..0ad057e229970748c7d4e3b330643b700fb2dfe2 --- /dev/null +++ b/applications/solvers/lagrangian/incompressibleUncoupledKinematicParcelDyMFoam/createFields.H @@ -0,0 +1,147 @@ + Info<< "\nReading transportProperties\n" << endl; + + IOdictionary transportProperties + ( + IOobject + ( + "transportProperties", + runTime.constant(), + mesh, + IOobject::MUST_READ_IF_MODIFIED, + IOobject::NO_WRITE + ) + ); + + dimensionedScalar rhoInfValue + ( + transportProperties.lookup("rhoInf") + ); + + volScalarField rhoInf + ( + IOobject + ( + "rho", + runTime.timeName(), + mesh, + IOobject::NO_READ, + IOobject::AUTO_WRITE + ), + mesh, + rhoInfValue + ); + + Info<< "Reading field U\n" << endl; + volVectorField U + ( + IOobject + ( + "U", + runTime.timeName(), + mesh, + IOobject::MUST_READ, + IOobject::AUTO_WRITE + ), + mesh + ); + + #include "createPhi.H" + + Info<< "Creating turbulence model\n" << endl; + + singlePhaseTransportModel laminarTransport(U, phi); + + const volScalarField nu = laminarTransport.nu(); + + autoPtr<incompressible::turbulenceModel> turbulence + ( + incompressible::turbulenceModel::New(U, phi, laminarTransport) + ); + + volScalarField mu + ( + IOobject + ( + "mu", + runTime.timeName(), + mesh, + IOobject::NO_READ, + IOobject::AUTO_WRITE + ), + nu*rhoInfValue + ); + + word kinematicCloudName("kinematicCloud"); + args.optionReadIfPresent("cloudName", kinematicCloudName); + + Info<< "Constructing kinematicCloud " << kinematicCloudName << endl; + basicKinematicCloud kinematicCloud + ( + kinematicCloudName, + rhoInf, + U, + mu, + g + ); + + IOobject Hheader + ( + "H", + runTime.timeName(), + mesh, + IOobject::NO_READ + ); + + autoPtr<volVectorField> HPtr_; + + if (Hheader.headerOk()) + { + Info<< "\nReading field H\n" << endl; + + HPtr_.reset + ( + new volVectorField + ( + IOobject + ( + "H", + runTime.timeName(), + mesh, + IOobject::MUST_READ, + IOobject::AUTO_WRITE + ), + mesh + ) + ); + } + + IOobject HdotGradHheader + ( + "HdotGradH", + runTime.timeName(), + mesh, + IOobject::NO_READ + ); + + autoPtr<volVectorField> HdotGradHPtr_; + + if (HdotGradHheader.headerOk()) + { + Info<< "Reading field HdotGradH" << endl; + + HdotGradHPtr_.reset + ( + new volVectorField + ( + IOobject + ( + "HdotGradH", + runTime.timeName(), + mesh, + IOobject::MUST_READ, + IOobject::AUTO_WRITE + ), + mesh + ) + ); + } diff --git a/applications/solvers/lagrangian/incompressibleUncoupledKinematicParcelDyMFoam/incompressibleUncoupledKinematicParcelDyMFoam.C b/applications/solvers/lagrangian/incompressibleUncoupledKinematicParcelDyMFoam/incompressibleUncoupledKinematicParcelDyMFoam.C new file mode 100644 index 0000000000000000000000000000000000000000..f5fba006e02b16e58ff06e24c1c1665879227ae0 --- /dev/null +++ b/applications/solvers/lagrangian/incompressibleUncoupledKinematicParcelDyMFoam/incompressibleUncoupledKinematicParcelDyMFoam.C @@ -0,0 +1,92 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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/>. + +Application + uncoupledKinematicParcelFoam + +Description + Transient solver for the passive transport of a single kinematic + particle could. + + Uses a pre-calculated velocity field to evolve the cloud. + +\*---------------------------------------------------------------------------*/ + +#include "fvCFD.H" +#include "dynamicFvMesh.H" +#include "singlePhaseTransportModel.H" +#include "turbulenceModel.H" +#include "basicKinematicCloud.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + argList::addOption + ( + "cloudName", + "name", + "specify alternative cloud name. default is 'kinematicCloud'" + ); + + #include "setRootCase.H" + #include "createTime.H" + # include "createDynamicFvMesh.H" + + #include "readGravitationalAcceleration.H" + #include "createFields.H" + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + Info<< "\nStarting time loop\n" << endl; + + while (runTime.loop()) + { + Info<< "Time = " << runTime.timeName() << nl << endl; + + mesh.update(); + + U.correctBoundaryConditions(); + + Info<< "Evolving " << kinematicCloud.name() << endl; + + laminarTransport.correct(); + + mu = nu*rhoInfValue; + + kinematicCloud.evolve(); + + runTime.write(); + + Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s" + << " ClockTime = " << runTime.elapsedClockTime() << " s" + << nl << endl; + } + + Info<< "End\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/solvers/lagrangian/reactingParcelFilmFoam/YEqn.H b/applications/solvers/lagrangian/reactingParcelFilmFoam/YEqn.H index c687f2035ba3fb4bb6d48efcd631d052eb189fce..0a2c36b7b50f53e5bee8f1d86a7e5b791dd79a6d 100644 --- a/applications/solvers/lagrangian/reactingParcelFilmFoam/YEqn.H +++ b/applications/solvers/lagrangian/reactingParcelFilmFoam/YEqn.H @@ -26,6 +26,7 @@ tmp<fv::convectionScheme<scalar> > mvConvection - fvm::laplacian(turbulence->muEff(), Yi) == parcels.Srho(i) + + surfaceFilm.Srho(i) + kappa*chemistry.RR(i)().dimensionedInternalField(), mesh.solver("Yi") ); diff --git a/applications/solvers/lagrangian/reactingParcelFilmFoam/hsEqn.H b/applications/solvers/lagrangian/reactingParcelFilmFoam/hsEqn.H index 156d5505ab8c469f6f2e990724188262f2ff867b..3c76f1384c8bc5d2d9f1c75906d41ceea6523b22 100644 --- a/applications/solvers/lagrangian/reactingParcelFilmFoam/hsEqn.H +++ b/applications/solvers/lagrangian/reactingParcelFilmFoam/hsEqn.H @@ -6,9 +6,10 @@ - fvm::laplacian(turbulence->alphaEff(), hs) == DpDt - + parcels.Sh() - + radiation->Shs(thermo) - + chemistrySh + + parcels.Sh() + + surfaceFilm.Sh() + + radiation->Shs(thermo) + + chemistrySh ); hsEqn.relax(); diff --git a/applications/solvers/lagrangian/reactingParcelFilmFoam/pEqn.H b/applications/solvers/lagrangian/reactingParcelFilmFoam/pEqn.H index d27afcce8ac2464b63b09e05645bcb5de6aa1282..93764f87de95b7934079d22f5fb4c2ddf7e3e3fb 100644 --- a/applications/solvers/lagrangian/reactingParcelFilmFoam/pEqn.H +++ b/applications/solvers/lagrangian/reactingParcelFilmFoam/pEqn.H @@ -24,6 +24,7 @@ if (transonic) - fvm::laplacian(rho*rUA, p) == parcels.Srho() + + surfaceFilm.Srho() ); pEqn.solve(); @@ -52,6 +53,7 @@ else - fvm::laplacian(rho*rUA, p) == parcels.Srho() + + surfaceFilm.Srho() ); pEqn.solve(); diff --git a/applications/solvers/lagrangian/reactingParcelFilmFoam/rhoEqn.H b/applications/solvers/lagrangian/reactingParcelFilmFoam/rhoEqn.H index b9b2d6a13f9ccfcced687b62d96a2c7adbb3b217..2c5d41f4fe5f3b0a48fd10f968bed824ae738ae7 100644 --- a/applications/solvers/lagrangian/reactingParcelFilmFoam/rhoEqn.H +++ b/applications/solvers/lagrangian/reactingParcelFilmFoam/rhoEqn.H @@ -36,6 +36,7 @@ Description + fvc::div(phi) == parcels.Srho() + + surfaceFilm.Srho() ); } diff --git a/applications/test/findCell-octree/findCell-octree.C b/applications/test/findCell-octree/findCell-octree.C index 2fbb9c0703fd9b1f404ddf9d466eb63e3aa6eccd..df8797eeb065947bd3460e9942623242c30223c3 100644 --- a/applications/test/findCell-octree/findCell-octree.C +++ b/applications/test/findCell-octree/findCell-octree.C @@ -29,6 +29,8 @@ License #include "IStringStream.H" #include "octree.H" #include "octreeDataCell.H" +#include "indexedOctree.H" +#include "treeDataCell.H" #include "OFstream.H" using namespace Foam; @@ -44,11 +46,13 @@ int main(int argc, char *argv[]) # include "createTime.H" # include "createMesh.H" + label nReps = 100000; + const point sample = args.argRead<point>(1); - treeBoundBox meshBb(mesh.points()); + treeBoundBox meshBb(mesh.bounds()); - // Calculate typical cell releated size to shift bb by. + // Calculate typical cell related size to shift bb by. scalar typDim = meshBb.avgDim()/(2.0*Foam::cbrt(scalar(mesh.nCells()))); treeBoundBox shiftedBb @@ -57,16 +61,13 @@ int main(int argc, char *argv[]) meshBb.max() + vector(typDim, typDim, typDim) ); - Info<< "Mesh" << endl; Info<< " bounding box : " << meshBb << endl; Info<< " bounding box (shifted) : " << shiftedBb << endl; Info<< " typical dimension : " << shiftedBb.typDim() << endl; - - /* - * Now we have allBb and shiftedBb - */ + Info<< "Initialised mesh in " + << runTime.cpuTimeIncrement() << " s" << endl; // Wrap indices and mesh information into helper object octreeDataCell shapes(mesh); @@ -80,14 +81,52 @@ int main(int argc, char *argv[]) 10.0 // maximum ratio of cubes v.s. cells ); - Info<< "Point:" << sample << " is in shape " - << oc.find(sample) << nl - << "Point:" << sample << " is in cell " - << mesh.findCell(sample) << endl; + for (label i = 0; i < nReps - 1 ; i++) + { + oc.find(sample); + } + Info<< "Point:" << sample << " is in shape " + << oc.find(sample) << endl; oc.printStats(Info); + Info<< "Found in octree " << nReps << " times in " + << runTime.cpuTimeIncrement() << " s" << endl; + + indexedOctree<treeDataCell> ioc + ( + treeDataCell(true, mesh), + shiftedBb, + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity + ); + + for (label i = 0; i < nReps - 1 ; i++) + { + ioc.findInside(sample); + } + + Info<< "Point:" << sample << " is in shape " + << ioc.findInside(sample) + << ", where the possible cells were:" << nl + << ioc.findIndices(sample) + << endl; + + Info<< "Found in indexedOctree " << nReps << " times in " + << runTime.cpuTimeIncrement() << " s" << endl; + + for (label i = 0; i < nReps - 1 ; i++) + { + mesh.findCell(sample); + } + + Info<< "Point:" << sample << " is in cell " + << mesh.findCell(sample) << endl; + + Info<< "Found in mesh.findCell " << nReps << " times in " + << runTime.cpuTimeIncrement() << " s" << endl; Info<< "End\n" << endl; diff --git a/applications/utilities/mesh/conversion/ansysToFoam/ansysToFoam.L b/applications/utilities/mesh/conversion/ansysToFoam/ansysToFoam.L index 16e3b9efe319d6a9c8e58ed77a246bb42feb0346..ddd97c3a05831787f45b3c3053df24f907a07132 100644 --- a/applications/utilities/mesh/conversion/ansysToFoam/ansysToFoam.L +++ b/applications/utilities/mesh/conversion/ansysToFoam/ansysToFoam.L @@ -63,11 +63,16 @@ label maxNodei = 0; SLPtrList<labelList> slCellLabels; SLList<label> slCellMap; +SLList<label> slCellType; label maxCelli = 0; PtrList<SLList<label> > slPatchCells; PtrList<SLList<label> > slPatchCellFaces; +// Cell types +Map<word> cellTypes; +label currentTypei = -1; + // Dummy yywrap to keep yylex happy at compile time. // It is called by yylex but is not used as the mechanism to change file. @@ -108,6 +113,8 @@ value {floatNum} node ^{space}"N"{cspace} element ^{space}"EN"{cspace} bface ^{space}"SFE"{cspace} +elementTypeName ^{space}"ET"{cspace} +elementType ^{space}"TYPE"{cspace} %% @@ -160,6 +167,7 @@ bface ^{space}"SFE"{cspace} slCellMap.append(celli); slCellLabels.append(new labelList(labels)); + slCellType.append(currentTypei); } @@ -210,6 +218,37 @@ bface ^{space}"SFE"{cspace} } +{elementTypeName}{label}{cspace}{identifier}{space}\n { + + IStringStream elementStream(YYText()); + char tag,c; + label cellTypei; + word cellTypeName; + elementStream + >> tag >> tag // skip 'ET' + >> c >> cellTypei + >> c >> cellTypeName; + + Info<< "Read typeName " << cellTypeName + << " for type " << cellTypei << endl; + + cellTypes.insert(cellTypei, cellTypeName); + } + + +{elementType}{label}{space}\n { + IStringStream elementStream(YYText()); + char tag,c; + label cellTypei; + elementStream + >> tag >> tag >> tag >> tag // skip 'TYPE' + >> c >> cellTypei; + + currentTypei = cellTypei; + } + + + /* ------------------------------------------------------------------------- *\ ------ Ignore remaining space and \n s. Any other characters are errors. \* ------------------------------------------------------------------------- */ @@ -231,6 +270,29 @@ bface ^{space}"SFE"{cspace} #include <fstream> using std::ifstream; + +label findFace(const polyMesh& mesh, const face& f) +{ + const labelList& pFaces = mesh.pointFaces()[f[0]]; + + forAll(pFaces, i) + { + label faceI = pFaces[i]; + + if (mesh.faces()[faceI] == f) + { + return faceI; + } + } + + FatalErrorIn("findFace(const polyMesh&, const face&)") + << "Cannot find a face matching " << f + << exit(FatalError); + + return -1; +} + + int main(int argc, char *argv[]) { argList::noParallel(); @@ -253,7 +315,7 @@ int main(int argc, char *argv[]) # include "createTime.H" - const fileName ansysFile = args[1]; + fileName ansysFile(args.additionalArgs()[0]); ifstream ansysStream(ansysFile.c_str()); if (!ansysStream) @@ -377,6 +439,34 @@ int main(int argc, char *argv[]) } } + + const word defaultFacesName = "defaultFaces"; + word defaultFacesType = emptyPolyPatch::typeName; + + // Create dummy mesh just to find out what are internal/external + // faces + autoPtr<polyMesh> dummyMesh + ( + new polyMesh + ( + IOobject + ( + "dummyMesh", + runTime.constant(), + runTime + ), + xferCopy(points), + cellShapes, + faceListList(0), + wordList(0), + wordList(0), + defaultFacesName, + defaultFacesType, + wordList(0) + ) + ); + + // Warning: tet face order has changed between version 1.9.6 and 2.0 // label faceIndex[7][6] = @@ -423,10 +513,53 @@ int main(int argc, char *argv[]) boundary[patchI] = patchFaces; patchNames[patchI] = word("patch") + name(patchI + 1); + } + + + // + // Lookup the face labels for all the boundary faces + // + labelListList boundaryFaceLabels(boundary.size()); + forAll(boundary, patchI) + { + const faceList& bFaces = boundary[patchI]; + labelList& bFaceLabels = boundaryFaceLabels[patchI]; + bFaceLabels.setSize(bFaces.size()); + forAll(bFaces, i) + { + bFaceLabels[i] = findFace(dummyMesh(), bFaces[i]); + } + } + + + // Now split the boundary faces into external and internal faces. All + // faces go into faceZones and external faces go into patches. + List<faceList> patchFaces(slPatchCells.size()); + labelList patchNFaces(slPatchCells.size(), 0); + forAll(boundary, patchI) + { + const faceList& bFaces = boundary[patchI]; + const labelList& bFaceLabels = boundaryFaceLabels[patchI]; + + patchFaces[patchI].setSize(bFaces.size()); + + forAll(bFaces, i) + { + if (!dummyMesh().isInternalFace(bFaceLabels[i])) + { + patchFaces[patchI][patchNFaces[patchI]++] = bFaces[i]; + } + } + patchFaces[patchI].setSize(patchNFaces[patchI]); + Info<< "Patch " << patchI << " named " << patchNames[patchI] << ": " << boundary[patchI].size() << " faces" << endl; } + // We no longer need the dummyMesh + dummyMesh.clear(); + + Info<< "ansysToFoam: " << endl << "Ansys file format does not provide information about the type of " << "the patch (eg. wall, symmetry plane, cyclic etc)." << endl @@ -434,10 +567,8 @@ int main(int argc, char *argv[]) << "as type patch. Please reset after mesh conversion as necessary." << endl; - wordList patchTypes(boundary.size(), polyPatch::typeName); - word defaultFacesName = "defaultFaces"; - word defaultFacesType = emptyPolyPatch::typeName; - wordList patchPhysicalTypes(boundary.size()); + wordList patchTypes(patchFaces.size(), polyPatch::typeName); + wordList patchPhysicalTypes(patchFaces.size()); preservePatchTypes ( @@ -461,7 +592,7 @@ int main(int argc, char *argv[]) ), xferMove(points), cellShapes, - boundary, + patchFaces, patchNames, patchTypes, defaultFacesName, @@ -469,6 +600,90 @@ int main(int argc, char *argv[]) patchPhysicalTypes ); + + if (cellTypes.size() > 0 || patchNames.size() > 0) + { + DynamicList<pointZone*> pz; + DynamicList<faceZone*> fz; + DynamicList<cellZone*> cz; + + // FaceZones + forAll(boundaryFaceLabels, patchI) + { + if (boundaryFaceLabels[patchI].size()) + { + // Re-do the boundaryFaceLabels since the boundary face + // labels will be different on the pShapeMesh. + const faceList& bFaces = boundary[patchI]; + labelList& bFaceLabels = boundaryFaceLabels[patchI]; + forAll(bFaceLabels, i) + { + bFaceLabels[i] = findFace(pShapeMesh, bFaces[i]); + } + + Info<< "Creating faceZone " << patchNames[patchI] + << " with " << bFaceLabels.size() << " faces" << endl; + + fz.append + ( + new faceZone + ( + patchNames[patchI], + bFaceLabels, + boolList(bFaceLabels.size(), false), + fz.size(), + pShapeMesh.faceZones() + ) + ); + } + } + + + // CellZones + labelList types = cellTypes.sortedToc(); + + forAll(types, j) + { + label cellType = types[j]; + + // Pick up cells in zone + DynamicList<label> addr; + + SLList<label>::iterator cellMapIter = slCellMap.begin(); + SLList<label>::iterator typeIter = slCellType.begin(); + + for + ( + ; + typeIter != slCellType.end(); + ++typeIter, ++cellMapIter + ) + { + if (typeIter() == cellType) + { + addr.append(cellMap[cellMapIter()]); + } + } + + Info<< "Creating cellZone " << cellTypes[cellType] + << " with " << addr.size() << " cells" << endl; + + cz.append + ( + new cellZone + ( + cellTypes[cellType], + addr, + j, + pShapeMesh.cellZones() + ) + ); + } + + pShapeMesh.addZones(pz, fz, cz); + } + + // Set the precision of the points data to 10 IOstream::defaultPrecision(10); diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict index 476dbe1afb41bc7d79139d7a5c17f358f9eca65a..a15aa483c4fa9fcebb8a47278d7db45b4f104d8f 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict @@ -341,11 +341,14 @@ meshQualityControls // Set to very negative number (e.g. -1E30) to disable. minVol 1e-13; - //- Minimum tet volume. Is absolute volume of the tet formed by the - // face-centre decomposition triangle and the cell centre. - // Set to a sensible fraction of the smallest cell volume expected. - // Set to very negative number (e.g. -1E30) to disable. - minTetVol 1e-20; + //- 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-9; //- Minimum face area. Set to <0 to disable. minArea -1; diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C b/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C index 57f892b8e44d0810f79b36cf8514db0d89c58e59..82e0dedd82ca1f1343325d865ec702eb09a7f8c4 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C +++ b/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C @@ -6,6 +6,7 @@ #include "EdgeMap.H" #include "wedgePolyPatch.H" #include "unitConversion.H" +#include "polyMeshTetDecomposition.H" // Find wedge with opposite orientation. Note: does not actually check that @@ -83,7 +84,7 @@ bool Foam::checkWedges { Info<< " Wedge " << pp.name() << " with angle " << radToDeg(wedgeAngle) << " degrees" - << endl; + << endl; } // Find opposite @@ -413,7 +414,6 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry) } } - { faceSet faces(mesh, "wrongOrientedFaces", mesh.nFaces()/100 + 1); if (mesh.checkFacePyramids(true, -SMALL, &faces)) @@ -434,8 +434,8 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry) } { - faceSet faces(mesh, "wrongOrientedTriangleFaces", mesh.nFaces()/100+1); - if (mesh.checkFaceTets(true, 0, &faces)) + faceSet faces(mesh, "skewFaces", mesh.nFaces()/100+1); + if (mesh.checkFaceSkewness(true, &faces)) { noFailedChecks++; @@ -444,17 +444,26 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry) if (nFaces > 0) { Info<< " <<Writing " << nFaces - << " faces with incorrectly orientated triangles to set " - << faces.name() << endl; + << " skew faces to set " << faces.name() << endl; faces.instance() = mesh.pointsInstance(); faces.write(); } } } + if (allGeometry) { - faceSet faces(mesh, "skewFaces", mesh.nFaces()/100+1); - if (mesh.checkFaceSkewness(true, &faces)) + faceSet faces(mesh, "lowQualityTetFaces", mesh.nFaces()/100+1); + if + ( + polyMeshTetDecomposition::checkFaceTets + ( + mesh, + polyMeshTetDecomposition::minTetQuality, + true, + &faces + ) + ) { noFailedChecks++; @@ -463,7 +472,8 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry) if (nFaces > 0) { Info<< " <<Writing " << nFaces - << " skew faces to set " << faces.name() << endl; + << " faces with low quality or negative volume " + << "decomposition tets to set " << faces.name() << endl; faces.instance() = mesh.pointsInstance(); faces.write(); } diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C b/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C index 66bbaa23fc3b42eddb7f18eba462372647b6760d..09fb5484e9e10fd6f021c11a2d0a93f365d5394d 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C +++ b/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C @@ -7,32 +7,6 @@ #include "pointSet.H" #include "IOmanip.H" -bool Foam::checkSync(const wordList& names) -{ - List<wordList> allNames(Pstream::nProcs()); - allNames[Pstream::myProcNo()] = names; - Pstream::gatherList(allNames); - Pstream::scatterList(allNames); - - bool hasError = false; - - for (label procI = 1; procI < allNames.size(); procI++) - { - if (allNames[procI] != allNames[0]) - { - hasError = true; - - Info<< " ***Inconsistent zones across processors, " - "processor 0 has zones:" << allNames[0] - << ", processor " << procI << " has zones:" - << allNames[procI] - << endl; - } - } - return hasError; -} - - Foam::label Foam::checkTopology ( const polyMesh& mesh, @@ -51,35 +25,22 @@ Foam::label Foam::checkTopology mesh.boundaryMesh().checkParallelSync(true); // Check names of zones are equal - if (checkSync(mesh.cellZones().names())) + mesh.cellZones().checkDefinition(true); + if (mesh.cellZones().checkParallelSync(true)) { noFailedChecks++; } - if (checkSync(mesh.faceZones().names())) + mesh.faceZones().checkDefinition(true); + if (mesh.faceZones().checkParallelSync(true)) { noFailedChecks++; } - if (checkSync(mesh.pointZones().names())) + mesh.pointZones().checkDefinition(true); + if (mesh.pointZones().checkParallelSync(true)) { noFailedChecks++; } - // Check contents of faceZones consistent - { - forAll(mesh.faceZones(), zoneI) - { - if (mesh.faceZones()[zoneI].checkParallelSync(false)) - { - Info<< " ***FaceZone " << mesh.faceZones()[zoneI].name() - << " is not correctly synchronised" - << " across coupled boundaries." - << " (coupled faces are either not both " - << " present in set or have same flipmap)" << endl; - noFailedChecks++; - } - } - } - { pointSet points(mesh, "unusedPoints", mesh.nPoints()/100); if (mesh.checkPoints(true, &points)) diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkTopology.H b/applications/utilities/mesh/manipulation/checkMesh/checkTopology.H index 4790765d16e408c18d9ada199da97235e4c82975..70443a86b6748f1cf128e39433b4c1ac63c74bf8 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/checkTopology.H +++ b/applications/utilities/mesh/manipulation/checkMesh/checkTopology.H @@ -5,7 +5,5 @@ namespace Foam { class polyMesh; - bool checkSync(const wordList& names); - label checkTopology(const polyMesh&, const bool, const bool); } diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C index 91a51e2ae57a1a48e0682be250d32dc0ef251a3e..0c72ca7ee72ea09c3ae4dc395da0e061e79c48d0 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C +++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C @@ -558,7 +558,6 @@ int main(int argc, char *argv[]) lagrangianScalarFieldFields ); - lagrangianFieldDecomposer::readFields ( cloudI, @@ -687,6 +686,19 @@ int main(int argc, char *argv[]) ) ); + labelIOList faceProcAddressing + ( + IOobject + ( + "faceProcAddressing", + procMesh.facesInstance(), + procMesh.meshSubDir, + procMesh, + IOobject::MUST_READ, + IOobject::NO_WRITE + ) + ); + labelIOList cellProcAddressing ( IOobject @@ -728,19 +740,6 @@ int main(int argc, char *argv[]) || surfaceTensorFields.size() ) { - labelIOList faceProcAddressing - ( - IOobject - ( - "faceProcAddressing", - procMesh.facesInstance(), - procMesh.meshSubDir, - procMesh, - IOobject::MUST_READ, - IOobject::NO_WRITE - ) - ); - fvFieldDecomposer fieldDecomposer ( mesh, @@ -814,6 +813,7 @@ int main(int argc, char *argv[]) ( mesh, procMesh, + faceProcAddressing, cellProcAddressing, cloudDirs[cloudI], lagrangianPositions[cloudI], diff --git a/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposer.C b/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposer.C index 234565fb488882994ac7b5baae81df0131ee27ef..a6b0c9594da0d52c746c694877afc3498c9ff938 100644 --- a/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposer.C +++ b/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposer.C @@ -35,6 +35,7 @@ Foam::lagrangianFieldDecomposer::lagrangianFieldDecomposer ( const polyMesh& mesh, const polyMesh& procMesh, + const labelList& faceProcAddressing, const labelList& cellProcAddressing, const word& cloudName, const Cloud<indexedParticle>& lagrangianPositions, @@ -47,6 +48,14 @@ Foam::lagrangianFieldDecomposer::lagrangianFieldDecomposer { label pi = 0; + // faceProcAddressing not required currently + // labelList decodedProcFaceAddressing(faceProcAddressing.size()); + + // forAll(faceProcAddressing, i) + // { + // decodedProcFaceAddressing[i] = mag(faceProcAddressing[i]) - 1; + // } + forAll(cellProcAddressing, procCelli) { label celli = cellProcAddressing[procCelli]; @@ -60,13 +69,41 @@ Foam::lagrangianFieldDecomposer::lagrangianFieldDecomposer const indexedParticle& ppi = *iter(); particleIndices_[pi++] = ppi.index(); + // label mappedTetFace = findIndex + // ( + // decodedProcFaceAddressing, + // ppi.tetFace() + // ); + + // if (mappedTetFace == -1) + // { + // FatalErrorIn + // ( + // "Foam::lagrangianFieldDecomposer" + // "::lagrangianFieldDecomposer" + // "(" + // "const polyMesh& mesh, " + // "const polyMesh& procMesh, " + // "const labelList& faceProcAddressing, " + // "const labelList& cellProcAddressing, " + // "const word& cloudName, " + // "const Cloud<indexedParticle>& " + // "lagrangianPositions, " + // "const List<SLList<indexedParticle*>*>& " + // "cellParticles" + // ")" + // ) << "Face lookup failure." << nl + // << abort(FatalError); + // } + positions_.append ( new passiveParticle ( positions_, ppi.position(), - procCelli + procCelli, + false ) ); } diff --git a/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposer.H b/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposer.H index bc0d42c5ed8f44931eeea3f3c52f518f67ebf728..dafd94c34308c4373f03a8ebbbe923e10d5493b5 100644 --- a/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposer.H +++ b/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposer.H @@ -84,6 +84,7 @@ public: ( const polyMesh& mesh, const polyMesh& procMesh, + const labelList& faceProcAddressing, const labelList& cellProcAddressing, const word& cloudName, const Cloud<indexedParticle>& lagrangianPositions, diff --git a/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposerDecomposeFields.C b/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposerDecomposeFields.C index 00c025c953d82965c06bf03e94cd4c98e7f21dd5..7e42907fd0ddde6bcef1658535fc2c61a2ea1ec9 100644 --- a/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposerDecomposeFields.C +++ b/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposerDecomposeFields.C @@ -51,7 +51,7 @@ void Foam::lagrangianFieldDecomposer::readFields ) ); - label lagrangianFieldi=0; + label lagrangianFieldi = 0; forAllIter(IOobjectList, lagrangianTypeObjects, iter) { lagrangianFields[cloudI].set @@ -91,7 +91,7 @@ void Foam::lagrangianFieldDecomposer::readFieldFields ) ); - label lagrangianFieldi=0; + label lagrangianFieldi = 0; forAllIter(IOobjectList, lagrangianTypeObjectsA, iter) { diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/options b/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/options index 01bd39cf760a42ba262d10035531bff92f59de5d..5d00838fdcdfd61c755a90def991e234a3a41c82 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/options +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/options @@ -1,10 +1,12 @@ EXE_INC = \ /* -DFULLDEBUG -g -O0 */ \ -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude EXE_LIBS = \ -lfiniteVolume \ + -lmeshTools \ -lgenericPatchFields \ -llagrangian diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/options b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/options index 9243ffdb03df08099835251b7c593966e9db74ca..40a58886bfc6baa03963fa432bd6529b22b96085 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/options +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/options @@ -1,10 +1,12 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \ -I$(LIB_SRC)/conversion/lnInclude EXE_LIBS = \ -lfiniteVolume \ -llagrangian \ + -lmeshTools \ -lgenericPatchFields \ -lconversion diff --git a/applications/utilities/postProcessing/dataConversion/foamToFieldview9/Make/options b/applications/utilities/postProcessing/dataConversion/foamToFieldview9/Make/options index a61c912ba0cb6c18a0857e0508dd8f4d853e08ce..0bc784e4c51713ba377f8f2dfc47e7340d8589e7 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToFieldview9/Make/options +++ b/applications/utilities/postProcessing/dataConversion/foamToFieldview9/Make/options @@ -1,8 +1,10 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude EXE_LIBS = \ -lfiniteVolume \ + -lmeshTools \ -lgenericPatchFields \ -llagrangian diff --git a/applications/utilities/postProcessing/dataConversion/foamToFieldview9/floatScalar.H b/applications/utilities/postProcessing/dataConversion/foamToFieldview9/floatScalar.H deleted file mode 100644 index ed73431ee7993930e2e9382e4c0a60d546327380..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToFieldview9/floatScalar.H +++ /dev/null @@ -1,290 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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/>. - -Typedef - Foam::floatScalar - -Description - single floating point number identical to float - -SourceFiles - floatScalar.C - -\*---------------------------------------------------------------------------*/ - -#ifndef floatScalar_H -#define floatScalar_H - -#include "label.H" -#include "word.H" - -#include <cmath> - -#ifdef ibm - float lgamma(float); -#endif - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -// Define floatScalar as a float - -namespace Foam -{ - typedef float floatScalar; -} - -/* -// Define floatScalar as a float - -namespace Foam -{ - typedef float floatScalar; - - // Largest and smallest floatScalar values allowed in certain - // parts of the code (6 is the number of significant figures in an - // IEEE single precision number. See limits.h or float.h) - static const floatScalar GREAT = 1.0e+6; - static const floatScalar VGREAT = 1.0e+37; - static const floatScalar SMALL = 1.0e-6; - static const floatScalar VSMALL = 1.0e-37; -} -*/ - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#include "pTraits.H" -#include "products.H" -#include "direction.H" - -namespace Foam -{ - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -// template specialisation for pTraits<floatScalar> -template<> -class pTraits<floatScalar> -{ - floatScalar p_; - -public: - - //- Component type - typedef floatScalar cmptType; - - // Member constants - - enum - { - dim = 3, // Dimensionality of space - rank = 0, // Rank od floatScalar is 0 - nComponents = 1 // Number of components in floatScalar is 1 - }; - - // Static data members - - static const char* const typeName; - static const char* componentNames[]; - static const floatScalar zero; - static const floatScalar one; - - // Constructors - - //- Construct from Istream - pTraits(Istream& is); - - // Member Functions - - operator floatScalar() const - { - return p_; - } -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -//template<class Cmpt> -//class typeOfRank<Cmpt, 0> -//{ -//public: -// -// typedef Cmpt type; -//}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -// Return a string representation of a floatScalar -word name(const floatScalar s) -{ - return name(scalar(s)); -} - -#define MAXMINPOW(retType, type1, type2) \ - \ -MAXMIN(retType, type1, type2) \ - \ -inline float pow(const type1 s, const type2 e) \ -{ \ - return ::pow(float(s), float(e)); \ -} - - -//MAXMINPOW(float, float, float) -//MAXMINPOW(float, float, int) -//MAXMINPOW(float, int, float) -//MAXMINPOW(float, float, long) -//MAXMINPOW(float, long, float) -//MAXMINPOW(float, float, int) -//MAXMINPOW(float, int, float) -//MAXMINPOW(float, float, long) -//MAXMINPOW(float, long, float) - -#undef MAXMINPOW - - -inline floatScalar mag(const floatScalar s) -{ - return ::fabs(s); -} - -inline floatScalar sign(const floatScalar s) -{ - return (s >= 0)? 1: -1; -} - -inline floatScalar pos(const floatScalar s) -{ - return (s >= 0)? 1: 0; -} - -inline floatScalar neg(const floatScalar s) -{ - return (s < 0)? 1: 0; -} - -inline floatScalar limit(const floatScalar s1, const floatScalar s2) -{ - return (mag(s1) < mag(s2))? s1: 0.0; -} - -inline floatScalar magSqr(const floatScalar s) -{ - return s*s; -} - -inline floatScalar sqr(const floatScalar s) -{ - return s*s; -} - -inline floatScalar pow3(const floatScalar s) -{ - return s*s*s; -} - -inline floatScalar pow4(const floatScalar s) -{ - return sqr(sqr(s)); -} - -inline floatScalar cmptAv(const floatScalar s) -{ - return s; -} - -inline floatScalar cmptMag(const floatScalar s) -{ - return mag(s); -} - -inline floatScalar scale(const floatScalar s, const floatScalar d) -{ - return s*d; -} - - -#define transFunc(func) \ -inline floatScalar func(const floatScalar s) \ -{ \ - return ::func(s); \ -} - -// Standard C++ transcendental functions -transFunc(sqrt) -transFunc(exp) -transFunc(log) -transFunc(log10) -transFunc(sin) -transFunc(cos) -transFunc(tan) -transFunc(asin) -transFunc(acos) -transFunc(atan) -transFunc(sinh) -transFunc(cosh) -transFunc(tanh) -transFunc(asinh) -transFunc(acosh) -transFunc(atanh) - -// Standard ANSI-C (but not in <cmath>) transcendental functions -transFunc(erf) -transFunc(erfc) -transFunc(lgamma) -transFunc(j0) -transFunc(j1) -transFunc(y0) -transFunc(y1) - -#undef transFunc - -// Stabilisation around zero for division -inline floatScalar stabilise(const floatScalar s, const floatScalar small) -{ - if (s >= 0) - { - return s + small; - } - else - { - return s - small; - } -} - - -// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // - -//floatScalar readScalar(Istream& is); -Istream& operator>>(Istream&, floatScalar&); -Ostream& operator<<(Ostream&, const floatScalar); - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToGMV/Make/options b/applications/utilities/postProcessing/dataConversion/foamToGMV/Make/options index e09f6bdc7f12155b1fd45a7313324597eb006400..5664dc4494ee8c6c86e7fc98266f8297e0254b06 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToGMV/Make/options +++ b/applications/utilities/postProcessing/dataConversion/foamToGMV/Make/options @@ -1,6 +1,7 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/sampling/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/turbulenceModels/incompressible/lnInclude \ -I$(LIB_SRC)/transportModels/incompressible/lnInclude \ -I$(LIB_SRC)/lagrangian/lnInclude \ @@ -14,5 +15,6 @@ EXE_INC = \ EXE_LIBS = \ -lfiniteVolume \ + -lmeshTools \ -lgenericPatchFields \ -llagrangian diff --git a/applications/utilities/postProcessing/graphics/ensightFoamReader/Make/options b/applications/utilities/postProcessing/graphics/ensightFoamReader/Make/options index 8d21a9eae4bf6e14c70a367b62a0037ab9ad777f..0d76f0304cb80b84d3b76b745da396950249f4a5 100644 --- a/applications/utilities/postProcessing/graphics/ensightFoamReader/Make/options +++ b/applications/utilities/postProcessing/graphics/ensightFoamReader/Make/options @@ -1,5 +1,6 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/browser/lnInclude \ -I$(LIB_SRC)/sampling/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude @@ -7,6 +8,7 @@ EXE_INC = \ LIB_LIBS = \ -lOpenFOAM \ -lfiniteVolume \ + -lmeshTools \ -lgenericPatchFields \ -llagrangian \ $(PROJECT_LIBS) diff --git a/applications/utilities/postProcessing/lagrangian/particleTracks/Make/options b/applications/utilities/postProcessing/lagrangian/particleTracks/Make/options index a61c912ba0cb6c18a0857e0508dd8f4d853e08ce..0bc784e4c51713ba377f8f2dfc47e7340d8589e7 100644 --- a/applications/utilities/postProcessing/lagrangian/particleTracks/Make/options +++ b/applications/utilities/postProcessing/lagrangian/particleTracks/Make/options @@ -1,8 +1,10 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude EXE_LIBS = \ -lfiniteVolume \ + -lmeshTools \ -lgenericPatchFields \ -llagrangian diff --git a/applications/utilities/preProcessing/dsmcInitialise/Make/options b/applications/utilities/preProcessing/dsmcInitialise/Make/options index bc99834af6ea732c365d0b07940f997e1c6cedfe..62520c19b0ea4fb400f41c1327a7ebcb243309f0 100644 --- a/applications/utilities/preProcessing/dsmcInitialise/Make/options +++ b/applications/utilities/preProcessing/dsmcInitialise/Make/options @@ -9,4 +9,3 @@ EXE_LIBS = \ -lfiniteVolume \ -llagrangian \ -ldsmc - diff --git a/applications/utilities/preProcessing/mapFields/MapLagrangianFields.H b/applications/utilities/preProcessing/mapFields/MapLagrangianFields.H index 3b9960408c45d87a55efd6f8a8ea04b7c11b9cd6..87b3746484af8fe9d44b960b55f82a329fca5116 100644 --- a/applications/utilities/preProcessing/mapFields/MapLagrangianFields.H +++ b/applications/utilities/preProcessing/mapFields/MapLagrangianFields.H @@ -37,6 +37,7 @@ Description #include "GeometricField.H" #include "meshToMesh.H" #include "IOobjectList.H" +#include "IOFieldField.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -56,37 +57,118 @@ void MapLagrangianFields { const fvMesh& meshTarget = meshToMeshInterp.toMesh(); - IOobjectList fields = objects.lookupClass(IOField<Type>::typeName); - - forAllIter(IOobjectList, fields, fieldIter) { - Info<< " mapping lagrangian field " << fieldIter()->name() << endl; + IOobjectList fields = objects.lookupClass(IOField<Type>::typeName); + + forAllIter(IOobjectList, fields, fieldIter) + { + Info<< " mapping lagrangian field " + << fieldIter()->name() << endl; - // Read field (does not need mesh) - IOField<Type> fieldSource(*fieldIter()); + // Read field (does not need mesh) + IOField<Type> fieldSource(*fieldIter()); - // Map - IOField<Type> fieldTarget - ( - IOobject + // Map + IOField<Type> fieldTarget ( - fieldIter()->name(), - meshTarget.time().timeName(), - cloud::prefix/cloudName, - meshTarget, - IOobject::NO_READ, - IOobject::NO_WRITE, - false - ), - addParticles.size() - ); - forAll(addParticles, i) + IOobject + ( + fieldIter()->name(), + meshTarget.time().timeName(), + cloud::prefix/cloudName, + meshTarget, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + addParticles.size() + ); + + forAll(addParticles, i) + { + fieldTarget[i] = fieldSource[addParticles[i]]; + } + + // Write field + fieldTarget.write(); + } + } + + { + IOobjectList fieldFields = + objects.lookupClass(IOField<Field<Type> >::typeName); + + forAllIter(IOobjectList, fieldFields, fieldIter) { - fieldTarget[i] = fieldSource[addParticles[i]]; + Info<< " mapping lagrangian fieldField " + << fieldIter()->name() << endl; + + // Read field (does not need mesh) + IOField<Field<Type> > fieldSource(*fieldIter()); + + // Map - use IOFieldField to automatically write in + // compact form for binary format. + IOFieldField<Field<Type>, Type> fieldTarget + ( + IOobject + ( + fieldIter()->name(), + meshTarget.time().timeName(), + cloud::prefix/cloudName, + meshTarget, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + addParticles.size() + ); + + forAll(addParticles, i) + { + fieldTarget[i] = fieldSource[addParticles[i]]; + } + + // Write field + fieldTarget.write(); } + } - // Write field - fieldTarget.write(); + { + IOobjectList fieldFields = + objects.lookupClass(IOFieldField<Field<Type>, Type>::typeName); + + forAllIter(IOobjectList, fieldFields, fieldIter) + { + Info<< " mapping lagrangian fieldField " + << fieldIter()->name() << endl; + + // Read field (does not need mesh) + IOFieldField<Field<Type>, Type> fieldSource(*fieldIter()); + + // Map + IOFieldField<Field<Type>, Type> fieldTarget + ( + IOobject + ( + fieldIter()->name(), + meshTarget.time().timeName(), + cloud::prefix/cloudName, + meshTarget, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + addParticles.size() + ); + + forAll(addParticles, i) + { + fieldTarget[i] = fieldSource[addParticles[i]]; + } + + // Write field + fieldTarget.write(); + } } } diff --git a/applications/utilities/preProcessing/mapFields/mapLagrangian.C b/applications/utilities/preProcessing/mapFields/mapLagrangian.C index 72e402b934c171e16156b73ffe498e16de7b0eba..17f03ea3403b682278edfff8b0c85531f41e4196 100644 --- a/applications/utilities/preProcessing/mapFields/mapLagrangian.C +++ b/applications/utilities/preProcessing/mapFields/mapLagrangian.C @@ -38,12 +38,13 @@ static const scalar perturbFactor = 1E-6; // Special version of findCell that generates a cell guaranteed to be // compatible with tracking. -static label findCell(const meshSearch& meshSearcher, const point& pt) +static label findCell(const Cloud<passiveParticle>& cloud, const point& pt) { - const polyMesh& mesh = meshSearcher.mesh(); + label cellI = -1; + label tetFaceI = -1; + label tetPtI = -1; - // Use tracking to find cell containing pt - label cellI = meshSearcher.findCell(pt); + cloud.findCellFacePt(pt, cellI, tetFaceI, tetPtI); if (cellI >= 0) { @@ -54,16 +55,24 @@ static label findCell(const meshSearch& meshSearcher, const point& pt) // See if particle on face by finding nearest face and shifting // particle. + const polyMesh& mesh = cloud.pMesh(); + + meshSearch meshSearcher(mesh, false); + label faceI = meshSearcher.findNearestBoundaryFace(pt); if (faceI >= 0) { const point& cc = mesh.cellCentres()[mesh.faceOwner()[faceI]]; + const point perturbPt = (1-perturbFactor)*pt+perturbFactor*cc; - return meshSearcher.findCell(perturbPt); + cloud.findCellFacePt(perturbPt, cellI, tetFaceI, tetPtI); + + return cellI; } } + return -1; } @@ -207,8 +216,6 @@ void mapLagrangian(const meshToMesh& meshToMeshInterp) if (unmappedSource.size()) { - meshSearch targetSearcher(meshTarget, false); - sourceParticleI = 0; forAllIter(Cloud<passiveParticle>, sourceParcels, iter) @@ -216,7 +223,7 @@ void mapLagrangian(const meshToMesh& meshToMeshInterp) if (unmappedSource.found(sourceParticleI)) { label targetCell = - findCell(targetSearcher, iter().position()); + findCell(targetParcels, iter().position()); if (targetCell >= 0) { diff --git a/applications/utilities/surface/surfaceSubset/surfaceSubset.C b/applications/utilities/surface/surfaceSubset/surfaceSubset.C index 51255242ef908dd0e52d04bc72e579c17a0ee2ad..6bc54d40addc9fedf385311bc1e19507f7cdb8bb 100644 --- a/applications/utilities/surface/surfaceSubset/surfaceSubset.C +++ b/applications/utilities/surface/surfaceSubset/surfaceSubset.C @@ -35,7 +35,6 @@ Description #include "IOdictionary.H" #include "boundBox.H" #include "indexedOctree.H" -#include "octree.H" #include "treeDataTriSurface.H" #include "Random.H" diff --git a/etc/controlDict b/etc/controlDict index 3d5aff5930422d659f1c82e3b5a972aa576f9b48..691e9701243f8512384196967f259417dfd986a2 100644 --- a/etc/controlDict +++ b/etc/controlDict @@ -780,6 +780,7 @@ DebugSwitches syringePressure 0; tensorAverageField 0; tensorField 0; + tetDecomposedPolyMesh 0; thermoCloud 0; thermophysicalFunction 0; time 0; diff --git a/src/Allwmake b/src/Allwmake index 33966ddb97b9725fcda388da50962eef9bb9beb1..43458cfc6211f8541fe70653c7205b1476f4620d 100755 --- a/src/Allwmake +++ b/src/Allwmake @@ -20,8 +20,6 @@ Pstream/Allwmake OSspecific/$WM_OSTYPE/Allwmake wmake libso OpenFOAM -wmake libso lagrangian/basic - wmake libso fileFormats wmake libso edgeMesh wmake libso surfMesh @@ -33,6 +31,7 @@ parallel/decompose/AllwmakeLnInclude dummyThirdParty/Allwmake wmake libso meshTools +wmake libso lagrangian/basic wmake libso finiteVolume wmake libso genericPatchFields diff --git a/src/ODE/ODESolvers/ODESolver/ODESolver.C b/src/ODE/ODESolvers/ODESolver/ODESolver.C index b4341894b5269e2c1519752580ed23fa96c2e333..f0c04518beea8a230a404fd252895ae2d8513f82 100644 --- a/src/ODE/ODESolvers/ODESolver/ODESolver.C +++ b/src/ODE/ODESolvers/ODESolver/ODESolver.C @@ -60,6 +60,8 @@ void Foam::ODESolver::solve scalar x = xStart; scalar h = hEst; + scalar hNext = 0; + scalar hPrev = 0; for (label nStep=0; nStep<MAXSTP; nStep++) { @@ -73,14 +75,24 @@ void Foam::ODESolver::solve if ((x + h - xEnd)*(x + h - xStart) > 0.0) { h = xEnd - x; + hPrev = hNext; } - scalar hNext, hDid; + hNext = 0; + scalar hDid; solve(ode, x, y, dydx_, eps, yScale_, h, hDid, hNext); if ((x - xEnd)*(xEnd - xStart) >= 0.0) { - hEst = hNext; + if (hPrev != 0) + { + hEst = hPrev; + } + else + { + hEst = hNext; + } + return; } diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index e9103f8020e637070dee9921c84df792945630cc..599d30fa094cbc485f9c9a170c7d4f89a379052f 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -365,6 +365,8 @@ $(globalMeshData)/globalPoints.C $(globalMeshData)/globalIndex.C $(polyMesh)/syncTools/syncTools.C +$(polyMesh)/polyMeshTetDecomposition/polyMeshTetDecomposition.C +$(polyMesh)/polyMeshTetDecomposition/tetIndices.C zone = $(polyMesh)/zones/zone $(zone)/zone.C diff --git a/src/OpenFOAM/meshes/polyMesh/polyMesh.C b/src/OpenFOAM/meshes/polyMesh/polyMesh.C index 2cbde73f8b31205e771a1f459263d5178e97a8b6..668320e1d6dd368334c0934de33ab7b9e209c5fb 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyMesh.C +++ b/src/OpenFOAM/meshes/polyMesh/polyMesh.C @@ -33,6 +33,7 @@ License #include "processorPolyPatch.H" #include "OSspecific.H" #include "demandDrivenData.H" +#include "polyMeshTetDecomposition.H" #include "pointMesh.H" @@ -204,6 +205,7 @@ Foam::polyMesh::polyMesh(const IOobject& io) bounds_(points_), geometricD_(Vector<label>::zero), solutionD_(Vector<label>::zero), + tetBasePtIsPtr_(NULL), pointZones_ ( IOobject @@ -392,6 +394,7 @@ Foam::polyMesh::polyMesh bounds_(points_, syncPar), geometricD_(Vector<label>::zero), solutionD_(Vector<label>::zero), + tetBasePtIsPtr_(NULL), pointZones_ ( IOobject @@ -548,6 +551,7 @@ Foam::polyMesh::polyMesh bounds_(points_, syncPar), geometricD_(Vector<label>::zero), solutionD_(Vector<label>::zero), + tetBasePtIsPtr_(NULL), pointZones_ ( IOobject @@ -847,6 +851,28 @@ Foam::label Foam::polyMesh::nSolutionD() const } +const Foam::labelList& Foam::polyMesh::tetBasePtIs() const +{ + if (!tetBasePtIsPtr_) + { + if (debug) + { + WarningIn("const labelList& polyMesh::tetBasePtIs() const") + << "Tet base point indices not available. " + << "Forcing storage of base points." + << endl; + } + + tetBasePtIsPtr_ = new labelList + ( + polyMeshTetDecomposition::findFaceBasePts(*this) + ); + } + + return *tetBasePtIsPtr_; +} + + // Add boundary patches. Constructor helper void Foam::polyMesh::addPatches ( diff --git a/src/OpenFOAM/meshes/polyMesh/polyMesh.H b/src/OpenFOAM/meshes/polyMesh/polyMesh.H index ec57faa9fbdd10fe53c46e36b398de7c99018f83..a100a358e158a18f3da364087a37ed9c742437cd 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyMesh.H +++ b/src/OpenFOAM/meshes/polyMesh/polyMesh.H @@ -62,6 +62,7 @@ namespace Foam class globalMeshData; class mapPolyMesh; +class polyMeshTetDecomposition; /*---------------------------------------------------------------------------*\ Class polyMesh Declaration @@ -127,6 +128,9 @@ private: // defined according to the presence of empty patches mutable Vector<label> solutionD_; + //- Base point for face decomposition into tets + mutable labelList* tetBasePtIsPtr_; + // Zoning information @@ -356,6 +360,9 @@ public: //- Return the number of valid solved-for dimensions in the mesh label nSolutionD() const; + //- Return the tetBasePtIs + const labelList& tetBasePtIs() const; + //- Return point zone mesh const pointZoneMesh& pointZones() const { diff --git a/src/OpenFOAM/meshes/polyMesh/polyMeshClear.C b/src/OpenFOAM/meshes/polyMesh/polyMeshClear.C index 187d3c128faf71889220c946df2fe71a22c888a1..56c2f2428cdb65430e47fac24af7dbb2aaaf8002 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyMeshClear.C +++ b/src/OpenFOAM/meshes/polyMesh/polyMeshClear.C @@ -71,6 +71,9 @@ void Foam::polyMesh::clearGeom() geometricD_ = Vector<label>::zero; solutionD_ = Vector<label>::zero; + // Remove the stored tet base points + deleteDemandDrivenData(tetBasePtIsPtr_); + pointMesh::Delete(*this); } diff --git a/src/OpenFOAM/meshes/polyMesh/polyMeshFromShapeMesh.C b/src/OpenFOAM/meshes/polyMesh/polyMeshFromShapeMesh.C index 0f35692b0ce6875e955c88941012786de7b1388f..73434502f4532f32eba38527107a1827287e01d2 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyMeshFromShapeMesh.C +++ b/src/OpenFOAM/meshes/polyMesh/polyMeshFromShapeMesh.C @@ -503,6 +503,7 @@ Foam::polyMesh::polyMesh bounds_(points_, syncPar), geometricD_(Vector<label>::zero), solutionD_(Vector<label>::zero), + tetBasePtIsPtr_(NULL), pointZones_ ( IOobject @@ -775,6 +776,7 @@ Foam::polyMesh::polyMesh bounds_(points_, syncPar), geometricD_(Vector<label>::zero), solutionD_(Vector<label>::zero), + tetBasePtIsPtr_(NULL), pointZones_ ( IOobject diff --git a/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/polyMeshTetDecomposition.C b/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/polyMeshTetDecomposition.C new file mode 100644 index 0000000000000000000000000000000000000000..23e7a3c52e2ef55168f48aeecfcec773fa6c4c40 --- /dev/null +++ b/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/polyMeshTetDecomposition.C @@ -0,0 +1,627 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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 "polyMeshTetDecomposition.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +const Foam::scalar Foam::polyMeshTetDecomposition::minTetQuality = 1e-9; + + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +Foam::label Foam::polyMeshTetDecomposition::findSharedBasePoint +( + const polyMesh& mesh, + label fI, + const point& nCc, + scalar tol, + bool report +) +{ + const faceList& pFaces = mesh.faces(); + const pointField& pPts = mesh.points(); + const vectorField& pC = mesh.cellCentres(); + const labelList& pOwner = mesh.faceOwner(); + + const face& f = pFaces[fI]; + + label oCI = pOwner[fI]; + + const point& oCc = pC[oCI]; + + forAll(f, faceBasePtI) + { + scalar thisBaseMinTetQuality = VGREAT; + + const point& tetBasePt = pPts[f[faceBasePtI]]; + + for (label tetPtI = 1; tetPtI < f.size() - 1; tetPtI++) + { + label facePtI = (tetPtI + faceBasePtI) % f.size(); + label otherFacePtI = f.fcIndex(facePtI); + + List<scalar> tetQualities(2, 0.0); + + { + // owner cell tet + label ptAI = f[facePtI]; + label ptBI = f[otherFacePtI]; + + const point& pA = pPts[ptAI]; + const point& pB = pPts[ptBI]; + + tetPointRef tet(oCc, tetBasePt, pA, pB); + + tetQualities[0] = tet.quality(); + } + + { + // neighbour cell tet + label ptAI = f[otherFacePtI]; + label ptBI = f[facePtI]; + + const point& pA = pPts[ptAI]; + const point& pB = pPts[ptBI]; + + tetPointRef tet(nCc, tetBasePt, pA, pB); + + tetQualities[1] = tet.quality(); + } + + if (min(tetQualities) < thisBaseMinTetQuality) + { + thisBaseMinTetQuality = min(tetQualities); + } + } + + if (thisBaseMinTetQuality > tol) + { + return faceBasePtI; + } + + } + + // If a base point hasn't triggered a return by now, then there is + // non that can produce a good decomposition + return -1; +} + + +Foam::label Foam::polyMeshTetDecomposition::findSharedBasePoint +( + const polyMesh& mesh, + label fI, + scalar tol, + bool report +) +{ + return findSharedBasePoint + ( + mesh, + fI, + mesh.cellCentres()[mesh.faceNeighbour()[fI]], + tol, + report + ); +} + + +Foam::label Foam::polyMeshTetDecomposition::findBasePoint +( + const polyMesh& mesh, + label fI, + scalar tol, + bool report +) +{ + const faceList& pFaces = mesh.faces(); + const pointField& pPts = mesh.points(); + const vectorField& pC = mesh.cellCentres(); + const labelList& pOwner = mesh.faceOwner(); + + const face& f = pFaces[fI]; + + label cI = pOwner[fI]; + + bool own = (pOwner[fI] == cI); + + const point& cC = pC[cI]; + + forAll(f, faceBasePtI) + { + scalar thisBaseMinTetQuality = VGREAT; + + const point& tetBasePt = pPts[f[faceBasePtI]]; + + for (label tetPtI = 1; tetPtI < f.size() - 1; tetPtI++) + { + label facePtI = (tetPtI + faceBasePtI) % f.size(); + label otherFacePtI = f.fcIndex(facePtI); + + label ptAI = -1; + label ptBI = -1; + + if (own) + { + ptAI = f[facePtI]; + ptBI = f[otherFacePtI]; + } + else + { + ptAI = f[otherFacePtI]; + ptBI = f[facePtI]; + } + + const point& pA = pPts[ptAI]; + const point& pB = pPts[ptBI]; + + tetPointRef tet(cC, tetBasePt, pA, pB); + + scalar tetQuality = tet.quality(); + + if (tetQuality < thisBaseMinTetQuality) + { + thisBaseMinTetQuality = tetQuality; + } + } + + if (thisBaseMinTetQuality > tol) + { + return faceBasePtI; + } + } + + // If a base point hasn't triggered a return by now, then there is + // non that can produce a good decomposition + return -1; +} + + +Foam::labelList Foam::polyMeshTetDecomposition::findFaceBasePts +( + const polyMesh& mesh, + scalar tol, + bool report +) +{ + const labelList& pOwner = mesh.faceOwner(); + + // Find a suitable base point for each face, considering both + // cells for interface faces or those on coupled patches + + labelList tetBasePtIs(mesh.nFaces(), -1); + + label nInternalFaces = mesh.nInternalFaces(); + + for (label fI = 0; fI < nInternalFaces; fI++) + { + tetBasePtIs[fI] = findSharedBasePoint(mesh, fI, tol, report); + } + + pointField neighbourCellCentres(mesh.nFaces() - nInternalFaces); + + for(label faceI = nInternalFaces; faceI < mesh.nFaces(); faceI++) + { + neighbourCellCentres[faceI - nInternalFaces] = + mesh.cellCentres()[pOwner[faceI]]; + } + + syncTools::swapBoundaryFacePositions(mesh, neighbourCellCentres); + + const polyBoundaryMesh& patches = mesh.boundaryMesh(); + + SubList<label> boundaryFaceTetBasePtIs + ( + tetBasePtIs, + mesh.nFaces() - nInternalFaces, + nInternalFaces + ); + + for + ( + label fI = nInternalFaces, bFI = 0; + fI < mesh.nFaces(); + fI++, bFI++ + ) + { + label patchI = + mesh.boundaryMesh().patchID()[bFI]; + + if (patches[patchI].coupled()) + { + const coupledPolyPatch& pp = + refCast<const coupledPolyPatch>(patches[patchI]); + + if (pp.owner()) + { + boundaryFaceTetBasePtIs[bFI] = findSharedBasePoint + ( + mesh, + fI, + neighbourCellCentres[bFI], + tol, + report + ); + } + else + { + // Assign -2, to distinguish from a failed base point + // find, which returns -1. + boundaryFaceTetBasePtIs[bFI] = -2; + } + } + else + { + boundaryFaceTetBasePtIs[bFI] = findBasePoint + ( + mesh, + fI, + tol, + report + ); + } + } + + // maxEqOp will replace the -2 values on the neighbour patches + // with the result from the owner base point find. + + syncTools::syncBoundaryFaceList + ( + mesh, + boundaryFaceTetBasePtIs, + maxEqOp<label>() + ); + + for + ( + label fI = nInternalFaces, bFI = 0; + fI < mesh.nFaces(); + fI++, bFI++ + ) + { + label& bFTetBasePtI = boundaryFaceTetBasePtIs[bFI]; + + if (bFTetBasePtI == -2) + { + FatalErrorIn + ( + "Foam::labelList" + "Foam::polyMeshTetDecomposition::findFaceBasePts" + "(" + "const polyMesh& mesh, " + "scalar tol, " + "bool report" + ")" + ) + << "Coupled face base point exchange failure for face " + << fI + << abort(FatalError); + } + + if (bFTetBasePtI < 1) + { + // If the base point is -1, it should be left as such to + // indicate a problem, if it is 0, then no action is required. + + continue; + } + + label patchI = mesh.boundaryMesh().patchID()[bFI]; + + if (patches[patchI].coupled()) + { + const coupledPolyPatch& pp = + refCast<const coupledPolyPatch>(patches[patchI]); + + // Calculated base points on coupled faces are those of + // the owner patch face. They need to be reindexed to for + // the non-owner face, which has the opposite order. + + // So, for fPtI_o != 0, fPtI_n = f.size() - fPtI_o + + // i.e.: + + // owner coupledPolyPatch face + // face (a b c d e f) + // fPtI 0 1 2 3 4 5 + // + + // # + + // neighbour coupledPolyPatch face + // face (a f e d c b) + // fPtI 0 1 2 3 4 5 + // + + // # + // +: 6 - 1 = 5 + // #: 6 - 2 = 4 + + if (!pp.owner()) + { + bFTetBasePtI = mesh.faces()[fI].size() - bFTetBasePtI; + } + } + } + + return tetBasePtIs; +} + + +bool Foam::polyMeshTetDecomposition::checkFaceTets +( + const polyMesh& mesh, + scalar tol, + const bool report, + labelHashSet* setPtr +) +{ + const labelList& own = mesh.faceOwner(); + const labelList& nei = mesh.faceNeighbour(); + const polyBoundaryMesh& patches = mesh.boundaryMesh(); + + const vectorField& cc = mesh.cellCentres(); + const vectorField& fc = mesh.faceCentres(); + + // Calculate coupled cell centre + pointField neiCc(mesh.nFaces() - mesh.nInternalFaces()); + + for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++) + { + neiCc[faceI - mesh.nInternalFaces()] = cc[own[faceI]]; + } + + syncTools::swapBoundaryFacePositions(mesh, neiCc); + + const faceList& fcs = mesh.faces(); + + const pointField& p = mesh.points(); + + label nErrorTets = 0; + + forAll(fcs, faceI) + { + const face& f = fcs[faceI]; + + forAll(f, fPtI) + { + scalar tetQual = tetPointRef + ( + p[f[fPtI]], + p[f.nextLabel(fPtI)], + fc[faceI], + cc[own[faceI]] + ).quality(); + + if (tetQual > -tol) + { + if (setPtr) + { + setPtr->insert(faceI); + } + + nErrorTets++; + break; // no need to check other tets + } + } + + if (mesh.isInternalFace(faceI)) + { + // Create the neighbour tet - it will have positive volume + const face& f = fcs[faceI]; + + forAll(f, fPtI) + { + scalar tetQual = tetPointRef + ( + p[f[fPtI]], + p[f.nextLabel(fPtI)], + fc[faceI], + cc[nei[faceI]] + ).quality(); + + if (tetQual < tol) + { + if (setPtr) + { + setPtr->insert(faceI); + } + + nErrorTets++; + break; + } + } + + if (findSharedBasePoint(mesh, faceI, tol, report) == -1) + { + if (setPtr) + { + setPtr->insert(faceI); + } + + nErrorTets++; + } + } + else + { + label patchI = patches.patchID()[faceI - mesh.nInternalFaces()]; + + if (patches[patchI].coupled()) + { + if + ( + findSharedBasePoint + ( + mesh, + faceI, + neiCc[faceI - mesh.nInternalFaces()], + tol, + report + ) == -1 + ) + { + if (setPtr) + { + setPtr->insert(faceI); + } + + nErrorTets++; + } + } + else + { + if (findBasePoint(mesh, faceI, tol, report) == -1) + { + if (setPtr) + { + setPtr->insert(faceI); + } + + nErrorTets++; + } + } + } + } + + reduce(nErrorTets, sumOp<label>()); + + if (nErrorTets > 0) + { + if (report) + { + Info<< " ***Error in face tets: " + << nErrorTets << " faces with low quality or negative volume " + << "decomposition tets." << endl; + } + + return true; + } + else + { + if (report) + { + Info<< " Face tets OK." << endl; + } + + return false; + } +} + + +Foam::List<Foam::tetIndices> Foam::polyMeshTetDecomposition::faceTetIndices +( + const polyMesh& mesh, + label fI, + label cI +) +{ + const faceList& pFaces = mesh.faces(); + const labelList& pOwner = mesh.faceOwner(); + + const face& f = pFaces[fI]; + + label nTets = f.size() - 2; + + List<tetIndices> faceTets(nTets); + + bool own = (pOwner[fI] == cI); + + label tetBasePtI = mesh.tetBasePtIs()[fI]; + + if (tetBasePtI == -1) + { + FatalErrorIn + ( + "Foam::List<Foam::FixedList<Foam::label, 4> >" + "Foam::Cloud<ParticleType>::" + "faceTetIndices(label fI, label cI) const" + ) + << "No base point for face " << fI << ", " << f + << ", produces a valid tet decomposition." + << abort(FatalError); + } + + for (label tetPtI = 1; tetPtI < f.size() - 1; tetPtI++) + { + tetIndices& faceTetIs = faceTets[tetPtI - 1]; + + label facePtI = (tetPtI + tetBasePtI) % f.size(); + label otherFacePtI = f.fcIndex(facePtI); + + faceTetIs.cell() = cI; + + faceTetIs.face() = fI; + + faceTetIs.faceBasePt() = tetBasePtI; + + if (own) + { + faceTetIs.facePtA() = facePtI; + faceTetIs.facePtB() = otherFacePtI; + } + else + { + faceTetIs.facePtA() = otherFacePtI; + faceTetIs.facePtB() = facePtI; + } + + faceTetIs.tetPt() = tetPtI; + } + + return faceTets; +} + + +Foam::List<Foam::tetIndices> Foam::polyMeshTetDecomposition::cellTetIndices +( + const polyMesh& mesh, + label cI +) +{ + const faceList& pFaces = mesh.faces(); + const cellList& pCells = mesh.cells(); + + const cell& thisCell = pCells[cI]; + + label nTets = 0; + + forAll(thisCell, cFI) + { + nTets += pFaces[thisCell[cFI]].size() - 2; + } + + DynamicList<tetIndices> cellTets(nTets); + + forAll(thisCell, cFI) + { + label fI = thisCell[cFI]; + + cellTets.append(faceTetIndices(mesh, fI, cI)); + } + + return cellTets; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/polyMeshTetDecomposition.H b/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/polyMeshTetDecomposition.H new file mode 100644 index 0000000000000000000000000000000000000000..cf2ea5e297137c79b3382b0290196e8017aaa9be --- /dev/null +++ b/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/polyMeshTetDecomposition.H @@ -0,0 +1,151 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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::polyMeshTetDecomposition + +Description + Tools for performing the minimum decomposition of faces of the + mesh into triangles so that the cells may be tet decomposed. + Includes functions for finding variable face starting (base) + points on each face to avoid the decomposition of cells into tets + that have negative or zero volume. + +SourceFiles + polyMeshTetDecomposition.C + +\*---------------------------------------------------------------------------*/ + +#ifndef polyMeshTetDecomposition_H +#define polyMeshTetDecomposition_H + +#include "polyMesh.H" +#include "coupledPolyPatch.H" +#include "syncTools.H" +#include "tetPointRef.H" +#include "tetIndices.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class polyMeshTetDecomposition Declaration +\*---------------------------------------------------------------------------*/ + +class polyMeshTetDecomposition +{ + +public: + + // Static data members + + //- Minimum tetrahedron quality + static const scalar minTetQuality; + + + // Member Functions + + //- Find the first suitable base point to use for a minimum + // triangle decomposition of the face, suiting owner and + // neighbour cells. Finds the first base point on the face + // whose worst quality tet from either cell is better than + // tolerance. Neighbour cell centre supplied. For coupled + // patches. + static label findSharedBasePoint + ( + const polyMesh& mesh, + label fI, + const point& nCc, + scalar tol, + bool report = false + ); + + //- As for findSharedBasePoint, but using neighbour cell + // centre from the mesh. For internal faces. + static label findSharedBasePoint + ( + const polyMesh& mesh, + label fI, + scalar tol, + bool report = false + ); + + //- Find the base point to use for a minimum triangle + // decomposition of the face, using only the owner + // information. For non-coupled boundary faces. + static label findBasePoint + ( + const polyMesh& mesh, + label fI, + scalar tol, + bool report = false + ); + + //- Find a suitable base point for each face for decomposition + // into tets + static labelList findFaceBasePts + ( + const polyMesh& mesh, + scalar tol = minTetQuality, + bool report = false + ); + + //- Check face-decomposition tet volume + static bool checkFaceTets + ( + const polyMesh& mesh, + scalar tol = minTetQuality, + const bool report = false, + labelHashSet* setPtr = NULL + ); + + //- Return the tet decomposition of the given face, with + // respect to the given cell + static List<tetIndices> faceTetIndices + ( + const polyMesh& mesh, + label fI, + label cI + ); + + //- Return the tet decomposition of the given cell, see + // findFacePt for the meaning of the indices + static List<tetIndices> cellTetIndices + ( + const polyMesh& mesh, + label cI + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/tetIndices.C b/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/tetIndices.C new file mode 100644 index 0000000000000000000000000000000000000000..163fccf49f3d89259e686e5ad9ea1f6944e16469 --- /dev/null +++ b/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/tetIndices.C @@ -0,0 +1,148 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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 "tetIndices.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::tetIndices::tetIndices() +: + cellI_(-1), + faceI_(-1), + faceBasePtI_(-1), + facePtAI_(-1), + facePtBI_(-1), + tetPtI_(-1) +{} + + +Foam::tetIndices::tetIndices +( + label cellI, + label faceI, + label faceBasePtI, + label facePtAI, + label facePtBI, + label tetPtI +) +: + cellI_(cellI), + faceI_(faceI), + faceBasePtI_(faceBasePtI), + facePtAI_(facePtAI), + facePtBI_(facePtBI), + tetPtI_(tetPtI) +{} + + +Foam::tetIndices::tetIndices +( + label cellI, + label faceI, + label tetPtI, + const polyMesh& mesh +) +: + cellI_(cellI), + faceI_(faceI), + faceBasePtI_(-1), + facePtAI_(-1), + facePtBI_(-1), + tetPtI_(tetPtI) +{ + const faceList& pFaces = mesh.faces(); + const labelList& pOwner = mesh.faceOwner(); + + const Foam::face& f = pFaces[faceI_]; + + bool own = (pOwner[faceI_] == cellI_); + + faceBasePtI_ = mesh.tetBasePtIs()[faceI_]; + + label facePtI = (tetPtI_ + faceBasePtI_) % f.size(); + label otherFacePtI = f.fcIndex(facePtI); + + if (own) + { + facePtAI_ = facePtI; + facePtBI_ = otherFacePtI; + } + else + { + facePtAI_ = otherFacePtI; + facePtBI_ = facePtI; + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::tetIndices::~tetIndices() +{} + + +// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // + +Foam::Istream& Foam::operator>>(Istream& is, tetIndices& tI) +{ + is >> tI.cell() + >> tI.face() + >> tI.faceBasePt() + >> tI.facePtA() + >> tI.facePtB() + >> tI.tetPt(); + + // Check state of Istream + is.check + ( + "Foam::Istream& Foam::operator>>(Foam::Istream&, Foam::tetIndices&)" + ); + + return is; +} + + +Foam::Ostream& Foam::operator<<(Ostream& os, const tetIndices& tI) +{ + os << tI.cell() << token::SPACE + << tI.face() << token::SPACE + << tI.faceBasePt() << token::SPACE + << tI.facePtA() << token::SPACE + << tI.facePtB() << token::SPACE + << tI.tetPt() << token::SPACE + << endl; + + // Check state of Ostream + os.check + ( + "Foam::Ostream& Foam::operator<<(Foam::Ostream&, " + "const Foam::tetIndices&)" + ); + + return os; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/tetIndices.H b/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/tetIndices.H new file mode 100644 index 0000000000000000000000000000000000000000..3e5ee425d6ed9a527dbb067732d07e7b809a9174 --- /dev/null +++ b/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/tetIndices.H @@ -0,0 +1,201 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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::tetIndices + +Description + Storage and named access for the indices of a tet which is part of + the decomposition of a cell. + +SourceFiles + tetIndicesI.H + tetIndices.C + +\*---------------------------------------------------------------------------*/ + +#ifndef tetIndices_H +#define tetIndices_H + +#include "label.H" +#include "tetPointRef.H" +#include "triPointRef.H" +#include "polyMesh.H" +#include "face.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class tetIndices Declaration +\*---------------------------------------------------------------------------*/ + +class tetIndices +{ + // Private data + + //- cell that this is a decomposed tet of + label cellI_; + + //- face that holds this decomposed tet + label faceI_; + + //- base point on the face + label faceBasePtI_; + + //- point on the face such that the right-hand circulation + // {faceBasePtI_, facePtIA_, facePtBI_} + // forms a triangle that points out of the tet + label facePtAI_; + + //- point on the face such that the right-hand circulation + // {faceBasePtI_, facePtIA_, facePtBI_} + // forms a triangle that points out of the tet + label facePtBI_; + + //- point on the face, *relative to the base point*, which + // characterises this tet on the face. + label tetPtI_; + + +public: + + // Constructors + + //- Construct null + tetIndices(); + + //- Construct from components + tetIndices + ( + label cellI, + label faceI, + label faceBasePtI, + label facePtAI, + label facePtBI, + label tetPtI + ); + + //- Construct from cell, face, pt description of tet + tetIndices + ( + label cellI, + label faceI, + label tetPtI, + const polyMesh& mesh + ); + + + //- Destructor + ~tetIndices(); + + + // Member Functions + + // Access + + //- Return the cell + inline label cell() const; + + //- Return the face + inline label face() const; + + //- Return the face base point + inline label faceBasePt() const; + + //- Return face point A + inline label facePtA() const; + + //- Return face point B + inline label facePtB() const; + + //- Return the characterising tetPtI + inline label tetPt() const; + + //- Return the geometry corresponding to this tet from the + // supplied mesh + inline tetPointRef tet(const polyMesh& mesh) const; + + //- Return the geometry corresponding to this tet from the + // supplied mesh using the old positions + inline tetPointRef oldTet(const polyMesh& mesh) const; + + //- Return the geometry corresponding to the tri on the + // mesh face for this tet from the supplied mesh + inline triPointRef faceTri(const polyMesh& mesh) const; + + //- Return the geometry corresponding to the tri on the + // mesh face for this tet from the supplied mesh using + // the old position + inline triPointRef oldFaceTri(const polyMesh& mesh) const; + + + // Edit + + //- Return non-const access to the cell + inline label& cell(); + + //- Return non-const access to the face + inline label& face(); + + //- Return non-const access to the face base point + inline label& faceBasePt(); + + //- Return non-const access to face point A + inline label& facePtA(); + + //- Return non-const access to face point B + inline label& facePtB(); + + //- Return non-const access to the characterising tetPtI + inline label& tetPt(); + + + // Member Operators + + inline bool operator==(const tetIndices&) const; + inline bool operator!=(const tetIndices&) const; + + + // IOstream Operators + + friend Istream& operator>>(Istream&, tetIndices&); + friend Ostream& operator<<(Ostream&, const tetIndices&); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "tetIndicesI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/tetIndicesI.H b/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/tetIndicesI.H new file mode 100644 index 0000000000000000000000000000000000000000..6b8a7871a04c6fbadb9ee3d61bf47215e8b5764c --- /dev/null +++ b/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/tetIndicesI.H @@ -0,0 +1,202 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::label Foam::tetIndices::cell() const +{ + return cellI_; +} + + +Foam::label Foam::tetIndices::face() const +{ + return faceI_; +} + + +Foam::label Foam::tetIndices::faceBasePt() const +{ + return faceBasePtI_; +} + + +Foam::label Foam::tetIndices::facePtA() const +{ + return facePtAI_; +} + + +Foam::label Foam::tetIndices::facePtB() const +{ + return facePtBI_; +} + + +Foam::label Foam::tetIndices::tetPt() const +{ + return tetPtI_; +} + + +Foam::tetPointRef Foam::tetIndices::tet(const polyMesh& mesh) const +{ + const pointField& pPts = mesh.points(); + const faceList& pFaces = mesh.faces(); + const vectorField& pC = mesh.cellCentres(); + + const Foam::face& f = pFaces[faceI_]; + + return tetPointRef + ( + pC[cellI_], + pPts[f[faceBasePtI_]], + pPts[f[facePtAI_]], + pPts[f[facePtBI_]] + ); +} + + +Foam::tetPointRef Foam::tetIndices::oldTet(const polyMesh& mesh) const +{ + const pointField& oldPPts = mesh.oldPoints(); + const faceList& pFaces = mesh.faces(); + + // We need to reconstruct the old Cc from oldPoints (it isn't + // stored) + point oldC = mesh.cells()[cellI_].centre + ( + oldPPts, + pFaces + ); + + const Foam::face& f = pFaces[faceI_]; + + return tetPointRef + ( + oldC, + oldPPts[f[faceBasePtI_]], + oldPPts[f[facePtAI_]], + oldPPts[f[facePtBI_]] + ); +} + + +Foam::triPointRef Foam::tetIndices::faceTri(const polyMesh& mesh) const +{ + const pointField& pPts = mesh.points(); + const faceList& pFaces = mesh.faces(); + + const Foam::face& f = pFaces[faceI_]; + + return triPointRef + ( + pPts[f[faceBasePtI_]], + pPts[f[facePtAI_]], + pPts[f[facePtBI_]] + ); +} + + +Foam::triPointRef Foam::tetIndices::oldFaceTri(const polyMesh& mesh) const +{ + const pointField& oldPPts = mesh.oldPoints(); + const faceList& pFaces = mesh.faces(); + + const Foam::face& f = pFaces[faceI_]; + + return triPointRef + ( + oldPPts[f[faceBasePtI_]], + oldPPts[f[facePtAI_]], + oldPPts[f[facePtBI_]] + ); +} + + +Foam::label& Foam::tetIndices::cell() +{ + return cellI_; +} + + +Foam::label& Foam::tetIndices::face() +{ + return faceI_; +} + + +Foam::label& Foam::tetIndices::faceBasePt() +{ + return faceBasePtI_; +} + + +Foam::label& Foam::tetIndices::facePtA() +{ + return facePtAI_; +} + + +Foam::label& Foam::tetIndices::facePtB() +{ + return facePtBI_; +} + + +Foam::label& Foam::tetIndices::tetPt() +{ + return tetPtI_; +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +inline bool Foam::tetIndices::operator==(const Foam::tetIndices& rhs) const +{ + return + ( + cell() == rhs.cell() + && face() == rhs.face() + && faceBasePt() == rhs.faceBasePt() + && facePtA() == rhs.facePtA() + && facePtB() == rhs.facePtB() + && tetPt() == rhs.tetPt() + ); +} + + +inline bool Foam::tetIndices::operator!=(const Foam::tetIndices& rhs) const +{ + return !(*this == rhs); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +// ************************************************************************* // diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H index 53aba7fd17f68d09b92382ae071c27b40b8f0d98..bda2eb19d6ca454461bebb6e1416e3b4f2a3b937 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H +++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H @@ -229,6 +229,19 @@ public: // Member functions + //- Return true only if this is a parallel run + virtual bool coupled() const + { + if (Pstream::parRun()) + { + return true; + } + else + { + return false; + } + } + //- Return processor number int myProcNo() const { diff --git a/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C b/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C index 5d35b85f75829660630f2fadf7853a0d45974e87..539aa1b6c6e65d9fde9ab7b2a7798de542c20206 100644 --- a/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C +++ b/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C @@ -1223,7 +1223,7 @@ void Foam::syncTools::syncBoundaryFaceList label patchStart = procPatch.start()-mesh.nInternalFaces(); UOPstream toNbr(procPatch.neighbProcNo(), pBufs); - toNbr << + toNbr << SubField<T> ( faceValues, @@ -1423,7 +1423,7 @@ void Foam::syncTools::syncFaceList cop(t, val1); faceValues[meshFace0] = t; - cop(val1, val0); + cop(val1, val0); faceValues[meshFace1] = val1; } } @@ -1683,7 +1683,7 @@ void Foam::syncTools::syncEdgeList const processorPolyPatch& procPatch = refCast<const processorPolyPatch>(patches[patchI]); - // Receive from neighbour. + // Receive from neighbour. List<unsigned int> nbrPatchInfo(procPatch.nEdges()); { diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C index 7df85dc6d55f4c798ed9f86d6ba9eb1a899687c1..3b3ad474b77ba1eb0fab86781d7c99418ce8cba0 100644 --- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C +++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C @@ -27,6 +27,7 @@ License #include "entry.H" #include "demandDrivenData.H" #include "stringListOps.H" +#include "Pstream.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -372,6 +373,84 @@ bool Foam::ZoneMesh<ZoneType, MeshType>::checkDefinition } +template<class ZoneType, class MeshType> +bool Foam::ZoneMesh<ZoneType, MeshType>::checkParallelSync +( + const bool report +) const +{ + if (!Pstream::parRun()) + { + return false; + } + + + const PtrList<ZoneType>& zones = *this; + + bool hasError = false; + + // Collect all names + List<wordList> allNames(Pstream::nProcs()); + allNames[Pstream::myProcNo()] = this->names(); + Pstream::gatherList(allNames); + Pstream::scatterList(allNames); + + List<wordList> allTypes(Pstream::nProcs()); + allTypes[Pstream::myProcNo()] = this->types(); + Pstream::gatherList(allTypes); + Pstream::scatterList(allTypes); + + // Have every processor check but only master print error. + + for (label procI = 1; procI < allNames.size(); procI++) + { + if + ( + (allNames[procI] != allNames[0]) + || (allTypes[procI] != allTypes[0]) + ) + { + hasError = true; + + if (debug || (report && Pstream::master())) + { + Info<< " ***Inconsistent zones across processors, " + "processor 0 has zone names:" << allNames[0] + << " zone types:" << allTypes[0] + << " processor " << procI << " has zone names:" + << allNames[procI] + << " zone types:" << allTypes[procI] + << endl; + } + } + } + + // Check contents + if (!hasError) + { + forAll(zones, zoneI) + { + if (zones[zoneI].checkParallelSync(false)) + { + hasError = true; + + if (debug || (report && Pstream::master())) + { + Info<< " ***Zone " << zones[zoneI].name() + << " of type " << zones[zoneI].type() + << " is not correctly synchronised" + << " across coupled boundaries." + << " (coupled faces are either not both " + << " present in set or have same flipmap)" << endl; + } + } + } + } + + return hasError; +} + + // Correct zone mesh after moving points template<class ZoneType, class MeshType> void Foam::ZoneMesh<ZoneType, MeshType>::movePoints(const pointField& p) diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H index 8854d9533b0e4aed4cb67357fc01d3010c98e191..15f715df5c8bc7a91f54cc44c602e5447d140b7d 100644 --- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H +++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H @@ -149,6 +149,10 @@ public: //- Check zone definition. Return true if in error. bool checkDefinition(const bool report = false) const; + //- Check whether all procs have all zones and in same order. Return + // true if in error. + bool checkParallelSync(const bool report = false) const; + //- Correct zone mesh after moving points void movePoints(const pointField&); diff --git a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H index 5f5d60a30fc87118a25b5a289b88886e11f24163..54b5ba9eb01debfa9c50fade5a3043ebf0066dce 100644 --- a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H +++ b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H @@ -209,6 +209,13 @@ public: //- Check zone definition. Return true if in error. virtual bool checkDefinition(const bool report = false) const; + //- Check whether zone is synchronised across coupled boundaries. Return + // true if in error. + virtual bool checkParallelSync(const bool report = false) const + { + return false; + } + //- Write dictionary virtual void writeDict(Ostream&) const; diff --git a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C index d6bca05438f60c62d1badae78098d2a1c9de820e..a37a786ae2b9c52f85e6460c8e7cfea440e170b0 100644 --- a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C +++ b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C @@ -29,6 +29,7 @@ License #include "polyMesh.H" #include "primitiveMesh.H" #include "demandDrivenData.H" +#include "syncTools.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -134,6 +135,49 @@ bool Foam::pointZone::checkDefinition(const bool report) const } +bool Foam::pointZone::checkParallelSync(const bool report) const +{ + const polyMesh& mesh = zoneMesh().mesh(); + + labelList maxZone(mesh.nPoints(), -1); + labelList minZone(mesh.nPoints(), labelMax); + forAll(*this, i) + { + label pointI = operator[](i); + maxZone[pointI] = index(); + minZone[pointI] = index(); + } + syncTools::syncPointList(mesh, maxZone, maxEqOp<label>(), -1); + syncTools::syncPointList(mesh, minZone, minEqOp<label>(), labelMax); + + bool error = false; + + forAll(maxZone, pointI) + { + // Check point in zone on both sides + if (maxZone[pointI] != minZone[pointI]) + { + if (report && !error) + { + Info<< " ***Problem with pointZone " << index() + << " named " << name() + << ". Point " << pointI + << " at " << mesh.points()[pointI] + << " is in zone " + << (minZone[pointI] == labelMax ? -1 : minZone[pointI]) + << " on some processors and in zone " + << maxZone[pointI] + << " on some other processors." + << endl; + } + error = true; + } + } + + return error; +} + + void Foam::pointZone::writeDict(Ostream& os) const { os << nl << name_ << nl << token::BEGIN_BLOCK << nl diff --git a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H index 177953990cfea7a2fdaf4afb0edc9ce230eefb88..22079a9407cf46706fc59a36640c1e5a7e6d5c9c 100644 --- a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H +++ b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H @@ -208,6 +208,10 @@ public: //- Check zone definition. Return true if in error. virtual bool checkDefinition(const bool report = false) const; + //- Check whether zone is synchronised across coupled boundaries. Return + // true if in error. + virtual bool checkParallelSync(const bool report = false) const; + //- Correct patch after moving points virtual void movePoints(const pointField&) {} diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.H b/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.H index efa78e3b303c3e56dc9d5a67b37830a311a6ea13..61c3da9bb9f644ecb74b66ac293f80a02d19fd0e 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.H +++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.H @@ -66,6 +66,7 @@ SourceFiles #include "HashSet.H" #include "Map.H" #include "EdgeMap.H" +#include "boundBox.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -577,14 +578,6 @@ public: labelHashSet* setPtr = NULL ) const; - //- Check face-decomposition tet volume - bool checkFaceTets - ( - const bool report = false, - const scalar minTetVol = 0, - labelHashSet* setPtr = NULL - ) const; - //- Check face skewness bool checkFaceSkewness ( diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshCheck.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshCheck.C index 04ef5b21bb4932b9bf5ad7baf45c5e36ecf5be2e..17b5bfd78ebe4a1968a2beffa2102fc7f844362e 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshCheck.C +++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshCheck.C @@ -618,114 +618,6 @@ bool Foam::primitiveMesh::checkFacePyramids } -bool Foam::primitiveMesh::checkFaceTets -( - const bool report, - const scalar minTetVol, - labelHashSet* setPtr -) const -{ - if (debug) - { - Info<< "bool primitiveMesh::checkFaceTets(" - << "const bool, const scalar, labelHashSet*) const: " - << "checking face orientation" << endl; - } - - // check whether face area vector points to the cell with higher label - const vectorField& cc = cellCentres(); - const vectorField& fc = faceCentres(); - - const labelList& own = faceOwner(); - const labelList& nei = faceNeighbour(); - - const faceList& fcs = faces(); - - const pointField& p = points(); - - label nErrorPyrs = 0; - - forAll(fcs, faceI) - { - // Create the owner tets - they will have negative volume - const face& f = fcs[faceI]; - - forAll(f, fp) - { - scalar tetVol = tetPointRef - ( - p[f[fp]], - p[f.nextLabel(fp)], - fc[faceI], - cc[own[faceI]] - ).mag(); - - if (tetVol > -minTetVol) - { - if (setPtr) - { - setPtr->insert(faceI); - } - - nErrorPyrs++; - break; // no need to check other tets - } - } - - if (isInternalFace(faceI)) - { - // Create the neighbour tet - it will have positive volume - const face& f = fcs[faceI]; - - forAll(f, fp) - { - scalar tetVol = tetPointRef - ( - p[f[fp]], - p[f.nextLabel(fp)], - fc[faceI], - cc[nei[faceI]] - ).mag(); - - if (tetVol < minTetVol) - { - if (setPtr) - { - setPtr->insert(faceI); - } - - nErrorPyrs++; - break; - } - } - } - } - - reduce(nErrorPyrs, sumOp<label>()); - - if (nErrorPyrs > 0) - { - if (debug || report) - { - Info<< " ***Error in face tets: " - << nErrorPyrs << " faces have incorrectly oriented face" - << " decomposition triangles." << endl; - } - - return true; - } - else - { - if (debug || report) - { - Info<< " Face tets OK." << endl; - } - - return false; - } -} - - bool Foam::primitiveMesh::checkFaceSkewness ( const bool report, diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshFindCell.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshFindCell.C index 6918235551d53e07a1210397d9b063a03e8a2c70..fecbc3c6fbd96fd516a978da1531e4c0dc5e7df1 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshFindCell.C +++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshFindCell.C @@ -32,32 +32,14 @@ License // Is the point in the cell bounding box bool Foam::primitiveMesh::pointInCellBB(const point& p, label celli) const { - const pointField& points = this->points(); - const faceList& f = faces(); - const vectorField& centres = cellCentres(); - const cellList& cf = cells(); - - labelList cellVertices = cf[celli].labels(f); - - vector bbmax = -GREAT*vector::one; - vector bbmin = GREAT*vector::one; - - forAll(cellVertices, vertexI) - { - bbmax = max(bbmax, points[cellVertices[vertexI]]); - bbmin = min(bbmin, points[cellVertices[vertexI]]); - } - - scalar distance = mag(centres[celli] - p); - - if ((distance - mag(bbmax - bbmin)) < SMALL) - { - return true; - } - else - { - return false; - } + return boundBox + ( + cells()[celli].points + ( + faces(), + points() + ) + ).contains(p); } diff --git a/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedron.C b/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedron.C index 2c801c1db9f455a18f6439f7a6588ac5caa55991..54f8168b60549ab3b0d6013311f7ea61a863525b 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedron.C +++ b/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedron.C @@ -30,7 +30,6 @@ Description #include "triPointRef.H" #include "scalarField.H" - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // (Probably very inefficient) minimum containment sphere calculation. diff --git a/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedron.H b/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedron.H index fe036de2d23ad01a492b7c1ce619e14f6af35e39..f80ac49d4061632c2a37e2ae20a37599472e33fe 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedron.H +++ b/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedron.H @@ -42,6 +42,7 @@ SourceFiles #include "point.H" #include "primitiveFieldsFwd.H" #include "pointHit.H" +#include "Random.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -133,16 +134,42 @@ public: inline vector Sd() const; + //- Return centre (centroid) + inline Point centre() const; //- Return volume inline scalar mag() const; //- Return circum-centre - inline vector circumCentre() const; + inline Point circumCentre() const; //- Return circum-radius inline scalar circumRadius() const; + //- Return quality: Ratio of tetrahedron and circum-sphere + // volume, scaled so that a regular tetrahedron has a + // quality of 1 + inline scalar quality() const; + + //- Return a random point in the tetrahedron from a + // uniform distribution + inline Point randomPoint(Random& rndGen) const; + + //- Calculate the barycentric coordinates of the given + // point, in the same order as a, b, c, d. Returns the + // determinant of the solution. + inline scalar barycentric + ( + const point& pt, + List<scalar>& bary + ) const; + + //- Return nearest point to p on tetrahedron + inline pointHit nearestPoint + ( + const point& p + ) const; + //- Return (min)containment sphere, i.e. the smallest sphere with // all points inside. Returns pointHit with: // - hit : if sphere is equal to circumsphere diff --git a/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedronI.H b/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedronI.H index 5fab6fa5381b1b856ad94f4a2f6400f60d049565..a96d9f577fc1277772acdbcaa235f37c19349625 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedronI.H +++ b/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedronI.H @@ -125,6 +125,13 @@ inline vector tetrahedron<Point, PointRef>::Sd() const } +template<class Point, class PointRef> +inline Point tetrahedron<Point, PointRef>::centre() const +{ + return 0.25*(a_ + b_ + c_ + d_); +} + + template<class Point, class PointRef> inline scalar tetrahedron<Point, PointRef>::mag() const { @@ -133,19 +140,19 @@ inline scalar tetrahedron<Point, PointRef>::mag() const template<class Point, class PointRef> -inline vector tetrahedron<Point, PointRef>::circumCentre() const +inline Point tetrahedron<Point, PointRef>::circumCentre() const { vector a = b_ - a_; vector b = c_ - a_; vector c = d_ - a_; - scalar lamda = magSqr(c) - (a&c); - scalar mu = magSqr(b) - (a&b); + scalar lambda = magSqr(c) - (a & c); + scalar mu = magSqr(b) - (a & b); - vector ba = b^a; - vector ca = c^a; + vector ba = b ^ a; + vector ca = c ^ a; - return a_ + 0.5*(a + (lamda*ba - mu*ca)/(c&ba)); + return a_ + 0.5*(a + (lambda*ba - mu*ca)/((c & ba) + ROOTVSMALL)); } @@ -156,6 +163,196 @@ inline scalar tetrahedron<Point, PointRef>::circumRadius() const } +template<class Point, class PointRef> +inline scalar tetrahedron<Point, PointRef>::quality() const +{ + // Note: 8/(9*sqrt(3)) = 0.5132002393 + + return mag()/(0.5132002393*pow3(min(circumRadius(), GREAT)) + ROOTVSMALL); +} + + +template<class Point, class PointRef> +inline Point tetrahedron<Point, PointRef>::randomPoint(Random& rndGen) const +{ + // Adapted from + // http://vcg.isti.cnr.it/activities/geometryegraphics/pointintetraedro.html + + scalar s = rndGen.scalar01(); + scalar t = rndGen.scalar01(); + scalar u = rndGen.scalar01(); + + if (s + t > 1.0) + { + s = 1.0 - s; + t = 1.0 - t; + } + + if (t + u > 1.0) + { + scalar tmp = u; + u = 1.0 - s - t; + t = 1.0 - tmp; + } + else if (s + t + u > 1.0) + { + scalar tmp = u; + u = s + t + u - 1.0; + s = 1.0 - t - tmp; + } + + return (1 - s - t - u)*a_ + s*b_ + t*c_ + u*d_; +} + + +template<class Point, class PointRef> +scalar tetrahedron<Point, PointRef>::barycentric +( + const point& pt, + List<scalar>& bary +) const +{ + // From: + // http://en.wikipedia.org/wiki/Barycentric_coordinate_system_(mathematics) + + vector e0(a_ - d_); + vector e1(b_ - d_); + vector e2(c_ - d_); + + tensor t + ( + e0.x(), e1.x(), e2.x(), + e0.y(), e1.y(), e2.y(), + e0.z(), e1.z(), e2.z() + ); + + scalar detT = det(t); + + if (Foam::mag(detT) < SMALL) + { + WarningIn + ( + "List<scalar> tetrahedron<Point, PointRef>::barycentric" + "(" + "const point& pt" + ") const" + ) + << "Degenerate triangle - returning 1/4 barycentric coordinates." + << endl; + + bary = List<scalar>(4, 0.25); + + return detT; + } + + vector res = inv(t, detT) & (pt - d_); + + bary.setSize(4); + + bary[0] = res.x(); + bary[1] = res.y(); + bary[2] = res.z(); + bary[3] = (1.0 - res.x() - res.y() - res.z()); + + return detT; +} + + +template<class Point, class PointRef> +inline pointHit tetrahedron<Point, PointRef>::nearestPoint +( + const point& p +) const +{ + // Adapted from: + // Real-time collision detection, Christer Ericson, 2005, p142-144 + + // Assuming initially that the point is inside all of the + // halfspaces, so closest to itself. + + point closestPt = p; + + scalar minOutsideDistance = VGREAT; + + bool inside = true; + + if (((p - b_) & Sa()) >= 0) + { + // p is outside halfspace plane of tri + pointHit info = triangle<Point, PointRef>(b_, c_, d_).nearestPoint(p); + + inside = false; + + if (info.distance() < minOutsideDistance) + { + closestPt = info.rawPoint(); + + minOutsideDistance = info.distance(); + } + } + + if (((p - a_) & Sb()) >= 0) + { + // p is outside halfspace plane of tri + pointHit info = triangle<Point, PointRef>(a_, d_, c_).nearestPoint(p); + + inside = false; + + if (info.distance() < minOutsideDistance) + { + closestPt = info.rawPoint(); + + minOutsideDistance = info.distance(); + } + } + + if (((p - a_) & Sc()) >= 0) + { + // p is outside halfspace plane of tri + pointHit info = triangle<Point, PointRef>(a_, b_, d_).nearestPoint(p); + + inside = false; + + if (info.distance() < minOutsideDistance) + { + closestPt = info.rawPoint(); + + minOutsideDistance = info.distance(); + } + } + + if (((p - a_) & Sd()) >= 0) + { + // p is outside halfspace plane of tri + pointHit info = triangle<Point, PointRef>(a_, c_, b_).nearestPoint(p); + + inside = false; + + if (info.distance() < minOutsideDistance) + { + closestPt = info.rawPoint(); + + minOutsideDistance = info.distance(); + } + } + + // If the point is inside, then the distance to the closest point + // is zero + if (inside) + { + minOutsideDistance = 0; + } + + return pointHit + ( + inside, + closestPt, + minOutsideDistance, + !inside + ); +} + + // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // template<class point, class pointRef> diff --git a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H index a5c246a3607644bef4abd36f174dde30f55a5196..64d9318306fa0322ac3626fccf89bc5f46cc8be6 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H +++ b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H @@ -39,7 +39,7 @@ SourceFiles #include "vector.H" #include "tensor.H" #include "pointHit.H" - +#include "Random.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -141,12 +141,14 @@ public: inline vector normal() const; //- Return circum-centre - inline vector circumCentre() const; + inline Point circumCentre() const; //- Return circum-radius inline scalar circumRadius() const; - //- Return quality: Ratio triangle and circum-circle area + //- Return quality: Ratio of triangle and circum-circle + // area, scaled so that an equilateral triangle has a + // quality of 1 inline scalar quality() const; //- Return swept-volume @@ -160,6 +162,19 @@ public: scalar density = 1.0 ) const; + //- Return a random point on the triangle from a uniform + // distribution + inline Point randomPoint(Random& rndGen) const; + + //- Calculate the barycentric coordinates of the given + // point, in the same order as a, b, c. Returns the + // determinant of the solution. + inline scalar barycentric + ( + const point& pt, + List<scalar>& bary + ) const; + //- Return point intersection with a ray. // For a hit, the distance is signed. Positive number // represents the point in front of triangle. diff --git a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H index 3587ac8d907d38e45d8871bbfd3f0f30600cc788..10267a923f720824e5f50a7606f31ae62089fb07 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H +++ b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H @@ -259,7 +259,7 @@ inline vector triangle<Point, PointRef>::normal() const template<class Point, class PointRef> -inline vector triangle<Point, PointRef>::circumCentre() const +inline Point triangle<Point, PointRef>::circumCentre() const { scalar d1 = (c_ - a_)&(b_ - a_); scalar d2 = -(c_ - b_)&(b_ - a_); @@ -303,12 +303,14 @@ inline scalar triangle<Point, PointRef>::circumRadius() const template<class Point, class PointRef> inline scalar triangle<Point, PointRef>::quality() const { + // Note: 3*sqr(3)/(4*pi) = 0.4134966716 + return mag() / ( constant::mathematical::pi *Foam::sqr(circumRadius()) - *0.413497 + *0.4134966716 + VSMALL ); } @@ -366,6 +368,72 @@ inline tensor triangle<Point, PointRef>::inertia *density; } + +template<class Point, class PointRef> +inline Point triangle<Point, PointRef>::randomPoint(Random& rndGen) const +{ + // Generating Random Points in Triangles + // by Greg Turk + // from "Graphics Gems", Academic Press, 1990 + // http://tog.acm.org/GraphicsGems/gems/TriPoints.c + + scalar s = rndGen.scalar01(); + + scalar t = sqrt(rndGen.scalar01()); + + return (1 - t)*a_ + (1 - s)*t*b_ + s*t*c_; +} + + +template<class Point, class PointRef> +scalar triangle<Point, PointRef>::barycentric +( + const point& pt, + List<scalar>& bary +) const +{ + // From: + // Real-time collision detection, Christer Ericson, 2005, p47-48 + + vector v0 = b_ - a_; + vector v1 = c_ - a_; + vector v2 = pt - a_; + + scalar d00 = v0 & v0; + scalar d01 = v0 & v1; + scalar d11 = v1 & v1; + scalar d20 = v2 & v0; + scalar d21 = v2 & v1; + + scalar denom = d00*d11 - d01*d01; + + if (Foam::mag(denom) < SMALL) + { + WarningIn + ( + "List<scalar> triangle<Point, PointRef>::barycentric" + "(" + "const point& pt" + ") const" + ) + << "Degenerate triangle - returning 1/3 barycentric coordinates." + << endl; + + bary = List<scalar>(3, 1.0/3.0); + + return denom; + } + + bary.setSize(3); + + bary[0] = (d11*d20 - d01*d21)/denom; + bary[1] = (d00*d21 - d01*d20)/denom; + bary[2] = 1.0 - bary[0] - bary[1]; + + return denom; +} + + template<class Point, class PointRef> inline pointHit triangle<Point, PointRef>::ray ( @@ -775,4 +843,3 @@ inline Ostream& operator<<(Ostream& os, const triangle<Point, PointRef>& t) } // End namespace Foam // ************************************************************************* // - diff --git a/src/OpenFOAM/primitives/Tensor/TensorI.H b/src/OpenFOAM/primitives/Tensor/TensorI.H index 8ca4f601693c7cffaf247bce243eac2035979cf6..11860b5c4c9a11175c53fd52c9af83e9316f34ec 100644 --- a/src/OpenFOAM/primitives/Tensor/TensorI.H +++ b/src/OpenFOAM/primitives/Tensor/TensorI.H @@ -481,7 +481,7 @@ inline Tensor<Cmpt> cof(const Tensor<Cmpt>& t) } -//- Return the inverse of a tensor give the determinant +//- Return the inverse of a tensor given the determinant template <class Cmpt> inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t, const Cmpt dett) { diff --git a/src/dynamicMesh/motionSmoother/motionSmootherCheck.C b/src/dynamicMesh/motionSmoother/motionSmootherCheck.C index 4823c3a429dfd9ca43ad15d422beeea644fd4339..5df1ca1dbcfd116d72bb504f98731e26e233545e 100644 --- a/src/dynamicMesh/motionSmoother/motionSmootherCheck.C +++ b/src/dynamicMesh/motionSmoother/motionSmootherCheck.C @@ -68,9 +68,9 @@ bool Foam::motionSmoother::checkMesh ( readScalar(dict.lookup("minVol", true)) ); - const scalar minTetVol + const scalar minTetQuality ( - readScalar(dict.lookup("minTetVol", true)) + readScalar(dict.lookup("minTetQuality", true)) ); const scalar maxConcave ( @@ -160,12 +160,12 @@ bool Foam::motionSmoother::checkMesh nWrongFaces = nNewWrongFaces; } - if (minTetVol > -GREAT) + if (minTetQuality > -GREAT) { polyMeshGeometry::checkFaceTets ( report, - minTetVol, + minTetQuality, mesh, mesh.cellCentres(), mesh.faceCentres(), @@ -177,8 +177,8 @@ bool Foam::motionSmoother::checkMesh label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>()); - Info<< " faces with face-decomposition tet volume < " - << setw(5) << minTetVol << " : " + Info<< " faces with face-decomposition tet quality < " + << setw(5) << minTetQuality << " : " << nNewWrongFaces-nWrongFaces << endl; nWrongFaces = nNewWrongFaces; @@ -443,9 +443,9 @@ bool Foam::motionSmoother::checkMesh ( readScalar(dict.lookup("minVol", true)) ); - const scalar minTetVol + const scalar minTetQuality ( - readScalar(dict.lookup("minTetVol", true)) + readScalar(dict.lookup("minTetQuality", true)) ); const scalar maxConcave ( @@ -531,12 +531,12 @@ bool Foam::motionSmoother::checkMesh nWrongFaces = nNewWrongFaces; } - if (minTetVol > -GREAT) + if (minTetQuality > -GREAT) { meshGeom.checkFaceTets ( report, - minTetVol, + minTetQuality, meshGeom.mesh().points(), checkFaces, baffles, @@ -545,8 +545,8 @@ bool Foam::motionSmoother::checkMesh label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>()); - Info<< " faces with face-decomposition tet volume < " - << setw(5) << minTetVol << " : " + Info<< " faces with face-decomposition tet quality < " + << setw(5) << minTetQuality << " : " << nNewWrongFaces-nWrongFaces << endl; nWrongFaces = nNewWrongFaces; diff --git a/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.C b/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.C index fb9ccb9631f01f430e92aa1d08045d472c4ee530..4df209498a8da3a698c35223f83ed7fc896db170 100644 --- a/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.C +++ b/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.C @@ -24,6 +24,7 @@ License \*---------------------------------------------------------------------------*/ #include "polyMeshGeometry.H" +#include "polyMeshTetDecomposition.H" #include "pyramidPointFaceRef.H" #include "tetPointRef.H" #include "syncTools.H" @@ -313,7 +314,7 @@ bool Foam::polyMeshGeometry::checkFaceTet ( const polyMesh& mesh, const bool report, - const scalar minTetVol, + const scalar minTetQuality, const pointField& p, const label faceI, const point& fc, // face centre @@ -326,15 +327,15 @@ bool Foam::polyMeshGeometry::checkFaceTet forAll(f, fp) { - scalar tetVol = tetPointRef + scalar tetQual = tetPointRef ( p[f[fp]], p[f.nextLabel(fp)], fc, cc - ).mag(); + ).quality(); - if (tetVol < minTetVol) + if (tetQual < minTetQuality) { if (report) { @@ -345,7 +346,7 @@ bool Foam::polyMeshGeometry::checkFaceTet << "face " << faceI << " has a triangle that points the wrong way." << endl - << "Tet volume: " << tetVol + << "Tet quality: " << tetQual << " Face " << faceI << endl; } @@ -423,16 +424,15 @@ bool Foam::polyMeshGeometry::checkFaceDotProduct // Severe nonorthogonality threshold const scalar severeNonorthogonalityThreshold = ::cos(degToRad(orthWarn)); - // Calculate coupled cell centre - pointField neiCc(mesh.nFaces()-mesh.nInternalFaces()); + pointField neiCc(mesh.nFaces() - mesh.nInternalFaces()); for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++) { neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]]; } - syncTools::swapBoundaryFacePositions(mesh, neiCc); + syncTools::swapBoundaryFacePositions(mesh, neiCc); scalar minDDotS = GREAT; @@ -754,7 +754,7 @@ bool Foam::polyMeshGeometry::checkFacePyramids "polyMeshGeometry::checkFacePyramids(" "const bool, const scalar, const pointField&" ", const labelList&, labelHashSet*)" - ) << "Error in face pyramids: faces pointing the wrong way!" + ) << "Error in face pyramids: faces pointing the wrong way." << endl; } @@ -775,7 +775,7 @@ bool Foam::polyMeshGeometry::checkFacePyramids bool Foam::polyMeshGeometry::checkFaceTets ( const bool report, - const scalar minTetVol, + const scalar minTetQuality, const polyMesh& mesh, const vectorField& cellCentres, const vectorField& faceCentres, @@ -785,11 +785,23 @@ bool Foam::polyMeshGeometry::checkFaceTets labelHashSet* setPtr ) { - // check whether face area vector points to the cell with higher label + // check whether decomposing each cell into tets results in + // positive volume, non-flat tets const labelList& own = mesh.faceOwner(); const labelList& nei = mesh.faceNeighbour(); + const polyBoundaryMesh& patches = mesh.boundaryMesh(); - label nErrorPyrs = 0; + // Calculate coupled cell centre + pointField neiCc(mesh.nFaces() - mesh.nInternalFaces()); + + for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++) + { + neiCc[faceI - mesh.nInternalFaces()] = cellCentres[own[faceI]]; + } + + syncTools::swapBoundaryFacePositions(mesh, neiCc); + + label nErrorTets = 0; forAll(checkFaces, i) { @@ -801,36 +813,104 @@ bool Foam::polyMeshGeometry::checkFaceTets ( mesh, report, - minTetVol, + minTetQuality, p, faceI, cellCentres[own[faceI]], // face centre - faceCentres[faceI], // cell centre + faceCentres[faceI], // cell centre setPtr ); if (tetError) { - nErrorPyrs++; + nErrorTets++; } if (mesh.isInternalFace(faceI)) { - // Create the neighbour pyramid - it will have positive volume + // Create the neighbour tets - they will have positive volume bool tetError = checkFaceTet ( mesh, report, - minTetVol, + minTetQuality, p, faceI, - faceCentres[faceI], // face centre + faceCentres[faceI], // face centre cellCentres[nei[faceI]], // cell centre setPtr ); + if (tetError) { - nErrorPyrs++; + nErrorTets++; + } + + if + ( + polyMeshTetDecomposition::findSharedBasePoint + ( + mesh, + faceI, + minTetQuality, + report + ) == -1 + ) + { + if (setPtr) + { + setPtr->insert(faceI); + } + + nErrorTets++; + } + } + else + { + label patchI = patches.whichPatch(faceI); + + if (patches[patchI].coupled()) + { + if + ( + polyMeshTetDecomposition::findSharedBasePoint + ( + mesh, + faceI, + neiCc[faceI - mesh.nInternalFaces()], + minTetQuality, + report + ) == -1 + ) + { + if (setPtr) + { + setPtr->insert(faceI); + } + + nErrorTets++; + } + } + else + { + if + ( + polyMeshTetDecomposition::findBasePoint + ( + mesh, + faceI, + minTetQuality, + report + ) == -1 + ) + { + if (setPtr) + { + setPtr->insert(faceI); + } + + nErrorTets++; + } } } } @@ -844,7 +924,7 @@ bool Foam::polyMeshGeometry::checkFaceTets ( mesh, report, - minTetVol, + minTetQuality, p, face0, cellCentres[own[face0]], // face centre @@ -854,15 +934,15 @@ bool Foam::polyMeshGeometry::checkFaceTets if (tetError) { - nErrorPyrs++; + nErrorTets++; } - // Create the neighbour pyramid - it will have positive volume + // Create the neighbour tets - they will have positive volume tetError = checkFaceTet ( mesh, report, - minTetVol, + minTetQuality, p, face0, faceCentres[face0], // face centre @@ -872,13 +952,33 @@ bool Foam::polyMeshGeometry::checkFaceTets if (tetError) { - nErrorPyrs++; + nErrorTets++; + } + + if + ( + polyMeshTetDecomposition::findSharedBasePoint + ( + mesh, + face0, + cellCentres[own[face1]], + minTetQuality, + report + ) == -1 + ) + { + if (setPtr) + { + setPtr->insert(face0); + } + + nErrorTets++; } } - reduce(nErrorPyrs, sumOp<label>()); + reduce(nErrorTets, sumOp<label>()); - if (nErrorPyrs > 0) + if (nErrorTets > 0) { if (report) { @@ -887,7 +987,7 @@ bool Foam::polyMeshGeometry::checkFaceTets "polyMeshGeometry::checkFaceTets(" "const bool, const scalar, const pointField&, const pointField&" ", const labelList&, labelHashSet*)" - ) << "Error in face pyramids: faces pointing the wrong way!" + ) << "Error in face decomposition: negative tets." << endl; } @@ -2135,7 +2235,7 @@ bool Foam::polyMeshGeometry::checkFacePyramids bool Foam::polyMeshGeometry::checkFaceTets ( const bool report, - const scalar minTetVol, + const scalar minTetQuality, const pointField& p, const labelList& checkFaces, const List<labelPair>& baffles, @@ -2145,7 +2245,7 @@ bool Foam::polyMeshGeometry::checkFaceTets return checkFaceTets ( report, - minTetVol, + minTetQuality, mesh_, cellCentres_, faceCentres_, diff --git a/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.H b/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.H index 4a8178b8f60008b77afa22c07f211a702e40c828..71f61447b5347efd81718bace29071d3d9a0cb60 100644 --- a/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.H +++ b/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.H @@ -113,7 +113,7 @@ class polyMeshGeometry ( const polyMesh&, const bool report, - const scalar minTetVol, + const scalar minTetQuality, const pointField& p, const label faceI, const point& fc, // face centre @@ -121,6 +121,7 @@ class polyMeshGeometry labelHashSet* setPtr ); + public: ClassName("polyMeshGeometry"); @@ -350,7 +351,7 @@ public: bool checkFaceTets ( const bool report, - const scalar minTetVol, + const scalar minTetQuality, const pointField& p, const labelList& checkFaces, const List<labelPair>& baffles, diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/cyclic/cyclicFvsPatchField.C b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclic/cyclicFvsPatchField.C index 5a9fadd441de79dda9c6e93420c9ef12fb631026..fe7b7662bc0305db1098363844222cc4b162599f 100644 --- a/src/finiteVolume/fields/fvsPatchFields/constraint/cyclic/cyclicFvsPatchField.C +++ b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclic/cyclicFvsPatchField.C @@ -56,7 +56,7 @@ cyclicFvsPatchField<Type>::cyclicFvsPatchField coupledFvsPatchField<Type>(ptf, p, iF, mapper), cyclicPatch_(refCast<const cyclicFvPatch>(p)) { - if (!isType<cyclicFvPatch>(this->patch())) + if (!isA<cyclicFvPatch>(this->patch())) { FatalErrorIn ( @@ -87,7 +87,7 @@ cyclicFvsPatchField<Type>::cyclicFvsPatchField coupledFvsPatchField<Type>(p, iF, dict), cyclicPatch_(refCast<const cyclicFvPatch>(p)) { - if (!isType<cyclicFvPatch>(p)) + if (!isA<cyclicFvPatch>(p)) { FatalIOErrorIn ( diff --git a/src/finiteVolume/interpolation/interpolation/interpolation/interpolation.H b/src/finiteVolume/interpolation/interpolation/interpolation/interpolation.H index ef200b354a81a6b52949ac6413d3b5c1f8e16377..e6df2154a4f4dd0e5471b7a39775cab7e616e2bd 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolation/interpolation.H +++ b/src/finiteVolume/interpolation/interpolation/interpolation/interpolation.H @@ -38,6 +38,7 @@ Description #include "typeInfo.H" #include "autoPtr.H" #include "runTimeSelectionTables.H" +#include "tetIndices.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -130,9 +131,23 @@ public: virtual Type interpolate ( const vector& position, - const label nCell, - const label facei = -1 + const label cellI, + const label faceI = -1 ) const = 0; + + //- Interpolate field to the given point in the tetrahedron + // defined by the given indices. Calls interpolate function + // above here execpt where overridden by derived + // interpolation types. + virtual Type interpolate + ( + const vector& position, + const tetIndices& tetIs, + const label faceI = -1 + ) const + { + return interpolate(position, tetIs.cell(), faceI); + } }; diff --git a/src/finiteVolume/interpolation/interpolation/interpolationCell/interpolationCell.C b/src/finiteVolume/interpolation/interpolation/interpolationCell/interpolationCell.C index fbf1bfa14aca2443d0ea248cb480684486072d87..760fd2ff63306e215fd18dbc7b151eb4eb280a34 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationCell/interpolationCell.C +++ b/src/finiteVolume/interpolation/interpolation/interpolationCell/interpolationCell.C @@ -49,11 +49,11 @@ template<class Type> Type interpolationCell<Type>::interpolate ( const vector&, - const label celli, + const label cellI, const label ) const { - return this->psi_[celli]; + return this->psi_[cellI]; } diff --git a/src/finiteVolume/interpolation/interpolation/interpolationCell/interpolationCell.H b/src/finiteVolume/interpolation/interpolation/interpolationCell/interpolationCell.H index 3c852da867979d5b524c05eeff0ed76392502bc0..fa9461805b1fe90a4e03a86a4cc9257dc921842b 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationCell/interpolationCell.H +++ b/src/finiteVolume/interpolation/interpolation/interpolationCell/interpolationCell.H @@ -72,8 +72,8 @@ public: Type interpolate ( const vector& position, - const label nCell, - const label facei = -1 + const label cellI, + const label faceI = -1 ) const; }; diff --git a/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/cellPointWeight/cellPointWeight.C b/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/cellPointWeight/cellPointWeight.C index 52ce6ba21e6bc8d6d65ab12b98677b4aa83fa429..99b10c10b54df9792e5a987a43b31d9f93f6f08d 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/cellPointWeight/cellPointWeight.C +++ b/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/cellPointWeight/cellPointWeight.C @@ -25,10 +25,13 @@ License #include "cellPointWeight.H" #include "polyMesh.H" +#include "tetPointRef.H" +#include "polyMeshTetDecomposition.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // int Foam::cellPointWeight::debug(debug::debugSwitch("cellPointWeight", 0)); + Foam::scalar Foam::cellPointWeight::tol(SMALL); // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // @@ -37,148 +40,101 @@ void Foam::cellPointWeight::findTetrahedron ( const polyMesh& mesh, const vector& position, - const label cellIndex + const label cellI ) { if (debug) { - Pout<< "\nFoam::cellPointWeight::findTetrahedron" << nl + Pout<< nl << "Foam::cellPointWeight::findTetrahedron" << nl << "position = " << position << nl - << "cellIndex = " << cellIndex << endl; + << "cellI = " << cellI << endl; } - // Initialise closest triangle variables - scalar minUVWClose = VGREAT; - label pointIClose = 0; - label faceClose = 0; + List<tetIndices> cellTets = polyMeshTetDecomposition::cellTetIndices + ( + mesh, + cellI + ); - const vector& P0 = mesh.cellCentres()[cellIndex]; - const labelList& cellFaces = mesh.cells()[cellIndex]; - const scalar cellVolume = mesh.cellVolumes()[cellIndex]; + const faceList& pFaces = mesh.faces(); + const scalar cellVolume = mesh.cellVolumes()[cellI]; - // Find the tet that the point occupies - forAll(cellFaces, faceI) + forAll(cellTets, tetI) { - // Decompose each face into triangles, making a tet when - // augmented by the cell centre - const labelList& facePoints = mesh.faces()[cellFaces[faceI]]; + const tetIndices& tetIs = cellTets[tetI]; + + const face& f = pFaces[tetIs.face()]; + + // Barycentric coordinates of the position + scalar det = tetIs.tet(mesh).barycentric(position, weights_); - label pointI = 1; - while ((pointI + 1) < facePoints.size()) + if (mag(det/cellVolume) > tol) { - // Cartesian co-ordinates of the triangle vertices - const vector& P1 = mesh.points()[facePoints[0]]; - const vector& P2 = mesh.points()[facePoints[pointI]]; - const vector& P3 = mesh.points()[facePoints[pointI + 1]]; + const scalar& u = weights_[0]; + const scalar& v = weights_[1]; + const scalar& w = weights_[2]; + + if + ( + (u + tol > 0) + && (v + tol > 0) + && (w + tol > 0) + && (u + v + w < 1 + tol) + ) + { + faceVertices_[0] = f[tetIs.faceBasePt()]; + faceVertices_[1] = f[tetIs.facePtA()];; + faceVertices_[2] = f[tetIs.facePtB()];; - // Edge vectors - const vector e1 = P1 - P0; - const vector e2 = P2 - P0; - const vector e3 = P3 - P0; + return; + } + } + } - // Solve for interpolation weighting factors + // A suitable point in a tetrahedron was not found, find the + // nearest. - // Source term - const vector rhs = position - P0; + scalar minNearDist = VGREAT; - // Determinant of coefficients matrix - // Note: if det(A) = 0 the tet is degenerate - const scalar detA = - e1.x()*e2.y()*e3.z() + e2.x()*e3.y()*e1.z() - + e3.x()*e1.y()*e2.z() - e1.x()*e3.y()*e2.z() - - e2.x()*e1.y()*e3.z() - e3.x()*e2.y()*e1.z(); + label nearestTetI = -1; - if (mag(detA/cellVolume) > tol) - { - // Solve using Cramers' rule - const scalar u = - ( - rhs.x()*e2.y()*e3.z() + e2.x()*e3.y()*rhs.z() - + e3.x()*rhs.y()*e2.z() - rhs.x()*e3.y()*e2.z() - - e2.x()*rhs.y()*e3.z() - e3.x()*e2.y()*rhs.z() - )/detA; - - const scalar v = - ( - e1.x()*rhs.y()*e3.z() + rhs.x()*e3.y()*e1.z() - + e3.x()*e1.y()*rhs.z() - e1.x()*e3.y()*rhs.z() - - rhs.x()*e1.y()*e3.z() - e3.x()*rhs.y()*e1.z() - )/detA; - - const scalar w = - ( - e1.x()*e2.y()*rhs.z() + e2.x()*rhs.y()*e1.z() - + rhs.x()*e1.y()*e2.z() - e1.x()*rhs.y()*e2.z() - - e2.x()*e1.y()*rhs.z() - rhs.x()*e2.y()*e1.z() - )/detA; - - // Check if point is in tet - // value = 0 indicates position lies on a tet face - if - ( - (u + tol > 0) && (v + tol > 0) && (w + tol > 0) - && (u + v + w < 1 + tol) - ) - { - faceVertices_[0] = facePoints[0]; - faceVertices_[1] = facePoints[pointI]; - faceVertices_[2] = facePoints[pointI + 1]; - - weights_[0] = u; - weights_[1] = v; - weights_[2] = w; - weights_[3] = 1.0 - (u + v + w); - - return; - } - else - { - scalar minU = mag(u); - scalar minV = mag(v); - scalar minW = mag(w); - if (minU > 1.0) - { - minU -= 1.0; - } - if (minV > 1.0) - { - minV -= 1.0; - } - if (minW > 1.0) - { - minW -= 1.0; - } - const scalar minUVW = mag(minU + minV + minW); - - if (minUVW < minUVWClose) - { - minUVWClose = minUVW; - pointIClose = pointI; - faceClose = faceI; - } - } - } + forAll(cellTets, tetI) + { + const tetIndices& tetIs = cellTets[tetI]; + + scalar nearDist = tetIs.tet(mesh).nearestPoint(position).distance(); - pointI++; + if (nearDist < minNearDist) + { + minNearDist = nearDist; + + nearestTetI = tetI; } } if (debug) { Pout<< "cellPointWeight::findTetrahedron" << nl - << " Tetrahedron search failed; using closest tet values to " - << "point " << nl << " cell: " << cellIndex << nl << endl; + << " Tetrahedron search failed; using closest tet to point " + << position << nl + << " cell: " + << cellI << nl + << endl; } - const labelList& facePointsClose = mesh.faces()[cellFaces[faceClose]]; - faceVertices_[0] = facePointsClose[0]; - faceVertices_[1] = facePointsClose[pointIClose]; - faceVertices_[2] = facePointsClose[pointIClose + 1]; - weights_[0] = 0.25; - weights_[1] = 0.25; - weights_[2] = 0.25; - weights_[3] = 0.25; + const tetIndices& tetIs = cellTets[nearestTetI]; + + const face& f = pFaces[tetIs.face()]; + + // Barycentric coordinates of the position, ignoring if the + // determinant is suitable. If not, the return from barycentric + // to weights_ is safe. + tetIs.tet(mesh).barycentric(position, weights_); + + faceVertices_[0] = f[tetIs.faceBasePt()]; + faceVertices_[1] = f[tetIs.facePtA()]; + faceVertices_[2] = f[tetIs.facePtB()]; } @@ -186,119 +142,112 @@ void Foam::cellPointWeight::findTriangle ( const polyMesh& mesh, const vector& position, - const label faceIndex + const label faceI ) { if (debug) { Pout<< "\nbool Foam::cellPointWeight::findTriangle" << nl << "position = " << position << nl - << "faceIndex = " << faceIndex << endl; + << "faceI = " << faceI << endl; } - // Initialise closest triangle variables - scalar minUVClose = VGREAT; - label pointIClose = 0; + List<tetIndices> faceTets = polyMeshTetDecomposition::faceTetIndices + ( + mesh, + mesh.faceOwner()[faceI], + faceI + ); - // Decompose each face into triangles, making a tet when - // augmented by the cell centre - const labelList& facePoints = mesh.faces()[faceIndex]; + const scalar faceAreaSqr = magSqr(mesh.faceAreas()[faceI]); - const scalar faceArea2 = magSqr(mesh.faceAreas()[faceIndex]); + const face& f = mesh.faces()[faceI]; - label pointI = 1; - while ((pointI + 1) < facePoints.size()) + forAll(faceTets, tetI) { - // Cartesian co-ordinates of the triangle vertices - const vector& P1 = mesh.points()[facePoints[0]]; - const vector& P2 = mesh.points()[facePoints[pointI]]; - const vector& P3 = mesh.points()[facePoints[pointI + 1]]; - - // Direction vectors - vector v1 = position - P1; - const vector v2 = P2 - P1; - const vector v3 = P3 - P1; - - // Plane normal - vector n = v2 ^ v3; - n /= mag(n); - - // Remove any offset to plane - v1 -= (n & v1)*v1; - - // Helper variables - const scalar d12 = v1 & v2; - const scalar d13 = v1 & v3; - const scalar d22 = v2 & v2; - const scalar d23 = v2 & v3; - const scalar d33 = v3 & v3; - - // Determinant of coefficients matrix - // Note: if det(A) = 0 the triangle is degenerate - const scalar detA = d22*d33 - d23*d23; - - if (0.25*detA/faceArea2 > tol) - { - // Solve using Cramers' rule - const scalar u = (d12*d33 - d23*d13)/detA; - const scalar v = (d22*d13 - d12*d23)/detA; + const tetIndices& tetIs = faceTets[tetI]; + + List<scalar> triWeights(3); - // Check if point is in triangle - if ((u + tol > 0) && (v + tol > 0) && (u + v < 1 + tol)) + // Barycentric coordinates of the position + scalar det = tetIs.faceTri(mesh).barycentric(position, triWeights); + + if (0.25*mag(det)/faceAreaSqr > tol) + { + const scalar& u = triWeights[0]; + const scalar& v = triWeights[1]; + + if + ( + (u + tol > 0) + && (v + tol > 0) + && (u + v < 1 + tol) + ) { - // Indices of the cell vertices making up the triangle - faceVertices_[0] = facePoints[0]; - faceVertices_[1] = facePoints[pointI]; - faceVertices_[2] = facePoints[pointI + 1]; + // Weight[0] is for the cell centre. + weights_[0] = 0; + weights_[1] = triWeights[0]; + weights_[2] = triWeights[1]; + weights_[3] = triWeights[2]; - weights_[0] = u; - weights_[1] = v; - weights_[2] = 1.0 - (u + v); - weights_[3] = 0.0; + faceVertices_[0] = f[tetIs.faceBasePt()]; + faceVertices_[1] = f[tetIs.facePtA()];; + faceVertices_[2] = f[tetIs.facePtB()];; return; } - else - { - scalar minU = mag(u); - scalar minV = mag(v); - if (minU > 1.0) - { - minU -= 1.0; - } - if (minV > 1.0) - { - minV -= 1.0; - } - const scalar minUV = mag(minU + minV); - - if (minUV < minUVClose) - { - minUVClose = minUV; - pointIClose = pointI; - } - } } + } + + // A suitable point in a triangle was not found, find the nearest. + + scalar minNearDist = VGREAT; + + label nearestTetI = -1; + + forAll(faceTets, tetI) + { + const tetIndices& tetIs = faceTets[tetI]; + + scalar nearDist = tetIs.faceTri(mesh).nearestPoint(position).distance(); - pointI++; + if (nearDist < minNearDist) + { + minNearDist = nearDist; + + nearestTetI = tetI; + } } if (debug) { - Pout<< "Foam::cellPointWeight::findTriangle" - << "Triangle search failed; using closest triangle to point" << nl - << " cell face: " << faceIndex << nl << endl; + Pout<< "cellPointWeight::findTriangle" << nl + << " Triangle search failed; using closest tri to point " + << position << nl + << " face: " + << faceI << nl + << endl; } - // Indices of the cell vertices making up the triangle - faceVertices_[0] = facePoints[0]; - faceVertices_[1] = facePoints[pointIClose]; - faceVertices_[2] = facePoints[pointIClose + 1]; + const tetIndices& tetIs = faceTets[nearestTetI]; + + // Barycentric coordinates of the position, ignoring if the + // determinant is suitable. If not, the return from barycentric + // to triWeights is safe. + + List<scalar> triWeights(3); + + tetIs.faceTri(mesh).barycentric(position, triWeights); + + // Weight[0] is for the cell centre. + weights_[0] = 0; + weights_[1] = triWeights[0]; + weights_[2] = triWeights[1]; + weights_[3] = triWeights[2]; - weights_[0] = 1.0/3.0; - weights_[1] = 1.0/3.0; - weights_[2] = 1.0/3.0; - weights_[3] = 0.0; + faceVertices_[0] = f[tetIs.faceBasePt()]; + faceVertices_[1] = f[tetIs.facePtA()]; + faceVertices_[2] = f[tetIs.facePtB()]; } @@ -308,21 +257,23 @@ Foam::cellPointWeight::cellPointWeight ( const polyMesh& mesh, const vector& position, - const label cellIndex, - const label faceIndex + const label cellI, + const label faceI ) : - cellIndex_(cellIndex) + cellI_(cellI), + weights_(4), + faceVertices_(3) { - if (faceIndex < 0) + if (faceI < 0) { // Face data not supplied - findTetrahedron(mesh, position, cellIndex); + findTetrahedron(mesh, position, cellI); } else { // Face data supplied - findTriangle(mesh, position, faceIndex); + findTriangle(mesh, position, faceI); } } diff --git a/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/cellPointWeight/cellPointWeight.H b/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/cellPointWeight/cellPointWeight.H index bb3647ac309c1463cd6086fe9f6c89abe60676d4..3042b926b1a1a90ab318277430518040f0a8f592 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/cellPointWeight/cellPointWeight.H +++ b/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/cellPointWeight/cellPointWeight.H @@ -55,13 +55,13 @@ protected: // Protected data //- Cell index - const label cellIndex_; + const label cellI_; //- Weights applied to tet vertices - FixedList<scalar, 4> weights_; + List<scalar> weights_; //- Face vertex indices - FixedList<label, 3> faceVertices_; + List<label> faceVertices_; // Protected Member Functions @@ -70,14 +70,14 @@ protected: ( const polyMesh& mesh, const vector& position, - const label cellIndex + const label cellI ); void findTriangle ( const polyMesh& mesh, const vector& position, - const label faceIndex + const label faceI ); @@ -98,8 +98,8 @@ public: ( const polyMesh& mesh, const vector& position, - const label nCell, - const label facei = -1 + const label cellI, + const label faceI = -1 ); @@ -108,17 +108,17 @@ public: //- Cell index inline label cell() const { - return cellIndex_; + return cellI_; } //- interpolation weights - inline const FixedList<scalar, 4>& weights() const + inline const List<scalar>& weights() const { return weights_; } //- interpolation addressing for points on face - inline const FixedList<label, 3>& faceVertices() const + inline const List<label>& faceVertices() const { return faceVertices_; } diff --git a/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/interpolationCellPoint.H b/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/interpolationCellPoint.H index e3424f3c4ce011e4929f5c715b0e0200c9839927..657d8168ac183731ad688bb72d4154fae6860b60 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/interpolationCellPoint.H +++ b/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/interpolationCellPoint.H @@ -25,7 +25,7 @@ Class Foam::interpolationCellPoint Description - Given cell centre values and point (vertex) values decompose into + Given cell centre values and point (vertex) values decompose into tetrahedra and linear interpolate within them. \*---------------------------------------------------------------------------*/ @@ -82,8 +82,17 @@ public: inline Type interpolate ( const vector& position, - const label nCell, - const label facei = -1 + const label cellI, + const label faceI = -1 + ) const; + + //- Interpolate field to the given point in the tetrahedron + // defined by the given indices. + inline Type interpolate + ( + const vector& position, + const tetIndices& tetIs, + const label faceI = -1 ) const; }; diff --git a/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/interpolationCellPointI.H b/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/interpolationCellPointI.H index 16c555224ce8d4b848ca59813ff98ccf112bb71b..35171984cf6bedf49489d5ce39534e280b84e57d 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/interpolationCellPointI.H +++ b/src/finiteVolume/interpolation/interpolation/interpolationCellPoint/interpolationCellPointI.H @@ -31,13 +31,13 @@ inline Type Foam::interpolationCellPoint<Type>::interpolate const cellPointWeight& cpw ) const { - const FixedList<scalar, 4>& weights = cpw.weights(); - const FixedList<label, 3>& faceVertices = cpw.faceVertices(); + const List<scalar>& weights = cpw.weights(); + const List<label>& faceVertices = cpw.faceVertices(); - Type t = psip_[faceVertices[0]]*weights[0]; - t += psip_[faceVertices[1]]*weights[1]; - t += psip_[faceVertices[2]]*weights[2]; - t += this->psi_[cpw.cell()]*weights[3]; + Type t = this->psi_[cpw.cell()]*weights[0]; + t += psip_[faceVertices[0]]*weights[1]; + t += psip_[faceVertices[1]]*weights[2]; + t += psip_[faceVertices[2]]*weights[3]; return t; } @@ -47,11 +47,66 @@ template<class Type> inline Type Foam::interpolationCellPoint<Type>::interpolate ( const vector& position, - const label celli, - const label facei + const label cellI, + const label faceI ) const { - return interpolate(cellPointWeight(this->pMesh_, position, celli, facei)); + return interpolate(cellPointWeight(this->pMesh_, position, cellI, faceI)); +} + + +template<class Type> +inline Type Foam::interpolationCellPoint<Type>::interpolate +( + const vector& position, + const tetIndices& tetIs, + const label faceI +) const +{ + // Assumes that the position is consistent with the supplied + // tetIndices. Does not pay attention to whether or not faceI is + // supplied or not - the result will be essentially the same. + // Performs a consistency check, however. + + if (faceI >= 0) + { + if (faceI != tetIs.face()) + { + FatalErrorIn + ( + "inline Type Foam::interpolationCellPoint<Type>::interpolate" + "(" + "const vector& position, " + "const tetIndices& tetIs, " + "const label faceI" + ") const" + ) + << "specified face " << faceI << " inconsistent with the face " + << "stored by tetIndices: " << tetIs.face() + << exit(FatalError); + } + } + + List<scalar> weights; + + tetIs.tet(this->pMesh_).barycentric(position, weights); + + const faceList& pFaces = this->pMesh_.faces(); + + const face& f = pFaces[tetIs.face()]; + + // Order of weights is the same as that of the vertices of the tet, i.e. + // cellCentre, faceBasePt, facePtA, facePtB. + + Type t = this->psi_[tetIs.cell()]*weights[0]; + + t += psip_[f[tetIs.faceBasePt()]]*weights[1]; + + t += psip_[f[tetIs.facePtA()]]*weights[2]; + + t += psip_[f[tetIs.facePtB()]]*weights[3]; + + return t; } diff --git a/src/finiteVolume/interpolation/interpolation/interpolationCellPointFace/interpolationCellPointFace.C b/src/finiteVolume/interpolation/interpolation/interpolationCellPointFace/interpolationCellPointFace.C index e075cb9014394d8ceea0f644699f099e736aefeb..c583a6555c2eae87a4e3cf2b9daa8cf4d968be9d 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationCellPointFace/interpolationCellPointFace.C +++ b/src/finiteVolume/interpolation/interpolation/interpolationCellPointFace/interpolationCellPointFace.C @@ -56,8 +56,8 @@ template<class Type> Type interpolationCellPointFace<Type>::interpolate ( const vector& position, - const label nCell, - const label facei + const label cellI, + const label faceI ) const { Type ts[4]; @@ -68,10 +68,10 @@ Type interpolationCellPointFace<Type>::interpolate Type t = pTraits<Type>::zero; // only use face information when the position is on a face - if (facei < 0) + if (faceI < 0) { - const vector& cellCentre = this->pMesh_.cellCentres()[nCell]; - const labelList& cellFaces = this->pMesh_.cells()[nCell]; + const vector& cellCentre = this->pMesh_.cellCentres()[cellI]; + const labelList& cellFaces = this->pMesh_.cells()[cellI]; vector projection = position - cellCentre; tetPoints[3] = cellCentre; @@ -85,9 +85,9 @@ Type interpolationCellPointFace<Type>::interpolate label closestFace = -1; scalar minDistance = GREAT; - forAll(cellFaces, facei) + forAll(cellFaces, faceI) { - label nFace = cellFaces[facei]; + label nFace = cellFaces[faceI]; vector normal = this->pMeshFaceAreas_[nFace]; normal /= mag(normal); @@ -160,10 +160,10 @@ Type interpolationCellPointFace<Type>::interpolate { minDistance = GREAT; - label facei = 0; - while (facei < cellFaces.size() && !foundTet) + label faceI = 0; + while (faceI < cellFaces.size() && !foundTet) { - label nFace = cellFaces[facei]; + label nFace = cellFaces[faceI]; if (nFace < this->pMeshFaceAreas_.size()) { foundTet = findTet @@ -179,7 +179,7 @@ Type interpolationCellPointFace<Type>::interpolate minDistance ); } - facei++; + faceI++; } } @@ -217,16 +217,16 @@ Type interpolationCellPointFace<Type>::interpolate } else { - label patchi = + label patchI = this->pMesh_.boundaryMesh().whichPatch(closestFace); // If the boundary patch is not empty use the face value // else use the cell value - if (this->psi_.boundaryField()[patchi].size()) + if (this->psi_.boundaryField()[patchI].size()) { - ts[2] = this->psi_.boundaryField()[patchi] + ts[2] = this->psi_.boundaryField()[patchI] [ - this->pMesh_.boundaryMesh()[patchi].whichFace + this->pMesh_.boundaryMesh()[patchI].whichFace ( closestFace ) @@ -234,11 +234,11 @@ Type interpolationCellPointFace<Type>::interpolate } else { - ts[2] = this->psi_[nCell]; + ts[2] = this->psi_[cellI]; } } - ts[3] = this->psi_[nCell]; + ts[3] = this->psi_[cellI]; for (label n=0; n<4; n++) { @@ -251,9 +251,9 @@ Type interpolationCellPointFace<Type>::interpolate else { Info<< "interpolationCellPointFace<Type>::interpolate" - << "(const vector&, const label nCell) const : " + << "(const vector&, const label cellI) const : " << "search failed; using closest cellFace value" << endl - << "cell number " << nCell << tab + << "cell number " << cellI << tab << "position " << position << endl; if (closestFace < psis_.size()) @@ -262,16 +262,16 @@ Type interpolationCellPointFace<Type>::interpolate } else { - label patchi = + label patchI = this->pMesh_.boundaryMesh().whichPatch(closestFace); // If the boundary patch is not empty use the face value // else use the cell value - if (this->psi_.boundaryField()[patchi].size()) + if (this->psi_.boundaryField()[patchI].size()) { - t = this->psi_.boundaryField()[patchi] + t = this->psi_.boundaryField()[patchI] [ - this->pMesh_.boundaryMesh()[patchi].whichFace + this->pMesh_.boundaryMesh()[patchI].whichFace ( closestFace ) @@ -279,7 +279,7 @@ Type interpolationCellPointFace<Type>::interpolate } else { - t = this->psi_[nCell]; + t = this->psi_[cellI]; } } } @@ -289,7 +289,7 @@ Type interpolationCellPointFace<Type>::interpolate bool foundTriangle = findTriangle ( position, - facei, + faceI, tetPointLabels, phi ); @@ -304,48 +304,48 @@ Type interpolationCellPointFace<Type>::interpolate } // ... and the face value - if (facei < psis_.size()) + if (faceI < psis_.size()) { - t += phi[2]*psis_[facei]; + t += phi[2]*psis_[faceI]; } else { - label patchi = this->pMesh_.boundaryMesh().whichPatch(facei); + label patchI = this->pMesh_.boundaryMesh().whichPatch(faceI); // If the boundary patch is not empty use the face value // else use the cell value - if (this->psi_.boundaryField()[patchi].size()) + if (this->psi_.boundaryField()[patchI].size()) { - t += phi[2]*this->psi_.boundaryField()[patchi] - [this->pMesh_.boundaryMesh()[patchi].whichFace(facei)]; + t += phi[2]*this->psi_.boundaryField()[patchI] + [this->pMesh_.boundaryMesh()[patchI].whichFace(faceI)]; } else { - t += phi[2]*this->psi_[nCell]; + t += phi[2]*this->psi_[cellI]; } } } else { // use face value only - if (facei < psis_.size()) + if (faceI < psis_.size()) { - t = psis_[facei]; + t = psis_[faceI]; } else { - label patchi = this->pMesh_.boundaryMesh().whichPatch(facei); + label patchI = this->pMesh_.boundaryMesh().whichPatch(faceI); // If the boundary patch is not empty use the face value // else use the cell value - if (this->psi_.boundaryField()[patchi].size()) + if (this->psi_.boundaryField()[patchI].size()) { - t = this->psi_.boundaryField()[patchi] - [this->pMesh_.boundaryMesh()[patchi].whichFace(facei)]; + t = this->psi_.boundaryField()[patchI] + [this->pMesh_.boundaryMesh()[patchI].whichFace(faceI)]; } else { - t = this->psi_[nCell]; + t = this->psi_[cellI]; } } } diff --git a/src/finiteVolume/interpolation/interpolation/interpolationCellPointFace/interpolationCellPointFace.H b/src/finiteVolume/interpolation/interpolation/interpolationCellPointFace/interpolationCellPointFace.H index e32b2ad68bb9d9aafc59152f78f1fa360ebc30fb..fb2f9954f81db7943df64bcf7505e4e85d156270 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationCellPointFace/interpolationCellPointFace.H +++ b/src/finiteVolume/interpolation/interpolation/interpolationCellPointFace/interpolationCellPointFace.H @@ -99,8 +99,8 @@ public: Type interpolate ( const vector& position, - const label nCell, - const label facei = -1 + const label cellI, + const label faceI = -1 ) const; }; diff --git a/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/cellPointWeightWallModified/cellPointWeightWallModified.C b/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/cellPointWeightWallModified/cellPointWeightWallModified.C index 5448de2dafe7735ffc806b0aee4d1411d4d76ff2..8716ade026b1c0aa4c5d2ab95374cea5c6de6d7c 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/cellPointWeightWallModified/cellPointWeightWallModified.C +++ b/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/cellPointWeightWallModified/cellPointWeightWallModified.C @@ -24,9 +24,6 @@ License \*---------------------------------------------------------------------------*/ #include "cellPointWeightWallModified.H" -#include "wallPolyPatch.H" -#include "polyMesh.H" -#include "polyBoundaryMesh.H" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -34,36 +31,30 @@ Foam::cellPointWeightWallModified::cellPointWeightWallModified ( const polyMesh& mesh, const vector& position, - const label cellIndex, - const label faceIndex + const label cellI, + const label faceI ) : - cellPointWeight(mesh, position, cellIndex, faceIndex) + cellPointWeight(mesh, position, cellI, faceI) { - if (faceIndex < 0) - { - findTetrahedron(mesh, position, cellIndex); - } - else + // findTetrahedron or findTriangle will already have been called + // by the cellPointWeight constructor + + if (faceI >= 0) { const polyBoundaryMesh& bm = mesh.boundaryMesh(); - label patchI = bm.whichPatch(faceIndex); + label patchI = bm.whichPatch(faceI); if (patchI != -1) { if (isA<wallPolyPatch>(bm[patchI])) { // Apply cell centre value wall faces - weights_[0] = 0.0; + weights_[0] = 1.0; weights_[1] = 0.0; weights_[2] = 0.0; - weights_[3] = 1.0; + weights_[3] = 0.0; } } - else - { - // Interpolate - findTriangle(mesh, position, faceIndex); - } } } diff --git a/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/cellPointWeightWallModified/cellPointWeightWallModified.H b/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/cellPointWeightWallModified/cellPointWeightWallModified.H index db4e35575d80dd30e1eefb24a3866e3aea2a9b24..0e12a145284de052ae9474c9d430d5dbd18eb5f8 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/cellPointWeightWallModified/cellPointWeightWallModified.H +++ b/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/cellPointWeightWallModified/cellPointWeightWallModified.H @@ -36,6 +36,9 @@ SourceFiles #define cellPointWeightWallModified_H #include "cellPointWeight.H" +#include "wallPolyPatch.H" +#include "polyMesh.H" +#include "polyBoundaryMesh.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -61,8 +64,8 @@ public: ( const polyMesh& mesh, const vector& position, - const label nCell, - const label facei = -1 + const label cellI, + const label faceI = -1 ); }; diff --git a/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/interpolationCellPointWallModified.H b/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/interpolationCellPointWallModified.H index d7b35c9a383c6586ce51883e6e8ecd826fc8cfcf..8bef893c58eb7cd814a93ef29f6665605d7ac731 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/interpolationCellPointWallModified.H +++ b/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/interpolationCellPointWallModified.H @@ -74,8 +74,17 @@ public: inline Type interpolate ( const vector& position, - const label nCell, - const label facei = -1 + const label cellI, + const label faceI = -1 + ) const; + + //- Interpolate field to the given point in the tetrahedron + // defined by the given indices. + inline Type interpolate + ( + const vector& position, + const tetIndices& tetIs, + const label faceI = -1 ) const; }; diff --git a/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/interpolationCellPointWallModifiedI.H b/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/interpolationCellPointWallModifiedI.H index d0284f0b0f587350f7f949e6507ead9489e8a5d1..d0ed41eef733a3cc500ec2ed2fcff2806ff75ff9 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/interpolationCellPointWallModifiedI.H +++ b/src/finiteVolume/interpolation/interpolation/interpolationCellPointWallModified/interpolationCellPointWallModifiedI.H @@ -31,13 +31,13 @@ inline Type Foam::interpolationCellPointWallModified<Type>::interpolate const cellPointWeightWallModified& cpw ) const { - const FixedList<scalar, 4>& weights = cpw.weights(); - const FixedList<label, 3>& faceVertices = cpw.faceVertices(); + const List<scalar>& weights = cpw.weights(); + const List<label>& faceVertices = cpw.faceVertices(); - Type t = this->psip_[faceVertices[0]]*weights[0]; - t += this->psip_[faceVertices[1]]*weights[1]; - t += this->psip_[faceVertices[2]]*weights[2]; - t += this->psi_[cpw.cell()]*weights[3]; + Type t = this->psi_[cpw.cell()]*weights[0]; + t += this->psip_[faceVertices[0]]*weights[1]; + t += this->psip_[faceVertices[1]]*weights[2]; + t += this->psip_[faceVertices[2]]*weights[3]; return t; } @@ -47,21 +47,73 @@ template<class Type> inline Type Foam::interpolationCellPointWallModified<Type>::interpolate ( const vector& position, - const label celli, - const label facei + const label cellI, + const label faceI ) const { - return - interpolate + return interpolate + ( + cellPointWeightWallModified ( - cellPointWeightWallModified + this->pMesh_, + position, + cellI, + faceI + ) + ); +} + + +template<class Type> +inline Type Foam::interpolationCellPointWallModified<Type>::interpolate +( + const vector& position, + const tetIndices& tetIs, + const label faceI +) const +{ + if (faceI >= 0) + { + if (faceI != tetIs.face()) + { + FatalErrorIn ( - this->pMesh_, - position, - celli, - facei + "inline Type " + "Foam::interpolationCellPointWallModifie<Type>::interpolate" + "(" + "const vector& position, " + "const tetIndices& tetIs, " + "const label faceI" + ") const" ) - ); + << "specified face " << faceI << " inconsistent with the face " + << "stored by tetIndices: " << tetIs.face() + << exit(FatalError); + } + + const polyBoundaryMesh& bm = this->pMesh_.boundaryMesh(); + label patchI = bm.whichPatch(faceI); + + if (patchI != -1) + { + if (isA<wallPolyPatch>(bm[patchI])) + { + Type t = this->psi_[tetIs.cell()]; + + return t; + } + } + } + + // If the wall face selection did not return, then use the normal + // interpolate method + + return interpolationCellPoint<Type>::interpolate + ( + position, + tetIs, + faceI + ); } diff --git a/src/finiteVolume/interpolation/interpolation/interpolationPoint/interpolationPoint.H b/src/finiteVolume/interpolation/interpolation/interpolationPoint/interpolationPoint.H index a3dc106eb0295b42d5761d4f60ec8871c23c69aa..46f102187fcb8305257b610732a50adcfe417bfc 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationPoint/interpolationPoint.H +++ b/src/finiteVolume/interpolation/interpolation/interpolationPoint/interpolationPoint.H @@ -81,8 +81,8 @@ public: inline Type interpolate ( const vector& position, - const label nCell, - const label facei = -1 + const label cellI, + const label faceI = -1 ) const; }; diff --git a/src/finiteVolume/interpolation/interpolation/interpolationPoint/interpolationPointI.H b/src/finiteVolume/interpolation/interpolation/interpolationPoint/interpolationPointI.H index e297e569fcaa35cc98e34dc306cd297f36a8ae2e..624bb9f5627aa632daadc2940604cc0a1739ab88 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationPoint/interpolationPointI.H +++ b/src/finiteVolume/interpolation/interpolation/interpolationPoint/interpolationPointI.H @@ -39,13 +39,13 @@ template<class Type> inline Type Foam::interpolationPoint<Type>::interpolate ( const vector& position, - const label celli, - const label facei + const label cellI, + const label faceI ) const { return interpolate ( - pointMVCWeight(this->pMesh_, position, celli, facei) + pointMVCWeight(this->pMesh_, position, cellI, faceI) ); } diff --git a/src/finiteVolume/interpolation/interpolation/interpolationPoint/pointMVCWeight.H b/src/finiteVolume/interpolation/interpolation/interpolationPoint/pointMVCWeight.H index a1cfd4507b01da4818ebd92602f2ca93cfd017bd..9cd2bec95b33d26427cf9325fa83fe266c98353c 100644 --- a/src/finiteVolume/interpolation/interpolation/interpolationPoint/pointMVCWeight.H +++ b/src/finiteVolume/interpolation/interpolation/interpolationPoint/pointMVCWeight.H @@ -119,8 +119,8 @@ public: ( const polyMesh& mesh, const vector& position, - const label nCell, - const label facei = -1 + const label cellI, + const label faceI = -1 ); diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/localBlended/localBlended.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/localBlended/localBlended.H index 1c6500e54c961e115024b83e44f808343923523d..9be5eaf087c1c531d2944e1ac40dd18c99c89a05 100644 --- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/localBlended/localBlended.H +++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/localBlended/localBlended.H @@ -153,6 +153,67 @@ public: blendingFactor*tScheme1_().interpolate(vf) + (scalar(1) - blendingFactor)*tScheme2_().interpolate(vf); } + + + //- Return true if this scheme uses an explicit correction + virtual bool corrected() const + { + return tScheme1_().corrected() || tScheme2_().corrected(); + } + + + //- Return the explicit correction to the face-interpolate + // for the given field + virtual tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > + correction + ( + const GeometricField<Type, fvPatchField, volMesh>& vf + ) const + { + const surfaceScalarField& blendingFactor = + this->mesh().objectRegistry:: + lookupObject<const surfaceScalarField> + ( + word(vf.name() + "BlendingFactor") + ); + + if (tScheme1_().corrected()) + { + if (tScheme2_().corrected()) + { + return + ( + blendingFactor + * tScheme1_().correction(vf) + + (scalar(1.0) - blendingFactor) + * tScheme2_().correction(vf) + ); + } + else + { + return + ( + blendingFactor + * tScheme1_().correction(vf) + ); + } + } + else if (tScheme2_().corrected()) + { + return + ( + (scalar(1.0) - blendingFactor) + * tScheme2_().correction(vf) + ); + } + else + { + return tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > + ( + NULL + ); + } + } }; diff --git a/src/lagrangian/basic/Cloud/Cloud.C b/src/lagrangian/basic/Cloud/Cloud.C index 8f817df7fb12a83fb4442887fc1cc168494c4799..2b39e286f26b5fd1c2b16ef435eba39c311bbf69 100644 --- a/src/lagrangian/basic/Cloud/Cloud.C +++ b/src/lagrangian/basic/Cloud/Cloud.C @@ -30,6 +30,41 @@ License #include "mapPolyMesh.H" #include "Time.H" #include "OFstream.H" +#include "wallPolyPatch.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +template<class ParticleType> +const Foam::scalar Foam::Cloud<ParticleType>::trackingCorrectionTol = 1e-5; + + +// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // + +template<class ParticleType> +void Foam::Cloud<ParticleType>::calcCellWallFaces() const +{ + cellWallFacesPtr_.reset(new PackedBoolList(pMesh().nCells(), false)); + + PackedBoolList& cellWallFaces = cellWallFacesPtr_(); + + const polyBoundaryMesh& patches = pMesh().boundaryMesh(); + + forAll(patches, patchI) + { + if (isA<wallPolyPatch>(patches[patchI])) + { + const polyPatch& patch = patches[patchI]; + + const labelList& pFaceCells = patch.faceCells(); + + forAll(pFaceCells, pFCI) + { + cellWallFaces[pFaceCells[pFCI]] = true; + } + } + } +} + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -43,7 +78,11 @@ Foam::Cloud<ParticleType>::Cloud cloud(pMesh), IDLList<ParticleType>(), polyMesh_(pMesh), - particleCount_(0) + particleCount_(0), + labels_(), + cellTree_(), + nTrackingRescues_(), + cellWallFacesPtr_() { IDLList<ParticleType>::operator=(particles); } @@ -60,7 +99,11 @@ Foam::Cloud<ParticleType>::Cloud cloud(pMesh, cloudName), IDLList<ParticleType>(), polyMesh_(pMesh), - particleCount_(0) + particleCount_(0), + labels_(), + cellTree_(), + nTrackingRescues_(), + cellWallFacesPtr_() { IDLList<ParticleType>::operator=(particles); } @@ -68,6 +111,250 @@ Foam::Cloud<ParticleType>::Cloud // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template<class ParticleType> +void Foam::Cloud<ParticleType>::findCellFacePt +( + const point& pt, + label& cellI, + label& tetFaceI, + label& tetPtI +) const +{ + cellI = -1; + tetFaceI = -1; + tetPtI = -1; + + const indexedOctree<treeDataCell>& tree = cellTree(); + + // Find nearest cell to the point + + pointIndexHit info = tree.findNearest(pt, sqr(GREAT)); + + if (info.hit()) + { + label nearestCellI = tree.shapes().cellLabels()[info.index()]; + + // Check the nearest cell to see if the point is inside. + findFacePt(nearestCellI, pt, tetFaceI, tetPtI); + + if (tetFaceI != -1) + { + // Point was in the nearest cell + + cellI = nearestCellI; + + return; + } + else + { + // Check the other possible cells that the point may be in + + labelList testCells = tree.findIndices(pt); + + forAll(testCells, pCI) + { + label testCellI = tree.shapes().cellLabels()[testCells[pCI]]; + + if (testCellI == nearestCellI) + { + // Don't retest the nearest cell + + continue; + } + + // Check the test cell to see if the point is inside. + findFacePt(testCellI, pt, tetFaceI, tetPtI); + + if (tetFaceI != -1) + { + // Point was in the test cell + + cellI = testCellI; + + return; + } + } + } + } + else + { + FatalErrorIn + ( + "void Foam::Cloud<ParticleType>::findCellFacePt" + "(" + "const point& pt, " + "label& cellI, " + "label& tetFaceI, " + "label& tetPtI" + ") const" + ) << "Did not find nearest cell in search tree." + << abort(FatalError); + } +} + + +template<class ParticleType> +void Foam::Cloud<ParticleType>::findFacePt +( + label cellI, + const point& pt, + label& tetFaceI, + label& tetPtI +) const +{ + tetFaceI = -1; + tetPtI = -1; + + List<tetIndices> cellTets = polyMeshTetDecomposition::cellTetIndices + ( + polyMesh_, + cellI + ); + + forAll(cellTets, tetI) + { + const tetIndices& cellTetIs = cellTets[tetI]; + + if (inTet(pt, cellTetIs.tet(polyMesh_))) + { + tetFaceI = cellTetIs.face(); + tetPtI = cellTetIs.tetPt(); + + return; + } + } +} + + +template<class ParticleType> +bool Foam::Cloud<ParticleType>::inTet +( + const point& pt, + const tetPointRef& tet +) const +{ + // For robustness, assuming that the point is in the tet unless + // "definitively" shown otherwise by obtaining a positive dot + // product greater than a tolerance of SMALL. + + // The tet is defined: tet(Cc, tetBasePt, pA, pB) where the normal + // vectors and base points for the half-space planes are: + // area[0] = tet.Sa(); + // area[1] = tet.Sb(); + // area[2] = tet.Sc(); + // area[3] = tet.Sd(); + // planeBase[0] = tetBasePt = tet.b() + // planeBase[1] = ptA = tet.c() + // planeBase[2] = tetBasePt = tet.b() + // planeBase[3] = tetBasePt = tet.b() + + vector n = vector::zero; + + { + // 0, a + const point& basePt = tet.b(); + + n = tet.Sa(); + n /= (mag(n) + VSMALL); + + if (((pt - basePt) & n) > SMALL) + { + return false; + } + } + + { + // 1, b + const point& basePt = tet.c(); + + n = tet.Sb(); + n /= (mag(n) + VSMALL); + + if (((pt - basePt) & n) > SMALL) + { + return false; + } + } + + { + // 2, c + const point& basePt = tet.b(); + + n = tet.Sc(); + n /= (mag(n) + VSMALL); + + if (((pt - basePt) & n) > SMALL) + { + return false; + } + } + + { + // 3, d + const point& basePt = tet.b(); + + n = tet.Sd(); + n /= (mag(n) + VSMALL); + + if (((pt - basePt) & n) > SMALL) + { + return false; + } + } + + return true; +} + + +template<class ParticleType> +const Foam::indexedOctree<Foam::treeDataCell>& +Foam::Cloud<ParticleType>::cellTree() const +{ + if (cellTree_.empty()) + { + treeBoundBox overallBb(polyMesh_.points()); + + Random rndGen(261782); + + overallBb = overallBb.extend(rndGen, 1E-4); + overallBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + overallBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + + cellTree_.reset + ( + new indexedOctree<treeDataCell> + ( + treeDataCell + ( + false, // not cache bb + polyMesh_ + ), + overallBb, + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity + ) + ); + } + + return cellTree_(); +} + + +template<class ParticleType> +const Foam::PackedBoolList& Foam::Cloud<ParticleType>::cellHasWallFaces() +const +{ + if (!cellWallFacesPtr_.valid()) + { + calcCellWallFaces(); + } + + return cellWallFacesPtr_(); +} + + + template<class ParticleType> Foam::label Foam::Cloud<ParticleType>::getNewParticleID() const { @@ -131,6 +418,9 @@ void Foam::Cloud<ParticleType>::move(TrackingData& td) pIter().stepFraction() = 0; } + // Reset nTrackingRescues + nTrackingRescues_ = 0; + // While there are particles to transfer while (true) { @@ -162,29 +452,29 @@ void Foam::Cloud<ParticleType>::move(TrackingData& td) { // If we are running in parallel and the particle is on a // boundary face - if (Pstream::parRun() && p.facei_ >= pMesh().nInternalFaces()) + if (Pstream::parRun() && p.faceI_ >= pMesh().nInternalFaces()) { - label patchi = pbm.whichPatch(p.facei_); + label patchI = pbm.whichPatch(p.faceI_); // ... and the face is on a processor patch // prepare it for transfer - if (procPatchIndices[patchi] != -1) + if (procPatchIndices[patchI] != -1) { label n = neighbourProcIndices [ refCast<const processorPolyPatch> ( - pbm[patchi] + pbm[patchI] ).neighbProcNo() ]; - p.prepareForParallelTransfer(patchi, td); + p.prepareForParallelTransfer(patchI, td); particleTransferLists[n].append(this->remove(&p)); patchIndexTransferLists[n].append ( - procPatchNeighbours[patchi] + procPatchNeighbours[patchI] ); } } @@ -270,15 +560,22 @@ void Foam::Cloud<ParticleType>::move(TrackingData& td) { ParticleType& newp = newpIter(); - label patchi = procPatches[receivePatchIndex[pI++]]; + label patchI = procPatches[receivePatchIndex[pI++]]; - newp.correctAfterParallelTransfer(patchi, td); + newp.correctAfterParallelTransfer(patchI, td); addParticle(newParticles.remove(&newp)); } } } } + + reduce(nTrackingRescues_, sumOp<label>()); + + if (nTrackingRescues_ > 0) + { + Info<< nTrackingRescues_ << " tracking rescue corrections" << endl; + } } @@ -294,24 +591,30 @@ void Foam::Cloud<ParticleType>::autoMap(const mapPolyMesh& mapper) const labelList& reverseCellMap = mapper.reverseCellMap(); const labelList& reverseFaceMap = mapper.reverseFaceMap(); + // Reset stored data that relies on the mesh + cellTree_.clear(); + cellWallFacesPtr_.clear(); + forAllIter(typename Cloud<ParticleType>, *this, pIter) { - if (reverseCellMap[pIter().celli_] >= 0) + if (reverseCellMap[pIter().cellI_] >= 0) { - pIter().celli_ = reverseCellMap[pIter().celli_]; + pIter().cellI_ = reverseCellMap[pIter().cellI_]; - if (pIter().facei_ >= 0 && reverseFaceMap[pIter().facei_] >= 0) + if (pIter().faceI_ >= 0 && reverseFaceMap[pIter().faceI_] >= 0) { - pIter().facei_ = reverseFaceMap[pIter().facei_]; + pIter().faceI_ = reverseFaceMap[pIter().faceI_]; } else { - pIter().facei_ = -1; + pIter().faceI_ = -1; } + + pIter().initCellFacePt(); } else { - label trackStartCell = mapper.mergedCell(pIter().celli_); + label trackStartCell = mapper.mergedCell(pIter().cellI_); if (trackStartCell < 0) { @@ -319,9 +622,14 @@ void Foam::Cloud<ParticleType>::autoMap(const mapPolyMesh& mapper) } vector p = pIter().position(); + const_cast<vector&>(pIter().position()) = polyMesh_.cellCentres()[trackStartCell]; + pIter().stepFraction() = 0; + + pIter().initCellFacePt(); + pIter().track(p); } } diff --git a/src/lagrangian/basic/Cloud/Cloud.H b/src/lagrangian/basic/Cloud/Cloud.H index 25cf3fce33daac6f353f653f4c53dc86dc6a72b8..0c9b32ebac5b02638b1589c5f99917a614ab3b41 100644 --- a/src/lagrangian/basic/Cloud/Cloud.H +++ b/src/lagrangian/basic/Cloud/Cloud.H @@ -40,6 +40,11 @@ SourceFiles #include "IOField.H" #include "IOFieldField.H" #include "polyMesh.H" +#include "indexedOctree.H" +#include "treeDataCell.H" +#include "tetPointRef.H" +#include "polyMeshTetDecomposition.H" +#include "PackedBoolList.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -78,15 +83,28 @@ class Cloud //- Overall count of particles ever created. Never decreases. mutable label particleCount_; - //- Temporary storage for addressing. Used in findFaces. + //- Temporary storage for addressing. Used in findTris. mutable DynamicList<label> labels_; + //- Search tree to allow spatial tet searching + mutable autoPtr<indexedOctree<treeDataCell> > cellTree_; + + //- Count of how many tracking rescue corrections have been + // applied + mutable label nTrackingRescues_; + + //- Does the cell have wall faces + mutable autoPtr<PackedBoolList> cellWallFacesPtr_; + // Private Member Functions //- Initialise cloud on IO constructor void initCloud(const bool checkClass); + //- Find all cells which have wall faces + void calcCellWallFaces() const; + //- Read cloud properties dictionary void readCloudUniformProperties(); @@ -115,6 +133,10 @@ public: //- Name of cloud properties dictionary static word cloudPropertiesName; + //- Fraction of distance to tet centre to move a particle to + // 'rescue' it from a tracking problem + static const scalar trackingCorrectionTol; + // Constructors @@ -163,27 +185,27 @@ public: } //- Is this global face an internal face? - bool internalFace(const label facei) const + bool internalFace(const label faceI) const { - return polyMesh_.isInternalFace(facei); + return polyMesh_.isInternalFace(faceI); } //- Is this global face a boundary face? - bool boundaryFace(const label facei) const + bool boundaryFace(const label faceI) const { - return !internalFace(facei); + return !internalFace(faceI); } //- Which patch is this global face on - label facePatch(const label facei) const + label facePatch(const label faceI) const { - return polyMesh_.boundaryMesh().whichPatch(facei); + return polyMesh_.boundaryMesh().whichPatch(faceI); } //- Which face of this patch is this global face - label patchFace(const label patchi, const label facei) const + label patchFace(const label patchI, const label faceI) const { - return polyMesh_.boundaryMesh()[patchi].whichFace(facei); + return polyMesh_.boundaryMesh()[patchI].whichFace(faceI); } label size() const @@ -191,6 +213,61 @@ public: return IDLList<ParticleType>::size(); }; + //- Find the cell, tetFaceI and tetPtI for the given + // position + void findCellFacePt + ( + const point& pt, + label& cellI, + label& tetFaceI, + label& tetPtI + ) const; + + //- Find the tetFaceI and tetPtI for the given position in + // the supplied cell, tetFaceI and tetPtI = -1 if not + // found + void findFacePt + ( + label cellI, + const point& pt, + label& tetFaceI, + label& tetPtI + ) const; + + //- Test if the given position is inside the give tet + bool inTet + ( + const point& pt, + const tetPointRef& tet + ) const; + + //- Build (if necessary) and return the cell search tree + const indexedOctree<treeDataCell>& cellTree() const; + + //- Return nTrackingRescues + label nTrackingRescues() const + { + return nTrackingRescues_; + } + + //- Increment the nTrackingRescues counter + void trackingRescue() const + { + nTrackingRescues_++; + } + + //- Whether each cell has any wall faces (demand driven data) + const PackedBoolList& cellHasWallFaces() const; + + //- Switch to specify if particles of the cloud can return + // non-zero wall distance values. By default, assume + // that they can't (default for wallImpactDistance in + // Particle is 0.0). + virtual bool hasWallImpactDistance() const + { + return false; + } + // Iterators diff --git a/src/lagrangian/basic/Cloud/CloudIO.C b/src/lagrangian/basic/Cloud/CloudIO.C index 388fba1c5747f63437260c73d55ca220882cdfeb..c12d12d6a517cdaf807eefd7edf148337731f893 100644 --- a/src/lagrangian/basic/Cloud/CloudIO.C +++ b/src/lagrangian/basic/Cloud/CloudIO.C @@ -126,6 +126,13 @@ void Foam::Cloud<ParticleType>::initCloud(const bool checkClass) << " " << ioP.path() << nl << " assuming the initial cloud contains 0 particles." << endl; } + + forAllIter(typename Cloud<ParticleType>, *this, pIter) + { + ParticleType& p = pIter(); + + p.initCellFacePt(); + } } @@ -140,7 +147,11 @@ Foam::Cloud<ParticleType>::Cloud : cloud(pMesh), polyMesh_(pMesh), - particleCount_(0) + particleCount_(0), + labels_(), + cellTree_(), + nTrackingRescues_(), + cellWallFacesPtr_() { initCloud(checkClass); } @@ -156,7 +167,11 @@ Foam::Cloud<ParticleType>::Cloud : cloud(pMesh, cloudName), polyMesh_(pMesh), - particleCount_(0) + particleCount_(0), + labels_(), + cellTree_(), + nTrackingRescues_(), + cellWallFacesPtr_() { initCloud(checkClass); } diff --git a/src/lagrangian/basic/Make/options b/src/lagrangian/basic/Make/options index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4b2f0a059fbac055ee17d31b510b95445907d34c 100644 --- a/src/lagrangian/basic/Make/options +++ b/src/lagrangian/basic/Make/options @@ -0,0 +1,5 @@ +EXE_INC = \ + -I$(LIB_SRC)/meshTools/lnInclude + +LIB_LIBS = \ + -lmeshTools diff --git a/src/lagrangian/basic/Particle/Particle.C b/src/lagrangian/basic/Particle/Particle.C index 99c00f07e5535a521b4e4030b0cadb79b1201348..704c9ebc1a9b32ab8fc6ab9660c2e478e019d075 100644 --- a/src/lagrangian/basic/Particle/Particle.C +++ b/src/lagrangian/basic/Particle/Particle.C @@ -29,73 +29,20 @@ License #include "symmetryPolyPatch.H" #include "cyclicPolyPatch.H" #include "processorPolyPatch.H" -#include "wallPolyPatch.H" #include "transform.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -template<class ParticleType> -void Foam::Particle<ParticleType>::findFaces -( - const vector& position, - DynamicList<label>& faceList -) const -{ - const polyMesh& mesh = cloud_.polyMesh_; - const labelList& faces = mesh.cells()[celli_]; - const vector& C = mesh.cellCentres()[celli_]; - - faceList.clear(); - forAll(faces, i) - { - label facei = faces[i]; - scalar lam = lambda(C, position, facei); - - if ((lam > 0) && (lam < 1.0)) - { - faceList.append(facei); - } - } -} - - -template<class ParticleType> -void Foam::Particle<ParticleType>::findFaces -( - const vector& position, - const label celli, - const scalar stepFraction, - DynamicList<label>& faceList -) const -{ - const polyMesh& mesh = cloud_.pMesh(); - const labelList& faces = mesh.cells()[celli]; - const vector& C = mesh.cellCentres()[celli]; - - faceList.clear(); - forAll(faces, i) - { - label facei = faces[i]; - scalar lam = lambda(C, position, facei, stepFraction); - - if ((lam > 0) && (lam < 1.0)) - { - faceList.append(facei); - } - } -} - - template<class ParticleType> template<class TrackData> void Foam::Particle<ParticleType>::prepareForParallelTransfer ( - const label patchi, + const label patchI, TrackData& td ) { // Convert the face index to be local to the processor patch - facei_ = patchFace(patchi, facei_); + faceI_ = patchFace(patchI, faceI_); } @@ -103,15 +50,15 @@ template<class ParticleType> template<class TrackData> void Foam::Particle<ParticleType>::correctAfterParallelTransfer ( - const label patchi, + const label patchI, TrackData& td ) { const processorPolyPatch& ppp = refCast<const processorPolyPatch> - (cloud_.pMesh().boundaryMesh()[patchi]); + (cloud_.pMesh().boundaryMesh()[patchI]); - celli_ = ppp.faceCells()[facei_]; + cellI_ = ppp.faceCells()[faceI_]; if (!ppp.parallel()) { @@ -123,7 +70,7 @@ void Foam::Particle<ParticleType>::correctAfterParallelTransfer } else { - const tensor& T = ppp.forwardT()[facei_]; + const tensor& T = ppp.forwardT()[faceI_]; transformPosition(T); static_cast<ParticleType&>(*this).transformProperties(T); } @@ -140,23 +87,48 @@ void Foam::Particle<ParticleType>::correctAfterParallelTransfer } else { - position_ -= ppp.separation()[facei_]; + position_ -= ppp.separation()[faceI_]; static_cast<ParticleType&>(*this).transformProperties ( - -ppp.separation()[facei_] + -ppp.separation()[faceI_] ); } } + tetFaceI_ = faceI_ + ppp.start(); + + // Faces either side of a coupled patch have matched base indices, + // tetPtI is specified relative to the base point, already and + // opposite circulation directions by design, so if the vertices + // are: + // source: + // face (a b c d e f) + // fPtI 0 1 2 3 4 5 + // + + // destination: + // face (a f e d c b) + // fPtI 0 1 2 3 4 5 + // + + // where a is the base point of the face are matching , and we + // have fPtI = 1 on the source processor face, i.e. vertex b, then + // this because of the face circulation direction change, vertex c + // is the characterising point on the destination processor face, + // giving the destination fPtI as: + // fPtI_d = f.size() - 1 - fPtI_s = 6 - 1 - 1 = 4 + // This relationship can be verified for other points and sizes of + // face. + + tetPtI_ = cloud_.polyMesh_.faces()[tetFaceI_].size() - 1 - tetPtI_; + // Reset the face index for the next tracking operation if (stepFraction_ > (1.0 - SMALL)) { stepFraction_ = 1.0; - facei_ = -1; + faceI_ = -1; } else { - facei_ += ppp.start(); + faceI_ += ppp.start(); } } @@ -168,27 +140,59 @@ Foam::Particle<ParticleType>::Particle ( const Cloud<ParticleType>& cloud, const vector& position, - const label celli + const label cellI, + const label tetFaceI, + const label tetPtI ) : cloud_(cloud), position_(position), - celli_(celli), - facei_(-1), + cellI_(cellI), + faceI_(-1), stepFraction_(0.0), + tetFaceI_(tetFaceI), + tetPtI_(tetPtI), origProc_(Pstream::myProcNo()), origId_(cloud_.getNewParticleID()) {} +template<class ParticleType> +Foam::Particle<ParticleType>::Particle +( + const Cloud<ParticleType>& cloud, + const vector& position, + const label cellI, + bool doCellFacePt +) +: + cloud_(cloud), + position_(position), + cellI_(cellI), + faceI_(-1), + stepFraction_(0.0), + tetFaceI_(-1), + tetPtI_(-1), + origProc_(Pstream::myProcNo()), + origId_(cloud_.getNewParticleID()) +{ + if (doCellFacePt) + { + initCellFacePt(); + } +} + + template<class ParticleType> Foam::Particle<ParticleType>::Particle(const Particle<ParticleType>& p) : cloud_(p.cloud_), position_(p.position_), - celli_(p.celli_), - facei_(p.facei_), + cellI_(p.cellI_), + faceI_(p.faceI_), stepFraction_(p.stepFraction_), + tetFaceI_(p.tetFaceI_), + tetPtI_(p.tetPtI_), origProc_(p.origProc_), origId_(p.origId_) {} @@ -204,7 +208,7 @@ Foam::label Foam::Particle<ParticleType>::track TrackData& td ) { - facei_ = -1; + faceI_ = -1; // Tracks to endPosition or stop on boundary while (!onBoundary() && stepFraction_ < 1.0 - SMALL) @@ -212,7 +216,7 @@ Foam::label Foam::Particle<ParticleType>::track stepFraction_ += trackToFace(endPosition, td)*(1.0 - stepFraction_); } - return facei_; + return faceI_; } @@ -224,6 +228,7 @@ Foam::label Foam::Particle<ParticleType>::track(const vector& endPosition) return track(endPosition, dummyTd); } + template<class ParticleType> template<class TrackData> Foam::scalar Foam::Particle<ParticleType>::trackToFace @@ -234,175 +239,414 @@ Foam::scalar Foam::Particle<ParticleType>::trackToFace { const polyMesh& mesh = cloud_.polyMesh_; - DynamicList<label>& faces = cloud_.labels_; - findFaces(endPosition, faces); + const faceList& pFaces = mesh.faces(); + const pointField& pPts = mesh.points(); + const vectorField& pC = mesh.cellCentres(); + + faceI_ = -1; - facei_ = -1; scalar trackFraction = 0.0; - if (faces.empty()) // inside cell - { - trackFraction = 1.0; - position_ = endPosition; - } - else // hit face + // Minimum tetrahedron decomposition of each cell of the mesh into + // using the cell centre, base point on face, and further two + // points on the face. For each face of n points, there are n - 2 + // tets generated. + + // The points for each tet are organised to match those used in the + // tetrahedron class, supplying them in the order: + // Cc, basePt, pA, pB + // where: + // + Cc is the cell centre; + // + basePt is the base point on the face; + // + pA and pB are the remaining points on the face, such that + // the circulation, {basePt, pA, pB} produces a positive + // normal by the right-hand rule. pA and pB are chosen from + // tetPtI_ do accomplish this depending if the cell owns the + // face, tetPtI_ is the vertex that characterises the tet, and + // is the first vertex on the tet when circulating around the + // face. Therefore, the same tetPtI represents the same face + // triangle for both the owner and neighbour cell. + // + // Each tet has its four triangles represented in the same order: + // 0) tri joining a tet to the tet across the face in next cell. + // This is the triangle opposite Cc. + // 1) tri joining a tet to the tet that is in the same cell, but + // belongs to the face that shares the edge of the current face + // that doesn't contain basePt. This is the triangle opposite + // basePt. + + // 2) tri joining a tet to the tet that is in the same cell, but + // belongs to the face that shares the tet-edge (basePt - pB). + // This may be on the same face, or a different one. This is + // the triangle opposite basePt. This is the triangle opposite + // pA. + + // 4) tri joining a tet to the tet that is in the same cell, but + // belongs to the face that shares the tet-edge (basePt - pA). + // This may be on the same face, or a different one. This is + // the triangle opposite basePt. This is the triangle opposite + // pA. + + // Which tri (0..3) of the tet has been crossed + label triI = -1; + + // Determine which face was actually crossed. lambdaMin < SMALL + // is considered a trigger for a tracking correction towards the + // current tet centre. + scalar lambdaMin = VGREAT; + + DynamicList<label>& tris = cloud_.labels_; + + // Tet indices that will be set by hitWallFaces if a wall face is + // to be hit, or are set when any wall tri of a tet is hit. + // Carries the description of the tet on which the cell face has + // been hit. For the case of being set in hitWallFaces, this may + // be a different tet to the one that the particle occupies. + tetIndices faceHitTetIs; + + do { - scalar lambdaMin = GREAT; + if (triI != -1) + { + // Change tet ownership because a tri face has been crossed + tetNeighbour(triI); + } + + const Foam::face& f = pFaces[tetFaceI_]; + + bool own = (mesh.faceOwner()[tetFaceI_] == cellI_); + + label tetBasePtI = mesh.tetBasePtIs()[tetFaceI_]; - if (faces.size() == 1) + label basePtI = f[tetBasePtI]; + + label facePtI = (tetPtI_ + tetBasePtI) % f.size(); + label otherFacePtI = f.fcIndex(facePtI); + + label fPtAI = -1; + label fPtBI = -1; + + if (own) { - lambdaMin = lambda(position_, endPosition, faces[0], stepFraction_); - facei_ = faces[0]; + fPtAI = facePtI; + fPtBI = otherFacePtI; } else { - // If the particle has to cross more than one cell to reach the - // endPosition, we check which way to go. - // If one of the faces is a boundary face and the particle is - // outside, we choose the boundary face. - // The particle is outside if one of the lambda's is > 1 or < 0 - forAll(faces, i) + fPtAI = otherFacePtI; + fPtBI = facePtI; + } + + tetPointRef tet + ( + pC[cellI_], + pPts[basePtI], + pPts[f[fPtAI]], + pPts[f[fPtBI]] + ); + + if (lambdaMin < SMALL) + { + // Apply tracking correction towards tet centre + + position_ += + Cloud<ParticleType>::trackingCorrectionTol + *(tet.centre() - position_); + + cloud_.trackingRescue(); + + return trackFraction; + } + + if (triI != -1 && mesh.moving()) + { + // Mesh motion requires stepFraction to be correct for + // each tracking portion, so trackToFace must return after + // every lambda calculation. + return trackFraction; + } + + FixedList<vector, 4> tetAreas; + + tetAreas[0] = tet.Sa(); + tetAreas[1] = tet.Sb(); + tetAreas[2] = tet.Sc(); + tetAreas[3] = tet.Sd(); + + FixedList<label, 4> tetPlaneBasePtIs; + + tetPlaneBasePtIs[0] = basePtI; + tetPlaneBasePtIs[1] = f[fPtAI]; + tetPlaneBasePtIs[2] = basePtI; + tetPlaneBasePtIs[3] = basePtI; + + findTris(endPosition, tris, tet, tetAreas, tetPlaneBasePtIs); + + // Reset variables for new track + triI = -1; + lambdaMin = VGREAT; + + // Sets a value for lambdaMin and faceI_ if a wall face is hit + // by the track. + hitWallFaces(position_, endPosition, lambdaMin, faceHitTetIs); + + // Did not hit any tet tri faces, and no wall face has been + // found to hit. + if (tris.empty() && faceI_ < 0) + { + position_ = endPosition; + + return 1.0; + } + else + { + // Loop over all found tris and see if any of them find a + // lambda value smaller than that found for a wall face. + forAll(tris, i) { - scalar lam = - lambda(position_, endPosition, faces[i], stepFraction_); + label tI = tris[i]; + + scalar lam = tetLambda + ( + position_, + endPosition, + triI, + tetAreas[tI], + tetPlaneBasePtIs[tI], + cellI_, + tetFaceI_, + tetPtI_ + ); if (lam < lambdaMin) { lambdaMin = lam; - facei_ = faces[i]; + + triI = tI; } } } - bool internalFace = cloud_.internalFace(facei_); + if (triI == 0) + { + // This must be a cell face crossing + faceI_ = tetFaceI_; - // For warped faces the particle can be 'outside' the cell. - // This will yield a lambda larger than 1, or smaller than 0 - // For values < 0, the particle travels away from the cell - // and we don't move the particle, only change cell. - // For values larger than 1, we move the particle to endPosition only. - if (lambdaMin > 0.0) + // Set the faceHitTetIs to those for the current tet in case a + // wall interaction is required with the cell face + faceHitTetIs = tetIndices + ( + cellI_, + tetFaceI_, + tetBasePtI, + fPtAI, + fPtBI, + tetPtI_ + ); + } + else if (triI > 0) + { + // A tri was found to be crossed before a wall face was hit (if any) + faceI_ = -1; + } + + // The particle can be 'outside' the tet. This will yield a + // lambda larger than 1, or smaller than 0. For values < 0, + // the particle travels away from the tet and we don't move + // the particle, only change tet/cell. For values larger than + // 1, we move the particle to endPosition before the tet/cell + // change. + if (lambdaMin > SMALL) { if (lambdaMin <= 1.0) { - trackFraction = lambdaMin; - position_ += trackFraction*(endPosition - position_); + trackFraction += lambdaMin*(1 - trackFraction); + + position_ += lambdaMin*(endPosition - position_); } else { trackFraction = 1.0; + position_ = endPosition; } } - else if (static_cast<ParticleType&>(*this).softImpact()) + else { - // Soft-sphere particles can travel outside the domain - // but we don't use lambda since this the particle - // is going away from face - trackFraction = 1.0; - position_ = endPosition; + // Set lambdaMin to zero to force a towards-tet-centre + // correction. + lambdaMin = 0.0; } - // change cell - if (internalFace) // Internal face + } while (faceI_ < 0); + + if (cloud_.internalFace(faceI_)) + { + // Change tet ownership because a tri face has been crossed, + // in general this is: + // tetNeighbour(triI); + // but triI must be 0; + // No modifications are required for triI = 0, no call required to + // tetNeighbour(0); + + if (cellI_ == mesh.faceOwner()[faceI_]) { - if (celli_ == mesh.faceOwner()[facei_]) + cellI_ = mesh.faceNeighbour()[faceI_]; + } + else if (cellI_ == mesh.faceNeighbour()[faceI_]) + { + cellI_ = mesh.faceOwner()[faceI_]; + } + else + { + FatalErrorIn + ( + "Particle::trackToFace(const vector&, TrackData&)" + ) << "addressing failure" << nl + << abort(FatalError); + } + } + else + { + ParticleType& p = static_cast<ParticleType&>(*this); + + label origFaceI = faceI_; + label patchI = patch(faceI_); + + // No action taken for tetPtI_ for tetFaceI_ here, handled by + // patch interaction call or later during processor transfer. + + if + ( + !p.hitPatch + ( + mesh.boundaryMesh()[patchI], + td, + patchI, + trackFraction, + faceHitTetIs + ) + ) + { + // Did patch interaction model switch patches? + if (faceI_ != origFaceI) { - celli_ = mesh.faceNeighbour()[facei_]; + patchI = patch(faceI_); } - else if (celli_ == mesh.faceNeighbour()[facei_]) + + const polyPatch& patch = mesh.boundaryMesh()[patchI]; + + if (isA<wedgePolyPatch>(patch)) { - celli_ = mesh.faceOwner()[facei_]; + p.hitWedgePatch + ( + static_cast<const wedgePolyPatch&>(patch), td + ); } - else + else if (isA<symmetryPolyPatch>(patch)) + { + p.hitSymmetryPatch + ( + static_cast<const symmetryPolyPatch&>(patch), td + ); + } + else if (isA<cyclicPolyPatch>(patch)) + { + p.hitCyclicPatch + ( + static_cast<const cyclicPolyPatch&>(patch), td + ); + } + else if (isA<processorPolyPatch>(patch)) + { + p.hitProcessorPatch + ( + static_cast<const processorPolyPatch&>(patch), td + ); + } + else if (isA<wallPolyPatch>(patch)) { - FatalErrorIn + p.hitWallPatch ( - "Particle::trackToFace(const vector&, TrackData&)" - )<< "addressing failure" << nl - << abort(FatalError); + static_cast<const wallPolyPatch&>(patch), td, faceHitTetIs + ); + } + else + { + p.hitPatch(patch, td); } } - else + } + + if (lambdaMin < SMALL) + { + // Apply tracking correction towards tet centre. + // Generate current tet to find centre to apply correction. + + tetPointRef tet = currentTet(); + + position_ += + Cloud<ParticleType>::trackingCorrectionTol + *(tet.centre() - position_); + + if + ( + cloud_.hasWallImpactDistance() + && !cloud_.internalFace(faceHitTetIs.face()) + && cloud_.cellHasWallFaces()[faceHitTetIs.cell()] + ) { - ParticleType& p = static_cast<ParticleType&>(*this); + const polyBoundaryMesh& patches = mesh.boundaryMesh(); - // Soft-sphere algorithm ignores the boundary - if (p.softImpact()) - { - trackFraction = 1.0; - position_ = endPosition; - } + label fI = faceHitTetIs.face(); - label origFacei = facei_; - label patchi = patch(facei_); + label patchI = patches.patchID()[fI - mesh.nInternalFaces()]; - if (!p.hitPatch(mesh.boundaryMesh()[patchi], td, patchi)) + if (isA<wallPolyPatch>(patches[patchI])) { - // Did patch interaction model switch patches? - if (facei_ != origFacei) - { - patchi = patch(facei_); - } - const polyPatch& patch = mesh.boundaryMesh()[patchi]; - - if (isA<wedgePolyPatch>(patch)) - { - p.hitWedgePatch - ( - static_cast<const wedgePolyPatch&>(patch), td - ); - } - else if (isA<symmetryPolyPatch>(patch)) - { - p.hitSymmetryPatch - ( - static_cast<const symmetryPolyPatch&>(patch), td + // In the case of collision with a wall where there is + // a non-zero wallImpactDistance, it is possible for + // there to be a tracking correction required to bring + // the particle into the domain, but the position of + // the particle is further from the wall than the tet + // centre, in which case the normal correction can be + // counter-productive, i.e. pushes the particle + // further out of the domain. In this case it is the + // position that hit the wall that is in need of a + // rescue correction. + + triPointRef wallTri = faceHitTetIs.faceTri(mesh); + + tetPointRef wallTet = faceHitTetIs.tet(mesh); + + vector nHat = wallTri.normal(); + nHat /= mag(nHat); + + const ParticleType& p = static_cast<const ParticleType&>(*this); + + scalar r = p.wallImpactDistance(nHat); + + // Removing (approximately) the wallTri normal + // component of the existing correction, to avoid the + // situation where the existing correction in the wall + // normal direction is larger towards the wall than + // the new correction is away from it. + position_ += + Cloud<ParticleType>::trackingCorrectionTol + *( + (wallTet.centre() - (position_ + r*nHat)) + - (nHat & (tet.centre() - position_))*nHat ); - } - else if (isA<cyclicPolyPatch>(patch)) - { - p.hitCyclicPatch - ( - static_cast<const cyclicPolyPatch&>(patch), td - ); - } - else if (isA<processorPolyPatch>(patch)) - { - p.hitProcessorPatch - ( - static_cast<const processorPolyPatch&>(patch), td - ); - } - else if (isA<wallPolyPatch>(patch)) - { - p.hitWallPatch - ( - static_cast<const wallPolyPatch&>(patch), td - ); - } - else - { - p.hitPatch(patch, td); - } } } - } - // If the trackFraction = 0 something went wrong. - // Either the particle is flipping back and forth across a face perhaps - // due to velocity interpolation errors or it is in a "hole" in the mesh - // caused by face warpage. - // In both cases resolve the positional ambiguity by moving the particle - // slightly towards the cell-centre. - if (trackFraction < SMALL) - { - position_ += 1.0e-3*(mesh.cellCentres()[celli_] - position_); + cloud_.trackingRescue(); } return trackFraction; } + template<class ParticleType> Foam::scalar Foam::Particle<ParticleType>::trackToFace ( @@ -413,6 +657,7 @@ Foam::scalar Foam::Particle<ParticleType>::trackToFace return trackToFace(endPosition, dummyTd); } + template<class ParticleType> void Foam::Particle<ParticleType>::transformPosition(const tensor& T) { @@ -436,7 +681,9 @@ bool Foam::Particle<ParticleType>::hitPatch ( const polyPatch&, TrackData&, - const label + const label, + const scalar, + const tetIndices& ) { return false; @@ -451,7 +698,17 @@ void Foam::Particle<ParticleType>::hitWedgePatch TrackData& ) { - vector nf = wpp.faceAreas()[wpp.whichFace(facei_)]; + FatalErrorIn + ( + "void Foam::Particle<ParticleType>::hitWedgePatch" + "(" + "const wedgePolyPatch& wpp, " + "TrackData&" + ")" + ) << "Hitting a wedge patch should not be possible." + << abort(FatalError); + + vector nf = normal(); nf /= mag(nf); static_cast<ParticleType&>(*this).transformProperties(I - 2.0*nf*nf); @@ -466,7 +723,7 @@ void Foam::Particle<ParticleType>::hitSymmetryPatch TrackData& ) { - vector nf = spp.faceAreas()[spp.whichFace(facei_)]; + vector nf = normal(); nf /= mag(nf); static_cast<ParticleType&>(*this).transformProperties(I - 2.0*nf*nf); @@ -481,11 +738,16 @@ void Foam::Particle<ParticleType>::hitCyclicPatch TrackData& ) { -// label patchFacei_ = cpp.whichFace(facei_); + // label patchFaceI_ = cpp.whichFace(faceI_); + + faceI_ = cpp.transformGlobalFace(faceI_); + + cellI_ = cloud_.polyMesh_.faceOwner()[faceI_]; - facei_ = cpp.transformGlobalFace(facei_); + tetFaceI_ = faceI_; - celli_ = cloud_.polyMesh_.faceOwner()[facei_]; + // See note in correctAfterParallelTransfer for tetPtI_ addressing. + tetPtI_ = cloud_.polyMesh_.faces()[tetFaceI_].size() - 1 - tetPtI_; // Now the particle is on the receiving side @@ -522,7 +784,8 @@ template<class TrackData> void Foam::Particle<ParticleType>::hitWallPatch ( const wallPolyPatch& spp, - TrackData& + TrackData&, + const tetIndices& ) {} @@ -549,7 +812,7 @@ bool Foam::operator== return ( pA.origProc() == pB.origProc() - && pA.origId() == pB.origId() + && pA.origId() == pB.origId() ); } diff --git a/src/lagrangian/basic/Particle/Particle.H b/src/lagrangian/basic/Particle/Particle.H index 39c21de0767a9e48a023f33e695fd5b9d5bcb99a..b28221a205dfb977c1d04a5943806d941b8d6c7d 100644 --- a/src/lagrangian/basic/Particle/Particle.H +++ b/src/lagrangian/basic/Particle/Particle.H @@ -38,6 +38,10 @@ Description #include "faceList.H" #include "typeInfo.H" #include "OFstream.H" +#include "tetPointRef.H" +#include "FixedList.H" +#include "polyMeshTetDecomposition.H" +#include "wallPolyPatch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -125,14 +129,23 @@ protected: vector position_; //- Index of the cell it is in - label celli_; + label cellI_; //- Face index if the particle is on a face otherwise -1 - label facei_; + label faceI_; //- Fraction of time-step completed scalar stepFraction_; + //- Index of the face that owns the decomposed tet that the + // particle is in + label tetFaceI_; + + //- Index of the point on the face that defines the decomposed + // tet that the particle is in. Relative to the face base + // point. + label tetPtI_; + //- Originating processor id label origProc_; @@ -142,54 +155,82 @@ protected: // Private Member Functions - //- Return the 'lambda' value for the position, p, on the face, - // where, p = from + lamda*(to - from) - // for non-static meshes - inline scalar lambda + //- Find the tet tri faces between position and tet centre + inline void findTris ( - const vector& from, - const vector& to, - const label facei, - const scalar stepFraction + const vector& position, + DynamicList<label>& faceList, + const tetPointRef& tet, + const FixedList<vector, 4>& tetAreas, + const FixedList<label, 4>& tetPlaneBasePtIs ) const; - //- Return the 'lambda' value for the position, p, on the face, - // where, p = from + lamda*(to - from) - // for static meshes - inline scalar lambda + //- Find the lambda value for the line to-from across the + // given tri face, where p = from + lambda*(to - from) + inline scalar tetLambda ( const vector& from, const vector& to, - const label facei + const label triI, + const vector& tetArea, + const label tetPlaneBasePtI, + const label cellI, + const label tetFaceI, + const label tetPtI ) const; - //- Find the faces between position and cell centre - void findFaces + //- Find the lambda value for a moving tri face + inline scalar movingTetLambda + ( + const vector& from, + const vector& to, + const label triI, + const vector& tetArea, + const label tetPlaneBasePtI, + const label cellI, + const label tetFaceI, + const label tetPtI + ) const; + + //- Modify the tet owner data by crossing triI + inline void tetNeighbour(label triI); + + //- Cross the from the given face across the given edge of the + // given cell to find the resulting face and tetPtI + inline void crossEdgeConnectedFace ( - const vector& position, - DynamicList<label>& faceList - ) const; + const label& cellI, + label& tetFaceI, + label& tetPtI, + const edge& e + ); - //- Find the faces between position and cell centre - void findFaces + //- Hit wall faces in the current cell if the + //- wallImpactDistance is non-zero. They may not be in + //- different tets to the current. + inline void hitWallFaces ( - const vector& position, - const label celli, - const scalar stepFraction, - DynamicList<label>& faceList - ) const; + const vector& from, + const vector& to, + scalar& lambdaMin, + tetIndices& closestTetIs + ); // Patch interactions - //- Overridable function to handle the particle hitting a patch - // Executed before other patch-hitting functions + //- Overridable function to handle the particle hitting a + // patch. Executed before other patch-hitting functions. + // trackFraction is passed in to allow mesh motion to + // interpolate in time to the correct face state. template<class TrackData> bool hitPatch ( const polyPatch&, TrackData& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ); //- Overridable function to handle the particle hitting a wedgePatch @@ -231,7 +272,8 @@ protected: void hitWallPatch ( const wallPolyPatch&, - TrackData& td + TrackData& td, + const tetIndices& tetIs ); //- Overridable function to handle the particle hitting a @@ -264,12 +306,12 @@ protected: //- Convert global addressing to the processor patch // local equivalents template<class TrackData> - void prepareForParallelTransfer(const label patchi, TrackData& td); + void prepareForParallelTransfer(const label patchI, TrackData& td); //- Convert processor patch addressing to the global equivalents - // and set the celli to the face-neighbour + // and set the cellI to the face-neighbour template<class TrackData> - void correctAfterParallelTransfer(const label patchi, TrackData& td); + void correctAfterParallelTransfer(const label patchI, TrackData& td); public: @@ -293,7 +335,19 @@ public: ( const Cloud<ParticleType>&, const vector& position, - const label celli + const label cellI, + const label tetFaceI, + const label tetPtI + ); + + //- Construct from components, tetFaceI_ and tetPtI_ are not + // supplied so they will be deduced by a search + Particle + ( + const Cloud<ParticleType>&, + const vector& position, + const label cellI, + bool doCellFacePt = true ); //- Construct from Istream @@ -355,17 +409,6 @@ public: // Access - //- Return true if particle is in cell - inline bool inCell() const; - - //- Return true if position is in cell i - inline bool inCell - ( - const vector& position, - const label celli, - const scalar stepFraction - ) const; - //- Return current particle position inline const vector& position() const; @@ -378,6 +421,35 @@ public: //- Return current cell particle is in inline label cell() const; + //- Return current tet face particle is in + inline label& tetFace(); + + //- Return current tet face particle is in + inline label tetFace() const; + + //- Return current tet face particle is in + inline label& tetPt(); + + //- Return current tet face particle is in + inline label tetPt() const; + + //- Return the indices of the current tet that the + // particle occupies. + inline tetIndices currentTetIndices() const; + + //- Return the geometry of the current tet that the + // particle occupies. + inline tetPointRef currentTet() const; + + //- Return the normal of the tri on tetFaceI_ for the + // current tet. + inline vector normal() const; + + //- Return the normal of the tri on tetFaceI_ for the + // current tet at the start of the timestep, i.e. based + // on oldPoints + inline vector oldNormal() const; + //- Return current face particle is on otherwise -1 inline label& face(); @@ -396,17 +468,21 @@ public: // Check + //- Check the stored cell value (setting if necessary) and + // initialise the tetFace and tetPt values + inline void initCellFacePt(); + //- Is the particle on the boundary/(or outside the domain)? inline bool onBoundary() const; //- Which patch is particle on - inline label patch(const label facei) const; + inline label patch(const label faceI) const; //- Which face of this patch is this particle on inline label patchFace ( - const label patchi, - const label facei + const label patchI, + const label faceI ) const; //- The nearest distance to a wall that diff --git a/src/lagrangian/basic/Particle/ParticleI.H b/src/lagrangian/basic/Particle/ParticleI.H index 43fd1d380656ab04453a6a494d47365843def290..35d658d11536d97fec56914f69db8c9d9ba70c3c 100644 --- a/src/lagrangian/basic/Particle/ParticleI.H +++ b/src/lagrangian/basic/Particle/ParticleI.H @@ -24,243 +24,776 @@ License \*---------------------------------------------------------------------------*/ #include "polyMesh.H" -#include "wallPolyPatch.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template<class ParticleType> -inline Foam::scalar Foam::Particle<ParticleType>::lambda +inline void Foam::Particle<ParticleType>::findTris +( + const vector& position, + DynamicList<label>& faceList, + const tetPointRef& tet, + const FixedList<vector, 4>& tetAreas, + const FixedList<label, 4>& tetPlaneBasePtIs +) const +{ + faceList.clear(); + + const point Ct = tet.centre(); + + for (label i = 0; i < 4; i++) + { + scalar lambda = tetLambda + ( + Ct, + position, + i, + tetAreas[i], + tetPlaneBasePtIs[i], + cellI_, + tetFaceI_, + tetPtI_ + ); + + if ((lambda > 0.0) && (lambda < 1.0)) + { + faceList.append(i); + } + } +} + + +template<class ParticleType> +inline Foam::scalar Foam::Particle<ParticleType>::tetLambda +( + const vector& from, + const vector& to, + const label triI, + const vector& n, + const label tetPlaneBasePtI, + const label cellI, + const label tetFaceI, + const label tetPtI +) const +{ + const polyMesh& mesh = cloud_.polyMesh_; + const pointField& pPts = mesh.points(); + + if (mesh.moving()) + { + return movingTetLambda + ( + from, + to, + triI, + n, + tetPlaneBasePtI, + cellI, + tetFaceI, + tetPtI + ); + } + + const point& base = pPts[tetPlaneBasePtI]; + + scalar lambdaNumerator = (base - from) & n; + scalar lambdaDenominator = (to - from) & n; + + if (mag(lambdaDenominator) < SMALL) + { + if (mag(lambdaNumerator) < SMALL) + { + // Track starts on the face, and is potentially + // parallel to it. +-SMALL)/+-SMALL is not a good + // comparison, return 0.0, in anticipation of tet + // centre correction. + + return 0.0; + } + else + { + if (mag((to - from)) < SMALL) + { + // Zero length track, not along the face, face + // cannot be crossed. + + return GREAT; + } + else + { + // Trajectory is non-zero and parallel to face + + lambdaDenominator = sign(lambdaDenominator)*SMALL; + } + } + } + + return lambdaNumerator/lambdaDenominator; +} + + + +template<class ParticleType> +inline Foam::scalar Foam::Particle<ParticleType>::movingTetLambda ( const vector& from, const vector& to, - const label facei, - const scalar stepFraction + const label triI, + const vector& n, + const label tetPlaneBasePtI, + const label cellI, + const label tetFaceI, + const label tetPtI ) const { const polyMesh& mesh = cloud_.polyMesh_; - bool movingMesh = mesh.moving(); + const pointField& pPts = mesh.points(); + const pointField& oldPPts = mesh.oldPoints(); + + // Base point of plane at end of motion + const point& b = pPts[tetPlaneBasePtI]; + + // n: Normal of plane at end of motion + + // Base point of plane at start of timestep + const point& b00 = oldPPts[tetPlaneBasePtI]; + + // Base point of plane at start of tracking portion (cast forward by + // stepFraction) + point b0 = b00 + stepFraction_*(b - b00); + + // Normal of plane at start of tracking portion + vector n0 = vector::zero; - if (movingMesh) { - vector Sf = mesh.faceAreas()[facei]; - Sf /= mag(Sf); - vector Cf = mesh.faceCentres()[facei]; + tetIndices tetIs(cellI, tetFaceI, tetPtI, mesh); + + // tet at timestep start + tetPointRef tet00 = tetIs.oldTet(mesh); - // patch interaction - if (!cloud_.internalFace(facei)) + // tet at timestep end + tetPointRef tet = tetIs.tet(mesh); + + point tet0PtA = tet00.a() + stepFraction_*(tet.a() - tet00.a()); + point tet0PtB = tet00.b() + stepFraction_*(tet.b() - tet00.b()); + point tet0PtC = tet00.c() + stepFraction_*(tet.c() - tet00.c()); + point tet0PtD = tet00.d() + stepFraction_*(tet.d() - tet00.d()); + + // Tracking portion start tet (cast forward by stepFraction) + tetPointRef tet0(tet0PtA, tet0PtB, tet0PtC, tet0PtD); + + switch (triI) { - label patchi = patch(facei); - const polyPatch& patch = mesh.boundaryMesh()[patchi]; + case 0: + { + n0 = tet0.Sa(); + break; + } + case 1: + { + n0 = tet0.Sb(); + break; + } + case 2: + { + n0 = tet0.Sc(); + break; + } + case 3: + { + n0 = tet0.Sd(); + break; + } + default: + { + break; + } + } + } + + if (mag(n0) < SMALL) + { + // If the old normal is zero (for example in layer addition) + // then use the current normal; - // move reference point for wall - if (isA<wallPolyPatch>(patch)) + n0 = n; + } + + scalar lambdaNumerator = 0; + scalar lambdaDenominator = 0; + + vector dP = to - from; + vector dN = n - n0; + vector dB = b - b0; + vector dS = from - b0; + + if (mag(dN) > SMALL) + { + scalar a = (dP - dB) & dN; + scalar b = ((dP - dB) & n0) + (dS & dN); + scalar c = dS & n0; + + if (mag(a) > SMALL) + { + + // Solve quadratic for lambda + scalar discriminant = sqr(b) - 4.0*a*c; + + if (discriminant < 0) + { + // Imaginary roots only - face not crossed + return GREAT; + } + else { - const vector& C = mesh.cellCentres()[celli_]; - scalar CCf = mag((C - Cf) & Sf); - // check if distance between cell centre and face centre - // is larger than wallImpactDistance - const ParticleType& p = - static_cast<const ParticleType&>(*this); - if (CCf > p.wallImpactDistance(Sf)) + // Numerical Recipes in C, + // Second Edition (1992), + // Section 5.6. + // q = -0.5*(b + sgn(b)*sqrt(b^2 - 4ac)) + // x1 = q/a + // x2 = c/q + + scalar q = -0.5*(b + sign(b)*Foam::sqrt(discriminant)); + + if (mag(q) < VSMALL) { - Cf -=p.wallImpactDistance(Sf)*Sf; + // If q is zero, then l1 = q/a is the required + // value of lambda, and is zero. + + return 0.0; + } + + scalar l1 = q/a; + scalar l2 = c/q; + + // There will be two roots, a big one and a little + // one, choose the little one. + + if (mag(l1) < mag(l2)) + { + return l1; + } + else + { + return l2; } } } + { + // When a is zero, solve the first order polynomial - // for a moving mesh we need to reconstruct the old - // Sf and Cf from oldPoints (they aren't stored) - - const vectorField& oldPoints = mesh.oldPoints(); + lambdaNumerator = -c; + lambdaDenominator = b; + } + } + else + { + // when n = n0 is zero, there is no plane rotation, solve the + // first order polynomial - vector Cf00 = mesh.faces()[facei].centre(oldPoints); - vector Cf0 = Cf00 + stepFraction*(Cf - Cf00); + lambdaNumerator = -(dS & n0); + lambdaDenominator = ((dP - dB) & n0); - vector Sf00 = mesh.faces()[facei].normal(oldPoints); + } - // for layer addition Sf00 = vector::zero and we use Sf - if (mag(Sf00) > SMALL) + if (mag(lambdaDenominator) < SMALL) + { + if (mag(lambdaNumerator) < SMALL) { - Sf00 /= mag(Sf00); + // Track starts on the face, and is potentially + // parallel to it. +-SMALL)/+-SMALL is not a good + // comparison, return 0.0, in anticipation of tet + // centre correction. + + return 0.0; } else { - Sf00 = Sf; + if (mag((to - from)) < SMALL) + { + // Zero length track, not along the face, face + // cannot be crossed. + + return GREAT; + } + else + { + // Trajectory is non-zero and parallel to face + + lambdaDenominator = sign(lambdaDenominator)*SMALL; + } } + } + + return lambdaNumerator/lambdaDenominator; +} + + +template<class ParticleType> +inline void Foam::Particle<ParticleType>::tetNeighbour(label triI) +{ + const polyMesh& mesh = cloud_.polyMesh_; - scalar magSfDiff = mag(Sf - Sf00); + const labelList& pOwner = mesh.faceOwner(); + const faceList& pFaces = mesh.faces(); - // check if the face is rotating - if (magSfDiff > SMALL) + bool own = (pOwner[tetFaceI_] == cellI_); + + const Foam::face& f = pFaces[tetFaceI_]; + + label tetBasePtI = mesh.tetBasePtIs()[tetFaceI_]; + + label facePtI = (tetPtI_ + tetBasePtI) % f.size(); + label otherFacePtI = f.fcIndex(facePtI); + + if (tetBasePtI == -1) + { + FatalErrorIn + ( + "inline void Foam::Particle<ParticleType>::tetNeighbour(label triI)" + ) + << "No base point for face " << tetFaceI_ << ", " << f + << ", produces a valid tet decomposition." + << abort(FatalError); + } + + switch (triI) + { + case 0: { - vector Sf0 = Sf00 + stepFraction*(Sf - Sf00); - - // find center of rotation - vector omega = Sf0 ^ Sf; - scalar magOmega = mag(omega); - omega /= magOmega + SMALL; - vector n0 = omega ^ Sf0; - scalar lam = ((Cf - Cf0) & Sf)/(n0 & Sf); - vector r0 = Cf0 + lam*n0; - - // solve '(p - r0) & Sfp = 0', where - // p = from + lambda*(to - from) - // Sfp = Sf0 + lambda*(Sf - Sf0) - // which results in the quadratic eq. - // a*lambda^2 + b*lambda + c = 0 - vector alpha = from - r0; - vector beta = to - from; - scalar a = beta & (Sf - Sf0); - scalar b = (alpha & (Sf - Sf0)) + (beta & Sf0); - scalar c = alpha & Sf0; - - if (mag(a) > SMALL) - { - // solve the second order polynomial - scalar ap = b/a; - scalar bp = c/a; - scalar cp = ap*ap - 4.0*bp; + // Crossing this triangle changes tet to that in the + // neighbour cell over tetFaceI + + // Modification of cellI_ will happen by other indexing, + // tetFaceI_ and tetPtI don't change. - if (cp < 0.0) + break; + } + case 1: + { + crossEdgeConnectedFace + ( + cellI_, + tetFaceI_, + tetPtI_, + Foam::edge(f[facePtI], f[otherFacePtI]) + ); + + break; + } + case 2: + { + if (own) + { + if (tetPtI_ < f.size() - 2) { - // imaginary roots only - return GREAT; + tetPtI_ = f.fcIndex(tetPtI_); } else { - scalar l1 = -0.5*(ap - ::sqrt(cp)); - scalar l2 = -0.5*(ap + ::sqrt(cp)); - - // one root is around 0-1, while - // the other is very large in mag - if (mag(l1) < mag(l2)) - { - return l1; - } - else - { - return l2; - } + crossEdgeConnectedFace + ( + cellI_, + tetFaceI_, + tetPtI_, + Foam::edge(f[tetBasePtI], f[otherFacePtI]) + ); } } else { - // when a==0, solve the first order polynomial - return (-c/b); + if (tetPtI_ > 1) + { + tetPtI_ = f.rcIndex(tetPtI_); + } + else + { + crossEdgeConnectedFace + ( + cellI_, + tetFaceI_, + tetPtI_, + Foam::edge(f[tetBasePtI], f[facePtI]) + ); + } } + + break; } - else // no rotation + case 3: { - vector alpha = from - Cf0; - vector beta = to - from - (Cf - Cf0); - scalar lambdaNominator = alpha & Sf; - scalar lambdaDenominator = beta & Sf; - - // check if trajectory is parallel to face - if (mag(lambdaDenominator) < SMALL) + if (own) + { + if (tetPtI_ > 1) + { + tetPtI_ = f.rcIndex(tetPtI_); + } + else + { + crossEdgeConnectedFace + ( + cellI_, + tetFaceI_, + tetPtI_, + Foam::edge(f[tetBasePtI], f[facePtI]) + ); + } + } + else { - if (lambdaDenominator < 0.0) + if (tetPtI_ < f.size() - 2) { - lambdaDenominator = -SMALL; + tetPtI_ = f.fcIndex(tetPtI_); } else { - lambdaDenominator = SMALL; + crossEdgeConnectedFace + ( + cellI_, + tetFaceI_, + tetPtI_, + Foam::edge(f[tetBasePtI], f[otherFacePtI]) + ); } } - return (-lambdaNominator/lambdaDenominator); + break; + } + default: + { + FatalErrorIn + ( + "inline void " + "Foam::Particle<ParticleType>::tetNeighbour(label triI)" + ) + << "Tet tri face index error, can only be 0..3, supplied " + << triI << nl + << abort(FatalError); + + break; } - } - else - { - // mesh is static and stepFraction is not needed - return lambda(from, to, facei); } } - template<class ParticleType> -inline Foam::scalar Foam::Particle<ParticleType>::lambda +inline void Foam::Particle<ParticleType>::crossEdgeConnectedFace ( - const vector& from, - const vector& to, - const label facei -) const + const label& cellI, + label& tetFaceI, + label& tetPtI, + const edge& e +) { const polyMesh& mesh = cloud_.polyMesh_; - vector Sf = mesh.faceAreas()[facei]; - Sf /= mag(Sf); - vector Cf = mesh.faceCentres()[facei]; + const faceList& pFaces = mesh.faces(); + const cellList& pCells = mesh.cells(); + + const Foam::face& f = pFaces[tetFaceI]; + + const Foam::cell& thisCell = pCells[cellI]; - // patch interaction - if (!cloud_.internalFace(facei)) + forAll(thisCell, cFI) { - label patchi = patch(facei); - const polyPatch& patch = mesh.boundaryMesh()[patchi]; + // Loop over all other faces of this cell and + // find the one that shares this edge - // move reference point for wall - if (isA<wallPolyPatch>(patch)) + label fI = thisCell[cFI]; + + if (tetFaceI == fI) { - const vector& C = mesh.cellCentres()[celli_]; - scalar CCf = mag((C - Cf) & Sf); - // check if distance between cell centre and face centre - // is larger than wallImpactDistance - const ParticleType& p = static_cast<const ParticleType&>(*this); - if (CCf > p.wallImpactDistance(Sf)) - { - Cf -=p.wallImpactDistance(Sf)*Sf; - } + continue; } - } - scalar lambdaNominator = (Cf - from) & Sf; - scalar lambdaDenominator = (to - from) & Sf; + const Foam::face& otherFace = pFaces[fI]; - // check if trajectory is parallel to face - if (mag(lambdaDenominator) < SMALL) - { - if (lambdaDenominator < 0.0) + label edDir = otherFace.edgeDirection(e); + + if (edDir == 0) { - lambdaDenominator = -SMALL; + continue; } else { - lambdaDenominator = SMALL; - } - } + //Found edge on other face + tetFaceI = fI; - return lambdaNominator/lambdaDenominator; -} + label eIndex = -1; + if (edDir == 1) + { + // Edge is in the forward circulation of this face, so + // work with the start point of the edge -template<class ParticleType> -inline bool Foam::Particle<ParticleType>::inCell() const -{ - DynamicList<label>& faces = cloud_.labels_; - findFaces(position_, faces); + eIndex = findIndex(otherFace, e.start()); + } + else + { + // edDir == -1, so the edge is in the reverse + // circulation of this face, so work with the end + // point of the edge - return (!faces.size()); + eIndex = findIndex(otherFace, e.end()); + } + + label tetBasePtI = mesh.tetBasePtIs()[fI]; + + if (tetBasePtI == -1) + { + FatalErrorIn + ( + "inline void " + "Foam::Particle<ParticleType>::crossEdgeConnectedFace" + "(" + "const label& cellI," + "label& tetFaceI," + "label& tetPtI," + "const edge& e" + ")" + ) + << "No base point for face " << fI << ", " << f + << ", produces a decomposition that has a minimum " + << "volume greater than tolerance." + << abort(FatalError); + } + + // Find eIndex relative to the base point on new face + eIndex -= tetBasePtI; + + if (neg(eIndex)) + { + eIndex = (eIndex + otherFace.size()) % otherFace.size(); + } + + if (eIndex == 0) + { + // The point is the base point, so this is first tet + // in the face circulation + + tetPtI = 1; + } + else if (eIndex == otherFace.size() - 1) + { + // The point is the last before the base point, so + // this is the last tet in the face circulation + + tetPtI = otherFace.size() - 2; + } + else + { + tetPtI = eIndex; + } + + break; + } + } } template<class ParticleType> -inline bool Foam::Particle<ParticleType>::inCell +inline void Foam::Particle<ParticleType>::hitWallFaces ( - const vector& position, - const label celli, - const scalar stepFraction -) const + const vector& from, + const vector& to, + scalar& lambdaMin, + tetIndices& closestTetIs +) { - DynamicList<label>& faces = cloud_.labels_; - findFaces(position, celli, stepFraction, faces); + if (!(cloud_.hasWallImpactDistance() && cloud_.cellHasWallFaces()[cellI_])) + { + return; + } + + const polyMesh& mesh = cloud_.polyMesh_; + const faceList& pFaces = mesh.faces(); + + const ParticleType& p = static_cast<const ParticleType&>(*this); - return (!faces.size()); + const Foam::cell& thisCell = mesh.cells()[cellI_]; + + const polyBoundaryMesh& patches = mesh.boundaryMesh(); + + forAll(thisCell, cFI) + { + label fI = thisCell[cFI]; + + if (cloud_.internalFace(fI)) + { + continue; + } + + label patchI = patches.patchID()[fI - mesh.nInternalFaces()]; + + if (isA<wallPolyPatch>(patches[patchI])) + { + // Get the decomposition of this wall face + + const List<tetIndices>& faceTetIs = + polyMeshTetDecomposition::faceTetIndices(mesh, fI, cellI_); + + const Foam::face& f = pFaces[fI]; + + forAll(faceTetIs, tI) + { + const tetIndices& tetIs = faceTetIs[tI]; + + triPointRef tri = tetIs.faceTri(mesh); + + vector n = tri.normal(); + + vector nHat = n/mag(n); + + // Radius of particle with respect to this wall face + // triangle. Assuming that the wallImpactDistance + // does not change as the particle or the mesh moves + // forward in time. + scalar r = p.wallImpactDistance(nHat); + + vector toPlusRNHat = to + r*nHat; + + // triI = 0 because it is the cell face tri of the tet + // we are concerned with. + scalar tetClambda = tetLambda + ( + tetIs.tet(mesh).centre(), + toPlusRNHat, + 0, + n, + f[tetIs.faceBasePt()], + cellI_, + fI, + tetIs.tetPt() + ); + + if ((tetClambda <= 0.0) || (tetClambda >= 1.0)) + { + // toPlusRNHat is not on the outside of the plane of + // the wall face tri, the tri cannot be hit. + continue; + } + + // Check if the actual trajectory of the near-tri + // points intersects the triangle. + + vector fromPlusRNHat = from + r*nHat; + + // triI = 0 because it is the cell face tri of the tet + // we are concerned with. + scalar lambda = tetLambda + ( + fromPlusRNHat, + toPlusRNHat, + 0, + n, + f[tetIs.faceBasePt()], + cellI_, + fI, + tetIs.tetPt() + ); + + pointHit hitInfo(vector::zero); + + if (mesh.moving()) + { + // For a moving mesh, the position of wall + // triangle needs to be moved in time to be + // consistent with the moment defined by the + // current value of stepFraction and the value of + // lambda just calculated. + + // Total fraction thought the timestep of the + // motion, including stepFraction before the + // current tracking step and the current + // lambda + // i.e. + // let s = stepFraction, l = lambda + // Motion of x in time: + // |-----------------|---------|---------| + // x00 x0 xi x + // + // where xi is the correct value of x at the required + // tracking instant. + // + // x0 = x00 + s*(x - x00) = s*x + (1 - s)*x00 + // + // i.e. the motion covered by previous tracking portions + // within this timestep, and + // + // xi = x0 + l*(x - x0) + // = l*x + (1 - l)*x0 + // = l*x + (1 - l)*(s*x + (1 - s)*x00) + // = (s + l - s*l)*x + (1 - (s + l - s*l))*x00 + // + // let m = (s + l - s*l) + // + // xi = m*x + (1 - m)*x00 = x00 + m*(x - x00); + // + // In the same form as before. + + // Clip lambda to 0.0-1.0 to ensure that sensible + // positions are used for triangle intersections. + scalar lam = max(0.0, min(1.0, lambda)); + + scalar m = stepFraction_ + lam - (stepFraction_*lam); + + triPointRef tri00 = tetIs.oldFaceTri(mesh); + + // Use SMALL positive tolerance to make the triangle + // slightly "fat" to improve robustness. Intersection + // is calculated as the ray (from + r*nHat) -> (to + + // r*nHat). + + point tPtA = tri00.a() + m*(tri.a() - tri00.a()); + point tPtB = tri00.b() + m*(tri.b() - tri00.b()); + point tPtC = tri00.c() + m*(tri.c() - tri00.c()); + + triPointRef t(tPtA, tPtB, tPtC); + + // The point fromPlusRNHat + m*(to - from) is on the + // plane of the triangle. Determine the + // intersection with this triangle by testing if + // this point is inside or outside of the triangle. + hitInfo = t.intersection + ( + fromPlusRNHat + m*(to - from), + t.normal(), + intersection::FULL_RAY, + SMALL + ); + } + else + { + // Use SMALL positive tolerance to make the triangle + // slightly "fat" to improve robustness. Intersection + // is calculated as the ray (from + r*nHat) -> (to + + // r*nHat). + hitInfo = tri.intersection + ( + fromPlusRNHat, + (to - from), + intersection::FULL_RAY, + SMALL + ); + } + + if (hitInfo.hit()) + { + if (lambda < lambdaMin) + { + lambdaMin = lambda; + + faceI_ = fI; + + closestTetIs = tetIs; + } + } + } + } + } } -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template<class ParticleType> inline Foam::Particle<ParticleType>::trackData::trackData @@ -272,6 +805,8 @@ inline Foam::Particle<ParticleType>::trackData::trackData {} +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + template<class ParticleType> inline Foam::Cloud<ParticleType>& Foam::Particle<ParticleType>::trackData::cloud() @@ -280,8 +815,6 @@ Foam::Particle<ParticleType>::trackData::cloud() } -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - template<class ParticleType> inline const Foam::Cloud<ParticleType>& Foam::Particle<ParticleType>::cloud() const @@ -307,35 +840,256 @@ inline Foam::vector& Foam::Particle<ParticleType>::position() template<class ParticleType> inline Foam::label Foam::Particle<ParticleType>::cell() const { - return celli_; + return cellI_; } template<class ParticleType> inline Foam::label& Foam::Particle<ParticleType>::cell() { - return celli_; + return cellI_; +} + + +template<class ParticleType> +inline Foam::label Foam::Particle<ParticleType>::tetFace() const +{ + return tetFaceI_; +} + + +template<class ParticleType> +inline Foam::label& Foam::Particle<ParticleType>::tetFace() +{ + return tetFaceI_; +} + + +template<class ParticleType> +inline Foam::label Foam::Particle<ParticleType>::tetPt() const +{ + return tetPtI_; +} + + +template<class ParticleType> +inline Foam::label& Foam::Particle<ParticleType>::tetPt() +{ + return tetPtI_; +} + + +template<class ParticleType> +inline Foam::tetIndices Foam::Particle<ParticleType>::currentTetIndices() const +{ + return tetIndices(cellI_, tetFaceI_, tetPtI_, cloud_.polyMesh_); +} + + +template<class ParticleType> +inline Foam::tetPointRef Foam::Particle<ParticleType>::currentTet() const +{ + return currentTetIndices().tet(cloud_.polyMesh_); +} + + +template<class ParticleType> +inline Foam::vector Foam::Particle<ParticleType>::normal() const +{ + return currentTetIndices().faceTri(cloud_.polyMesh_).normal(); +} + + +template<class ParticleType> +inline Foam::vector +Foam::Particle<ParticleType>::oldNormal() const +{ + return currentTetIndices().oldFaceTri(cloud_.polyMesh_).normal(); } template<class ParticleType> inline Foam::label Foam::Particle<ParticleType>::face() const { - return facei_; + return faceI_; } template<class ParticleType> inline Foam::label& Foam::Particle<ParticleType>::face() { - return facei_; + return faceI_; +} + + +template<class ParticleType> +inline void Foam::Particle<ParticleType>::initCellFacePt() +{ + if (cellI_ == -1) + { + cloud_.findCellFacePt + ( + position_, + cellI_, + tetFaceI_, + tetPtI_ + ); + + if (cellI_ == -1) + { + FatalErrorIn + ( + "Foam::Particle<ParticleType>::Particle" + "(" + "void Foam::Particle<ParticleType>::initCellFacePt()" + ")" + ) << "cell, tetFace and tetPt search failure at position " + << position_ << nl + << abort(FatalError); + } + } + else + { + cloud_.findFacePt(cellI_, position_, tetFaceI_, tetPtI_); + + if (tetFaceI_ == -1 || tetPtI_ == -1) + { + label oldCellI = cellI_; + + cloud_.findCellFacePt + ( + position_, + cellI_, + tetFaceI_, + tetPtI_ + ); + + if (cellI_ == -1 || tetFaceI_ == -1 || tetPtI_ == -1) + { + // The particle has entered this function with a cell + // number, but hasn't been able to find a cell to + // occupy. + + if(!cloud_.polyMesh_.pointInCellBB(position_, oldCellI)) + { + // If the position is not inside the bound-box of + // the cell that it thought it should be in, then + // this is considered an error. + + FatalErrorIn + ( + "Foam::Particle<ParticleType>::Particle" + "(" + "void " + "Foam::Particle<ParticleType>::initCellFacePt()" + ")" + ) << "cell, tetFace and tetPt search failure at position " + << position_ << nl + << abort(FatalError); + } + + // The position is in the bound-box of the cell. This + // situation may arise because the face decomposition + // of the cell is not the same as when the particle + // acquired the cell index. For example, it has been + // read into a mesh that has made a different face + // base-point decision for a boundary face and now + // this particle is in a position that is not in the + // mesh. Gradually move the particle towards the + // centre of the cell that it thought that it was in. + + cellI_ = oldCellI; + + point newPosition = position_; + + const point& cC = cloud_.polyMesh_.cellCentres()[cellI_]; + + label trap(1.0/Cloud<ParticleType>::trackingCorrectionTol + 1); + + label iterNo = 0; + + do + { + newPosition += + Cloud<ParticleType>::trackingCorrectionTol + *(cC - position_); + + cloud_.findFacePt + ( + cellI_, + newPosition, + tetFaceI_, + tetPtI_ + ); + + iterNo++; + + } while (tetFaceI_ < 0 && iterNo <= trap); + + if(tetFaceI_ == -1) + { + FatalErrorIn + ( + "Foam::Particle<ParticleType>::Particle" + "(" + "void " + "Foam::Particle<ParticleType>::initCellFacePt()" + ")" + ) << "cell, tetFace and tetPt search failure at position " + << position_ << nl + << abort(FatalError); + } + + WarningIn + ( + "Foam::Particle<ParticleType>::Particle" + "(" + "void Foam::Particle<ParticleType>::initCellFacePt()" + ")" + ) + << "Particle moved from " << position_ + << " to " << newPosition + << " in cell " << cellI_ + << " tetFace " << tetFaceI_ + << " tetPt " << tetPtI_ << nl + << " (A fraction of " + << 1.0 - mag(cC - newPosition)/mag(cC - position_) + << " of the distance to the cell centre)" + << " because a decomposition tetFace and tetPt " + << "could not be found." + << endl; + + position_ = newPosition; + } + + if (cellI_ != oldCellI) + { + WarningIn + ( + "Foam::Particle<ParticleType>::Particle" + "(" + "void Foam::Particle<ParticleType>::initCellFacePt()" + ")" + ) + << "Particle at position " << position_ + << " searched for a cell, tetFace and tetPt." << nl + << " Found" + << " cell " << cellI_ + << " tetFace " << tetFaceI_ + << " tetPt " << tetPtI_ << nl + << " This is a different cell to that which was supplied" + << " (" << oldCellI << ")." << nl + << endl; + } + } + } } template<class ParticleType> inline bool Foam::Particle<ParticleType>::onBoundary() const { - return facei_ != -1 && facei_ >= cloud_.pMesh().nInternalFaces(); + return faceI_ != -1 && faceI_ >= cloud_.pMesh().nInternalFaces(); } @@ -384,20 +1138,20 @@ inline Foam::scalar Foam::Particle<ParticleType>::currentTime() const template<class ParticleType> -inline Foam::label Foam::Particle<ParticleType>::patch(const label facei) const +inline Foam::label Foam::Particle<ParticleType>::patch(const label faceI) const { - return cloud_.facePatch(facei); + return cloud_.facePatch(faceI); } template<class ParticleType> inline Foam::label Foam::Particle<ParticleType>::patchFace ( - const label patchi, - const label facei + const label patchI, + const label faceI ) const { - return cloud_.patchFace(patchi, facei); + return cloud_.patchFace(patchI, faceI); } @@ -412,7 +1166,7 @@ Foam::Particle<ParticleType>::wallImpactDistance(const vector&) const template<class ParticleType> inline Foam::label Foam::Particle<ParticleType>::faceInterpolation() const { - return facei_; + return faceI_; } diff --git a/src/lagrangian/basic/Particle/ParticleIO.C b/src/lagrangian/basic/Particle/ParticleIO.C index 3212c1f4861039250b5ca51810d6c41ecb8d38f1..18d170645980642a51bbfc7316becf32ac46ef6e 100644 --- a/src/lagrangian/basic/Particle/ParticleIO.C +++ b/src/lagrangian/basic/Particle/ParticleIO.C @@ -31,7 +31,8 @@ License template<class ParticleType> Foam::string Foam::Particle<ParticleType>::propHeader = - "(Px Py Pz) cellI origProc origId"; + "(Px Py Pz) cellI tetFaceI tetPtI origProc origId"; + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -44,20 +45,24 @@ Foam::Particle<ParticleType>::Particle ) : cloud_(cloud), - facei_(-1), + position_(), + cellI_(-1), + faceI_(-1), stepFraction_(0.0), + tetFaceI_(-1), + tetPtI_(-1), origProc_(Pstream::myProcNo()), origId_(-1) { - // readFields : read additional data. Should be consistent with writeFields. if (is.format() == IOstream::ASCII) { - is >> position_ >> celli_; + is >> position_ >> cellI_; + if (readFields) { - is >> origProc_ >> origId_; + is >> tetFaceI_ >> tetPtI_ >> origProc_ >> origId_; } } else @@ -69,9 +74,11 @@ Foam::Particle<ParticleType>::Particle ( reinterpret_cast<char*>(&position_), sizeof(position_) - + sizeof(celli_) - + sizeof(facei_) + + sizeof(cellI_) + + sizeof(faceI_) + sizeof(stepFraction_) + + sizeof(tetFaceI_) + + sizeof(tetPtI_) + sizeof(origProc_) + sizeof(origId_) ); @@ -82,18 +89,13 @@ Foam::Particle<ParticleType>::Particle ( reinterpret_cast<char*>(&position_), sizeof(position_) - + sizeof(celli_) - + sizeof(facei_) + + sizeof(cellI_) + + sizeof(faceI_) + sizeof(stepFraction_) ); } } - if (celli_ == -1) - { - celli_ = cloud_.pMesh().findCell(position_); - } - // Check state of Istream is.check("Particle<ParticleType>::Particle(Istream&)"); } @@ -176,29 +178,33 @@ void Foam::Particle<ParticleType>::write(Ostream& os, bool writeFields) const if (writeFields) { // Write the additional entries - os << position_ - << token::SPACE << celli_ - << token::SPACE << origProc_ - << token::SPACE << origId_; + os << position_ + << token::SPACE << cellI_ + << token::SPACE << tetFaceI_ + << token::SPACE << tetPtI_ + << token::SPACE << origProc_ + << token::SPACE << origId_; } else { - os << position_ - << token::SPACE << celli_; + os << position_ + << token::SPACE << cellI_; } } else { - // In binary write both celli_ and facei_, needed for parallel transfer + // In binary write both cellI_ and faceI_, needed for parallel transfer if (writeFields) { os.write ( reinterpret_cast<const char*>(&position_), sizeof(position_) - + sizeof(celli_) - + sizeof(facei_) + + sizeof(cellI_) + + sizeof(faceI_) + sizeof(stepFraction_) + + sizeof(tetFaceI_) + + sizeof(tetPtI_) + sizeof(origProc_) + sizeof(origId_) ); @@ -209,8 +215,8 @@ void Foam::Particle<ParticleType>::write(Ostream& os, bool writeFields) const ( reinterpret_cast<const char*>(&position_), sizeof(position_) - + sizeof(celli_) - + sizeof(facei_) + + sizeof(cellI_) + + sizeof(faceI_) + sizeof(stepFraction_) ); } diff --git a/src/lagrangian/basic/indexedParticle/indexedParticle.H b/src/lagrangian/basic/indexedParticle/indexedParticle.H index 9f725d5f550883f1c7bd9e375e1d49138fc52f33..6c940d0b70b7d109cecfa1dfaf33d61c4e4eb3ac 100644 --- a/src/lagrangian/basic/indexedParticle/indexedParticle.H +++ b/src/lagrangian/basic/indexedParticle/indexedParticle.H @@ -67,11 +67,26 @@ public: ( const Cloud<indexedParticle>& c, const vector& position, - const label celli, + const label cellI, + const label tetFaceI, + const label tetPtI, const label index = 0 ) : - Particle<indexedParticle>(c, position, celli), + Particle<indexedParticle>(c, position, cellI, tetFaceI, tetPtI), + index_(index) + {} + + //- Construct from components, with searching for tetFace and tetPt + indexedParticle + ( + const Cloud<indexedParticle>& c, + const vector& position, + const label cellI, + const label index = 0 + ) + : + Particle<indexedParticle>(c, position, cellI), index_(index) {} diff --git a/src/lagrangian/basic/passiveParticle/passiveParticle.H b/src/lagrangian/basic/passiveParticle/passiveParticle.H index fec00ea922f44ccbcd88ee3abcf970ce398ceaa4..50697e3a69d2f65b749c341be3eec8500803d833 100644 --- a/src/lagrangian/basic/passiveParticle/passiveParticle.H +++ b/src/lagrangian/basic/passiveParticle/passiveParticle.H @@ -60,10 +60,25 @@ public: ( const Cloud<passiveParticle>& c, const vector& position, - const label celli + const label cellI, + const label tetFaceI, + const label tetPtI ) : - Particle<passiveParticle>(c, position, celli) + Particle<passiveParticle>(c, position, cellI, tetFaceI, tetPtI) + {} + + //- Construct from components, with searching for tetFace and + // tetPt unless disabled by doCellFacePt = false. + passiveParticle + ( + const Cloud<passiveParticle>& c, + const vector& position, + const label cellI, + bool doCellFacePt = true + ) + : + Particle<passiveParticle>(c, position, cellI, doCellFacePt) {} //- Construct from Istream diff --git a/src/lagrangian/coalCombustion/coalParcel/coalParcel.C b/src/lagrangian/coalCombustion/coalParcel/coalParcel.C index 21086b996cdc038654db09b3186c60f464cce718..3445afe14eb3bd32418d0f01e087a92414158d9f 100644 --- a/src/lagrangian/coalCombustion/coalParcel/coalParcel.C +++ b/src/lagrangian/coalCombustion/coalParcel/coalParcel.C @@ -31,10 +31,19 @@ Foam::coalParcel::coalParcel ( ReactingMultiphaseCloud<coalParcel>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ) : - ReactingMultiphaseParcel<coalParcel>(owner, position, cellI) + ReactingMultiphaseParcel<coalParcel> + ( + owner, + position, + cellI, + tetFaceI, + tetPtI + ) {} @@ -43,9 +52,12 @@ Foam::coalParcel::coalParcel ReactingMultiphaseCloud<coalParcel>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& pi0, @@ -62,9 +74,12 @@ Foam::coalParcel::coalParcel owner, position, cellI, + tetFaceI, + tetPtI, typeId, nParticle0, d0, + dTarget0, U0, f0, pi0, diff --git a/src/lagrangian/coalCombustion/coalParcel/coalParcel.H b/src/lagrangian/coalCombustion/coalParcel/coalParcel.H index 2904ccbbcfd12d913e4412e3de841070aa5c363f..6195de8439bb01ce34a359bac1d296c3aff3d398 100644 --- a/src/lagrangian/coalCombustion/coalParcel/coalParcel.H +++ b/src/lagrangian/coalCombustion/coalParcel/coalParcel.H @@ -63,7 +63,9 @@ public: ( ReactingMultiphaseCloud<coalParcel>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ); //- Construct from components @@ -72,9 +74,12 @@ public: ReactingMultiphaseCloud<coalParcel>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& pi0, diff --git a/src/lagrangian/dieselSpray/Make/options b/src/lagrangian/dieselSpray/Make/options index 454c4f15bfae582e59a09888022a83a0261b2475..40cb013fbb7939a2c04f5e346bd6619018400346 100644 --- a/src/lagrangian/dieselSpray/Make/options +++ b/src/lagrangian/dieselSpray/Make/options @@ -1,5 +1,6 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \ -I$(LIB_SRC)/turbulenceModels \ -I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \ @@ -16,6 +17,7 @@ EXE_INC = \ LIB_LIBS = \ -llagrangian \ + -lmeshTools \ -lfiniteVolume \ -lcompressibleRASModels \ -lcompressibleLESModels \ diff --git a/src/lagrangian/dieselSpray/parcel/boundaryTreatment.H b/src/lagrangian/dieselSpray/parcel/boundaryTreatment.H index 4420773172bd85a6e5bd84fa60d8ddea4b38ac7f..a2e03dc676fbfe750739a489046148913f0befe2 100644 --- a/src/lagrangian/dieselSpray/parcel/boundaryTreatment.H +++ b/src/lagrangian/dieselSpray/parcel/boundaryTreatment.H @@ -15,12 +15,11 @@ if (isA<wallPolyPatch>(pbMesh[patch(face())])) else if (isA<wedgePolyPatch>(pbMesh[patch(face())])) { // check if parcel is trying to move out of the domain - label patchi = patch(face()); - label patchFacei = patchFace(patchi, face()); - const polyPatch& patch = mesh.boundaryMesh()[patchi]; - vector nf = patch.faceAreas()[patchFacei]; + + vector nf = normal(); scalar Un = U() & nf; + if (Un > 0) { scalar Un2 = U() & n(); @@ -30,12 +29,11 @@ else if (isA<wedgePolyPatch>(pbMesh[patch(face())])) else if (isA<symmetryPolyPatch>(pbMesh[patch(face())])) { // check if parcel is trying to move out of the domain - label patchi = patch(face()); - label patchFacei = patchFace(patchi, face()); - const polyPatch& patch = mesh.boundaryMesh()[patchi]; - vector nf = patch.faceAreas()[patchFacei]; + + vector nf = normal(); scalar Un = U() & nf; + if (Un > 0) { if (sDB.twoD()) diff --git a/src/lagrangian/dieselSpray/parcel/parcel.C b/src/lagrangian/dieselSpray/parcel/parcel.C index b255d61916096d4d1aa561863e488ec375044c33..50837a923d42581b8f60e3b5933744b97ae30c32 100644 --- a/src/lagrangian/dieselSpray/parcel/parcel.C +++ b/src/lagrangian/dieselSpray/parcel/parcel.C @@ -50,6 +50,8 @@ Foam::parcel::parcel const Cloud<parcel>& cloud, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const vector& n, const scalar d, const scalar T, @@ -67,7 +69,7 @@ Foam::parcel::parcel const List<word>& liquidNames ) : - Particle<parcel>(cloud, position, cellI), + Particle<parcel>(cloud, position, cellI, tetFaceI, tetPtI), liquidComponents_ ( liquidNames @@ -103,12 +105,13 @@ bool Foam::parcel::move(spray& sDB) label Nf = fuels.components().size(); label Ns = sDB.composition().Y().size(); + tetIndices tetIs = this->currentTetIndices(); + // Calculate the interpolated gas properties at the position of the parcel - vector Up = sDB.UInterpolator().interpolate(position(), cell()) - + Uturb(); - scalar rhog = sDB.rhoInterpolator().interpolate(position(), cell()); - scalar pg = sDB.pInterpolator().interpolate(position(), cell()); - scalar Tg = sDB.TInterpolator().interpolate(position(), cell()); + vector Up = sDB.UInterpolator().interpolate(position(), tetIs) + Uturb(); + scalar rhog = sDB.rhoInterpolator().interpolate(position(), tetIs); + scalar pg = sDB.pInterpolator().interpolate(position(), tetIs); + scalar Tg = sDB.TInterpolator().interpolate(position(), tetIs); scalarField Yfg(Nf, 0.0); @@ -119,8 +122,8 @@ bool Foam::parcel::move(spray& sDB) if (sDB.isLiquidFuel()[i]) { label j = sDB.gasToLiquidIndex()[i]; - scalar Yicelli = Yi[cell()]; - Yfg[j] = Yicelli; + scalar YicellI = Yi[cell()]; + Yfg[j] = YicellI; } cpMixture += Yi[cell()]*sDB.gasProperties()[i].Cp(Tg); } @@ -199,8 +202,8 @@ bool Foam::parcel::move(spray& sDB) // remember which cell the parcel is in // since this will change if a face is hit - label celli = cell(); - scalar p = sDB.p()[celli]; + label cellI = cell(); + scalar p = sDB.p()[cellI]; // track parcel to face, or end of trajectory if (keepParcel) @@ -259,7 +262,7 @@ bool Foam::parcel::move(spray& sDB) ( dt, sDB, - celli, + cellI, face() ); @@ -283,11 +286,11 @@ bool Foam::parcel::move(spray& sDB) // Update the Spray Source Terms forAll(nMass, i) { - sDB.srhos()[i][celli] += oMass[i] - nMass[i]; + sDB.srhos()[i][cellI] += oMass[i] - nMass[i]; } - sDB.sms()[celli] += oMom - nMom; + sDB.sms()[cellI] += oMom - nMom; - sDB.shs()[celli] += oTotMass*(oH + oPE) - m()*(nH + nPE); + sDB.shs()[cellI] += oTotMass*(oH + oPE) - m()*(nH + nPE); // Remove evaporated mass from stripped mass ms() -= ms()*(oTotMass-m())/oTotMass; @@ -300,11 +303,11 @@ bool Foam::parcel::move(spray& sDB) // ... and add the removed 'stuff' to the gas forAll(nMass, i) { - sDB.srhos()[i][celli] += nMass[i]; + sDB.srhos()[i][cellI] += nMass[i]; } - sDB.sms()[celli] += nMom; - sDB.shs()[celli] += m()*(nH + nPE); + sDB.sms()[cellI] += nMom; + sDB.shs()[cellI] += m()*(nH + nPE); } if (onBoundary() && keepParcel) @@ -327,8 +330,8 @@ void Foam::parcel::updateParcelProperties ( const scalar dt, spray& sDB, - const label celli, - const label facei + const label cellI, + const label faceI ) { const liquidMixture& fuels = sDB.fuels(); @@ -340,34 +343,34 @@ void Foam::parcel::updateParcelProperties scalar W = 0.0; for (label i=0; i<Ns; i++) { - W += sDB.composition().Y()[i][celli]/sDB.gasProperties()[i].W(); + W += sDB.composition().Y()[i][cellI]/sDB.gasProperties()[i].W(); } W = 1.0/W; // Calculate the interpolated gas properties at the position of the parcel - vector Up = sDB.UInterpolator().interpolate(position(), celli, facei) + vector Up = sDB.UInterpolator().interpolate(position(), cellI, faceI) + Uturb(); - scalar rhog = sDB.rhoInterpolator().interpolate(position(), celli, facei); - scalar pg = sDB.pInterpolator().interpolate(position(), celli, facei); - scalar Tg0 = sDB.TInterpolator().interpolate(position(), celli, facei); + scalar rhog = sDB.rhoInterpolator().interpolate(position(), cellI, faceI); + scalar pg = sDB.pInterpolator().interpolate(position(), cellI, faceI); + scalar Tg0 = sDB.TInterpolator().interpolate(position(), cellI, faceI); // correct the gaseous temperature for evaporated fuel scalar cpMix = 0.0; for (label i=0; i<Ns; i++) { - cpMix += sDB.composition().Y()[i][celli] + cpMix += sDB.composition().Y()[i][cellI] *sDB.gasProperties()[i].Cp(T()); } - scalar cellV = sDB.mesh().V()[celli]; - scalar rho = sDB.rho()[celli]; + scalar cellV = sDB.mesh().V()[cellI]; + scalar rho = sDB.rho()[cellI]; scalar cellMass = rho*cellV; - scalar dh = sDB.shs()[celli]; + scalar dh = sDB.shs()[cellI]; scalarField addedMass(Nf, 0.0); forAll(addedMass, i) { - addedMass[i] += sDB.srhos()[i][celli]*cellV; + addedMass[i] += sDB.srhos()[i][cellI]*cellV; } scalar Tg = Tg0 + dh/(cpMix*cellMass); @@ -378,7 +381,7 @@ void Foam::parcel::updateParcelProperties { label j = sDB.liquidToGasIndex()[i]; const volScalarField& Yj = sDB.composition().Y()[j]; - scalar Yfg0 = Yj[celli]; + scalar Yfg0 = Yj[cellI]; Yfg[i] = (Yfg0*cellMass + addedMass[i])/(addedMass[i] + cellMass); } @@ -389,7 +392,7 @@ void Foam::parcel::updateParcelProperties setRelaxationTimes ( - celli, + cellI, tauMomentum, tauEvaporation, tauHeatTransfer, @@ -492,14 +495,14 @@ void Foam::parcel::updateParcelProperties { label j = sDB.liquidToGasIndex()[i]; const volScalarField& Yj = sDB.composition().Y()[j]; - scalar Yfg0 = Yj[celli]; + scalar Yfg0 = Yj[cellI]; Yfg[i] = (Yfg0*cellMass + addedMass[i] + dm) /(addedMass[i] + cellMass + dm); } setRelaxationTimes ( - celli, + cellI, tauMomentum, tauEvaporation, tauHeatTransfer, @@ -530,7 +533,7 @@ void Foam::parcel::updateParcelProperties } else { - scalar Y = sDB.composition().Y()[i][celli]; + scalar Y = sDB.composition().Y()[i][cellI]; cpMix += Y*sDB.gasProperties()[i].Cp(Taverage); } } @@ -579,7 +582,7 @@ void Foam::parcel::updateParcelProperties { // can not go above boiling temperature scalar Terr = 1.0e-3; - label n=0; + label n = 0; scalar dT = 1.0; scalar pOld = pAtSurface; while (dT > Terr) diff --git a/src/lagrangian/dieselSpray/parcel/parcel.H b/src/lagrangian/dieselSpray/parcel/parcel.H index c96abd9155c8a933e42b276ce0b4e1df316246d5..90d46e0231e4d51f38255c66cf962c88693c6340 100644 --- a/src/lagrangian/dieselSpray/parcel/parcel.H +++ b/src/lagrangian/dieselSpray/parcel/parcel.H @@ -113,7 +113,7 @@ class parcel //- Set the relaxation times void setRelaxationTimes ( - label celli, + label cellI, scalar& tauMomentum, scalarField& tauEvaporation, scalar& tauHeatTransfer, @@ -133,8 +133,8 @@ class parcel ( const scalar dt, spray& sprayData, - const label celli, - const label facei + const label cellI, + const label faceI ); @@ -150,7 +150,9 @@ public: ( const Cloud<parcel>& cloud, const vector& position, - const label celli, + const label cellI, + const label tetFaceI, + const label tetPtI, const vector& n, const scalar d, const scalar T, diff --git a/src/lagrangian/dieselSpray/parcel/setRelaxationTimes.C b/src/lagrangian/dieselSpray/parcel/setRelaxationTimes.C index 7565a747102590720112f76ecf19de5adf40a7ac..0b4b305f0cdf82168eac3ba7dae1235ff116df33 100644 --- a/src/lagrangian/dieselSpray/parcel/setRelaxationTimes.C +++ b/src/lagrangian/dieselSpray/parcel/setRelaxationTimes.C @@ -36,7 +36,7 @@ License void Foam::parcel::setRelaxationTimes ( - label celli, + label cellI, scalar& tauMomentum, scalarField& tauEvaporation, scalar& tauHeatTransfer, @@ -70,7 +70,7 @@ void Foam::parcel::setRelaxationTimes for (label i=0; i<Ns; i++) { - scalar Y = sDB.composition().Y()[i][celli]; + scalar Y = sDB.composition().Y()[i][cellI]; W += Y/sDB.gasProperties()[i].W(); // Using mass-fractions to average... kMixture += Y*sDB.gasProperties()[i].kappa(Tf); @@ -87,7 +87,7 @@ void Foam::parcel::setRelaxationTimes for (label i=0; i<Nf; i++) { label j = sDB.liquidToGasIndex()[i]; - scalar Y = sDB.composition().Y()[j][celli]; + scalar Y = sDB.composition().Y()[j][cellI]; scalar Wi = sDB.gasProperties()[j].W(); Yf[i] = Y; Xf[i] = Y*W/Wi; @@ -264,10 +264,10 @@ void Foam::parcel::setRelaxationTimes forAll(sDB.gasProperties(), k) { vapourSurfaceEnthalpy += - sDB.composition().Y()[k][celli] + sDB.composition().Y()[k][cellI] *sDB.gasProperties()[k].H(tBoilingSurface); vapourFarEnthalpy += - sDB.composition().Y()[k][celli] + sDB.composition().Y()[k][cellI] *sDB.gasProperties()[k].H(temperature); } diff --git a/src/lagrangian/dieselSpray/spray/findInjectorCell.H b/src/lagrangian/dieselSpray/spray/findInjectorCell.H index ff4eea7904a78fa3b5fa03f224d9597041540b0e..e9e8a7bfa809bffad01ef79bbfe47d93eda40184 100644 --- a/src/lagrangian/dieselSpray/spray/findInjectorCell.H +++ b/src/lagrangian/dieselSpray/spray/findInjectorCell.H @@ -22,7 +22,14 @@ reduce(foundCell, orOp<bool>()); if (!foundCell) { injectionPosition = it->position(n); - injectorCell = mesh_.findCell(injectionPosition); + + findCellFacePt + ( + injectionPosition, + injectorCell, + injectorTetFaceI, + injectorTetPtI + ); if (injectorCell >= 0) { diff --git a/src/lagrangian/dieselSpray/spray/spray.C b/src/lagrangian/dieselSpray/spray/spray.C index 6ff9319f9a55f5eb013fe9a3a0ba7c15f9484be8..81047c6809480bc37eeda8868845c13b6a52c986 100644 --- a/src/lagrangian/dieselSpray/spray/spray.C +++ b/src/lagrangian/dieselSpray/spray/spray.C @@ -241,16 +241,16 @@ Foam::spray::spray label n=0; // check for the type of boundary condition - forAll(bMesh, patchi) + forAll(bMesh, patchI) { - if (isA<symmetryPolyPatch>(bMesh[patchi])) + if (isA<symmetryPolyPatch>(bMesh[patchI])) { symPlaneExist = true; } - else if (isA<wedgePolyPatch>(bMesh[patchi])) + else if (isA<wedgePolyPatch>(bMesh[patchI])) { wedgeExist = true; - patches[n++] = patchi; + patches[n++] = patchI; } } diff --git a/src/lagrangian/dieselSpray/spray/sprayFunctions.C b/src/lagrangian/dieselSpray/spray/sprayFunctions.C index 2a7de13c54c8d06e793a1fed5b9a494adbb3ce24..9a1d066942862bb58289459455dccb0143fb7e63 100644 --- a/src/lagrangian/dieselSpray/spray/sprayFunctions.C +++ b/src/lagrangian/dieselSpray/spray/sprayFunctions.C @@ -149,9 +149,9 @@ Foam::scalar Foam::spray::liquidTotalEnthalpy() const forAllConstIter(spray, *this, iter) { - label celli = iter().cell(); + label cellI = iter().cell(); scalar T = iter().T(); - scalar pc = p()[celli]; + scalar pc = p()[cellI]; scalar rho = fuels().rho(pc, T, iter().X()); scalar hlat = fuels().hl(pc, T, iter().X()); scalar hg = 0.0; @@ -351,8 +351,8 @@ Foam::scalar Foam::spray::smd() const forAllConstIter(spray, *this, iter) { - label celli = iter().cell(); - scalar Pc = p()[celli]; + label cellI = iter().cell(); + scalar Pc = p()[cellI]; scalar T = iter().T(); scalar rho = fuels_->rho(Pc, T, iter().X()); diff --git a/src/lagrangian/dieselSpray/spray/sprayInject.C b/src/lagrangian/dieselSpray/spray/sprayInject.C index f27769dfb6d7e23ac3ec26528f084fcf6d8ed29a..06dbc9b7c6160aae62ed2fd345c028f9c1c875a4 100644 --- a/src/lagrangian/dieselSpray/spray/sprayInject.C +++ b/src/lagrangian/dieselSpray/spray/sprayInject.C @@ -107,7 +107,17 @@ void Foam::spray::inject() scalar deviation = breakup().y0(); scalar ddev = breakup().yDot0(); - label injectorCell = mesh_.findCell(injectionPosition); + label injectorCell = -1; + label injectorTetFaceI = -1; + label injectorTetPtI = -1; + + findCellFacePt + ( + injectionPosition, + injectorCell, + injectorTetFaceI, + injectorTetPtI + ); # include "findInjectorCell.H" @@ -122,6 +132,8 @@ void Foam::spray::inject() *this, injectionPosition, injectorCell, + injectorTetFaceI, + injectorTetPtI, normal, diameter, it->T(toi), diff --git a/src/lagrangian/dieselSpray/spray/sprayOps.C b/src/lagrangian/dieselSpray/spray/sprayOps.C index 6210c0196727bd5fa65116a98fb1410477c67c49..7904771fa14cb31e5eeb3f73ef832f2a435ec9a5 100644 --- a/src/lagrangian/dieselSpray/spray/sprayOps.C +++ b/src/lagrangian/dieselSpray/spray/sprayOps.C @@ -88,7 +88,7 @@ void Foam::spray::breakupLoop() vector velocity = UInterpolator().interpolate ( elmnt().position(), - elmnt().cell() + elmnt().currentTetIndices() ); // liquidCore < 0.5 indicates discrete drops @@ -122,7 +122,7 @@ void Foam::spray::atomizationLoop() vector velocity = UInterpolator().interpolate ( elmnt().position(), - elmnt().cell() + elmnt().currentTetIndices() ); // liquidCore > 0.5 indicates a liquid core diff --git a/src/lagrangian/dieselSpray/spraySubModels/breakupModel/SHF/SHF.C b/src/lagrangian/dieselSpray/spraySubModels/breakupModel/SHF/SHF.C index 12a3a6771b9a6da4913c21c001f8406d13354e0a..4824d253f856f99ca16ab5df74220b23d2206c6d 100644 --- a/src/lagrangian/dieselSpray/spraySubModels/breakupModel/SHF/SHF.C +++ b/src/lagrangian/dieselSpray/spraySubModels/breakupModel/SHF/SHF.C @@ -102,14 +102,14 @@ void Foam::SHF::breakupParcel const liquidMixture& fuels ) const { - label celli = p.cell(); + label cellI = p.cell(); scalar T = p.T(); - scalar pc = spray_.p()[celli]; + scalar pc = spray_.p()[cellI]; scalar sigma = fuels.sigma(pc, T, p.X()); scalar rhoLiquid = fuels.rho(pc, T, p.X()); scalar muLiquid = fuels.mu(pc, T, p.X()); - scalar rhoGas = spray_.rho()[celli]; + scalar rhoGas = spray_.rho()[cellI]; scalar weGas = p.We(vel, rhoGas, sigma); scalar weLiquid = p.We(vel, rhoLiquid, sigma); @@ -237,6 +237,8 @@ void Foam::SHF::breakupParcel spray_, p.position(), p.cell(), + p.tetFace(), + p.tetPt(), p.n(), d, p.T(), diff --git a/src/lagrangian/dieselSpray/spraySubModels/breakupModel/reitzKHRT/reitzKHRT.C b/src/lagrangian/dieselSpray/spraySubModels/breakupModel/reitzKHRT/reitzKHRT.C index 921af9c5858c13d2836d9701d9a88fe374a78aaa..5c03fedba98a836d6e60df911eb4f7ff9ca1a7fd 100644 --- a/src/lagrangian/dieselSpray/spraySubModels/breakupModel/reitzKHRT/reitzKHRT.C +++ b/src/lagrangian/dieselSpray/spraySubModels/breakupModel/reitzKHRT/reitzKHRT.C @@ -78,15 +78,15 @@ void Foam::reitzKHRT::breakupParcel const liquidMixture& fuels ) const { - label celli = p.cell(); + label cellI = p.cell(); scalar T = p.T(); scalar r = 0.5*p.d(); - scalar pc = spray_.p()[celli]; + scalar pc = spray_.p()[cellI]; scalar sigma = fuels.sigma(pc, T, p.X()); scalar rhoLiquid = fuels.rho(pc, T, p.X()); scalar muLiquid = fuels.mu(pc, T, p.X()); - scalar rhoGas = spray_.rho()[celli]; + scalar rhoGas = spray_.rho()[cellI]; scalar Np = p.N(rhoLiquid); scalar semiMass = Np*pow3(p.d()); @@ -198,6 +198,8 @@ void Foam::reitzKHRT::breakupParcel spray_, p.position(), p.cell(), + p.tetFace(), + p.tetPt(), p.n(), dc, p.T(), diff --git a/src/lagrangian/dieselSpray/spraySubModels/wallModel/reflectParcel/reflectParcel.C b/src/lagrangian/dieselSpray/spraySubModels/wallModel/reflectParcel/reflectParcel.C index e776b78f49046a99b43396fb3d9e39b5907135b8..162484d5f23aa7cb4c4ca2cb2027d5cf8715f447 100644 --- a/src/lagrangian/dieselSpray/spraySubModels/wallModel/reflectParcel/reflectParcel.C +++ b/src/lagrangian/dieselSpray/spraySubModels/wallModel/reflectParcel/reflectParcel.C @@ -70,18 +70,18 @@ Foam::reflectParcel::~reflectParcel() bool Foam::reflectParcel::wallTreatment ( parcel& p, - const label globalFacei + const label globalFaceI ) const { - label patchi = p.patch(globalFacei); - label facei = p.patchFace(patchi, globalFacei); + label patchI = p.patch(globalFaceI); + label faceI = p.patchFace(patchI, globalFaceI); const polyMesh& mesh = spray_.mesh(); - if (isA<wallPolyPatch>(mesh_.boundaryMesh()[patchi])) + if (isA<wallPolyPatch>(mesh_.boundaryMesh()[patchI])) { // wallNormal defined to point outwards of domain - vector Sf = mesh_.Sf().boundaryField()[patchi][facei]; + vector Sf = mesh_.Sf().boundaryField()[patchI][faceI]; Sf /= mag(Sf); if (!mesh.moving()) @@ -97,17 +97,17 @@ bool Foam::reflectParcel::wallTreatment else { // moving mesh - vector Ub1 = U_.boundaryField()[patchi][facei]; - vector Ub0 = U_.oldTime().boundaryField()[patchi][facei]; + vector Ub1 = U_.boundaryField()[patchI][faceI]; + vector Ub0 = U_.oldTime().boundaryField()[patchI][faceI]; scalar dt = spray_.runTime().deltaTValue(); const vectorField& oldPoints = mesh.oldPoints(); - const vector& Cf1 = mesh.faceCentres()[globalFacei]; + const vector& Cf1 = mesh.faceCentres()[globalFaceI]; - vector Cf0 = mesh.faces()[globalFacei].centre(oldPoints); + vector Cf0 = mesh.faces()[globalFaceI].centre(oldPoints); vector Cf = Cf0 + p.stepFraction()*(Cf1 - Cf0); - vector Sf0 = mesh.faces()[globalFacei].normal(oldPoints); + vector Sf0 = mesh.faces()[globalFaceI].normal(oldPoints); // for layer addition Sf0 = vector::zero and we use Sf if (mag(Sf0) > SMALL) @@ -157,10 +157,10 @@ bool Foam::reflectParcel::wallTreatment { Info<< "reflectParcel:: v = " << v << ", Ub = " << Ub - << ", facei = " << facei - << ", patchi = " << patchi - << ", globalFacei = " << globalFacei - << ", name = " << mesh_.boundaryMesh()[patchi].name() + << ", faceI = " << faceI + << ", patchI = " << patchI + << ", globalFaceI = " << globalFaceI + << ", name = " << mesh_.boundaryMesh()[patchI].name() << endl; } */ @@ -175,7 +175,7 @@ bool Foam::reflectParcel::wallTreatment else { FatalErrorIn("bool reflectParcel::wallTreatment(parcel& parcel) const") - << " parcel has hit a boundary " << mesh_.boundary()[patchi].type() + << " parcel has hit a boundary " << mesh_.boundary()[patchI].type() << " which not yet has been implemented." << nl << abort(FatalError); } diff --git a/src/lagrangian/dieselSpray/spraySubModels/wallModel/reflectParcel/reflectParcel.H b/src/lagrangian/dieselSpray/spraySubModels/wallModel/reflectParcel/reflectParcel.H index be19fafe24bcade942eedde95db0eb18ddf44cc3..0316e1d819e1c2fe9519ef98dae4a2ffcdd18806 100644 --- a/src/lagrangian/dieselSpray/spraySubModels/wallModel/reflectParcel/reflectParcel.H +++ b/src/lagrangian/dieselSpray/spraySubModels/wallModel/reflectParcel/reflectParcel.H @@ -87,7 +87,7 @@ public: //- Return true if parcel is to be kept, and false if it is to be // removed - bool wallTreatment(parcel& parcel, const label facei) const; + bool wallTreatment(parcel& parcel, const label faceI) const; }; diff --git a/src/lagrangian/dieselSpray/spraySubModels/wallModel/removeParcel/removeParcel.C b/src/lagrangian/dieselSpray/spraySubModels/wallModel/removeParcel/removeParcel.C index b62ba09778d8351c369884f8574f7b49a6ddb97b..f4f74742de93d2697056e84b1f783e2e5265125f 100644 --- a/src/lagrangian/dieselSpray/spraySubModels/wallModel/removeParcel/removeParcel.C +++ b/src/lagrangian/dieselSpray/spraySubModels/wallModel/removeParcel/removeParcel.C @@ -65,7 +65,7 @@ Foam::removeParcel::~removeParcel() bool Foam::removeParcel::wallTreatment ( parcel&, - const label facei + const label faceI ) const { return false; diff --git a/src/lagrangian/dieselSpray/spraySubModels/wallModel/removeParcel/removeParcel.H b/src/lagrangian/dieselSpray/spraySubModels/wallModel/removeParcel/removeParcel.H index f07761847a95b55939b5b08b87b12cea79f29e71..a25b04b565d0ada9358782d38efc04a9390384a2 100644 --- a/src/lagrangian/dieselSpray/spraySubModels/wallModel/removeParcel/removeParcel.H +++ b/src/lagrangian/dieselSpray/spraySubModels/wallModel/removeParcel/removeParcel.H @@ -73,7 +73,7 @@ public: //- Return true if parcel is to be kept, and false if it is to be // removed - bool wallTreatment(parcel& parcel, const label facei) const; + bool wallTreatment(parcel& parcel, const label faceI) const; }; diff --git a/src/lagrangian/dieselSpray/spraySubModels/wallModel/wallModel/wallModel.H b/src/lagrangian/dieselSpray/spraySubModels/wallModel/wallModel/wallModel.H index 598c6803d125847382311fda24de824ca9e92d09..a17e4c078fb6d44539f0646dbfb4692e94211d2d 100644 --- a/src/lagrangian/dieselSpray/spraySubModels/wallModel/wallModel/wallModel.H +++ b/src/lagrangian/dieselSpray/spraySubModels/wallModel/wallModel/wallModel.H @@ -118,7 +118,7 @@ public: virtual bool wallTreatment ( parcel&, - const label facei + const label faceI ) const = 0; }; diff --git a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C index 80e0dea37d5faa8b9914f8dbe23707954ba5c52b..8b92319bcb545972c6305688344ca8f8aecab161 100644 --- a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C +++ b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C @@ -109,161 +109,86 @@ void Foam::DsmcCloud<ParcelType>::initialise numberDensities /= nParticle_; - forAll(mesh_.cells(), cell) + forAll(mesh_.cells(), cellI) { - const vector& cC = mesh_.cellCentres()[cell]; - const labelList& cellFaces = mesh_.cells()[cell]; - const scalar cV = mesh_.cellVolumes()[cell]; - - label nTets = 0; + List<tetIndices> cellTets = polyMeshTetDecomposition::cellTetIndices + ( + mesh_, + cellI + ); - // Each face is split into nEdges (or nVertices) - 2 tets. - forAll(cellFaces, face) + forAll(cellTets, tetI) { - nTets += mesh_.faces()[cellFaces[face]].size() - 2; - } - - // Calculate the cumulative tet volumes circulating around the cell and - // record the vertex labels of each. - scalarList cTetVFracs(nTets, 0.0); + const tetIndices& cellTetIs = cellTets[tetI]; - List<labelList> tetPtIs(nTets, labelList(3,-1)); + tetPointRef tet = cellTetIs.tet(mesh_); - // Keep track of which tet this is. - label tet = 0; + scalar tetVolume = tet.mag(); - forAll(cellFaces, face) - { - const labelList& facePoints = mesh_.faces()[cellFaces[face]]; - - label pointI = 1; - while ((pointI + 1) < facePoints.size()) + forAll(molecules, i) { + const word& moleculeName(molecules[i]); - const vector& pA = mesh_.points()[facePoints[0]]; - const vector& pB = mesh_.points()[facePoints[pointI]]; - const vector& pC = mesh_.points()[facePoints[pointI + 1]]; - - cTetVFracs[tet] = - mag(((pA - cC) ^ (pB - cC)) & (pC - cC))/(cV*6.0) - + cTetVFracs[max((tet - 1),0)]; - - tetPtIs[tet][0] = facePoints[0]; - tetPtIs[tet][1] = facePoints[pointI]; - tetPtIs[tet][2] = facePoints[pointI + 1]; - - pointI++; - tet++; - } - } - - // Force the last volume fraction value to 1.0 to avoid any - // rounding/non-flat face errors giving a value < 1.0 - cTetVFracs[nTets - 1] = 1.0; - - forAll(molecules, i) - { - const word& moleculeName(molecules[i]); - - label typeId(findIndex(typeIdList_, moleculeName)); + label typeId(findIndex(typeIdList_, moleculeName)); - if (typeId == -1) - { - FatalErrorIn("Foam::DsmcCloud<ParcelType>::initialise") - << "typeId " << moleculeName << "not defined." << nl - << abort(FatalError); - } + if (typeId == -1) + { + FatalErrorIn("Foam::DsmcCloud<ParcelType>::initialise") + << "typeId " << moleculeName << "not defined." << nl + << abort(FatalError); + } - const typename ParcelType::constantProperties& cP = + const typename ParcelType::constantProperties& cP = constProps(typeId); - scalar numberDensity = numberDensities[i]; - - // Calculate the number of particles required - scalar particlesRequired = numberDensity*mesh_.cellVolumes()[cell]; - - // Only integer numbers of particles can be inserted - label nParticlesToInsert = label(particlesRequired); + scalar numberDensity = numberDensities[i]; - // Add another particle with a probability proportional to the - // remainder of taking the integer part of particlesRequired - if ((particlesRequired - nParticlesToInsert) > rndGen_.scalar01()) - { - nParticlesToInsert++; - } + // Calculate the number of particles required + scalar particlesRequired = numberDensity*tetVolume; - for (label pI = 0; pI < nParticlesToInsert; pI++) - { - // Choose a random point in a generic tetrahedron + // Only integer numbers of particles can be inserted + label nParticlesToInsert = label(particlesRequired); - scalar s = rndGen_.scalar01(); - scalar t = rndGen_.scalar01(); - scalar u = rndGen_.scalar01(); - - if (s + t > 1.0) + // Add another particle with a probability proportional to the + // remainder of taking the integer part of particlesRequired + if + ( + (particlesRequired - nParticlesToInsert) + > rndGen_.scalar01() + ) { - s = 1.0 - s; - t = 1.0 - t; + nParticlesToInsert++; } - if (t + u > 1.0) - { - scalar tmp = u; - u = 1.0 - s - t; - t = 1.0 - tmp; - } - else if (s + t + u > 1.0) + for (label pI = 0; pI < nParticlesToInsert; pI++) { - scalar tmp = u; - u = s + t + u - 1.0; - s = 1.0 - t - tmp; - } + point p = tet.randomPoint(rndGen_); - // Choose a tetrahedron to insert in, based on their relative - // volumes - scalar tetSelection = rndGen_.scalar01(); + vector U = equipartitionLinearVelocity + ( + temperature, + cP.mass() + ); - // Selected tetrahedron - label sTet = -1; + scalar Ei = equipartitionInternalEnergy + ( + temperature, + cP.internalDegreesOfFreedom() + ); - forAll(cTetVFracs, tet) - { - sTet = tet; + U += velocity; - if (cTetVFracs[tet] >= tetSelection) - { - break; - } + addNewParcel + ( + p, + U, + Ei, + cellI, + cellTetIs.face(), + cellTetIs.tetPt(), + typeId + ); } - - vector p = - (1 - s - t - u)*cC - + s*mesh_.points()[tetPtIs[sTet][0]] - + t*mesh_.points()[tetPtIs[sTet][1]] - + u*mesh_.points()[tetPtIs[sTet][2]]; - - vector U = equipartitionLinearVelocity - ( - temperature, - cP.mass() - ); - - scalar Ei = equipartitionInternalEnergy - ( - temperature, - cP.internalDegreesOfFreedom() - ); - - U += velocity; - - addNewParcel - ( - p, - U, - Ei, - cell, - typeId - ); } } } @@ -306,9 +231,9 @@ void Foam::DsmcCloud<ParcelType>::collisions() label collisions = 0; - forAll(cellOccupancy_, celli) + forAll(cellOccupancy_, cellI) { - const DynamicList<ParcelType*>& cellParcels(cellOccupancy_[celli]); + const DynamicList<ParcelType*>& cellParcels(cellOccupancy_[cellI]); label nC(cellParcels.size()); @@ -327,13 +252,13 @@ void Foam::DsmcCloud<ParcelType>::collisions() // Inverse addressing specifying which subCell a parcel is in List<label> whichSubCell(cellParcels.size()); - const point& cC = mesh_.cellCentres()[celli]; + const point& cC = mesh_.cellCentres()[cellI]; forAll(cellParcels, i) { - ParcelType* p = cellParcels[i]; + const ParcelType& p = *cellParcels[i]; - vector relPos = p->position() - cC; + vector relPos = p.position() - cC; label subCell = pos(relPos.x()) + 2*pos(relPos.y()) + 4*pos(relPos.z()); @@ -345,16 +270,16 @@ void Foam::DsmcCloud<ParcelType>::collisions() // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - scalar sigmaTcRMax = sigmaTcRMax_[celli]; + scalar sigmaTcRMax = sigmaTcRMax_[cellI]; scalar selectedPairs = - collisionSelectionRemainder_[celli] + collisionSelectionRemainder_[cellI] + 0.5*nC*(nC - 1)*nParticle_*sigmaTcRMax*deltaT - /mesh_.cellVolumes()[celli]; + /mesh_.cellVolumes()[cellI]; label nCandidates(selectedPairs); - collisionSelectionRemainder_[celli] = selectedPairs - nCandidates; + collisionSelectionRemainder_[cellI] = selectedPairs - nCandidates; collisionCandidates += nCandidates; @@ -415,39 +340,30 @@ void Foam::DsmcCloud<ParcelType>::collisions() // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ParcelType* parcelP = cellParcels[candidateP]; - ParcelType* parcelQ = cellParcels[candidateQ]; - - label typeIdP = parcelP->typeId(); - label typeIdQ = parcelQ->typeId(); + ParcelType& parcelP = *cellParcels[candidateP]; + ParcelType& parcelQ = *cellParcels[candidateQ]; scalar sigmaTcR = binaryCollision().sigmaTcR ( - typeIdP, - typeIdQ, - parcelP->U(), - parcelQ->U() + parcelP, + parcelQ ); // Update the maximum value of sigmaTcR stored, but use the // initial value in the acceptance-rejection criteria because // the number of collision candidates selected was based on this - if (sigmaTcR > sigmaTcRMax_[celli]) + if (sigmaTcR > sigmaTcRMax_[cellI]) { - sigmaTcRMax_[celli] = sigmaTcR; + sigmaTcRMax_[cellI] = sigmaTcR; } if ((sigmaTcR/sigmaTcRMax) > rndGen_.scalar01()) { binaryCollision().collide ( - typeIdP, - typeIdQ, - parcelP->U(), - parcelQ->U(), - parcelP->Ei(), - parcelQ->Ei() + parcelP, + parcelQ ); collisions++; @@ -577,7 +493,9 @@ void Foam::DsmcCloud<ParcelType>::addNewParcel const vector& position, const vector& U, const scalar Ei, - const label cellId, + const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId ) { @@ -587,7 +505,9 @@ void Foam::DsmcCloud<ParcelType>::addNewParcel position, U, Ei, - cellId, + cellI, + tetFaceI, + tetPtI, typeId ); diff --git a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.H b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.H index aba26e7bf83ad714a05bcf9a57283800626fa3d2..1df0dee9748c505a39cb7b7737ddbeabf9782358 100644 --- a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.H +++ b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.H @@ -214,6 +214,10 @@ public: virtual ~DsmcCloud(); + //- Type of parcel the cloud was instantiated for + typedef ParcelType parcelType; + + // Member Functions // Access @@ -452,7 +456,9 @@ public: const vector& position, const vector& U, const scalar Ei, - const label cellId, + const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId ); diff --git a/src/lagrangian/dsmc/parcels/Templates/DsmcParcel/DsmcParcel.C b/src/lagrangian/dsmc/parcels/Templates/DsmcParcel/DsmcParcel.C index a88836309248ee76943caf6923a608ae7c644f60..a6a6949122c7204d7c21d55ac59b4dfac034858b 100644 --- a/src/lagrangian/dsmc/parcels/Templates/DsmcParcel/DsmcParcel.C +++ b/src/lagrangian/dsmc/parcels/Templates/DsmcParcel/DsmcParcel.C @@ -92,7 +92,9 @@ bool Foam::DsmcParcel<ParcelType>::hitPatch ( const polyPatch&, TrackData& td, - const label patchI + const label, + const scalar, + const tetIndices& ) { return false; @@ -125,7 +127,8 @@ template<class TrackData> void Foam::DsmcParcel<ParcelType>::hitWallPatch ( const wallPolyPatch& wpp, - TrackData& td + TrackData& td, + const tetIndices& tetIs ) { label wppIndex = wpp.index(); @@ -171,11 +174,8 @@ void Foam::DsmcParcel<ParcelType>::hitWallPatch td.cloud().wallInteraction().correct ( - wpp, - this->face(), - U_, - Ei_, - typeId_ + static_cast<ParcelType&>(*this), + wpp ); U_dot_nw = U_ & nw; @@ -219,7 +219,8 @@ template<class ParcelType> void Foam::DsmcParcel<ParcelType>::hitWallPatch ( const wallPolyPatch&, - int& + int&, + const tetIndices& ) {} diff --git a/src/lagrangian/dsmc/parcels/Templates/DsmcParcel/DsmcParcel.H b/src/lagrangian/dsmc/parcels/Templates/DsmcParcel/DsmcParcel.H index 8a644652d0cd8a5d56302783ff9050556bc8e0cc..8d09a91e8d7db8558a82236fa7e72462d58c59da 100644 --- a/src/lagrangian/dsmc/parcels/Templates/DsmcParcel/DsmcParcel.H +++ b/src/lagrangian/dsmc/parcels/Templates/DsmcParcel/DsmcParcel.H @@ -185,7 +185,9 @@ public: const vector& position, const vector& U, const scalar Ei, - const label celli, + const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId ); @@ -244,7 +246,9 @@ public: ( const polyPatch&, TrackData& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ); //- Overridable function to handle the particle hitting a @@ -269,7 +273,8 @@ public: void hitWallPatch ( const wallPolyPatch&, - TrackData& td + TrackData& td, + const tetIndices& ); //- Overridable function to handle the particle hitting a wallPatch @@ -277,7 +282,8 @@ public: void hitWallPatch ( const wallPolyPatch&, - int& + int&, + const tetIndices& ); //- Overridable function to handle the particle hitting a polyPatch @@ -352,4 +358,3 @@ public: #endif // ************************************************************************* // - diff --git a/src/lagrangian/dsmc/parcels/Templates/DsmcParcel/DsmcParcelI.H b/src/lagrangian/dsmc/parcels/Templates/DsmcParcel/DsmcParcelI.H index 9f6d661ec6b84cac516e5f6339ebfec73a5bb332..5bfc61b44b0e83c886a549cb1196336b0cb1d459 100644 --- a/src/lagrangian/dsmc/parcels/Templates/DsmcParcel/DsmcParcelI.H +++ b/src/lagrangian/dsmc/parcels/Templates/DsmcParcel/DsmcParcelI.H @@ -69,11 +69,13 @@ inline Foam::DsmcParcel<ParcelType>::DsmcParcel const vector& position, const vector& U, const scalar Ei, - const label celli, + const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId ) : - Particle<ParcelType>(owner, position, celli), + Particle<ParcelType>(owner, position, cellI, tetFaceI, tetPtI), U_(U), Ei_(Ei), typeId_(typeId) diff --git a/src/lagrangian/dsmc/parcels/derived/dsmcParcel/dsmcParcel.C b/src/lagrangian/dsmc/parcels/derived/dsmcParcel/dsmcParcel.C index b46bb2452fc882b4f6678ac8957f5fbdea972bca..91fa156c639fa6b9c2e7f141f2c419456983b9fe 100644 --- a/src/lagrangian/dsmc/parcels/derived/dsmcParcel/dsmcParcel.C +++ b/src/lagrangian/dsmc/parcels/derived/dsmcParcel/dsmcParcel.C @@ -43,7 +43,9 @@ Foam::dsmcParcel::dsmcParcel const vector& position, const vector& U, const scalar Ei, - const label celli, + const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId ) : @@ -53,7 +55,9 @@ Foam::dsmcParcel::dsmcParcel position, U, Ei, - celli, + cellI, + tetFaceI, + tetPtI, typeId ) {} diff --git a/src/lagrangian/dsmc/parcels/derived/dsmcParcel/dsmcParcel.H b/src/lagrangian/dsmc/parcels/derived/dsmcParcel/dsmcParcel.H index 8cc4bf11849a8d25169119484094985240138df8..6286e06c60e10fd81fafd6929c13eefc6a99fc1e 100644 --- a/src/lagrangian/dsmc/parcels/derived/dsmcParcel/dsmcParcel.H +++ b/src/lagrangian/dsmc/parcels/derived/dsmcParcel/dsmcParcel.H @@ -66,7 +66,9 @@ public: const vector& position, const vector& U, const scalar Ei, - const label celli, + const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId ); diff --git a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/BinaryCollisionModel/BinaryCollisionModel.H b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/BinaryCollisionModel/BinaryCollisionModel.H index 0136cd5f6a0f53a3078e31a78436708ccf7e88b6..bd0ce0fa3157ca3345fb664350c6e61e4af89526 100644 --- a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/BinaryCollisionModel/BinaryCollisionModel.H +++ b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/BinaryCollisionModel/BinaryCollisionModel.H @@ -132,21 +132,15 @@ public: //- Return the collision cross section * relative velocity product virtual scalar sigmaTcR ( - label typeIdP, - label typeIdQ, - const vector& UP, - const vector& UQ + const typename CloudType::parcelType& pP, + const typename CloudType::parcelType& pQ ) const = 0; //- Apply collision virtual void collide ( - label typeIdP, - label typeIdQ, - vector& UP, - vector& UQ, - scalar& EiP, - scalar& EiQ + typename CloudType::parcelType& pP, + typename CloudType::parcelType& pQ ) = 0; }; diff --git a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/LarsenBorgnakkeVariableHardSphere/LarsenBorgnakkeVariableHardSphere.C b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/LarsenBorgnakkeVariableHardSphere/LarsenBorgnakkeVariableHardSphere.C index 85f0eb12ec7021ace0603d4102068067720a44b7..5e067847b5d128e4cfa4c3dbe9b0d3f54e99c41a 100644 --- a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/LarsenBorgnakkeVariableHardSphere/LarsenBorgnakkeVariableHardSphere.C +++ b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/LarsenBorgnakkeVariableHardSphere/LarsenBorgnakkeVariableHardSphere.C @@ -128,14 +128,15 @@ bool Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::active() const template <class CloudType> Foam::scalar Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::sigmaTcR ( - label typeIdP, - label typeIdQ, - const vector& UP, - const vector& UQ + const typename CloudType::parcelType& pP, + const typename CloudType::parcelType& pQ ) const { const CloudType& cloud(this->owner()); + label typeIdP = pP.typeId(); + label typeIdQ = pQ.typeId(); + scalar dPQ = 0.5 *( @@ -150,7 +151,7 @@ Foam::scalar Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::sigmaTcR + cloud.constProps(typeIdQ).omega() ); - scalar cR = mag(UP - UQ); + scalar cR = mag(pP.U() - pQ.U()); if (cR < VSMALL) { @@ -176,16 +177,19 @@ Foam::scalar Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::sigmaTcR template <class CloudType> void Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::collide ( - label typeIdP, - label typeIdQ, - vector& UP, - vector& UQ, - scalar& EiP, - scalar& EiQ + typename CloudType::parcelType& pP, + typename CloudType::parcelType& pQ ) { CloudType& cloud(this->owner()); + label typeIdP = pP.typeId(); + label typeIdQ = pQ.typeId(); + vector& UP = pP.U(); + vector& UQ = pQ.U(); + scalar& EiP = pP.Ei(); + scalar& EiQ = pQ.Ei(); + Random& rndGen(cloud.rndGen()); scalar inverseCollisionNumber = 1/relaxationCollisionNumber_; diff --git a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/LarsenBorgnakkeVariableHardSphere/LarsenBorgnakkeVariableHardSphere.H b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/LarsenBorgnakkeVariableHardSphere/LarsenBorgnakkeVariableHardSphere.H index 3f742a78ae607e445172c54efeea1faed1e8351c..fa4f232a02b48c621d7bb56e14333038662feb1c 100644 --- a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/LarsenBorgnakkeVariableHardSphere/LarsenBorgnakkeVariableHardSphere.H +++ b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/LarsenBorgnakkeVariableHardSphere/LarsenBorgnakkeVariableHardSphere.H @@ -95,21 +95,15 @@ public: //- Return the collision cross section * relative velocity product virtual scalar sigmaTcR ( - label typeIdP, - label typeIdQ, - const vector& UP, - const vector& UQ + const typename CloudType::parcelType& pP, + const typename CloudType::parcelType& pQ ) const; //- Apply collision virtual void collide ( - label typeIdP, - label typeIdQ, - vector& UP, - vector& UQ, - scalar& EiP, - scalar& EiQ + typename CloudType::parcelType& pP, + typename CloudType::parcelType& pQ ); }; diff --git a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/NoBinaryCollision/NoBinaryCollision.C b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/NoBinaryCollision/NoBinaryCollision.C index 5ff988963832ad558c1d7a510bc728fa865d64c9..67a1b4443ea602fb3a457c478bf51b21a2fff580 100644 --- a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/NoBinaryCollision/NoBinaryCollision.C +++ b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/NoBinaryCollision/NoBinaryCollision.C @@ -60,10 +60,8 @@ bool Foam::NoBinaryCollision<CloudType>::active() const template <class CloudType> Foam::scalar Foam::NoBinaryCollision<CloudType>::sigmaTcR ( - label typeIdP, - label typeIdQ, - const vector& UP, - const vector& UQ + const typename CloudType::parcelType& pP, + const typename CloudType::parcelType& pQ ) const { FatalErrorIn @@ -89,12 +87,8 @@ Foam::scalar Foam::NoBinaryCollision<CloudType>::sigmaTcR template <class CloudType> void Foam::NoBinaryCollision<CloudType>::collide ( - label typeIdP, - label typeIdQ, - vector& UP, - vector& UQ, - scalar& EiP, - scalar& EiQ + typename CloudType::parcelType& pP, + typename CloudType::parcelType& pQ ) {} diff --git a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/NoBinaryCollision/NoBinaryCollision.H b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/NoBinaryCollision/NoBinaryCollision.H index b48cedb316ee780f18cd1976773e0b4748b0ecad..9ceea73e3031839598a2259c8f572723ba0181ff 100644 --- a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/NoBinaryCollision/NoBinaryCollision.H +++ b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/NoBinaryCollision/NoBinaryCollision.H @@ -74,21 +74,15 @@ public: //- Return the collision cross section * relative velocity product virtual scalar sigmaTcR ( - label typeIdP, - label typeIdQ, - const vector& UP, - const vector& UQ + const typename CloudType::parcelType& pP, + const typename CloudType::parcelType& pQ ) const; //- Apply collision virtual void collide ( - label typeIdP, - label typeIdQ, - vector& UP, - vector& UQ, - scalar& EiP, - scalar& EiQ + typename CloudType::parcelType& pP, + typename CloudType::parcelType& pQ ); }; diff --git a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/VariableHardSphere/VariableHardSphere.C b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/VariableHardSphere/VariableHardSphere.C index 8f7d13dd7de02915be2b97acc3b6b69a861870eb..450e1218ed06a1fa93f5ac347df74a86a07359dc 100644 --- a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/VariableHardSphere/VariableHardSphere.C +++ b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/VariableHardSphere/VariableHardSphere.C @@ -61,14 +61,15 @@ bool Foam::VariableHardSphere<CloudType>::active() const template <class CloudType> Foam::scalar Foam::VariableHardSphere<CloudType>::sigmaTcR ( - label typeIdP, - label typeIdQ, - const vector& UP, - const vector& UQ + const typename CloudType::parcelType& pP, + const typename CloudType::parcelType& pQ ) const { const CloudType& cloud(this->owner()); + label typeIdP = pP.typeId(); + label typeIdQ = pQ.typeId(); + scalar dPQ = 0.5 *( @@ -83,7 +84,7 @@ Foam::scalar Foam::VariableHardSphere<CloudType>::sigmaTcR + cloud.constProps(typeIdQ).omega() ); - scalar cR = mag(UP - UQ); + scalar cR = mag(pP.U() - pQ.U()); if (cR < VSMALL) { @@ -109,16 +110,17 @@ Foam::scalar Foam::VariableHardSphere<CloudType>::sigmaTcR template <class CloudType> void Foam::VariableHardSphere<CloudType>::collide ( - label typeIdP, - label typeIdQ, - vector& UP, - vector& UQ, - scalar& EiP, - scalar& EiQ + typename CloudType::parcelType& pP, + typename CloudType::parcelType& pQ ) { CloudType& cloud(this->owner()); + label typeIdP = pP.typeId(); + label typeIdQ = pQ.typeId(); + vector& UP = pP.U(); + vector& UQ = pQ.U(); + Random& rndGen(cloud.rndGen()); scalar mP = cloud.constProps(typeIdP).mass(); diff --git a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/VariableHardSphere/VariableHardSphere.H b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/VariableHardSphere/VariableHardSphere.H index bf986189c0b058ee0a1e6e15738f6fb4f52f00ef..2540107f7b1a29e1efe07c6d1d52513b22ba56cd 100644 --- a/src/lagrangian/dsmc/submodels/BinaryCollisionModel/VariableHardSphere/VariableHardSphere.H +++ b/src/lagrangian/dsmc/submodels/BinaryCollisionModel/VariableHardSphere/VariableHardSphere.H @@ -80,21 +80,15 @@ public: //- Return the collision cross section * relative velocity product virtual scalar sigmaTcR ( - label typeIdP, - label typeIdQ, - const vector& UP, - const vector& UQ + const typename CloudType::parcelType& pP, + const typename CloudType::parcelType& pQ ) const; //- Apply collision virtual void collide ( - label typeIdP, - label typeIdQ, - vector& UP, - vector& UQ, - scalar& EiP, - scalar& EiQ + typename CloudType::parcelType& pP, + typename CloudType::parcelType& pQ ); }; diff --git a/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C b/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C index b8818aa9cdfc819a413b7454715dcc335cee497a..df835e735d008961222ce12cc0ff3a155ef2fef5 100644 --- a/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C +++ b/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C @@ -25,6 +25,8 @@ License #include "FreeStream.H" #include "constants.H" +#include "triPointRef.H" +#include "tetIndices.H" using namespace Foam::constant::mathematical; @@ -181,13 +183,13 @@ void Foam::FreeStream<CloudType>::inflow() ) ); - // Dotting boundary velocity with the face unit normal (which points - // out of the domain, so it must be negated), dividing by the most - // probable speed to form molecularSpeedRatio * cosTheta + // Dotting boundary velocity with the face unit normal + // (which points out of the domain, so it must be + // negated), dividing by the most probable speed to form + // molecularSpeedRatio * cosTheta scalarField sCosTheta = - boundaryU[patchI] - & -patch.faceAreas()/mag(patch.faceAreas()) + (boundaryU[patchI] & -patch.faceAreas()/mag(patch.faceAreas())) /mostProbableSpeed; // From Bird eqn 4.22 @@ -201,50 +203,56 @@ void Foam::FreeStream<CloudType>::inflow() /(2.0*sqrtPi); } - forAll(patch, f) + forAll(patch, pFI) { // Loop over all faces as the outer loop to avoid calculating // geometrical properties multiple times. - labelList faceVertices = patch[f]; + const face& f = patch[pFI]; - label nVertices = faceVertices.size(); + label globalFaceIndex = pFI + patch.start(); - label globalFaceIndex = f + patch.start(); + label cellI = mesh.faceOwner()[globalFaceIndex]; - label cell = mesh.faceOwner()[globalFaceIndex]; + const vector& fC = patch.faceCentres()[pFI]; - const vector& fC = patch.faceCentres()[f]; + scalar fA = mag(patch.faceAreas()[pFI]); - scalar fA = mag(patch.faceAreas()[f]); + List<tetIndices> faceTets = polyMeshTetDecomposition::faceTetIndices + ( + mesh, + globalFaceIndex, + cellI + ); // Cumulative triangle area fractions - List<scalar> cTriAFracs(nVertices); - cTriAFracs[0] = 0.0; + List<scalar> cTriAFracs(faceTets.size(), 0.0); - for (label v = 0; v < nVertices - 1; v++) + scalar previousCummulativeSum = 0.0; + + forAll(faceTets, triI) { - const point& vA = mesh.points()[faceVertices[v]]; + const tetIndices& faceTetIs = faceTets[triI]; - const point& vB = mesh.points()[faceVertices[(v + 1)]]; + cTriAFracs[triI] = + faceTetIs.faceTri(mesh).mag()/fA + + previousCummulativeSum; - cTriAFracs[v] = - 0.5*mag((vA - fC)^(vB - fC))/fA - + cTriAFracs[max((v - 1), 0)]; + previousCummulativeSum = cTriAFracs[triI]; } // Force the last area fraction value to 1.0 to avoid any // rounding/non-flat face errors giving a value < 1.0 - cTriAFracs[nVertices - 1] = 1.0; + cTriAFracs.last() = 1.0; // Normal unit vector *negative* so normal is pointing into the // domain - vector n = patch.faceAreas()[f]; + vector n = patch.faceAreas()[pFI]; n /= -mag(n); // Wall tangential unit vector. Use the direction between the // face centre and the first vertex in the list - vector t1 = fC - (mesh.points()[faceVertices[0]]); + vector t1 = fC - (mesh.points()[f[0]]); t1 /= mag(t1); // Other tangential unit vector. Rescaling in case face is not @@ -252,13 +260,13 @@ void Foam::FreeStream<CloudType>::inflow() vector t2 = n^t1; t2 /= mag(t2); - scalar faceTemperature = boundaryT[patchI][f]; + scalar faceTemperature = boundaryT[patchI][pFI]; - const vector& faceVelocity = boundaryU[patchI][f]; + const vector& faceVelocity = boundaryU[patchI][pFI]; forAll(pFA, i) { - scalar& faceAccumulator = pFA[i][f]; + scalar& faceAccumulator = pFA[i][pFI]; // Number of whole particles to insert label nI = max(label(faceAccumulator), 0); @@ -284,34 +292,23 @@ void Foam::FreeStream<CloudType>::inflow() scalar triSelection = rndGen.scalar01(); // Selected triangle - label sTri = -1; + label selectedTriI = -1; - forAll(cTriAFracs, tri) + forAll(cTriAFracs, triI) { - sTri = tri; + selectedTriI = triI; - if (cTriAFracs[tri] >= triSelection) + if (cTriAFracs[triI] >= triSelection) { break; } } - // Randomly distribute the points on the triangle, using the - // method from: - // Generating Random Points in Triangles - // by Greg Turk - // from "Graphics Gems", Academic Press, 1990 - // http://tog.acm.org/GraphicsGems/gems/TriPoints.c - - const point& A = fC; - const point& B = mesh.points()[faceVertices[sTri]]; - const point& C = - mesh.points()[faceVertices[(sTri + 1) % nVertices]]; + // Randomly distribute the points on the triangle. - scalar s = rndGen.scalar01(); - scalar t = sqrt(rndGen.scalar01()); + const tetIndices& faceTetIs = faceTets[selectedTriI]; - point p = (1 - t)*A + (1 - s)*t*B + s*t*C; + point p = faceTetIs.faceTri(mesh).randomPoint(rndGen); // Velocity generation @@ -393,7 +390,9 @@ void Foam::FreeStream<CloudType>::inflow() p, U, Ei, - cell, + cellI, + globalFaceIndex, + faceTetIs.tetPt(), typeId ); diff --git a/src/lagrangian/dsmc/submodels/WallInteractionModel/MaxwellianThermal/MaxwellianThermal.C b/src/lagrangian/dsmc/submodels/WallInteractionModel/MaxwellianThermal/MaxwellianThermal.C index 467e5fad4fe780de750fc96e939e6bae0b5584ac..c05e6ae2013e7e61586522ab2bc197c954d867b6 100644 --- a/src/lagrangian/dsmc/submodels/WallInteractionModel/MaxwellianThermal/MaxwellianThermal.C +++ b/src/lagrangian/dsmc/submodels/WallInteractionModel/MaxwellianThermal/MaxwellianThermal.C @@ -53,20 +53,21 @@ Foam::MaxwellianThermal<CloudType>::~MaxwellianThermal() template <class CloudType> void Foam::MaxwellianThermal<CloudType>::correct ( - const wallPolyPatch& wpp, - const label faceId, - vector& U, - scalar& Ei, - label typeId + typename CloudType::parcelType& p, + const wallPolyPatch& wpp ) { - label wppIndex = wpp.index(); + vector& U = p.U(); + + scalar& Ei = p.Ei(); - label wppLocalFace = wpp.whichFace(faceId); + label typeId = p.typeId(); + + label wppIndex = wpp.index(); - vector nw = wpp.faceAreas()[wppLocalFace]; + label wppLocalFace = wpp.whichFace(p.face()); - // Normal unit vector + vector nw = p.normal(); nw /= mag(nw); // Normal velocity magnitude diff --git a/src/lagrangian/dsmc/submodels/WallInteractionModel/MaxwellianThermal/MaxwellianThermal.H b/src/lagrangian/dsmc/submodels/WallInteractionModel/MaxwellianThermal/MaxwellianThermal.H index f42382b7da04fded732bae43602f15ba69510887..2ed030bbe741c21ee23173174f299b8d3862a54d 100644 --- a/src/lagrangian/dsmc/submodels/WallInteractionModel/MaxwellianThermal/MaxwellianThermal.H +++ b/src/lagrangian/dsmc/submodels/WallInteractionModel/MaxwellianThermal/MaxwellianThermal.H @@ -25,8 +25,9 @@ Class Foam::MaxwellianThermal Description - Wall interaction setting microscopic velocity to a random one drawn from a - Maxwellian distribution corresponding to a specified temperature + Wall interaction setting microscopic velocity to a random one + drawn from a Maxwellian distribution corresponding to a specified + temperature \*---------------------------------------------------------------------------*/ @@ -73,11 +74,8 @@ public: //- Apply wall correction virtual void correct ( - const wallPolyPatch& wpp, - const label faceId, - vector& U, - scalar& Ei, - label typeId + typename CloudType::parcelType& p, + const wallPolyPatch& wpp ); }; diff --git a/src/lagrangian/dsmc/submodels/WallInteractionModel/MixedDiffuseSpecular/MixedDiffuseSpecular.C b/src/lagrangian/dsmc/submodels/WallInteractionModel/MixedDiffuseSpecular/MixedDiffuseSpecular.C index 91c103a4aa4f54aee5ede5514ff22e02e9ab4892..9614c81cff846444952f794f2cb674fffaf75de2 100644 --- a/src/lagrangian/dsmc/submodels/WallInteractionModel/MixedDiffuseSpecular/MixedDiffuseSpecular.C +++ b/src/lagrangian/dsmc/submodels/WallInteractionModel/MixedDiffuseSpecular/MixedDiffuseSpecular.C @@ -51,20 +51,21 @@ Foam::MixedDiffuseSpecular<CloudType>::~MixedDiffuseSpecular() template <class CloudType> void Foam::MixedDiffuseSpecular<CloudType>::correct ( - const wallPolyPatch& wpp, - const label faceId, - vector& U, - scalar& Ei, - label typeId + typename CloudType::parcelType& p, + const wallPolyPatch& wpp ) { - label wppIndex = wpp.index(); + vector& U = p.U(); + + scalar& Ei = p.Ei(); - label wppLocalFace = wpp.whichFace(faceId); + label typeId = p.typeId(); + + label wppIndex = wpp.index(); - vector nw = wpp.faceAreas()[wppLocalFace]; + label wppLocalFace = wpp.whichFace(p.face()); - // Normal unit vector + vector nw = p.normal(); nw /= mag(nw); // Normal velocity magnitude diff --git a/src/lagrangian/dsmc/submodels/WallInteractionModel/MixedDiffuseSpecular/MixedDiffuseSpecular.H b/src/lagrangian/dsmc/submodels/WallInteractionModel/MixedDiffuseSpecular/MixedDiffuseSpecular.H index f3745dbc907a44c9b7752cda13ef219b39c4bcdb..3a375d5c7a6176b9aba5b2fd6500fcee64f902ec 100644 --- a/src/lagrangian/dsmc/submodels/WallInteractionModel/MixedDiffuseSpecular/MixedDiffuseSpecular.H +++ b/src/lagrangian/dsmc/submodels/WallInteractionModel/MixedDiffuseSpecular/MixedDiffuseSpecular.H @@ -25,8 +25,11 @@ Class Foam::MixedDiffuseSpecular Description - Wall interaction setting microscopic velocity to a random one drawn from a - Maxwellian distribution corresponding to a specified temperature + Wall interaction setting microscopic velocity to a random one + drawn from a Maxwellian distribution corresponding to a specified + temperature for a specified fraction of collisions, and reversing + the wall-normal component of the particle velocity for the + remainder. \*---------------------------------------------------------------------------*/ @@ -79,11 +82,8 @@ public: //- Apply wall correction virtual void correct ( - const wallPolyPatch& wpp, - const label faceId, - vector& U, - scalar& Ei, - label typeId + typename CloudType::parcelType& p, + const wallPolyPatch& wpp ); }; diff --git a/src/lagrangian/dsmc/submodels/WallInteractionModel/SpecularReflection/SpecularReflection.C b/src/lagrangian/dsmc/submodels/WallInteractionModel/SpecularReflection/SpecularReflection.C index b690a0f87e8393d1ac81c850fd597d854ce1465d..e15a416dd673a8af00de4a6326e1e721a770a350 100644 --- a/src/lagrangian/dsmc/submodels/WallInteractionModel/SpecularReflection/SpecularReflection.C +++ b/src/lagrangian/dsmc/submodels/WallInteractionModel/SpecularReflection/SpecularReflection.C @@ -52,14 +52,13 @@ Foam::SpecularReflection<CloudType>::~SpecularReflection() template <class CloudType> void Foam::SpecularReflection<CloudType>::correct ( - const wallPolyPatch& wpp, - const label faceId, - vector& U, - scalar& Ei, - label typeId + typename CloudType::parcelType& p, + const wallPolyPatch& wpp ) { - vector nw = wpp.faceAreas()[wpp.whichFace(faceId)]; + vector& U = p.U(); + + vector nw = p.normal(); nw /= mag(nw); scalar U_dot_nw = U & nw; diff --git a/src/lagrangian/dsmc/submodels/WallInteractionModel/SpecularReflection/SpecularReflection.H b/src/lagrangian/dsmc/submodels/WallInteractionModel/SpecularReflection/SpecularReflection.H index 1c47640fe38c4779f53f188460547312290c3628..68bf2da68915502fd287d136c293a8edb8902c75 100644 --- a/src/lagrangian/dsmc/submodels/WallInteractionModel/SpecularReflection/SpecularReflection.H +++ b/src/lagrangian/dsmc/submodels/WallInteractionModel/SpecularReflection/SpecularReflection.H @@ -72,11 +72,8 @@ public: //- Apply wall correction virtual void correct ( - const wallPolyPatch& wpp, - const label faceId, - vector& U, - scalar& Ei, - label typeId + typename CloudType::parcelType& p, + const wallPolyPatch& wpp ); }; diff --git a/src/lagrangian/dsmc/submodels/WallInteractionModel/WallInteractionModel/WallInteractionModel.H b/src/lagrangian/dsmc/submodels/WallInteractionModel/WallInteractionModel/WallInteractionModel.H index dfed430ff76b954b5bf6dab8bd604bf129495dae..e0af2025a93b5797b6374136fe2e17b11e6c058c 100644 --- a/src/lagrangian/dsmc/submodels/WallInteractionModel/WallInteractionModel/WallInteractionModel.H +++ b/src/lagrangian/dsmc/submodels/WallInteractionModel/WallInteractionModel/WallInteractionModel.H @@ -129,11 +129,8 @@ public: //- Apply wall correction virtual void correct ( - const wallPolyPatch& wpp, - const label faceId, - vector& U, - scalar& Ei, - label typeId + typename CloudType::parcelType& p, + const wallPolyPatch& wpp ) = 0; }; diff --git a/src/lagrangian/intermediate/Make/options b/src/lagrangian/intermediate/Make/options index 5625914e28d229d3211607fe9a91275ec3a0accf..7a2084545386d6913e16a5e4572f2aa3faa39185 100644 --- a/src/lagrangian/intermediate/Make/options +++ b/src/lagrangian/intermediate/Make/options @@ -17,7 +17,8 @@ EXE_INC = \ -I$(LIB_SRC)/turbulenceModels/compressible/RAS/lnInclude \ -I$(LIB_SRC)/turbulenceModels/LES/LESdeltas/lnInclude \ -I$(LIB_SRC)/turbulenceModels/compressible/LES/lnInclude \ - -I$(LIB_SRC)/surfaceFilmModels/lnInclude + -I$(LIB_SRC)/surfaceFilmModels/lnInclude \ + -I$(LIB_SRC)/dynamicFvMesh/lnInclude LIB_LIBS = \ -lfiniteVolume \ @@ -37,4 +38,6 @@ LIB_LIBS = \ -lODE \ -lcompressibleRASModels \ -lcompressibleLESModels \ + -ldynamicFvMesh \ -lsurfaceFilmModels + diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C index 10fccde371cc711a59e4d67d21dbf88991c8f062..9666d617197033ac7b61081dc18fb85f6058216e 100644 --- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C +++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C @@ -43,6 +43,52 @@ void Foam::KinematicCloud<ParcelType>::preEvolve() { this->dispersion().cacheFields(true); forces_.cacheFields(true, interpolationSchemes_); + updateCellOccupancy(); +} + + +template<class ParcelType> +void Foam::KinematicCloud<ParcelType>::buildCellOccupancy() +{ + if (cellOccupancyPtr_.empty()) + { + cellOccupancyPtr_.reset + ( + new List<DynamicList<ParcelType*> >(mesh_.nCells()) + ); + } + else if (cellOccupancyPtr_().size() != mesh_.nCells()) + { + // If the size of the mesh has changed, reset the + // cellOccupancy size + + cellOccupancyPtr_().setSize(mesh_.nCells()); + } + + List<DynamicList<ParcelType*> >& cellOccupancy = cellOccupancyPtr_(); + + forAll(cellOccupancy, cO) + { + cellOccupancy[cO].clear(); + } + + forAllIter(typename KinematicCloud<ParcelType>, *this, iter) + { + cellOccupancy[iter().cell()].append(&iter()); + } +} + + +template<class ParcelType> +void Foam::KinematicCloud<ParcelType>::updateCellOccupancy() +{ + // Only build the cellOccupancy if the pointer is set, i.e. it has + // been requested before. + + if (cellOccupancyPtr_.valid()) + { + buildCellOccupancy(); + } } @@ -80,8 +126,19 @@ void Foam::KinematicCloud<ParcelType>::evolveCloud() g_.value() ); + label preInjectionSize = this->size(); + this->surfaceFilm().inject(td); + // Update the cellOccupancy if the size of the cloud has changed + // during the injection. + if (preInjectionSize != this->size()) + { + updateCellOccupancy(); + + preInjectionSize = this->size(); + } + this->injection().inject(td); if (coupled_) @@ -89,6 +146,18 @@ void Foam::KinematicCloud<ParcelType>::evolveCloud() resetSourceTerms(); } + // Assume that motion will update the cellOccupancy as necessary + // before it is required. + motion(td); +} + + +template<class ParcelType> +void Foam::KinematicCloud<ParcelType>::motion +( + typename ParcelType::trackData& td +) +{ // Sympletic leapfrog integration of particle forces: // + apply half deltaV with stored force // + move positions with new velocity @@ -136,6 +205,8 @@ void Foam::KinematicCloud<ParcelType>::moveCollide // td.part() = ParcelType::trackData::tpRotationalTrack; // Cloud<ParcelType>::move(td); + updateCellOccupancy(); + this->collision().collide(); td.part() = ParcelType::trackData::tpVelocityHalfStep; @@ -194,6 +265,7 @@ Foam::KinematicCloud<ParcelType>::KinematicCloud particleProperties_.lookup("cellValueSourceCorrection") ), rndGen_(label(0)), + cellOccupancyPtr_(), rho_(rho), U_(U), mu_(mu), diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H index c09988c76d75a5fe1256334d9c1ba5f7a917c5e2..1d0a903810222341e512845b8097b661689ca990 100644 --- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H +++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H @@ -136,6 +136,9 @@ protected: //- Random number generator - used by some injection routines Random rndGen_; + //- Cell occupancy information for each parcel, (demand driven) + autoPtr<List<DynamicList<ParcelType*> > > cellOccupancyPtr_; + // References to the carrier gas fields @@ -209,10 +212,20 @@ protected: //- Pre-evolve void preEvolve(); + //- Build the cellOccupancy + void buildCellOccupancy(); + + //- Update (i.e. build) the cellOccupancy if it has + // already been used + void updateCellOccupancy(); + //- Evolve the cloud void evolveCloud(); - //- Move-collide + //- Particle motion + void motion(typename ParcelType::trackData& td); + + //- Move-collide particles void moveCollide(typename ParcelType::trackData& td); //- Post-evolve @@ -247,6 +260,13 @@ public: // Access + //- If the collision model controls the wall interaction, + // then the wall impact distance should be zero. + // Otherwise, it should be allowed to be the value from + // the Parcel. + inline bool hasWallImpactDistance() const; + + // References to the mesh and databases //- Return refernce to the mesh @@ -277,6 +297,12 @@ public: //- Return refernce to the random object inline Random& rndGen(); + //- Return the cell occupancy information for each + // parcel, non-const access, the caller is + // responsible for updating it for its own purposes + // if particles are removed or created. + inline List<DynamicList<ParcelType*> >& cellOccupancy(); + // References to the carrier gas fields diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H index ed65e9809ba1408a72037f2280abbff24ae615da..536e4e677380c9a7c852dcd3c30d90d8c865ec9a 100644 --- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H +++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H @@ -27,6 +27,13 @@ License // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template<class ParcelType> +inline bool Foam::KinematicCloud<ParcelType>::hasWallImpactDistance() const +{ + return !collision().controlsWallInteraction(); +} + + template<class ParcelType> inline Foam::label Foam::KinematicCloud<ParcelType>::parcelTypeId() const { @@ -295,6 +302,19 @@ inline Foam::Random& Foam::KinematicCloud<ParcelType>::rndGen() } +template<class ParcelType> +inline Foam::List<Foam::DynamicList<ParcelType*> >& +Foam::KinematicCloud<ParcelType>::cellOccupancy() +{ + if (cellOccupancyPtr_.empty()) + { + buildCellOccupancy(); + } + + return cellOccupancyPtr_(); +} + + template<class ParcelType> inline Foam::DimensionedField<Foam::vector, Foam::volMesh>& Foam::KinematicCloud<ParcelType>::UTrans() diff --git a/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.C b/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.C index fec5e02ea30c1d5827ef3c2a99645650f5ed0ee2..f3fb165b0e81d9eb1f28573bc5c95d95e5939c20 100644 --- a/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.C +++ b/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.C @@ -120,8 +120,19 @@ void Foam::ReactingCloud<ParcelType>::evolveCloud() this->g().value() ); + label preInjectionSize = this->size(); + this->surfaceFilm().inject(td); + // Update the cellOccupancy if the size of the cloud has changed + // during the injection. + if (preInjectionSize != this->size()) + { + this->updateCellOccupancy(); + + preInjectionSize = this->size(); + } + this->injection().inject(td); if (this->coupled()) @@ -129,7 +140,19 @@ void Foam::ReactingCloud<ParcelType>::evolveCloud() resetSourceTerms(); } - Cloud<ParcelType>::move(td); + // Assume that motion will update the cellOccupancy as necessary + // before it is required. + motion(td); +} + + +template<class ParcelType> +void Foam::ReactingCloud<ParcelType>::motion +( + typename ParcelType::trackData& td +) +{ + ThermoCloud<ParcelType>::motion(td); } diff --git a/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.H b/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.H index 38b33eab48f3d2c196a0d635ce731b2d314df5d4..def51f895573a74b37d84664cc3a168621917344 100644 --- a/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.H +++ b/src/lagrangian/intermediate/clouds/Templates/ReactingCloud/ReactingCloud.H @@ -130,6 +130,9 @@ protected: //- Evolve the cloud void evolveCloud(); + //- Particle motion + void motion(typename ParcelType::trackData& td); + //- Post-evolve void postEvolve(); diff --git a/src/lagrangian/intermediate/clouds/Templates/ReactingMultiphaseCloud/ReactingMultiphaseCloud.C b/src/lagrangian/intermediate/clouds/Templates/ReactingMultiphaseCloud/ReactingMultiphaseCloud.C index 954f0486347b2a444c6bace7dbefae9cbd535041..451e3716d43e45a71b878bc3de8050b892f27fe8 100644 --- a/src/lagrangian/intermediate/clouds/Templates/ReactingMultiphaseCloud/ReactingMultiphaseCloud.C +++ b/src/lagrangian/intermediate/clouds/Templates/ReactingMultiphaseCloud/ReactingMultiphaseCloud.C @@ -93,8 +93,19 @@ void Foam::ReactingMultiphaseCloud<ParcelType>::evolveCloud() this->g().value() ); + label preInjectionSize = this->size(); + this->surfaceFilm().inject(td); + // Update the cellOccupancy if the size of the cloud has changed + // during the injection. + if (preInjectionSize != this->size()) + { + this->updateCellOccupancy(); + + preInjectionSize = this->size(); + } + this->injection().inject(td); if (this->coupled()) @@ -102,7 +113,19 @@ void Foam::ReactingMultiphaseCloud<ParcelType>::evolveCloud() resetSourceTerms(); } - Cloud<ParcelType>::move(td); + // Assume that motion will update the cellOccupancy as necessary + // before it is required. + motion(td); +} + + +template<class ParcelType> +void Foam::ReactingMultiphaseCloud<ParcelType>::motion +( + typename ParcelType::trackData& td +) +{ + ReactingCloud<ParcelType>::motion(td); } diff --git a/src/lagrangian/intermediate/clouds/Templates/ReactingMultiphaseCloud/ReactingMultiphaseCloud.H b/src/lagrangian/intermediate/clouds/Templates/ReactingMultiphaseCloud/ReactingMultiphaseCloud.H index efd1eaab8e0762c20a297bcb8551ed281784afbe..af2199261e5021a3d46f82520079c0291dd02c82 100644 --- a/src/lagrangian/intermediate/clouds/Templates/ReactingMultiphaseCloud/ReactingMultiphaseCloud.H +++ b/src/lagrangian/intermediate/clouds/Templates/ReactingMultiphaseCloud/ReactingMultiphaseCloud.H @@ -121,6 +121,9 @@ protected: //- Evolve the cloud void evolveCloud(); + //- Particle motion + void motion(typename ParcelType::trackData& td); + //- Post-evolve void postEvolve(); diff --git a/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.C b/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.C index 96d6d59b8adf0abf45e44e10456cec209bebaa1b..26cbeedcc6a1fce4ffb9d9cd63804a4709853c07 100644 --- a/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.C +++ b/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.C @@ -86,8 +86,19 @@ void Foam::ThermoCloud<ParcelType>::evolveCloud() this->g().value() ); + label preInjectionSize = this->size(); + + // Update the cellOccupancy if the size of the cloud has changed + // during the injection. this->surfaceFilm().inject(td); + if (preInjectionSize != this->size()) + { + this->updateCellOccupancy(); + + preInjectionSize = this->size(); + } + this->injection().inject(td); if (this->coupled()) @@ -95,7 +106,19 @@ void Foam::ThermoCloud<ParcelType>::evolveCloud() resetSourceTerms(); } - Cloud<ParcelType>::move(td); + // Assume that motion will update the cellOccupancy as necessary + // before it is required. + motion(td); +} + + +template<class ParcelType> +void Foam::ThermoCloud<ParcelType>::motion +( + typename ParcelType::trackData& td +) +{ + KinematicCloud<ParcelType>::motion(td); } diff --git a/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.H b/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.H index 0f7c8afb234ccd6feec750cec3d7efb46be2c244..a476dcb6f759be350d25d63cab1f60882ee5981c 100644 --- a/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.H +++ b/src/lagrangian/intermediate/clouds/Templates/ThermoCloud/ThermoCloud.H @@ -121,6 +121,9 @@ protected: //- Evolve the cloud void evolveCloud(); + //- Particle motion + void motion(typename ParcelType::trackData& td); + //- Post-evolve void postEvolve(); diff --git a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/CollisionRecordList/CollisionRecordList.C b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/CollisionRecordList/CollisionRecordList.C index aa2db0b4de6fd7b220d6b773886ea7423a803e85..4e80d16d6f63d683db81b504d7d2561fa36aa5e6 100644 --- a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/CollisionRecordList/CollisionRecordList.C +++ b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/CollisionRecordList/CollisionRecordList.C @@ -300,6 +300,27 @@ Foam::CollisionRecordList<PairType, WallType>::matchPairRecord } +template<class PairType, class WallType> +bool Foam::CollisionRecordList<PairType, WallType>::checkPairRecord +( + label origProcOfOther, + label origIdOfOther +) +{ + forAll(pairRecords_, i) + { + PairCollisionRecord<PairType>& pCR = pairRecords_[i]; + + if (pCR.match(origProcOfOther, origIdOfOther)) + { + return true; + } + } + + return false; +} + + template<class PairType, class WallType> Foam::WallCollisionRecord<WallType>& Foam::CollisionRecordList<PairType, WallType>::matchWallRecord @@ -333,6 +354,26 @@ Foam::CollisionRecordList<PairType, WallType>::matchWallRecord } +template<class PairType, class WallType> +bool Foam::CollisionRecordList<PairType, WallType>::checkWallRecord +( + const vector& pRel, + scalar radius +) +{ + forAll(wallRecords_, i) + { + WallCollisionRecord<WallType>& wCR = wallRecords_[i]; + + if (wCR.match(pRel, radius)) + { + return true; + } + } + + return false; +} + template<class PairType, class WallType> void Foam::CollisionRecordList<PairType, WallType>::update() diff --git a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/CollisionRecordList/CollisionRecordList.H b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/CollisionRecordList/CollisionRecordList.H index 51aa29849f3f6359d6e1c7015b802479277613b8..a933b35ca02e8c68af30c4739a5d3dae44d2bd73 100644 --- a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/CollisionRecordList/CollisionRecordList.H +++ b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/CollisionRecordList/CollisionRecordList.H @@ -168,6 +168,10 @@ public: label origIdOfOther ); + //- Enquire if the specified record exists without modifying + // its accessed status + bool checkPairRecord(label origProcOfOther, label origIdOfOther); + //- Enquires if the position of wall impact relative to the // particle centre is present in the records. If so, return // access to the WallCollisionRecord (hence the data) and @@ -179,6 +183,10 @@ public: scalar radius ); + //- Enquire if the specified record exists without modifying + // its accessed status + bool checkWallRecord(const vector& pRel, scalar radius); + //- Update the collision records, deleting any records not // marked as having been accessed, then mark all records as // not accessed ready for the next evaluation diff --git a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C index 66e4523fcb292dd82816f9a8d8bb4217156913e0..f6ba6aeed3a74760a53e98ae973796c438b2ef95 100644 --- a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C +++ b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C @@ -36,7 +36,10 @@ void Foam::KinematicParcel<ParcelType>::setCellValues const label cellI ) { - rhoc_ = td.rhoInterp().interpolate(this->position(), cellI); + tetIndices tetIs = this->currentTetIndices(); + + rhoc_ = td.rhoInterp().interpolate(this->position(), tetIs); + if (rhoc_ < td.constProps().rhoMin()) { WarningIn @@ -53,9 +56,9 @@ void Foam::KinematicParcel<ParcelType>::setCellValues rhoc_ = td.constProps().rhoMin(); } - Uc_ = td.UInterp().interpolate(this->position(), cellI); + Uc_ = td.UInterp().interpolate(this->position(), tetIs); - muc_ = td.muInterp().interpolate(this->position(), cellI); + muc_ = td.muInterp().interpolate(this->position(), tetIs); // Apply dispersion components to carrier phase velocity Uc_ = td.cloud().dispersion().update @@ -159,11 +162,13 @@ const Foam::vector Foam::KinematicParcel<ParcelType>::calcVelocity // Momentum transfer coefficient const scalar utc = td.cloud().drag().utc(Re, d, mu) + ROOTVSMALL; + tetIndices tetIs = this->currentTetIndices(); + // Momentum source due to particle forces const vector FCoupled = mass*td.cloud().forces().calcCoupled ( this->position(), - cellI, + tetIs, dt, rhoc_, rho, @@ -175,7 +180,7 @@ const Foam::vector Foam::KinematicParcel<ParcelType>::calcVelocity const vector FNonCoupled = mass*td.cloud().forces().calcNonCoupled ( this->position(), - cellI, + tetIs, dt, rhoc_, rho, @@ -220,6 +225,7 @@ Foam::KinematicParcel<ParcelType>::KinematicParcel typeId_(p.typeId_), nParticle_(p.nParticle_), d_(p.d_), + dTarget_(p.dTarget_), U_(p.U_), f_(p.f_), angularMomentum_(p.angularMomentum_), @@ -340,7 +346,9 @@ bool Foam::KinematicParcel<ParcelType>::hitPatch ( const polyPatch& pp, TrackData& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ) { ParcelType& p = static_cast<ParcelType&>(*this); @@ -360,15 +368,14 @@ bool Foam::KinematicParcel<ParcelType>::hitPatch else { // Invoke patch interaction model - return - td.cloud().patchInteraction().correct - ( - pp, - this->face(), - td.keepParticle, - active_, - U_ - ); + return td.cloud().patchInteraction().correct + ( + static_cast<ParcelType&>(*this), + pp, + td.keepParticle, + trackFraction, + tetIs + ); } } @@ -378,7 +385,9 @@ bool Foam::KinematicParcel<ParcelType>::hitPatch ( const polyPatch& pp, int& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ) { return false; @@ -411,7 +420,8 @@ template<class TrackData> void Foam::KinematicParcel<ParcelType>::hitWallPatch ( const wallPolyPatch& wpp, - TrackData& td + TrackData& td, + const tetIndices& ) { // Wall interactions handled by generic hitPatch function @@ -422,7 +432,8 @@ template<class ParcelType> void Foam::KinematicParcel<ParcelType>::hitWallPatch ( const wallPolyPatch&, - int& + int&, + const tetIndices& ) {} @@ -440,7 +451,11 @@ void Foam::KinematicParcel<ParcelType>::hitPatch template<class ParcelType> -void Foam::KinematicParcel<ParcelType>::hitPatch(const polyPatch&, int&) +void Foam::KinematicParcel<ParcelType>::hitPatch +( + const polyPatch&, + int& +) {} diff --git a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.H b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.H index 8b693c6220889d1386e7e0542ae34ed6c97357c0..4a76cb0173c634584c2f9b6ee7ce480843c8b592 100644 --- a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.H +++ b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.H @@ -250,6 +250,9 @@ protected: //- Diameter [m] scalar d_; + //- Target diameter [m] + scalar dTarget_; + //- Velocity of Parcel [m/s] vector U_; @@ -331,7 +334,9 @@ public: ( KinematicCloud<ParcelType>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ); //- Construct from components @@ -340,9 +345,12 @@ public: KinematicCloud<ParcelType>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, @@ -384,6 +392,9 @@ public: //- Return const access to diameter inline scalar d() const; + //- Return const access to target diameter + inline scalar dTarget() const; + //- Return const access to velocity inline const vector& U() const; @@ -423,6 +434,9 @@ public: //- Return access to diameter inline scalar& d(); + //- Return access to target diameter + inline scalar& dTarget(); + //- Return access to velocity inline vector& U(); @@ -474,19 +488,19 @@ public: inline scalar volume() const; //- Particle volume for a given diameter - inline scalar volume(const scalar d) const; + inline static scalar volume(const scalar d); //- Particle projected area inline scalar areaP() const; //- Projected area for given diameter - inline scalar areaP(const scalar d) const; + inline static scalar areaP(const scalar d); //- Particle surface area inline scalar areaS() const; //- Surface area for given diameter - inline scalar areaS(const scalar d) const; + inline static scalar areaS(const scalar d); //- Reynolds number inline scalar Re @@ -544,20 +558,22 @@ public: ( const polyPatch& p, TrackData& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ); - //- Overridable function to handle the particle hitting a patch // Executed before other patch-hitting functions without trackData bool hitPatch ( const polyPatch& p, int& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ); - //- Overridable function to handle the particle hitting a // processorPatch template<class TrackData> @@ -580,7 +596,8 @@ public: void hitWallPatch ( const wallPolyPatch&, - TrackData& td + TrackData& td, + const tetIndices& ); //- Overridable function to handle the particle hitting a wallPatch @@ -588,7 +605,8 @@ public: void hitWallPatch ( const wallPolyPatch&, - int& + int&, + const tetIndices& ); //- Overridable function to handle the particle hitting a polyPatch diff --git a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelI.H b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelI.H index 1a274b258b153fd1337f8399ad31fa7e3b3717bf..e39a9f43af0d32dc9a07b981d33c4ecd8b988e8f 100644 --- a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelI.H +++ b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelI.H @@ -81,14 +81,17 @@ inline Foam::KinematicParcel<ParcelType>::KinematicParcel ( KinematicCloud<ParcelType>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ) : - Particle<ParcelType>(owner, position, cellI), + Particle<ParcelType>(owner, position, cellI, tetFaceI, tetPtI), active_(true), typeId_(owner.parcelTypeId()), nParticle_(0), d_(0.0), + dTarget_(0.0), U_(vector::zero), f_(vector::zero), angularMomentum_(vector::zero), @@ -109,9 +112,12 @@ inline Foam::KinematicParcel<ParcelType>::KinematicParcel KinematicCloud<ParcelType>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, @@ -119,11 +125,12 @@ inline Foam::KinematicParcel<ParcelType>::KinematicParcel const constantProperties& constProps ) : - Particle<ParcelType>(owner, position, cellI), + Particle<ParcelType>(owner, position, cellI, tetFaceI, tetPtI), active_(true), typeId_(typeId), nParticle_(nParticle0), d_(d0), + dTarget_(dTarget0), U_(U0), f_(f0), angularMomentum_(angularMomentum0), @@ -288,6 +295,13 @@ inline Foam::scalar Foam::KinematicParcel<ParcelType>::d() const } +template <class ParcelType> +inline Foam::scalar Foam::KinematicParcel<ParcelType>::dTarget() const +{ + return dTarget_; +} + + template <class ParcelType> inline const Foam::vector& Foam::KinematicParcel<ParcelType>::U() const { @@ -376,6 +390,13 @@ inline Foam::scalar& Foam::KinematicParcel<ParcelType>::d() } +template <class ParcelType> +inline Foam::scalar& Foam::KinematicParcel<ParcelType>::dTarget() +{ + return dTarget_; +} + + template <class ParcelType> inline Foam::vector& Foam::KinematicParcel<ParcelType>::U() { @@ -439,23 +460,7 @@ inline Foam::scalar Foam::KinematicParcel<ParcelType>::wallImpactDistance const vector& ) const { - const KinematicCloud<ParcelType>& c = - dynamic_cast<const KinematicCloud<ParcelType>&>(this->cloud()); - - if (c.collision().controlsWallInteraction()) - { - // Do not use a wall impact distance if the collision model - // controls wall interactions to allow proper multiple face - // collisions. In a twisted mesh the particle can be within - // range of a wall but not in the cell attached to a wall - // face, hence miss the interaction. - - return 0.0; - } - else - { - return 0.5*d_; - } + return 0.5*d_; } @@ -516,7 +521,7 @@ inline Foam::scalar Foam::KinematicParcel<ParcelType>::volume() const template <class ParcelType> inline Foam::scalar -Foam::KinematicParcel<ParcelType>::volume(const scalar d) const +Foam::KinematicParcel<ParcelType>::volume(const scalar d) { return pi/6.0*pow3(d); } @@ -531,7 +536,7 @@ inline Foam::scalar Foam::KinematicParcel<ParcelType>::areaP() const template <class ParcelType> inline Foam::scalar -Foam::KinematicParcel<ParcelType>::areaP(const scalar d) const +Foam::KinematicParcel<ParcelType>::areaP(const scalar d) { return 0.25*areaS(d); } @@ -546,7 +551,7 @@ inline Foam::scalar Foam::KinematicParcel<ParcelType>::areaS() const template <class ParcelType> inline Foam::scalar -Foam::KinematicParcel<ParcelType>::areaS(const scalar d) const +Foam::KinematicParcel<ParcelType>::areaS(const scalar d) { return pi*d*d; } diff --git a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelIO.C b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelIO.C index 7660070383dd2f234dd09d93233ed70481f6f763..8f1645db60622d0fe9b053c19d49446eeb87dc7d 100644 --- a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelIO.C +++ b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelIO.C @@ -37,6 +37,7 @@ Foam::string Foam::KinematicParcel<ParcelType>::propHeader = + " typeId" + " nParticle" + " d" + + " dTarget " + " (Ux Uy Uz)" + " (fx fy fz)" + " (angularMomentumx angularMomentumy angularMomentumz)" @@ -68,6 +69,7 @@ Foam::KinematicParcel<ParcelType>::KinematicParcel typeId_(0), nParticle_(0.0), d_(0.0), + dTarget_(0.0), U_(vector::zero), f_(vector::zero), angularMomentum_(vector::zero), @@ -88,6 +90,7 @@ Foam::KinematicParcel<ParcelType>::KinematicParcel typeId_ = readLabel(is); nParticle_ = readScalar(is); d_ = readScalar(is); + dTarget_ = readScalar(is); is >> U_; is >> f_; is >> angularMomentum_; @@ -106,6 +109,7 @@ Foam::KinematicParcel<ParcelType>::KinematicParcel + sizeof(typeId_) + sizeof(nParticle_) + sizeof(d_) + + sizeof(dTarget_) + sizeof(U_) + sizeof(f_) + sizeof(angularMomentum_) @@ -150,6 +154,9 @@ void Foam::KinematicParcel<ParcelType>::readFields(Cloud<ParcelType>& c) IOField<scalar> d(c.fieldIOobject("d", IOobject::MUST_READ)); c.checkFieldIOobject(c, d); + IOField<scalar> dTarget(c.fieldIOobject("dTarget", IOobject::MUST_READ)); + c.checkFieldIOobject(c, dTarget); + IOField<vector> U(c.fieldIOobject("U", IOobject::MUST_READ)); c.checkFieldIOobject(c, U); @@ -234,6 +241,7 @@ void Foam::KinematicParcel<ParcelType>::readFields(Cloud<ParcelType>& c) p.typeId_ = typeId[i]; p.nParticle_ = nParticle[i]; p.d_ = d[i]; + p.dTarget_ = dTarget[i]; p.U_ = U[i]; p.f_ = f[i]; p.angularMomentum_ = angularMomentum[i]; @@ -271,6 +279,7 @@ void Foam::KinematicParcel<ParcelType>::writeFields(const Cloud<ParcelType>& c) np ); IOField<scalar> d(c.fieldIOobject("d", IOobject::NO_READ), np); + IOField<scalar> dTarget(c.fieldIOobject("dTarget", IOobject::NO_READ), np); IOField<vector> U(c.fieldIOobject("U", IOobject::NO_READ), np); IOField<vector> f(c.fieldIOobject("f", IOobject::NO_READ), np); IOField<vector> angularMomentum @@ -333,6 +342,7 @@ void Foam::KinematicParcel<ParcelType>::writeFields(const Cloud<ParcelType>& c) typeId[i] = p.typeId(); nParticle[i] = p.nParticle(); d[i] = p.d(); + dTarget[i] = p.dTarget(); U[i] = p.U(); f[i] = p.f(); angularMomentum[i] = p.angularMomentum(); @@ -357,6 +367,7 @@ void Foam::KinematicParcel<ParcelType>::writeFields(const Cloud<ParcelType>& c) typeId.write(); nParticle.write(); d.write(); + dTarget.write(); U.write(); f.write(); angularMomentum.write(); @@ -390,6 +401,7 @@ Foam::Ostream& Foam::operator<< << token::SPACE << p.typeId() << token::SPACE << p.nParticle() << token::SPACE << p.d() + << token::SPACE << p.dTarget() << token::SPACE << p.U() << token::SPACE << p.f() << token::SPACE << p.angularMomentum() @@ -409,6 +421,7 @@ Foam::Ostream& Foam::operator<< + sizeof(p.typeId()) + sizeof(p.nParticle()) + sizeof(p.d()) + + sizeof(p.dTarget()) + sizeof(p.U()) + sizeof(p.f()) + sizeof(p.angularMomentum()) diff --git a/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcel.H b/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcel.H index ffb7f9b47e1c33e9567b969f04966d84a5ad58c9..ed0b11e88e5b478b7e682cfca45e06be153c3e6f 100644 --- a/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcel.H +++ b/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcel.H @@ -289,7 +289,9 @@ public: ( ReactingMultiphaseCloud<ParcelType>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ); @@ -299,9 +301,12 @@ public: ReactingMultiphaseCloud<ParcelType>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, diff --git a/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcelI.H b/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcelI.H index c7a557fba6f525ffc2e77b2340e86fe64ad79cb7..960a298ad7cdb1ce03f2bc9d0b133376b7dc76d4 100644 --- a/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcelI.H +++ b/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcelI.H @@ -89,10 +89,12 @@ inline Foam::ReactingMultiphaseParcel<ParcelType>::ReactingMultiphaseParcel ( ReactingMultiphaseCloud<ParcelType>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ) : - ReactingParcel<ParcelType>(owner, position, cellI), + ReactingParcel<ParcelType>(owner, position, cellI, tetFaceI, tetPtI), YGas_(0), YLiquid_(0), YSolid_(0), @@ -106,9 +108,12 @@ inline Foam::ReactingMultiphaseParcel<ParcelType>::ReactingMultiphaseParcel ReactingMultiphaseCloud<ParcelType>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, @@ -125,9 +130,12 @@ inline Foam::ReactingMultiphaseParcel<ParcelType>::ReactingMultiphaseParcel owner, position, cellI, + tetFaceI, + tetPtI, typeId, nParticle0, d0, + dTarget0, U0, f0, angularMomentum0, diff --git a/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcel.C b/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcel.C index fa5f3f5ede367168962dbb2760e647fb69c12c63..f03219885604b71d52474469ebcad7c495465271 100644 --- a/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcel.C +++ b/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcel.C @@ -42,7 +42,12 @@ void Foam::ReactingParcel<ParcelType>::setCellValues { ThermoParcel<ParcelType>::setCellValues(td, dt, cellI); - pc_ = td.pInterp().interpolate(this->position(), cellI); + pc_ = td.pInterp().interpolate + ( + this->position(), + this->currentTetIndices() + ); + if (pc_ < td.constProps().pMin()) { WarningIn diff --git a/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcel.H b/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcel.H index 38e607bd39f904c293bbd3687e6ffbbd382ef32e..6ae15d5098ebe41cbbb03109d748002d0530cf4a 100644 --- a/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcel.H +++ b/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcel.H @@ -239,7 +239,9 @@ public: ( ReactingCloud<ParcelType>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ); //- Construct from components @@ -248,9 +250,12 @@ public: ReactingCloud<ParcelType>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, diff --git a/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcelI.H b/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcelI.H index 736b230f08bdc4e8af8b564f1f482b4fb879ec86..60c1556b8f2fb641113a07e0293ac7c19f459798 100644 --- a/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcelI.H +++ b/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcelI.H @@ -75,10 +75,12 @@ inline Foam::ReactingParcel<ParcelType>::ReactingParcel ( ReactingCloud<ParcelType>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ) : - ThermoParcel<ParcelType>(owner, position, cellI), + ThermoParcel<ParcelType>(owner, position, cellI, tetFaceI, tetPtI), mass0_(0.0), Y_(0), pc_(0.0) @@ -91,9 +93,12 @@ inline Foam::ReactingParcel<ParcelType>::ReactingParcel ReactingCloud<ParcelType>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, @@ -107,9 +112,12 @@ inline Foam::ReactingParcel<ParcelType>::ReactingParcel owner, position, cellI, + tetFaceI, + tetPtI, typeId, nParticle0, d0, + dTarget0, U0, f0, angularMomentum0, diff --git a/src/lagrangian/intermediate/parcels/Templates/ThermoParcel/ThermoParcel.C b/src/lagrangian/intermediate/parcels/Templates/ThermoParcel/ThermoParcel.C index 6800129a9bdc629c55d0a3d98424938888730e47..dbcc01ad2ab5c5d42acdb707c9293e5d59777295 100644 --- a/src/lagrangian/intermediate/parcels/Templates/ThermoParcel/ThermoParcel.C +++ b/src/lagrangian/intermediate/parcels/Templates/ThermoParcel/ThermoParcel.C @@ -41,9 +41,11 @@ void Foam::ThermoParcel<ParcelType>::setCellValues { KinematicParcel<ParcelType>::setCellValues(td, dt, cellI); - cpc_ = td.cpInterp().interpolate(this->position(), cellI); + tetIndices tetIs = this->currentTetIndices(); - Tc_ = td.TInterp().interpolate(this->position(), cellI); + cpc_ = td.cpInterp().interpolate(this->position(), tetIs); + + Tc_ = td.TInterp().interpolate(this->position(), tetIs); if (Tc_ < td.constProps().TMin()) { @@ -96,10 +98,14 @@ void Foam::ThermoParcel<ParcelType>::calcSurfaceValues // Surface temperature using two thirds rule Ts = (2.0*T + Tc_)/3.0; + tetIndices tetIs = this->currentTetIndices(); + // Assuming thermo props vary linearly with T for small dT - scalar factor = td.TInterp().interpolate(this->position(), cellI)/Ts; + scalar factor = td.TInterp().interpolate (this->position(), tetIs)/Ts; + rhos = this->rhoc_*factor; - mus = td.muInterp().interpolate(this->position(), cellI)/factor; + + mus = td.muInterp().interpolate (this->position(), tetIs)/factor; Pr = td.constProps().Pr(); kappa = cpc_*mus/Pr; diff --git a/src/lagrangian/intermediate/parcels/Templates/ThermoParcel/ThermoParcel.H b/src/lagrangian/intermediate/parcels/Templates/ThermoParcel/ThermoParcel.H index 8715aa570e95ba7d503bc40d3fb9c0e7d2be0a66..dc97dcba6c41e0303396b2e863976c596ac4c14c 100644 --- a/src/lagrangian/intermediate/parcels/Templates/ThermoParcel/ThermoParcel.H +++ b/src/lagrangian/intermediate/parcels/Templates/ThermoParcel/ThermoParcel.H @@ -252,7 +252,9 @@ public: ( ThermoCloud<ParcelType>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ); //- Construct from components @@ -261,9 +263,12 @@ public: ThermoCloud<ParcelType>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, diff --git a/src/lagrangian/intermediate/parcels/Templates/ThermoParcel/ThermoParcelI.H b/src/lagrangian/intermediate/parcels/Templates/ThermoParcel/ThermoParcelI.H index 05dce5832d99f084cd40a5047a9ec173dea025fe..b728ce65cbb40c4302ea1239562615d4feb9caec 100644 --- a/src/lagrangian/intermediate/parcels/Templates/ThermoParcel/ThermoParcelI.H +++ b/src/lagrangian/intermediate/parcels/Templates/ThermoParcel/ThermoParcelI.H @@ -75,10 +75,12 @@ inline Foam::ThermoParcel<ParcelType>::ThermoParcel ( ThermoCloud<ParcelType>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ) : - KinematicParcel<ParcelType>(owner, position, cellI), + KinematicParcel<ParcelType>(owner, position, cellI, tetFaceI, tetPtI), T_(0.0), cp_(0.0), Tc_(0.0), @@ -92,9 +94,12 @@ inline Foam::ThermoParcel<ParcelType>::ThermoParcel ThermoCloud<ParcelType>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, @@ -107,9 +112,12 @@ inline Foam::ThermoParcel<ParcelType>::ThermoParcel owner, position, cellI, + tetFaceI, + tetPtI, typeId, nParticle0, d0, + dTarget0, U0, f0, angularMomentum0, diff --git a/src/lagrangian/intermediate/parcels/derived/basicKinematicParcel/basicKinematicParcel.C b/src/lagrangian/intermediate/parcels/derived/basicKinematicParcel/basicKinematicParcel.C index 61b201f282b419ec8206121199dbc46bcd81d54b..adc4fc409bd59ec5e933e6838ba78adbfc33abc8 100644 --- a/src/lagrangian/intermediate/parcels/derived/basicKinematicParcel/basicKinematicParcel.C +++ b/src/lagrangian/intermediate/parcels/derived/basicKinematicParcel/basicKinematicParcel.C @@ -41,10 +41,19 @@ Foam::basicKinematicParcel::basicKinematicParcel ( KinematicCloud<basicKinematicParcel>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ) : - KinematicParcel<basicKinematicParcel>(owner, position, cellI) + KinematicParcel<basicKinematicParcel> + ( + owner, + position, + cellI, + tetFaceI, + tetPtI + ) {} @@ -53,9 +62,12 @@ Foam::basicKinematicParcel::basicKinematicParcel KinematicCloud<basicKinematicParcel>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, @@ -68,9 +80,12 @@ Foam::basicKinematicParcel::basicKinematicParcel owner, position, cellI, + tetFaceI, + tetPtI, typeId, nParticle0, d0, + dTarget0, U0, f0, angularMomentum0, diff --git a/src/lagrangian/intermediate/parcels/derived/basicKinematicParcel/basicKinematicParcel.H b/src/lagrangian/intermediate/parcels/derived/basicKinematicParcel/basicKinematicParcel.H index bd86c395b75e31b608cd2ea6327c54d1b85d398a..5fdb8777a5c2ec5b8ec4202ebf595c73519d0a6c 100644 --- a/src/lagrangian/intermediate/parcels/derived/basicKinematicParcel/basicKinematicParcel.H +++ b/src/lagrangian/intermediate/parcels/derived/basicKinematicParcel/basicKinematicParcel.H @@ -65,7 +65,9 @@ public: ( KinematicCloud<basicKinematicParcel>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ); //- Construct from components @@ -74,9 +76,12 @@ public: KinematicCloud<basicKinematicParcel>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, diff --git a/src/lagrangian/intermediate/parcels/derived/basicReactingMultiphaseParcel/basicReactingMultiphaseParcel.C b/src/lagrangian/intermediate/parcels/derived/basicReactingMultiphaseParcel/basicReactingMultiphaseParcel.C index 56359e0d9612cd524f30909cac242a6de0849f86..748122567e9bdb30486e9f8b43bef4b187ae5823 100644 --- a/src/lagrangian/intermediate/parcels/derived/basicReactingMultiphaseParcel/basicReactingMultiphaseParcel.C +++ b/src/lagrangian/intermediate/parcels/derived/basicReactingMultiphaseParcel/basicReactingMultiphaseParcel.C @@ -31,14 +31,18 @@ Foam::basicReactingMultiphaseParcel::basicReactingMultiphaseParcel ( ReactingMultiphaseCloud<basicReactingMultiphaseParcel>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ) : ReactingMultiphaseParcel<basicReactingMultiphaseParcel> ( owner, position, - cellI + cellI, + tetFaceI, + tetPtI ) {} @@ -48,9 +52,12 @@ Foam::basicReactingMultiphaseParcel::basicReactingMultiphaseParcel ReactingMultiphaseCloud<basicReactingMultiphaseParcel>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, @@ -63,14 +70,17 @@ Foam::basicReactingMultiphaseParcel::basicReactingMultiphaseParcel constantProperties& constProps ) : - ReactingMultiphaseParcel<basicReactingMultiphaseParcel > + ReactingMultiphaseParcel<basicReactingMultiphaseParcel> ( owner, position, cellI, + tetFaceI, + tetPtI, typeId, nParticle0, d0, + dTarget0, U0, f0, angularMomentum0, diff --git a/src/lagrangian/intermediate/parcels/derived/basicReactingMultiphaseParcel/basicReactingMultiphaseParcel.H b/src/lagrangian/intermediate/parcels/derived/basicReactingMultiphaseParcel/basicReactingMultiphaseParcel.H index 6cc9d2f535a6b29ca67ae9dc73f9f94ae7976ed8..2fa913c2299865b7bc9bc28b866de8b77e497560 100644 --- a/src/lagrangian/intermediate/parcels/derived/basicReactingMultiphaseParcel/basicReactingMultiphaseParcel.H +++ b/src/lagrangian/intermediate/parcels/derived/basicReactingMultiphaseParcel/basicReactingMultiphaseParcel.H @@ -66,7 +66,9 @@ public: ( ReactingMultiphaseCloud<basicReactingMultiphaseParcel>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ); //- Construct from components @@ -75,9 +77,12 @@ public: ReactingMultiphaseCloud<basicReactingMultiphaseParcel>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, diff --git a/src/lagrangian/intermediate/parcels/derived/basicReactingParcel/basicReactingParcel.C b/src/lagrangian/intermediate/parcels/derived/basicReactingParcel/basicReactingParcel.C index 23ef85c02ec919f3fd8e8efd6c7f92632ad1c023..25b0c4c26aea6ff009cfe93614f90ece1f77381f 100644 --- a/src/lagrangian/intermediate/parcels/derived/basicReactingParcel/basicReactingParcel.C +++ b/src/lagrangian/intermediate/parcels/derived/basicReactingParcel/basicReactingParcel.C @@ -29,23 +29,35 @@ License Foam::basicReactingParcel::basicReactingParcel ( - ReactingCloud<basicReactingParcel >& owner, + ReactingCloud<basicReactingParcel>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ) : - ReactingParcel<basicReactingParcel >(owner, position, cellI) + ReactingParcel<basicReactingParcel> + ( + owner, + position, + cellI, + tetFaceI, + tetPtI + ) {} Foam::basicReactingParcel::basicReactingParcel ( - ReactingCloud<basicReactingParcel >& owner, + ReactingCloud<basicReactingParcel>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, @@ -54,14 +66,17 @@ Foam::basicReactingParcel::basicReactingParcel const ReactingParcel<basicReactingParcel>::constantProperties& constProps ) : - ReactingParcel<basicReactingParcel > + ReactingParcel<basicReactingParcel> ( owner, position, cellI, + tetFaceI, + tetPtI, typeId, nParticle0, d0, + dTarget0, U0, f0, angularMomentum0, @@ -74,7 +89,7 @@ Foam::basicReactingParcel::basicReactingParcel Foam::basicReactingParcel::basicReactingParcel ( - const Cloud<basicReactingParcel >& cloud, + const Cloud<basicReactingParcel>& cloud, Istream& is, bool readFields ) diff --git a/src/lagrangian/intermediate/parcels/derived/basicReactingParcel/basicReactingParcel.H b/src/lagrangian/intermediate/parcels/derived/basicReactingParcel/basicReactingParcel.H index 86e9d726f5a3d9e063841de632072f9585e434c8..49e26aadb70c6dbbbe297b54b54685e0d703ca2c 100644 --- a/src/lagrangian/intermediate/parcels/derived/basicReactingParcel/basicReactingParcel.H +++ b/src/lagrangian/intermediate/parcels/derived/basicReactingParcel/basicReactingParcel.H @@ -64,7 +64,9 @@ public: ( ReactingCloud<basicReactingParcel>& owner, const vector& position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ); //- Construct from components @@ -73,9 +75,12 @@ public: ReactingCloud<basicReactingParcel>& owner, const vector& position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector& U0, const vector& f0, const vector& angularMomentum0, diff --git a/src/lagrangian/intermediate/parcels/derived/basicThermoParcel/basicThermoParcel.C b/src/lagrangian/intermediate/parcels/derived/basicThermoParcel/basicThermoParcel.C index c233efbd6fe91cb7773a03f5dcfe6733fb7f5224..5b5fddb1bbc4924f5c58742fddbb46642ce8c1cb 100644 --- a/src/lagrangian/intermediate/parcels/derived/basicThermoParcel/basicThermoParcel.C +++ b/src/lagrangian/intermediate/parcels/derived/basicThermoParcel/basicThermoParcel.C @@ -41,10 +41,12 @@ Foam::basicThermoParcel::basicThermoParcel ( ThermoCloud<basicThermoParcel>& owner, const vector position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ) : - ThermoParcel<basicThermoParcel>(owner, position, cellI) + ThermoParcel<basicThermoParcel>(owner, position, cellI, tetFaceI, tetPtI) {} @@ -53,9 +55,12 @@ Foam::basicThermoParcel::basicThermoParcel ThermoCloud<basicThermoParcel>& owner, const vector position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector U0, const vector& f0, const vector& angularMomentum0, @@ -68,9 +73,12 @@ Foam::basicThermoParcel::basicThermoParcel owner, position, cellI, + tetFaceI, + tetPtI, typeId, nParticle0, d0, + dTarget0, U0, f0, angularMomentum0, diff --git a/src/lagrangian/intermediate/parcels/derived/basicThermoParcel/basicThermoParcel.H b/src/lagrangian/intermediate/parcels/derived/basicThermoParcel/basicThermoParcel.H index 63c5b505570bf248f202f620baf07f01e199f94d..8f3720b365f79c6da7ccc168b7f4607c29d13c5f 100644 --- a/src/lagrangian/intermediate/parcels/derived/basicThermoParcel/basicThermoParcel.H +++ b/src/lagrangian/intermediate/parcels/derived/basicThermoParcel/basicThermoParcel.H @@ -64,7 +64,9 @@ public: ( ThermoCloud<basicThermoParcel>& owner, const vector position, - const label cellI + const label cellI, + const label tetFaceI, + const label tetPtI ); //- Construct from components @@ -73,9 +75,12 @@ public: ThermoCloud<basicThermoParcel>& owner, const vector position, const label cellI, + const label tetFaceI, + const label tetPtI, const label typeId, const scalar nParticle0, const scalar d0, + const scalar dTarget0, const vector U0, const vector& f0, const vector& angularMomentum0, diff --git a/src/lagrangian/intermediate/parcels/include/makeParcelInjectionModels.H b/src/lagrangian/intermediate/parcels/include/makeParcelInjectionModels.H index ea8dcd57f475f72fa3684ed1e9cbc84fdae61af0..b673d3d84cc2fd75ef476b54ed41866d6ea25f59 100644 --- a/src/lagrangian/intermediate/parcels/include/makeParcelInjectionModels.H +++ b/src/lagrangian/intermediate/parcels/include/makeParcelInjectionModels.H @@ -33,11 +33,13 @@ License #include "ConeInjection.H" #include "ConeInjectionMP.H" #include "FieldActivatedInjection.H" +#include "InflationInjection.H" #include "KinematicLookupTableInjection.H" #include "ManualInjection.H" #include "NoInjection.H" #include "PatchInjection.H" + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #define makeParcelInjectionModels(ParcelType) \ @@ -63,6 +65,12 @@ License ParcelType \ ); \ makeInjectionModelType \ + ( \ + InflationInjection, \ + KinematicCloud, \ + ParcelType \ + ); \ + makeInjectionModelType \ ( \ KinematicLookupTableInjection, \ KinematicCloud, \ diff --git a/src/lagrangian/intermediate/particleForces/particleForces.C b/src/lagrangian/intermediate/particleForces/particleForces.C index 6591d2b8d44c7b38aef6beedb8d55d88fcb5676d..3a2865d41db278b4617769f9993a05dd2f99f7b5 100644 --- a/src/lagrangian/intermediate/particleForces/particleForces.C +++ b/src/lagrangian/intermediate/particleForces/particleForces.C @@ -68,8 +68,8 @@ Foam::particleForces::particleForces pressureGradient_(dict_.lookup("pressureGradient")), paramagnetic_(dict_.lookup("paramagnetic")), magneticSusceptibility_(0.0), - UName_(dict_.lookupOrDefault<word>("U", "U")), - HdotGradHName_(dict_.lookupOrDefault<word>("HdotGradH", "HdotGradH")) + UName_(dict_.lookupOrDefault<word>("UName", "U")), + HdotGradHName_(dict_.lookupOrDefault<word>("HdotGradHName", "HdotGradH")) { if (virtualMass_) { @@ -211,7 +211,7 @@ void Foam::particleForces::cacheFields Foam::vector Foam::particleForces::calcCoupled ( const vector& position, - const label cellI, + const tetIndices& tetIs, const scalar dt, const scalar rhoc, const scalar rho, @@ -236,7 +236,7 @@ Foam::vector Foam::particleForces::calcCoupled if (pressureGradient_) { const volTensorField& gradU = *gradUPtr_; - accelTot += rhoc/rho*(U & gradU[cellI]); + accelTot += rhoc/rho*(U & gradU[tetIs.cell()]); } return accelTot; @@ -246,7 +246,7 @@ Foam::vector Foam::particleForces::calcCoupled Foam::vector Foam::particleForces::calcNonCoupled ( const vector& position, - const label cellI, + const tetIndices& tetIs, const scalar dt, const scalar rhoc, const scalar rho, @@ -272,7 +272,7 @@ Foam::vector Foam::particleForces::calcNonCoupled accelTot += 3.0*constant::electromagnetic::mu0.value()/rho *magneticSusceptibility_/(magneticSusceptibility_ + 3) - *HdotGradHInter.interpolate(position, cellI); + *HdotGradHInter.interpolate(position, tetIs); // force is: diff --git a/src/lagrangian/intermediate/particleForces/particleForces.H b/src/lagrangian/intermediate/particleForces/particleForces.H index 8c76b1f773dfbba1d90f146878e649468b36abcd..7aacee74b34416475628b184b8adee25727486ff 100644 --- a/src/lagrangian/intermediate/particleForces/particleForces.H +++ b/src/lagrangian/intermediate/particleForces/particleForces.H @@ -41,6 +41,7 @@ SourceFiles #include "vector.H" #include "volFieldsFwd.H" #include "interpolation.H" +#include "tetIndices.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -179,7 +180,7 @@ public: vector calcCoupled ( const vector& position, - const label cellI, + const tetIndices& tetIs, const scalar dt, const scalar rhoc, const scalar rho, @@ -192,7 +193,7 @@ public: vector calcNonCoupled ( const vector& position, - const label cellI, + const tetIndices& tetIs, const scalar dt, const scalar rhoc, const scalar rho, diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.C b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.C index e1e1587c95dc9afae113bd90d7129d9f2eb85111..0657ea96a9d5e9bfb56a26a7553531f17d26f549 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.C @@ -51,8 +51,6 @@ void Foam::PairCollision<CloudType>::preInteraction() p.torque() = vector::zero; } - - buildCellOccupancy(); } @@ -61,7 +59,7 @@ void Foam::PairCollision<CloudType>::parcelInteraction() { PstreamBuffers pBufs(Pstream::nonBlocking); - il_.sendReferredData(cellOccupancy_, pBufs); + il_.sendReferredData(this->owner().cellOccupancy(), pBufs); realRealInteraction(); @@ -80,17 +78,20 @@ void Foam::PairCollision<CloudType>::realRealInteraction() typename CloudType::parcelType* pA_ptr = NULL; typename CloudType::parcelType* pB_ptr = NULL; + List<DynamicList<typename CloudType::parcelType*> >& cellOccupancy = + this->owner().cellOccupancy(); + forAll(dil, realCellI) { // Loop over all Parcels in cell A (a) - forAll(cellOccupancy_[realCellI], a) + forAll(cellOccupancy[realCellI], a) { - pA_ptr = cellOccupancy_[realCellI][a]; + pA_ptr = cellOccupancy[realCellI][a]; forAll(dil[realCellI], interactingCells) { List<typename CloudType::parcelType*> cellBParcels = - cellOccupancy_[dil[realCellI][interactingCells]]; + cellOccupancy[dil[realCellI][interactingCells]]; // Loop over all Parcels in cell B (b) forAll(cellBParcels, b) @@ -102,9 +103,9 @@ void Foam::PairCollision<CloudType>::realRealInteraction() } // Loop over the other Parcels in cell A (aO) - forAll(cellOccupancy_[realCellI], aO) + forAll(cellOccupancy[realCellI], aO) { - pB_ptr = cellOccupancy_[realCellI][aO]; + pB_ptr = cellOccupancy[realCellI][aO]; // Do not double-evaluate, compare pointers, arbitrary // order @@ -127,6 +128,9 @@ void Foam::PairCollision<CloudType>::realReferredInteraction() List<IDLList<typename CloudType::parcelType> >& referredParticles = il_.referredParticles(); + List<DynamicList<typename CloudType::parcelType*> >& cellOccupancy = + this->owner().cellOccupancy(); + // Loop over all referred cells forAll(ril, refCellI) { @@ -150,7 +154,7 @@ void Foam::PairCollision<CloudType>::realReferredInteraction() forAll(realCells, realCellI) { List<typename CloudType::parcelType*> realCellParcels = - cellOccupancy_[realCells[realCellI]]; + cellOccupancy[realCells[realCellI]]; forAll(realCellParcels, realParcelI) { @@ -179,6 +183,9 @@ void Foam::PairCollision<CloudType>::wallInteraction() const volVectorField& U = mesh.lookupObject<volVectorField>(il_.UName()); + List<DynamicList<typename CloudType::parcelType*> >& cellOccupancy = + this->owner().cellOccupancy(); + // Storage for the wall interaction sites DynamicList<point> flatSitePoints; DynamicList<scalar> flatSiteExclusionDistancesSqr; @@ -196,7 +203,7 @@ void Foam::PairCollision<CloudType>::wallInteraction() const labelList& realWallFaces = directWallFaces[realCellI]; // Loop over all Parcels in cell - forAll(cellOccupancy_[realCellI], cellParticleI) + forAll(cellOccupancy[realCellI], cellParticleI) { flatSitePoints.clear(); flatSiteExclusionDistancesSqr.clear(); @@ -209,7 +216,7 @@ void Foam::PairCollision<CloudType>::wallInteraction() sharpSiteData.clear(); typename CloudType::parcelType& p = - *cellOccupancy_[realCellI][cellParticleI]; + *cellOccupancy[realCellI][cellParticleI]; const point& pos = p.position(); @@ -482,21 +489,6 @@ void Foam::PairCollision<CloudType>::postInteraction() } -template<class CloudType> -void Foam::PairCollision<CloudType>::buildCellOccupancy() -{ - forAll(cellOccupancy_, cO) - { - cellOccupancy_[cO].clear(); - } - - forAllIter(typename CloudType, this->owner(), iter) - { - cellOccupancy_[iter().cell()].append(&iter()); - } -} - - template<class CloudType> void Foam::PairCollision<CloudType>::evaluatePair ( @@ -539,7 +531,6 @@ Foam::PairCollision<CloudType>::PairCollision ) : CollisionModel<CloudType>(dict, owner, typeName), - cellOccupancy_(owner.mesh().nCells()), pairModel_ ( PairModel<CloudType>::New @@ -560,7 +551,14 @@ Foam::PairCollision<CloudType>::PairCollision ( owner.mesh(), readScalar(this->coeffDict().lookup("maxInteractionDistance")), - Switch(this->coeffDict().lookup("writeReferredParticleCloud")), + Switch + ( + this->coeffDict().lookupOrDefault + ( + "writeReferredParticleCloud", + false + ) + ), this->coeffDict().lookupOrDefault("UName", word("U")) ) {} diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.H b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.H index 8699d477cdd225f52000a58bd283e8a175a4defd..6ad4130e1c783ae53f00d9c1617504bef1aa9497 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.H @@ -76,9 +76,6 @@ class PairCollision // Private data - //- Cell occupancy information for each parcel - List<DynamicList<typename CloudType::parcelType*> > cellOccupancy_; - //- PairModel to calculate the interaction between two parcels autoPtr<PairModel<CloudType> > pairModel_; @@ -124,9 +121,6 @@ class PairCollision //- Post collision tasks void postInteraction(); - //- Build the cell occupancy information for each parcel - void buildCellOccupancy(); - //- Calculate the pair force between parcels void evaluatePair ( diff --git a/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/DispersionModel/DispersionModel.H b/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/DispersionModel/DispersionModel.H index b1634db21e1d44f7b29a2ab434b040470adbf94b..afb063d0f5cd8fe717f4c692dfb196594b9e85ef 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/DispersionModel/DispersionModel.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/DispersionModel/DispersionModel.H @@ -127,7 +127,7 @@ public: virtual vector update ( const scalar dt, - const label celli, + const label cellI, const vector& U, const vector& Uc, vector& UTurb, diff --git a/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/GradientDispersionRAS/GradientDispersionRAS.C b/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/GradientDispersionRAS/GradientDispersionRAS.C index d214303427ebc0618c6b02042b0d43be4fa420b2..05617f25dae9b0af1c9cd06598ce8a2fd473c7cf 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/GradientDispersionRAS/GradientDispersionRAS.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/GradientDispersionRAS/GradientDispersionRAS.C @@ -81,7 +81,7 @@ template<class CloudType> Foam::vector Foam::GradientDispersionRAS<CloudType>::update ( const scalar dt, - const label celli, + const label cellI, const vector& U, const vector& Uc, vector& UTurb, @@ -98,8 +98,8 @@ Foam::vector Foam::GradientDispersionRAS<CloudType>::update const scalar tTurbLoc = min ( - k[celli]/epsilon[celli], - cps*pow(k[celli], 1.5)/epsilon[celli]/(UrelMag + SMALL) + k[cellI]/epsilon[cellI], + cps*pow(k[cellI], 1.5)/epsilon[cellI]/(UrelMag + SMALL) ); // Parcel is perturbed by the turbulence @@ -111,8 +111,8 @@ Foam::vector Foam::GradientDispersionRAS<CloudType>::update { tTurb = 0.0; - scalar sigma = sqrt(2.0*k[celli]/3.0); - vector dir = -gradk[celli]/(mag(gradk[celli]) + SMALL); + scalar sigma = sqrt(2.0*k[cellI]/3.0); + vector dir = -gradk[cellI]/(mag(gradk[cellI]) + SMALL); // Numerical Recipes... Ch. 7. Random Numbers... scalar x1 = 0.0; diff --git a/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/GradientDispersionRAS/GradientDispersionRAS.H b/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/GradientDispersionRAS/GradientDispersionRAS.H index eb4c97e0614dc5eca4a67ae58e5f3355f4cd0b0d..af74d2578b16dd4952ee243c5670b2d226499c33 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/GradientDispersionRAS/GradientDispersionRAS.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/GradientDispersionRAS/GradientDispersionRAS.H @@ -90,7 +90,7 @@ public: virtual vector update ( const scalar dt, - const label celli, + const label cellI, const vector& U, const vector& Uc, vector& UTurb, diff --git a/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/NoDispersion/NoDispersion.H b/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/NoDispersion/NoDispersion.H index a8bba39ef467181f0b210618259bfb43db12f4ef..e63abbda213a81e391626c1c74f891735b9dc0a8 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/NoDispersion/NoDispersion.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/NoDispersion/NoDispersion.H @@ -80,7 +80,7 @@ public: virtual vector update ( const scalar dt, - const label celli, + const label cellI, const vector& U, const vector& Uc, vector& UTurb, diff --git a/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/StochasticDispersionRAS/StochasticDispersionRAS.C b/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/StochasticDispersionRAS/StochasticDispersionRAS.C index 20368957d7066ef89dfdb6fc42c0762c4eb3160a..a43b00c10f9f07ef6166a8c3a514284d9378af45 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/StochasticDispersionRAS/StochasticDispersionRAS.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/StochasticDispersionRAS/StochasticDispersionRAS.C @@ -58,7 +58,7 @@ template<class CloudType> Foam::vector Foam::StochasticDispersionRAS<CloudType>::update ( const scalar dt, - const label celli, + const label cellI, const vector& U, const vector& Uc, vector& UTurb, @@ -74,8 +74,8 @@ Foam::vector Foam::StochasticDispersionRAS<CloudType>::update const scalar tTurbLoc = min ( - k[celli]/epsilon[celli], - cps*pow(k[celli], 1.5)/epsilon[celli]/(UrelMag + SMALL) + k[cellI]/epsilon[cellI], + cps*pow(k[cellI], 1.5)/epsilon[cellI]/(UrelMag + SMALL) ); // Parcel is perturbed by the turbulence @@ -87,7 +87,7 @@ Foam::vector Foam::StochasticDispersionRAS<CloudType>::update { tTurb = 0.0; - scalar sigma = sqrt(2.0*k[celli]/3.0); + scalar sigma = sqrt(2.0*k[cellI]/3.0); vector dir = 2.0*this->owner().rndGen().vector01() - vector::one; dir /= mag(dir) + SMALL; diff --git a/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/StochasticDispersionRAS/StochasticDispersionRAS.H b/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/StochasticDispersionRAS/StochasticDispersionRAS.H index b9663a9059565826975f14ba7ab6f075db97eae9..dae1658c9127ccef8540b858013f699cd1824877 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/StochasticDispersionRAS/StochasticDispersionRAS.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/DispersionModel/StochasticDispersionRAS/StochasticDispersionRAS.H @@ -79,7 +79,7 @@ public: virtual vector update ( const scalar dt, - const label celli, + const label cellI, const vector& U, const vector& Uc, vector& UTurb, diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjection/ConeInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjection/ConeInjection.C index cb665641ccb1d7b9d9af4030aa53c4fe37cb6278..438b32b2252b07350225323df1e0fe8c49c77e35 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjection/ConeInjection.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjection/ConeInjection.C @@ -36,7 +36,7 @@ Foam::label Foam::ConeInjection<CloudType>::parcelsToInject ( const scalar time0, const scalar time1 -) const +) { if ((time0 >= 0.0) && (time0 < duration_)) { @@ -54,7 +54,7 @@ Foam::scalar Foam::ConeInjection<CloudType>::volumeToInject ( const scalar time0, const scalar time1 -) const +) { if ((time0 >= 0.0) && (time0 < duration_)) { @@ -80,6 +80,8 @@ Foam::ConeInjection<CloudType>::ConeInjection duration_(readScalar(this->coeffDict().lookup("duration"))), position_(this->coeffDict().lookup("position")), injectorCell_(-1), + injectorTetFace_(-1), + injectorTetPt_(-1), direction_(this->coeffDict().lookup("direction")), parcelsPerSecond_ ( @@ -150,7 +152,13 @@ Foam::ConeInjection<CloudType>::ConeInjection this->volumeTotal_ = flowRateProfile_().integrate(0.0, duration_); // Set/cache the injector cell - this->findCellAtPosition(injectorCell_, position_); + this->findCellAtPosition + ( + injectorCell_, + injectorTetFace_, + injectorTetPt_, + position_ + ); } @@ -184,11 +192,15 @@ void Foam::ConeInjection<CloudType>::setPositionAndCell const label, const scalar, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ) { position = position_; cellOwner = injectorCell_; + tetFaceI = injectorTetFace_; + tetPtI = injectorTetPt_; } diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjection/ConeInjection.H b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjection/ConeInjection.H index 6246f4cdc9e9bccbf16cf2a7d15bbe06b4dd7ea8..a9c289d6d48d44b5be1c59fba2697b6e1c661591 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjection/ConeInjection.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjection/ConeInjection.H @@ -77,6 +77,12 @@ class ConeInjection //- Cell containing injector position [] label injectorCell_; + //- tetFace of tet containing injector position [] + label injectorTetFace_; + + //- tetPt of tet containing injector position [] + label injectorTetPt_; + //- Injector direction [] vector direction_; @@ -117,14 +123,14 @@ protected: ( const scalar time0, const scalar time1 - ) const; + ); //- Number of parcels to introduce over the time step relative to SOI scalar volumeToInject ( const scalar time0, const scalar time1 - ) const; + ); public: @@ -158,14 +164,16 @@ public: // Injection geometry - //- Set the injection position and owner cell + //- Set the injection position and owner cell, tetFace and tetPt virtual void setPositionAndCell ( const label parcelI, const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ); //- Set the parcel properties diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjectionMP/ConeInjectionMP.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjectionMP/ConeInjectionMP.C index 1d3f49aaa59ad286ea10b24d803a170b627332f1..6639c43587fc4e7fb237ac09962a53bb73b909cd 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjectionMP/ConeInjectionMP.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjectionMP/ConeInjectionMP.C @@ -36,7 +36,7 @@ Foam::label Foam::ConeInjectionMP<CloudType>::parcelsToInject ( const scalar time0, const scalar time1 -) const +) { if ((time0 >= 0.0) && (time0 < duration_)) { @@ -63,7 +63,7 @@ Foam::scalar Foam::ConeInjectionMP<CloudType>::volumeToInject ( const scalar time0, const scalar time1 -) const +) { if ((time0 >= 0.0) && (time0 < duration_)) { @@ -99,6 +99,8 @@ Foam::ConeInjectionMP<CloudType>::ConeInjectionMP ) ), injectorCells_(positions_.size()), + injectorTetFaces_(positions_.size()), + injectorTetPts_(positions_.size()), axesFile_(this->coeffDict().lookup("axesFile")), axes_ ( @@ -190,6 +192,8 @@ Foam::ConeInjectionMP<CloudType>::ConeInjectionMP this->findCellAtPosition ( injectorCells_[i], + injectorTetFaces_[i], + injectorTetPts_[i], positions_[i] ); } @@ -226,13 +230,17 @@ void Foam::ConeInjectionMP<CloudType>::setPositionAndCell const label, const scalar, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ) { - const label i = parcelI%positions_.size(); + const label i = parcelI % positions_.size(); position = positions_[i]; cellOwner = injectorCells_[i]; + tetFaceI = injectorTetFaces_[i]; + tetPtI = injectorTetPts_[i]; } diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjectionMP/ConeInjectionMP.H b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjectionMP/ConeInjectionMP.H index 5401deebee8db0a4a8475242bc66cba9609c8523..2b0d4e8c313e5586a92fc20926fa1c58925c1c72 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjectionMP/ConeInjectionMP.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeInjectionMP/ConeInjectionMP.H @@ -75,9 +75,15 @@ class ConeInjectionMP //- Field of injector positions vectorIOField positions_; - //- Field of cell labels corresoponding to injector positions + //- List of cell labels corresponding to injector positions labelList injectorCells_; + //- List of tetFace labels corresponding to injector positions + labelList injectorTetFaces_; + + //- List of tetPt labels corresponding to injector positions + labelList injectorTetPts_; + //- Name of file containing axes data const word axesFile_; @@ -127,14 +133,14 @@ protected: ( const scalar time0, const scalar time1 - ) const; + ); //- Number of parcels to introduce over the time step scalar volumeToInject ( const scalar time0, const scalar time1 - ) const; + ); public: @@ -168,14 +174,16 @@ public: // Injection geometry - //- Set the injection position and owner cell + //- Set the injection position and owner cell, tetFace and tetPt virtual void setPositionAndCell ( const label parcelI, const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ); //- Set the parcel properties diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/FieldActivatedInjection/FieldActivatedInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/FieldActivatedInjection/FieldActivatedInjection.C index 533febfadcf439cf4c9d15e0497820565df7046c..44cebec90388d605251285ca144b5a2cfaa20516 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/FieldActivatedInjection/FieldActivatedInjection.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/FieldActivatedInjection/FieldActivatedInjection.C @@ -36,7 +36,7 @@ Foam::label Foam::FieldActivatedInjection<CloudType>::parcelsToInject ( const scalar time0, const scalar time1 -) const +) { if (sum(nParcelsInjected_) < nParcelsPerInjector_*positions_.size()) { @@ -54,7 +54,7 @@ Foam::scalar Foam::FieldActivatedInjection<CloudType>::volumeToInject ( const scalar time0, const scalar time1 -) const +) { if (sum(nParcelsInjected_) < nParcelsPerInjector_*positions_.size()) { @@ -105,6 +105,8 @@ Foam::FieldActivatedInjection<CloudType>::FieldActivatedInjection ) ), injectorCells_(positions_.size()), + injectorTetFaces_(positions_.size()), + injectorTetPts_(positions_.size()), nParcelsPerInjector_ ( readLabel(this->coeffDict().lookup("parcelsPerInjector")) @@ -137,6 +139,8 @@ Foam::FieldActivatedInjection<CloudType>::FieldActivatedInjection this->findCellAtPosition ( injectorCells_[i], + injectorTetFaces_[i], + injectorTetPts_[i], positions_[i] ); } @@ -173,11 +177,15 @@ void Foam::FieldActivatedInjection<CloudType>::setPositionAndCell const label, const scalar, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ) { position = positions_[parcelI]; cellOwner = injectorCells_[parcelI]; + tetFaceI = injectorTetFaces_[parcelI]; + tetPtI = injectorTetPts_[parcelI]; } diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/FieldActivatedInjection/FieldActivatedInjection.H b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/FieldActivatedInjection/FieldActivatedInjection.H index f2aebb0fd8cdfe224bde3434e65df94a6e258101..9acf379154d5f99162cc6744ff48fd7d711366f1 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/FieldActivatedInjection/FieldActivatedInjection.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/FieldActivatedInjection/FieldActivatedInjection.H @@ -86,13 +86,19 @@ class FieldActivatedInjection //- Field of injector (x,y,z) positions vectorIOField positions_; - //- Field of cell labels corresponding to injector positions + //- List of cell labels corresponding to injector positions labelList injectorCells_; + //- List of tetFace labels corresponding to injector positions + labelList injectorTetFaces_; + + //- List of tetPt labels corresponding to injector positions + labelList injectorTetPts_; + //- Number of parcels per injector const label nParcelsPerInjector_; - //- Field of number of parcels injected for each injector + //- List of number of parcels injected for each injector labelList nParcelsInjected_; @@ -101,7 +107,7 @@ class FieldActivatedInjection //- Initial parcel velocity const vector U0_; - //- Field of parcel diameters + //- List of parcel diameters scalarList diameters_; //- Parcel size PDF model @@ -117,14 +123,14 @@ protected: ( const scalar time0, const scalar time1 - ) const; + ); //- Volume of parcels to introduce over the time step relative to SOI scalar volumeToInject ( const scalar time0, const scalar time1 - ) const; + ); public: @@ -158,14 +164,16 @@ public: // Injection geometry - //- Set the injection position and owner cell + //- Set the injection position and owner cell, tetFace and tetPt virtual void setPositionAndCell ( const label parcelI, const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ); //- Set the parcel properties diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.C new file mode 100644 index 0000000000000000000000000000000000000000..e1d3bd6d3ddd641d3729ec499c22b8b7c842037b --- /dev/null +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.C @@ -0,0 +1,466 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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 "InflationInjection.H" +#include "mathematicalConstants.H" +#include "PackedBoolList.H" +#include "Switch.H" +#include "cellSet.H" +#include "ListListOps.H" + +using namespace Foam::constant::mathematical; + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +template<class CloudType> +Foam::label Foam::InflationInjection<CloudType>::parcelsToInject +( + const scalar time0, + const scalar time1 +) +{ + const polyMesh& mesh = this->owner().mesh(); + + List<DynamicList<typename CloudType::parcelType*> >& cellOccupancy = + this->owner().cellOccupancy(); + + scalar gR = growthRate_().value(time1); + + scalar dT = time1 - time0; + + // Inflate existing particles + + forAll(inflationCells_, iCI) + { + label cI = inflationCells_[iCI]; + + typename CloudType::parcelType* pPtr = NULL; + + forAll(cellOccupancy[cI], cPI) + { + pPtr = cellOccupancy[cI][cPI]; + + scalar dTarget = pPtr->dTarget(); + + pPtr->d() = min(dTarget, pPtr->d() + gR*dT); + } + } + + // Generate new particles + + newParticles_.clear(); + + Random& rnd = this->owner().rndGen(); + + // Diameter factor, when splitting particles into 4, this is the + // factor that modifies the diameter. + scalar dFact = sqrt(2.0)/(sqrt(3.0) + sqrt(2.0)); + + if ((time0 >= 0.0) && (time0 < duration_)) + { + volumeAccumulator_ += + fraction_*flowRateProfile_().integrate(time0, time1); + } + + labelHashSet cellCentresUsed; + + // Loop escape counter + label maxIterations = max + ( + 1, + (10*volumeAccumulator_) + /CloudType::parcelType::volume(parcelPDF_().minValue()) + ); + + label iterationNo = 0; + + // Info<< "Accumulated volume to inject: " + // << returnReduce(volumeAccumulator_, sumOp<scalar>()) << endl; + + while (!generationCells_.empty() && volumeAccumulator_ > 0) + { + if (iterationNo > maxIterations) + { + WarningIn + ( + "Foam::label " + "Foam::InflationInjection<CloudType>::parcelsToInject" + "(" + "const scalar time0, " + "const scalar time1" + ")" + ) + << "Maximum particle split iterations (" + << maxIterations << ") exceeded" << endl; + + break; + } + + label cI = + generationCells_[rnd.integer(0, generationCells_.size() - 1)]; + + // Pick a particle at random from the cell - if there are + // none, insert one at the cell centre. Otherwise, split an + // existing particle into four new ones. + + if (cellOccupancy[cI].empty()) + { + if (!cellCentresUsed.found(cI)) + { + scalar dNew = parcelPDF_().sample(); + + newParticles_.append + ( + vectorPairScalarPair + ( + Pair<vector>(mesh.cellCentres()[cI], vector::zero), + Pair<scalar>(dNew, dNew) + ) + ); + + volumeAccumulator_ -= CloudType::parcelType::volume(dNew); + + cellCentresUsed.insert(cI); + } + } + else + { + label cPI = rnd.integer(0, cellOccupancy[cI].size() - 1); + + // This has to be a reference to the pointer so that it + // can be set to NULL when the particle is deleted. + typename CloudType::parcelType*& pPtr = cellOccupancy[cI][cPI]; + + if (pPtr != NULL) + { + scalar pD = pPtr->d(); + + // Select bigger particles by preference + if ((pD/pPtr->dTarget()) < rnd.scalar01()) + { + continue; + } + + const point& pP = pPtr->position(); + const vector& pU = pPtr->U(); + + // Generate a tetrahedron of new positions with the + // four new spheres fitting inside the old one, where + // a is the diameter of the new spheres, and is + // related to the diameter of the enclosing sphere, A, + // by a = sqrt(2)*A/(sqrt(3) + sqrt(2)); + + // Positions around the origin, which is the + // tetrahedron centroid (centre of old sphere). + + // x = a/sqrt(3) + // r = a/(2*sqrt(6)) + // R = sqrt(3)*a/(2*sqrt(2)) + // d = a/(2*sqrt(3)) + + // p0(x, 0, -r) + // p1(-d, a/2, -r) + // p2(-d, -a/2, -r) + // p3(0, 0, R) + + scalar a = pD*dFact; + + scalar x = a/sqrt(3.0); + scalar r = a/(2.0*sqrt(6.0)); + scalar R = sqrt(3.0)*a/(2.0*sqrt(2.0)); + scalar d = a/(2.0*sqrt(3.0)); + + scalar dNew = parcelPDF_().sample(); + scalar volNew = CloudType::parcelType::volume(dNew); + + newParticles_.append + ( + vectorPairScalarPair + ( + Pair<vector>(vector(x, 0, -r) + pP, pU), + Pair<scalar>(a, dNew) + ) + ); + volumeAccumulator_ -= volNew; + + dNew = parcelPDF_().sample(); + newParticles_.append + ( + vectorPairScalarPair + ( + Pair<vector>(vector(-d, a/2, -r) + pP, pU), + Pair<scalar>(a, dNew) + ) + ); + volumeAccumulator_ -= volNew; + + dNew = parcelPDF_().sample(); + newParticles_.append + ( + vectorPairScalarPair + ( + Pair<vector>(vector(-d, -a/2, -r) + pP, pU), + Pair<scalar>(a, dNew) + ) + ); + volumeAccumulator_ -= volNew; + + dNew = parcelPDF_().sample(); + newParticles_.append + ( + vectorPairScalarPair + ( + Pair<vector>(vector(0, 0, R) + pP, pU), + Pair<scalar>(a, dNew) + ) + ); + volumeAccumulator_ -= volNew; + + // Account for the lost volume of the particle which + // is to be deleted + volumeAccumulator_ += CloudType::parcelType::volume + ( + pPtr->dTarget() + ); + + this->owner().deleteParticle(*pPtr); + + pPtr = NULL; + } + } + + iterationNo++; + } + + if (Pstream::parRun()) + { + List<List<vectorPairScalarPair> > gatheredNewParticles + ( + Pstream::nProcs() + ); + + gatheredNewParticles[Pstream::myProcNo()] = newParticles_; + + // Gather data onto master + Pstream::gatherList(gatheredNewParticles); + + // Combine + List<vectorPairScalarPair> combinedNewParticles + ( + ListListOps::combine<List<vectorPairScalarPair> > + ( + gatheredNewParticles, + accessOp<List<vectorPairScalarPair> >() + ) + ); + + if (Pstream::master()) + { + newParticles_ = combinedNewParticles; + } + + Pstream::scatter(newParticles_); + } + + return newParticles_.size(); +} + + +template<class CloudType> +Foam::scalar Foam::InflationInjection<CloudType>::volumeToInject +( + const scalar time0, + const scalar time1 +) +{ + if ((time0 >= 0.0) && (time0 < duration_)) + { + return fraction_*flowRateProfile_().integrate(time0, time1); + } + else + { + return 0.0; + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class CloudType> +Foam::InflationInjection<CloudType>::InflationInjection +( + const dictionary& dict, + CloudType& owner +) +: + InjectionModel<CloudType>(dict, owner, typeName), + generationSetName_(this->coeffDict().lookup("generationCellSet")), + inflationSetName_(this->coeffDict().lookup("inflationCellSet")), + generationCells_(), + inflationCells_(), + duration_(readScalar(this->coeffDict().lookup("duration"))), + flowRateProfile_ + ( + DataEntry<scalar>::New + ( + "flowRateProfile", + this->coeffDict() + ) + ), + growthRate_ + ( + DataEntry<scalar>::New + ( + "growthRate", + this->coeffDict() + ) + ), + newParticles_(), + volumeAccumulator_(0.0), + fraction_(1.0), + parcelPDF_ + ( + pdfs::pdf::New + ( + this->coeffDict().subDict("parcelPDF"), + owner.rndGen() + ) + ) +{ + cellSet generationCells(this->owner().mesh(), generationSetName_); + + generationCells_ = generationCells.toc(); + + cellSet inflationCells(this->owner().mesh(), inflationSetName_); + + // Union of cellSets + inflationCells |= generationCells; + + inflationCells_ = inflationCells.toc(); + + if (Pstream::parRun()) + { + scalar generationVolume = 0.0; + + forAll(generationCells_, gCI) + { + label cI = generationCells_[gCI]; + + generationVolume += this->owner().mesh().cellVolumes()[cI]; + } + + scalar totalGenerationVolume = generationVolume; + + reduce(totalGenerationVolume, sumOp<scalar>()); + + fraction_ = generationVolume/totalGenerationVolume; + } + + // Set total volume/mass to inject + this->volumeTotal_ = fraction_*flowRateProfile_().integrate(0.0, duration_); + this->massTotal_ *= fraction_; +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template<class CloudType> +Foam::InflationInjection<CloudType>::~InflationInjection() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class CloudType> +bool Foam::InflationInjection<CloudType>::active() const +{ + return true; +} + + +template<class CloudType> +Foam::scalar Foam::InflationInjection<CloudType>::timeEnd() const +{ + return this->SOI_ + duration_; +} + + +template<class CloudType> +void Foam::InflationInjection<CloudType>::setPositionAndCell +( + const label parcelI, + const label, + const scalar, + vector& position, + label& cellOwner, + label& tetFaceI, + label& tetPtI +) +{ + position = newParticles_[parcelI].first().first(); + + this->findCellAtPosition + ( + cellOwner, + tetFaceI, + tetPtI, + position, + false + ); +} + + +template<class CloudType> +void Foam::InflationInjection<CloudType>::setProperties +( + const label parcelI, + const label, + const scalar, + typename CloudType::parcelType& parcel +) +{ + parcel.U() = newParticles_[parcelI].first().second(); + + parcel.d() = newParticles_[parcelI].second().first(); + + parcel.dTarget() = newParticles_[parcelI].second().second(); +} + + +template<class CloudType> +bool Foam::InflationInjection<CloudType>::fullyDescribed() const +{ + return false; +} + + +template<class CloudType> +bool Foam::InflationInjection<CloudType>::validInjection(const label) +{ + return true; +} + + +// ************************************************************************* // diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.H b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.H new file mode 100644 index 0000000000000000000000000000000000000000..70724124300621dba60e09c7a256e1aec9567af2 --- /dev/null +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.H @@ -0,0 +1,200 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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::InflationInjection + +Description + Inflation injection - creates new particles by splitting existing + particles within in a set of generation cells, then inflating them + to a target diameter within the generation cells and an additional + set of inflation cells. + +SourceFiles + InflationInjection.C + +\*---------------------------------------------------------------------------*/ + +#ifndef InflationInjection_H +#define InflationInjection_H + +#include "InjectionModel.H" +#include "pdf.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Structure to hold: +// + position = vectorPairScalarPair::first().first() +// + velocity = vectorPairScalarPair::first().second() +// + diameter = vectorPairScalarPair::second().first() +// + target diameter = vectorPairScalarPair::second().second() +// One structure to allow single operation parallel comms +typedef Tuple2<Pair<vector>, Pair<scalar> > vectorPairScalarPair; + + +/*---------------------------------------------------------------------------*\ + Class InflationInjection Declaration +\*---------------------------------------------------------------------------*/ + +template<class CloudType> +class InflationInjection +: + public InjectionModel<CloudType> +{ + // Private data + + //- Name of cellSet for generating new particles + word generationSetName_; + + //- Name of cellSet for inflating new particles + word inflationSetName_; + + //- Set of cells to generate particles in + labelList generationCells_; + + //- Set of cells to inflate particles in, includes all + // generation cells + labelList inflationCells_; + + //- Injection duration [s] + const scalar duration_; + + //- Flow rate profile relative to SOI [m3/s] + const autoPtr<DataEntry<scalar> > flowRateProfile_; + + //- Growth rate of particle diameters towards target [m/s] + const autoPtr<DataEntry<scalar> > growthRate_; + + //- Positions, velocities, diameters and target diameters of + // new particles after splitting + DynamicList<vectorPairScalarPair> newParticles_; + + //- Accumulation variable to carry over volume from one injection + // to the next + scalar volumeAccumulator_; + + //- Fraction of injection controlled by this processor + scalar fraction_; + + //- Parcel size PDF model + const autoPtr<pdfs::pdf> parcelPDF_; + + +protected: + + // Protected Member Functions + + //- Number of parcels to introduce over the time step relative to SOI + label parcelsToInject + ( + const scalar time0, + const scalar time1 + ); + + //- Volume of parcels to introduce over the time step relative to SOI + scalar volumeToInject + ( + const scalar time0, + const scalar time1 + ); + + +public: + + //- Runtime type information + TypeName("InflationInjection"); + + + // Constructors + + //- Construct from dictionary + InflationInjection + ( + const dictionary& dict, + CloudType& owner + ); + + + //- Destructor + virtual ~InflationInjection(); + + + // Member Functions + + //- Flag to indicate whether model activates injection model + bool active() const; + + //- Return the end-of-injection time + scalar timeEnd() const; + + + // Injection geometry + + //- Set the injection position and owner cell, tetFace and tetPt + virtual void setPositionAndCell + ( + const label parcelI, + const label nParcels, + const scalar time, + vector& position, + label& cellOwner, + label& tetFaceI, + label& tetPtI + ); + + //- Set the parcel properties + virtual void setProperties + ( + const label parcelI, + const label nParcels, + const scalar time, + typename CloudType::parcelType& parcel + ); + + //- Flag to identify whether model fully describes the parcel + virtual bool fullyDescribed() const; + + //- Return flag to identify whether or not injection of parcelI is + // permitted + virtual bool validInjection(const label parcelI); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "InflationInjection.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C index c56ff296183545103ce726d421955a1ed4853ee6..5a386e4397e10a863a17b2aae75bb9f8aee9dcfd 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C @@ -132,6 +132,8 @@ template<class CloudType> bool Foam::InjectionModel<CloudType>::findCellAtPosition ( label& cellI, + label& tetFaceI, + label& tetPtI, vector& position, bool errorOnNotFound ) @@ -140,7 +142,13 @@ bool Foam::InjectionModel<CloudType>::findCellAtPosition const vector p0 = position; - cellI = owner_.mesh().findCell(position); + owner_.findCellFacePt + ( + position, + cellI, + tetFaceI, + tetPtI + ); label procI = -1; @@ -148,17 +156,24 @@ bool Foam::InjectionModel<CloudType>::findCellAtPosition { procI = Pstream::myProcNo(); } + reduce(procI, maxOp<label>()); + + // Ensure that only one processor attempts to insert this Parcel + if (procI != Pstream::myProcNo()) { cellI = -1; + tetFaceI = -1; + tetPtI = -1; } - // Last chance - find nearest cell and try that one - // - the point is probably on an edge + // Last chance - find nearest cell and try that one - the point is + // probably on an edge if (procI == -1) { cellI = owner_.mesh().findNearestCell(position); + if (cellI >= 0) { position += SMALL*(cellCentres[cellI] - position); @@ -168,10 +183,14 @@ bool Foam::InjectionModel<CloudType>::findCellAtPosition procI = Pstream::myProcNo(); } } + reduce(procI, maxOp<label>()); + if (procI != Pstream::myProcNo()) { cellI = -1; + tetFaceI = -1; + tetPtI = -1; } } @@ -412,17 +431,31 @@ void Foam::InjectionModel<CloudType>::inject(TrackData& td) const scalar padTime = max(0.0, SOI_ - time0_); // Introduce new parcels linearly across carrier phase timestep - for (label parcelI=0; parcelI<newParcels; parcelI++) + for (label parcelI = 0; parcelI < newParcels; parcelI++) { if (validInjection(parcelI)) { // Calculate the pseudo time of injection for parcel 'parcelI' scalar timeInj = time0_ + padTime + deltaT*parcelI/newParcels; - // Determine the injection position and owner cell + // Determine the injection position and owner cell, + // tetFace and tetPt label cellI = -1; + label tetFaceI = -1; + label tetPtI = -1; + vector pos = vector::zero; - setPositionAndCell(parcelI, newParcels, timeInj, pos, cellI); + + setPositionAndCell + ( + parcelI, + newParcels, + timeInj, + pos, + cellI, + tetFaceI, + tetPtI + ); if (cellI > -1) { @@ -433,7 +466,14 @@ void Foam::InjectionModel<CloudType>::inject(TrackData& td) meshTools::constrainToMeshCentre(mesh, pos); // Create a new parcel - parcelType* pPtr = new parcelType(td.cloud(), pos, cellI); + parcelType* pPtr = new parcelType + ( + td.cloud(), + pos, + cellI, + tetFaceI, + tetPtI + ); // Assign new parcel properties in injection model setProperties(parcelI, newParcels, timeInj, *pPtr); diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.H b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.H index b40abbde90fb9eff70b5a7d7c86b1f8cbcf2168d..5b225c0781487a7b805a9912ef0d07ac759faf82 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.H @@ -156,14 +156,14 @@ protected: ( const scalar time0, const scalar time1 - ) const = 0; + ) = 0; //- Volume of parcels to introduce over the time step relative to SOI virtual scalar volumeToInject ( const scalar time0, const scalar time1 - ) const = 0; + ) = 0; //- Additional flag to identify whether or not injection of parcelI is // permitted @@ -183,6 +183,8 @@ protected: virtual bool findCellAtPosition ( label& cellI, + label& tetFaceI, + label& tetPtI, vector& position, bool errorOnNotFound = true ); @@ -305,14 +307,16 @@ public: // Injection geometry - //- Set the injection position and owner cell + //- Set the injection position and owner cell, tetFace and tetPt virtual void setPositionAndCell ( const label parcelI, const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ) = 0; //- Set the parcel properties diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.C index 413af8a073193a08c9d360d5094cbb19dea6eb20..b87449f225d352beac22560726458b11baaec702 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.C @@ -33,7 +33,7 @@ Foam::label Foam::KinematicLookupTableInjection<CloudType>::parcelsToInject ( const scalar time0, const scalar time1 -) const +) { if ((time0 >= 0.0) && (time0 < duration_)) { @@ -51,7 +51,7 @@ Foam::scalar Foam::KinematicLookupTableInjection<CloudType>::volumeToInject ( const scalar time0, const scalar time1 -) const +) { scalar volume = 0.0; if ((time0 >= 0.0) && (time0 < duration_)) @@ -93,13 +93,24 @@ Foam::KinematicLookupTableInjection<CloudType>::KinematicLookupTableInjection IOobject::NO_WRITE ) ), - injectorCells_(0) + injectorCells_(0), + injectorTetFaces_(0), + injectorTetPts_(0) { // Set/cache the injector cells injectorCells_.setSize(injectors_.size()); + injectorTetFaces_.setSize(injectors_.size()); + injectorTetPts_.setSize(injectors_.size()); + forAll(injectors_, i) { - this->findCellAtPosition(injectorCells_[i], injectors_[i].x()); + this->findCellAtPosition + ( + injectorCells_[i], + injectorTetFaces_[i], + injectorTetPts_[i], + injectors_[i].x() + ); } // Determine volume of particles to inject @@ -142,13 +153,17 @@ void Foam::KinematicLookupTableInjection<CloudType>::setPositionAndCell const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ) { label injectorI = parcelI*injectorCells_.size()/nParcels; position = injectors_[injectorI].x(); cellOwner = injectorCells_[injectorI]; + tetFaceI = injectorTetFaces_[injectorI]; + tetPtI = injectorTetPts_[injectorI]; } diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.H b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.H index d888c47582e2c490fc7fcfbe3b71679d127a5875..ff840187f26d126f3989820ec5ce7043162ad7e0 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.H @@ -81,8 +81,14 @@ class KinematicLookupTableInjection //- List of injectors kinematicParcelInjectionDataIOList injectors_; - //- List of injector cells per injector - List<label> injectorCells_; + //- List of cell labels corresponding to injector positions + labelList injectorCells_; + + //- List of tetFace labels corresponding to injector positions + labelList injectorTetFaces_; + + //- List of tetPt labels corresponding to injector positions + labelList injectorTetPts_; protected: @@ -94,14 +100,14 @@ protected: ( const scalar time0, const scalar time1 - ) const; + ); //- Volume of parcels to introduce over the time step relative to SOI scalar volumeToInject ( const scalar time0, const scalar time1 - ) const; + ); public: @@ -135,14 +141,16 @@ public: // Injection geometry - //- Set the injection position and owner cell + //- Set the injection position and owner cell, tetFace and tetPt virtual void setPositionAndCell ( const label parcelI, const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ); //- Set the parcel properties diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ManualInjection/ManualInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ManualInjection/ManualInjection.C index f64cdc22681c5282cb6547327e116b9781fc8dbf..48b156d1e2e8b70014adf7020e199d17c2567ae3 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ManualInjection/ManualInjection.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ManualInjection/ManualInjection.C @@ -37,7 +37,7 @@ Foam::label Foam::ManualInjection<CloudType>::parcelsToInject ( const scalar time0, const scalar time1 -) const +) { if ((0.0 >= time0) && (0.0 < time1)) { @@ -55,7 +55,7 @@ Foam::scalar Foam::ManualInjection<CloudType>::volumeToInject ( const scalar time0, const scalar time1 -) const +) { // All parcels introduced at SOI if ((0.0 >= time0) && (0.0 < time1)) @@ -92,6 +92,9 @@ Foam::ManualInjection<CloudType>::ManualInjection ) ), diameters_(positions_.size()), + injectorCells_(positions_.size(), -1), + injectorTetFaces_(positions_.size(), -1), + injectorTetPts_(positions_.size(), -1), U0_(this->coeffDict().lookup("U0")), parcelPDF_ ( @@ -102,38 +105,45 @@ Foam::ManualInjection<CloudType>::ManualInjection ) ) { - Switch checkAndIgnoreOutOfBounds + Switch ignoreOutOfBounds ( - this->coeffDict().lookupOrDefault("checkAndIgnoreOutOfBounds", false) + this->coeffDict().lookupOrDefault("ignoreOutOfBounds", false) ); label nRejected = 0; - if (checkAndIgnoreOutOfBounds) - { - // Dummy cell - label cellI = -1; - - PackedBoolList keep(positions_.size(), true); + PackedBoolList keep(positions_.size(), true); - forAll(positions_, pI) + forAll(positions_, pI) + { + if + ( + !this->findCellAtPosition + ( + injectorCells_[pI], + injectorTetFaces_[pI], + injectorTetPts_[pI], + positions_[pI], + !ignoreOutOfBounds + ) + ) { - if (!this->findCellAtPosition(cellI, positions_[pI], false)) - { - keep[pI] = false; + keep[pI] = false; - nRejected++; - } + nRejected++; } + } - if (nRejected > 0) - { - inplaceSubset(keep, positions_); - inplaceSubset(keep, diameters_); - - Info<< " " << nRejected - << " particles ignored, out of bounds." << endl; - } + if (nRejected > 0) + { + inplaceSubset(keep, positions_); + inplaceSubset(keep, diameters_); + inplaceSubset(keep, injectorCells_); + inplaceSubset(keep, injectorTetFaces_); + inplaceSubset(keep, injectorTetPts_); + + Info<< " " << nRejected + << " particles ignored, out of bounds." << endl; } // Construct parcel diameters @@ -178,11 +188,15 @@ void Foam::ManualInjection<CloudType>::setPositionAndCell const label, const scalar, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ) { position = positions_[parcelI]; - this->findCellAtPosition(cellOwner, position); + cellOwner = injectorCells_[parcelI]; + tetFaceI = injectorTetFaces_[parcelI]; + tetPtI = injectorTetPts_[parcelI]; } diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ManualInjection/ManualInjection.H b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ManualInjection/ManualInjection.H index 0202c9eb60be1a3c10324b67fd057208cdc1aa42..b4feea97441a0f974912e146914dc93ac1df3391 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ManualInjection/ManualInjection.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ManualInjection/ManualInjection.H @@ -70,7 +70,16 @@ class ManualInjection //- Field of parcel diameters scalarList diameters_; - //- Initial parcel velocity + //- List of cell labels corresponding to injector positions + labelList injectorCells_; + + //- List of tetFace labels corresponding to injector positions + labelList injectorTetFaces_; + + //- List of tetPt labels corresponding to injector positions + labelList injectorTetPts_; + + //- Initial parcel velocity const vector U0_; //- Parcel size PDF model @@ -86,14 +95,14 @@ protected: ( const scalar time0, const scalar time1 - ) const; + ); //- Volume of parcels to introduce over the time step relative to SOI scalar volumeToInject ( const scalar time0, const scalar time1 - ) const; + ); public: @@ -127,14 +136,16 @@ public: // Injection geometry - //- Set the injection position and owner cell + //- Set the injection position and owner cell, tetFace and tetPt virtual void setPositionAndCell ( const label parcelI, const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ); //- Set the parcel properties diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/NoInjection/NoInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/NoInjection/NoInjection.C index 15452159300471885456e98f668dc8e857c1661e..8391c3654b633b2b1ca6d56ae89f92aa7becda0a 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/NoInjection/NoInjection.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/NoInjection/NoInjection.C @@ -33,7 +33,7 @@ Foam::label Foam::NoInjection<CloudType>::parcelsToInject ( const scalar, const scalar -) const +) { return 0; } @@ -44,7 +44,7 @@ Foam::scalar Foam::NoInjection<CloudType>::volumeToInject ( const scalar, const scalar -) const +) { return 0.0; } @@ -93,6 +93,8 @@ void Foam::NoInjection<CloudType>::setPositionAndCell const label, const scalar, vector&, + label&, + label&, label& ) {} diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/NoInjection/NoInjection.H b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/NoInjection/NoInjection.H index 6dea7c9dd15e9850d322cfc8cee584a0ddb8e317..c16a9367785ff5abfb735682fc5cdec156c30beb 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/NoInjection/NoInjection.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/NoInjection/NoInjection.H @@ -60,14 +60,14 @@ protected: ( const scalar, const scalar - ) const; + ); //- Volume of parcels to introduce over the time step relative to SOI scalar volumeToInject ( const scalar, const scalar - ) const; + ); public: @@ -101,14 +101,16 @@ public: // Injection geometry - //- Set the injection position and owner cell + //- Set the injection position and owner cell, tetFace and tetPt virtual void setPositionAndCell ( const label parcelI, const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ); virtual void setProperties diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/PatchInjection/PatchInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/PatchInjection/PatchInjection.C index b3ed38cf8842f9691bdb50a5d861bbf92f437b7d..088546930733dbc406830eb839272e56fd7a99c0 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/PatchInjection/PatchInjection.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/PatchInjection/PatchInjection.C @@ -34,7 +34,7 @@ Foam::label Foam::PatchInjection<CloudType>::parcelsToInject ( const scalar time0, const scalar time1 -) const +) { if ((time0 >= 0.0) && (time0 < duration_)) { @@ -52,7 +52,7 @@ Foam::scalar Foam::PatchInjection<CloudType>::volumeToInject ( const scalar time0, const scalar time1 -) const +) { if ((time0 >= 0.0) && (time0 < duration_)) { @@ -98,7 +98,7 @@ Foam::PatchInjection<CloudType>::PatchInjection owner.rndGen() ) ), - cellOwners_(), + injectorCells_(), fraction_(1.0) { const label patchId = owner.mesh().boundaryMesh().findPatchID(patchName_); @@ -119,9 +119,9 @@ Foam::PatchInjection<CloudType>::PatchInjection const polyPatch& patch = owner.mesh().boundaryMesh()[patchId]; - cellOwners_ = patch.faceCells(); + injectorCells_ = patch.faceCells(); - label patchSize = cellOwners_.size(); + label patchSize = injectorCells_.size(); label totalPatchSize = patchSize; reduce(totalPatchSize, sumOp<label>()); fraction_ = scalar(patchSize)/totalPatchSize; @@ -162,19 +162,37 @@ void Foam::PatchInjection<CloudType>::setPositionAndCell const label, const scalar, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ) { - if (cellOwners_.size() > 0) + if (injectorCells_.size() > 0) { - label cellI = this->owner().rndGen().integer(0, cellOwners_.size() - 1); + label cellI = this->owner().rndGen().integer + ( + 0, + injectorCells_.size() - 1 + ); + + cellOwner = injectorCells_[cellI]; + + // The position is at the cell centre, which could be in any + // tet of the decomposed cell, so arbitrarily choose the first + // face of the cell as the tetFace and the first point after + // the base point on the face as the tetPt. The tracking will + // pick the cell consistent with the motion in the first + // tracking step. + tetFaceI = this->owner().mesh().cells()[cellOwner][0]; + tetPtI = 1; - cellOwner = cellOwners_[cellI]; position = this->owner().mesh().C()[cellOwner]; } else { cellOwner = -1; + tetFaceI = -1; + tetPtI = -1; // dummy position position = pTraits<vector>::max; } diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/PatchInjection/PatchInjection.H b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/PatchInjection/PatchInjection.H index f8d5840ffe0118326b8cb7b65773ef4f972758d6..85dbb2fcb63b11e7d8bb08067e0ae8f88af2439a 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/PatchInjection/PatchInjection.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/PatchInjection/PatchInjection.H @@ -85,8 +85,8 @@ class PatchInjection //- Parcel size PDF model const autoPtr<pdfs::pdf> parcelPDF_; - //- Cell owners - labelList cellOwners_; + //- List of cell labels corresponding to injector positions + labelList injectorCells_; //- Fraction of injection controlled by this processor scalar fraction_; @@ -101,14 +101,14 @@ protected: ( const scalar time0, const scalar time1 - ) const; + ); //- Volume of parcels to introduce over the time step relative to SOI scalar volumeToInject ( const scalar time0, const scalar time1 - ) const; + ); public: @@ -142,14 +142,16 @@ public: // Injection geometry - //- Set the injection position and owner cell + //- Set the injection position and owner cell, tetFace and tetPt virtual void setPositionAndCell ( const label parcelI, const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ); virtual void setProperties diff --git a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/LocalInteraction/LocalInteraction.C b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/LocalInteraction/LocalInteraction.C index b9fd7b819e59217cca924083765c0822ad6947d8..0786df08a758aef50dd6eb53b9af7d0c9cfe7208 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/LocalInteraction/LocalInteraction.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/LocalInteraction/LocalInteraction.C @@ -55,16 +55,16 @@ Foam::LocalInteraction<CloudType>::LocalInteraction ) : PatchInteractionModel<CloudType>(dict, cloud, typeName), - patchData_(this->coeffDict().lookup("patches")), - patchIds_(patchData_.size()) + patchProperties_(this->coeffDict().lookup("patches")), + patchIds_(patchProperties_.size()) { const polyMesh& mesh = cloud.mesh(); const polyBoundaryMesh& bMesh = mesh.boundaryMesh(); // check that user patches are valid region patches - forAll(patchData_, patchI) + forAll(patchProperties_, patchI) { - const word& patchName = patchData_[patchI].patchName(); + const word& patchName = patchProperties_[patchI].patchName(); patchIds_[patchI] = bMesh.findPatchID(patchName); if (patchIds_[patchI] < 0) { @@ -97,16 +97,16 @@ Foam::LocalInteraction<CloudType>::LocalInteraction } // check that interactions are valid/specified - forAll(patchData_, patchI) + forAll(patchProperties_, patchI) { const word& interactionTypeName = - patchData_[patchI].interactionTypeName(); + patchProperties_[patchI].interactionTypeName(); const typename PatchInteractionModel<CloudType>::interactionType& it = this->wordToInteractionType(interactionTypeName); if (it == PatchInteractionModel<CloudType>::itOther) { - const word& patchName = patchData_[patchI].patchName(); + const word& patchName = patchProperties_[patchI].patchName(); FatalErrorIn("LocalInteraction(const dictionary&, CloudType&)") << "Unknown patch interaction type " << interactionTypeName << " for patch " << patchName @@ -137,13 +137,17 @@ bool Foam::LocalInteraction<CloudType>::active() const template <class CloudType> bool Foam::LocalInteraction<CloudType>::correct ( + typename CloudType::parcelType& p, const polyPatch& pp, - const label faceId, bool& keepParticle, - bool& active, - vector& U + const scalar trackFraction, + const tetIndices& tetIs ) const { + vector& U = p.U(); + + bool& active = p.active(); + label patchI = applyToPatch(pp.index()); if (patchI >= 0) @@ -151,7 +155,7 @@ bool Foam::LocalInteraction<CloudType>::correct typename PatchInteractionModel<CloudType>::interactionType it = this->wordToInteractionType ( - patchData_[patchI].interactionTypeName() + patchProperties_[patchI].interactionTypeName() ); switch (it) @@ -175,18 +179,26 @@ bool Foam::LocalInteraction<CloudType>::correct keepParticle = true; active = true; - vector nw = pp.faceAreas()[pp.whichFace(faceId)]; - nw /= mag(nw); + vector nw; + vector Up; + + this->patchData(p, pp, trackFraction, tetIs, nw, Up); + + // Calculate motion relative to patch velocity + U -= Up; scalar Un = U & nw; vector Ut = U - Un*nw; if (Un > 0) { - U -= (1.0 + patchData_[patchI].e())*Un*nw; + U -= (1.0 + patchProperties_[patchI].e())*Un*nw; } - U -= patchData_[patchI].mu()*Ut; + U -= patchProperties_[patchI].mu()*Ut; + + // Return velocity to global space + U += Up; break; } @@ -202,9 +214,9 @@ bool Foam::LocalInteraction<CloudType>::correct "vector&" ") const" ) << "Unknown interaction type " - << patchData_[patchI].interactionTypeName() + << patchProperties_[patchI].interactionTypeName() << "(" << it << ") for patch " - << patchData_[patchI].patchName() + << patchProperties_[patchI].patchName() << ". Valid selections are:" << this->interactionTypeNames_ << endl << abort(FatalError); } diff --git a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/LocalInteraction/LocalInteraction.H b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/LocalInteraction/LocalInteraction.H index 4fa890042307882e323fec296c95eea2f8ae6ba9..7b5446209acda9a5e6df7cb1c32d079496227750 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/LocalInteraction/LocalInteraction.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/LocalInteraction/LocalInteraction.H @@ -51,7 +51,7 @@ class LocalInteraction // Private data //- List of participating patches - const List<patchInteractionData> patchData_; + const List<patchInteractionData> patchProperties_; //- List of participating patch ids List<label> patchIds_; @@ -89,11 +89,11 @@ public: // Returns true if particle remains in same cell virtual bool correct ( + typename CloudType::parcelType& p, const polyPatch& pp, - const label faceId, bool& keepParticle, - bool& active, - vector& U + const scalar trackFraction, + const tetIndices& tetIs ) const; }; diff --git a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/PatchInteractionModel/PatchInteractionModel.C b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/PatchInteractionModel/PatchInteractionModel.C index 6947fc93bf68221aaf966875fe9bafb2cbceccab..0eca6dea6657a23f902587914c003ef7557fcb13 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/PatchInteractionModel/PatchInteractionModel.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/PatchInteractionModel/PatchInteractionModel.C @@ -24,6 +24,9 @@ License \*---------------------------------------------------------------------------*/ #include "PatchInteractionModel.H" +#include "fvMesh.H" +#include "Time.H" +#include "volFields.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -111,7 +114,8 @@ Foam::PatchInteractionModel<CloudType>::PatchInteractionModel : dict_(dict), owner_(owner), - coeffDict_(dict.subDict(type + "Coeffs")) + coeffDict_(dict.subDict(type + "Coeffs")), + UName_(coeffDict_.lookupOrDefault<word>("UName", "U")) {} @@ -147,9 +151,166 @@ Foam::PatchInteractionModel<CloudType>::coeffDict() const } +template<class CloudType> +const Foam::word& Foam::PatchInteractionModel<CloudType>::UName() const +{ + return UName_; +} + + +template<class CloudType> +void Foam::PatchInteractionModel<CloudType>::patchData +( + typename CloudType::parcelType& p, + const polyPatch& pp, + const scalar trackFraction, + const tetIndices& tetIs, + vector& nw, + vector& Up +) const +{ + const fvMesh& mesh = this->owner().mesh(); + + const volVectorField& Ufield = + mesh.objectRegistry::lookupObject<volVectorField>(UName_); + + label patchI = pp.index(); + label patchFaceI = pp.whichFace(p.face()); + + vector n = tetIs.faceTri(mesh).normal(); + n /= mag(n); + + vector U = Ufield.boundaryField()[patchI][patchFaceI]; + + // Unless the face is rotating, the required normal is n; + nw = n; + + if (!mesh.moving()) + { + // Only wall patches may have a non-zero wall velocity from + // the velocity field when the mesh is not moving. + + if (isA<wallPolyPatch>(pp)) + { + Up = U; + } + else + { + Up = vector::zero; + } + } + else + { + vector U00 = Ufield.oldTime().boundaryField()[patchI][patchFaceI]; + + vector n00 = tetIs.oldFaceTri(mesh).normal(); + + // Difference in normal over timestep + vector dn = vector::zero; + + if (mag(n00) > SMALL) + { + // If the old normal is zero (for example in layer + // addition) then use the current normal, meaning that the + // motion can only be translational, and dn remains zero, + // otherwise, calculate dn: + + n00 /= mag(n00); + + dn = n - n00; + } + + // Total fraction thought the timestep of the motion, + // including stepFraction before the current tracking step + // and the current trackFraction + // i.e. + // let s = stepFraction, t = trackFraction + // Motion of x in time: + // |-----------------|---------|---------| + // x00 x0 xi x + // + // where xi is the correct value of x at the required + // tracking instant. + // + // x0 = x00 + s*(x - x00) = s*x + (1 - s)*x00 + // + // i.e. the motion covered by previous tracking portions + // within this timestep, and + // + // xi = x0 + t*(x - x0) + // = t*x + (1 - t)*x0 + // = t*x + (1 - t)*(s*x + (1 - s)*x00) + // = (s + t - s*t)*x + (1 - (s + t - s*t))*x00 + // + // let m = (s + t - s*t) + // + // xi = m*x + (1 - m)*x00 = x00 + m*(x - x00); + // + // In the same form as before. + + scalar m = + p.stepFraction() + + trackFraction + - (p.stepFraction()*trackFraction); + + // When the mesh is moving, the velocity field on wall patches + // will contain the velocity associated with the motion of the + // mesh, in which case it is interpolated in time using m. + // For other patches the face velocity will need to be + // reconstructed from the face centre motion. + + const vector& Cf = mesh.faceCentres()[p.face()]; + + vector Cf00 = mesh.faces()[p.face()].centre(mesh.oldPoints()); + + if (isA<wallPolyPatch>(pp)) + { + Up = U00 + m*(U - U00); + } + else + { + Up = (Cf - Cf00)/mesh.time().deltaTValue(); + } + + if (mag(dn) > SMALL) + { + // Rotational motion, nw requires interpolation and a + // rotational velocity around face centre correction to Up + // is required. + + nw = n00 + m*dn; + + // Cf at tracking instant + vector Cfi = Cf00 + m*(Cf - Cf00); + + // Normal vector cross product + vector omega = (n00 ^ n); + + scalar magOmega = mag(omega); + + // magOmega = sin(angle between unit normals) + // Normalise omega vector by magOmega, then multiply by + // angle/dt to give the correct angular velocity vector. + omega *= Foam::asin(magOmega)/(magOmega*mesh.time().deltaTValue()); + + // Project position onto face and calculate this position + // relative to the face centre. + vector facePos = + p.position() + - ((p.position() - Cfi) & nw)*nw + - Cfi; + + Up += (omega ^ facePos); + } + + // No further action is required if the motion is + // translational only, nw and Up have already been set. + } +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #include "PatchInteractionModelNew.C" // ************************************************************************* // - diff --git a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/PatchInteractionModel/PatchInteractionModel.H b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/PatchInteractionModel/PatchInteractionModel.H index 1bd16847733a8ab87ac64641606501c3e72848a6..c3c883eaeb84631c728e00cd75d3208f6c6d9f62 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/PatchInteractionModel/PatchInteractionModel.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/PatchInteractionModel/PatchInteractionModel.H @@ -40,6 +40,8 @@ SourceFiles #include "autoPtr.H" #include "runTimeSelectionTables.H" #include "polyPatch.H" +#include "wallPolyPatch.H" +#include "tetIndices.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -82,6 +84,9 @@ private: //- The coefficients dictionary const dictionary coeffDict_; + //- Name of velocity field - default = "U" + const word UName_; + public: @@ -136,6 +141,9 @@ public: //- Return the coefficients dictionary const dictionary& coeffDict() const; + //- Return name of velocity field + const word& UName() const; + // Member Functions @@ -152,12 +160,24 @@ public: // Returns true if particle remains in same cell virtual bool correct ( + typename CloudType::parcelType& p, const polyPatch& pp, - const label faceId, bool& keepParticle, - bool& active, - vector& U + const scalar trackFraction, + const tetIndices& tetIs ) const = 0; + + //- Calculate the patch normal and velocity to interact with, + // accounting for patch motion if required. + void patchData + ( + typename CloudType::parcelType& p, + const polyPatch& pp, + const scalar trackFraction, + const tetIndices& tetIs, + vector& normal, + vector& Up + ) const; }; diff --git a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/Rebound/Rebound.C b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/Rebound/Rebound.C index 71207833079fd65bebff77a18a240a5d526fe8f8..69b3749429cac63506174ad21327c0a1f95f2033 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/Rebound/Rebound.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/Rebound/Rebound.C @@ -58,18 +58,25 @@ bool Foam::Rebound<CloudType>::active() const template<class CloudType> bool Foam::Rebound<CloudType>::correct ( + typename CloudType::parcelType& p, const polyPatch& pp, - const label faceId, bool& keepParticle, - bool& active, - vector& U + const scalar trackFraction, + const tetIndices& tetIs ) const { + vector& U = p.U(); + keepParticle = true; - active = true; + p.active() = true; + + vector nw; + vector Up; - vector nw = pp.faceAreas()[pp.whichFace(faceId)]; - nw /= mag(nw); + this->patchData(p, pp, trackFraction, tetIs, nw, Up); + + // Calculate motion relative to patch velocity + U -= Up; scalar Un = U & nw; @@ -78,6 +85,9 @@ bool Foam::Rebound<CloudType>::correct U -= UFactor_*2.0*Un*nw; } + // Return velocity to global space + U += Up; + return true; } diff --git a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/Rebound/Rebound.H b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/Rebound/Rebound.H index e9cc326c3025bd45e364f2975015946cac2da7dc..c1ca658470aec4bc8a8433abf90ed117d957840a 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/Rebound/Rebound.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/Rebound/Rebound.H @@ -79,11 +79,11 @@ public: // Returns true if particle remains in same cell virtual bool correct ( + typename CloudType::parcelType& p, const polyPatch& pp, - const label faceId, bool& keepParticle, - bool& active, - vector& U + const scalar trackFraction, + const tetIndices& tetIs ) const; }; diff --git a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/StandardWallInteraction/StandardWallInteraction.C b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/StandardWallInteraction/StandardWallInteraction.C index 7d89c40df67e942751572ad23953ed8c2272d3f6..7d2b11cdca428e8e9ccd4d6125d714430eb2dc17 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/StandardWallInteraction/StandardWallInteraction.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/StandardWallInteraction/StandardWallInteraction.C @@ -95,13 +95,17 @@ bool Foam::StandardWallInteraction<CloudType>::active() const template <class CloudType> bool Foam::StandardWallInteraction<CloudType>::correct ( + typename CloudType::parcelType& p, const polyPatch& pp, - const label faceId, bool& keepParticle, - bool& active, - vector& U + const scalar trackFraction, + const tetIndices& tetIs ) const { + vector& U = p.U(); + + bool& active = p.active(); + if (isA<wallPolyPatch>(pp)) { switch (interactionType_) @@ -125,8 +129,13 @@ bool Foam::StandardWallInteraction<CloudType>::correct keepParticle = true; active = true; - vector nw = pp.faceAreas()[pp.whichFace(faceId)]; - nw /= mag(nw); + vector nw; + vector Up; + + this->patchData(p, pp, trackFraction, tetIs, nw, Up); + + // Calculate motion relative to patch velocity + U -= Up; scalar Un = U & nw; vector Ut = U - Un*nw; @@ -138,6 +147,9 @@ bool Foam::StandardWallInteraction<CloudType>::correct U -= mu_*Ut; + // Return velocity to global space + U += Up; + break; } default: diff --git a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/StandardWallInteraction/StandardWallInteraction.H b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/StandardWallInteraction/StandardWallInteraction.H index 476bd7d63a2c66ba4a922302e37d57a19f8aa07f..bae46785ea2a86e486428f1634983e7d6a22d697 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/StandardWallInteraction/StandardWallInteraction.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/StandardWallInteraction/StandardWallInteraction.H @@ -99,11 +99,11 @@ public: // Returns true if particle remains in same cell virtual bool correct ( + typename CloudType::parcelType& p, const polyPatch& pp, - const label faceId, bool& keepParticle, - bool& active, - vector& U + const scalar trackFraction, + const tetIndices& tetIs ) const; }; diff --git a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C index 8f98590bf42a43f303c73b22106fb71338b19d1f..41d31901cad0a2c095dcb5bcd3d6a2da11382728 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C @@ -40,7 +40,6 @@ Foam::SurfaceFilmModel<CloudType>::SurfaceFilmModel(CloudType& owner) g_(dimensionedVector("zero", dimAcceleration, vector::zero)), coeffDict_(dictionary::null), active_(false), - injectorCellsPatch_(0), massParcelPatch_(0), diameterParcelPatch_(0), UFilmPatch_(0), @@ -64,7 +63,6 @@ Foam::SurfaceFilmModel<CloudType>::SurfaceFilmModel g_(g), coeffDict_(dict.subDict(type + "Coeffs")), active_(true), - injectorCellsPatch_(0), massParcelPatch_(0), diameterParcelPatch_(0), UFilmPatch_(0), @@ -112,22 +110,41 @@ void Foam::SurfaceFilmModel<CloudType>::inject(TrackData& td) this->owner().mesh().boundaryMesh()[primaryPatchI] ); - injectorCellsPatch_ = wpp.faceCells(); + const labelList& injectorCellsPatch = wpp.faceCells(); const label filmPatchI = filmPatches[i]; const mapDistribute& distMap = wpp.map(); cacheFilmFields(filmPatchI, distMap, filmModel); - forAll(injectorCellsPatch_, j) + forAll(injectorCellsPatch, j) { if (diameterParcelPatch_[j] > 0) { - const label cellI = injectorCellsPatch_[j]; + const label cellI = injectorCellsPatch[j]; + + // The position is at the cell centre, which could be + // in any tet of the decomposed cell, so arbitrarily + // choose the first face of the cell as the tetFace + // and the first point on the face after the base + // point as the tetPt. The tracking will + // pick the cell consistent with the motion in the + // first tracking step. + const label tetFaceI = this->owner().mesh().cells()[cellI][0]; + const label tetPtI = 1; + const point& pos = this->owner().mesh().C()[cellI]; // Create a new parcel typename CloudType::parcelType* pPtr = - new typename CloudType::parcelType(td.cloud(), pos, cellI); + new typename CloudType::parcelType + ( + td.cloud(), + pos, + cellI, + tetFaceI, + tetPtI + ); + setParcelProperties(*pPtr, j); // Check new parcel properties @@ -159,7 +176,7 @@ void Foam::SurfaceFilmModel<CloudType>::cacheFilmFields filmModel.diametersForPrimary().boundaryField()[filmPatchI]; distMap.distribute(diameterParcelPatch_); - UFilmPatch_ = filmModel.U().boundaryField()[filmPatchI]; + UFilmPatch_ = filmModel.Us().boundaryField()[filmPatchI]; distMap.distribute(UFilmPatch_); rhoFilmPatch_ = filmModel.rho().boundaryField()[filmPatchI]; diff --git a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H index 986bd943d85ef7e806bf0f0be5aaea9c560f4318..f94c3c29bd9189954ebf402cdac08bdc4fc0756c 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H @@ -85,9 +85,6 @@ protected: // Cached injector fields per film patch - //- Injector cell / patch face - labelList injectorCellsPatch_; - //- Parcel mass / patch face scalarList massParcelPatch_; diff --git a/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.C b/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.C index 00b6667f9d58445995258a639ca19521d293ffe7..5c4b49370b1a5ec6a610120cab03006e107856ce 100644 --- a/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.C +++ b/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.C @@ -32,7 +32,7 @@ Foam::label Foam::ReactingLookupTableInjection<CloudType>::parcelsToInject ( const scalar time0, const scalar time1 -) const +) { if ((time0 >= 0.0) && (time0 < duration_)) { @@ -50,7 +50,7 @@ Foam::scalar Foam::ReactingLookupTableInjection<CloudType>::volumeToInject ( const scalar time0, const scalar time1 -) const +) { scalar volume = 0.0; if ((time0 >= 0.0) && (time0 < duration_)) @@ -92,13 +92,24 @@ Foam::ReactingLookupTableInjection<CloudType>::ReactingLookupTableInjection IOobject::NO_WRITE ) ), - injectorCells_(0) + injectorCells_(0), + injectorTetFaces_(0), + injectorTetPts_(0) { // Set/cache the injector cells injectorCells_.setSize(injectors_.size()); + injectorTetFaces_.setSize(injectors_.size()); + injectorTetPts_.setSize(injectors_.size()); + forAll(injectors_, i) { - this->findCellAtPosition(injectorCells_[i], injectors_[i].x()); + this->findCellAtPosition + ( + injectorCells_[i], + injectorTetFaces_[i], + injectorTetPts_[i], + injectors_[i].x() + ); } // Determine volume of particles to inject @@ -141,13 +152,17 @@ void Foam::ReactingLookupTableInjection<CloudType>::setPositionAndCell const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ) { label injectorI = parcelI*injectorCells_.size()/nParcels; position = injectors_[injectorI].x(); cellOwner = injectorCells_[injectorI]; + tetFaceI = injectorTetFaces_[injectorI]; + tetPtI = injectorTetPts_[injectorI]; } diff --git a/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.H b/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.H index 52cf535665e497e4f93f7aef7544b21baa6da42b..e13169a5b75318ffe4b33d06e12dec1d9ccfde53 100644 --- a/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.H +++ b/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.H @@ -84,8 +84,14 @@ class ReactingLookupTableInjection //- List of injectors reactingParcelInjectionDataIOList injectors_; - //- List of injector cells per injector - List<label> injectorCells_; + //- List of cell labels corresoponding to injector positions + labelList injectorCells_; + + //- List of tetFace labels corresoponding to injector positions + labelList injectorTetFaces_; + + //- List of tetPt labels corresoponding to injector positions + labelList injectorTetPts_; protected: @@ -97,14 +103,14 @@ protected: ( const scalar time0, const scalar time1 - ) const; + ); //- Volume of parcels to introduce over the time step relative to SOI scalar volumeToInject ( const scalar time0, const scalar time1 - ) const; + ); public: @@ -138,14 +144,16 @@ public: // Injection geometry - //- Set the injection position and owner cell + //- Set the injection position and owner cell, tetFace and tetPt virtual void setPositionAndCell ( const label parcelI, const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ); //- Set the parcel properties diff --git a/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.C b/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.C index 4d68b40b09d19a93fc657ee7f7353c4e785caa6f..1178b5cc33f05394a18a0cbc59a346fd19d86a5f 100644 --- a/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.C +++ b/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.C @@ -33,7 +33,7 @@ Foam::ReactingMultiphaseLookupTableInjection<CloudType>::parcelsToInject ( const scalar time0, const scalar time1 -) const +) { if ((time0 >= 0.0) && (time0 < duration_)) { @@ -52,7 +52,7 @@ Foam::ReactingMultiphaseLookupTableInjection<CloudType>::volumeToInject ( const scalar time0, const scalar time1 -) const +) { scalar volume = 0.0; if ((time0 >= 0.0) && (time0 < duration_)) @@ -95,13 +95,24 @@ ReactingMultiphaseLookupTableInjection IOobject::NO_WRITE ) ), - injectorCells_(0) + injectorCells_(0), + injectorTetFaces_(0), + injectorTetPts_(0) { // Set/cache the injector cells injectorCells_.setSize(injectors_.size()); + injectorTetFaces_.setSize(injectors_.size()); + injectorTetPts_.setSize(injectors_.size()); + forAll(injectors_, i) { - this->findCellAtPosition(injectorCells_[i], injectors_[i].x()); + this->findCellAtPosition + ( + injectorCells_[i], + injectorTetFaces_[i], + injectorTetPts_[i], + injectors_[i].x() + ); } // Determine volume of particles to inject @@ -146,13 +157,17 @@ void Foam::ReactingMultiphaseLookupTableInjection<CloudType>::setPositionAndCell const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ) { label injectorI = parcelI*injectorCells_.size()/nParcels; position = injectors_[injectorI].x(); cellOwner = injectorCells_[injectorI]; + tetFaceI = injectorTetFaces_[injectorI]; + tetPtI = injectorTetPts_[injectorI]; } diff --git a/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.H b/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.H index 2307ca20050f7a614a038f0ba0168766d14c895a..5b0ecae379350a54a13a1dcb58dc70337830674b 100644 --- a/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.H +++ b/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.H @@ -87,8 +87,14 @@ class ReactingMultiphaseLookupTableInjection //- List of injectors reactingMultiphaseParcelInjectionDataIOList injectors_; - //- List of injector cells per injector - List<label> injectorCells_; + //- List of cell labels corresoponding to injector positions + labelList injectorCells_; + + //- List of tetFace labels corresoponding to injector positions + labelList injectorTetFaces_; + + //- List of tetPt labels corresoponding to injector positions + labelList injectorTetPts_; protected: @@ -100,14 +106,14 @@ protected: ( const scalar time0, const scalar time1 - ) const; + ); //- Volume of parcels to introduce over the time step relative to SOI scalar volumeToInject ( const scalar time0, const scalar time1 - ) const; + ); public: @@ -141,14 +147,16 @@ public: // Injection geometry - //- Set the injection position and owner cell + //- Set the injection position and owner cell, tetFace and tetPt virtual void setPositionAndCell ( const label parcelI, const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ); //- Set the parcel properties diff --git a/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.C b/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.C index 88c13c4f8f72bcfccf7b5844a1460856b447a90c..6d7c9aef2cbc416a824da9e538e6a6dc5258f570 100644 --- a/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.C +++ b/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.C @@ -33,7 +33,7 @@ Foam::label Foam::ThermoLookupTableInjection<CloudType>::parcelsToInject ( const scalar time0, const scalar time1 -) const +) { if ((time0 >= 0.0) && (time0 < duration_)) { @@ -51,7 +51,7 @@ Foam::scalar Foam::ThermoLookupTableInjection<CloudType>::volumeToInject ( const scalar time0, const scalar time1 -) const +) { scalar volume = 0.0; if ((time0 >= 0.0) && (time0 < duration_)) @@ -93,13 +93,24 @@ Foam::ThermoLookupTableInjection<CloudType>::ThermoLookupTableInjection IOobject::NO_WRITE ) ), - injectorCells_(0) + injectorCells_(0), + injectorTetFaces_(0), + injectorTetPts_(0) { // Set/cache the injector cells injectorCells_.setSize(injectors_.size()); + injectorTetFaces_.setSize(injectors_.size()); + injectorTetPts_.setSize(injectors_.size()); + forAll(injectors_, i) { - this->findCellAtPosition(injectorCells_[injectorI], injectors_[i].x()); + this->findCellAtPosition + ( + injectorCells_[i], + injectorTetFaces_[i], + injectorTetPts_[i], + injectors_[i].x() + ); } // Determine volume of particles to inject @@ -142,13 +153,17 @@ void Foam::ThermoLookupTableInjection<CloudType>::setPositionAndCell const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ) { label injectorI = parcelI*injectorCells_.size()/nParcels; position = injectors_[injectorI].x(); cellOwner = injectorCells_[injectorI]; + tetFaceI = injectorTetFaces_[injectorI]; + tetPtI = injectorTetPts_[injectorI]; } diff --git a/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.H b/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.H index fa009ff00e41e918fd23d5c1246840ec40c055f4..4fd93884b46fa6ea5afdbc9b0b4be8cc239be36f 100644 --- a/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.H +++ b/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.H @@ -83,8 +83,14 @@ class ThermoLookupTableInjection //- List of injectors kinematicParcelInjectionDataIOList injectors_; - //- List of injector cells per injector - List<label> injectorCells_; + //- List of cell labels corresoponding to injector positions + labelList injectorCells_; + + //- List of tetFace labels corresoponding to injector positions + labelList injectorTetFaces_; + + //- List of tetPt labels corresoponding to injector positions + labelList injectorTetPts_; protected: @@ -96,14 +102,14 @@ protected: ( const scalar time0, const scalar time1 - ) const; + ); //- Volume of parcels to introduce over the time step relative to SOI scalar volumeToInject ( const scalar time0, const scalar time1 - ) const; + ); public: @@ -137,14 +143,16 @@ public: // Injection geometry - //- Set the injection position and owner cell + //- Set the injection position and owner cell, tetFace and tetPt virtual void setPositionAndCell ( const label parcelI, const label nParcels, const scalar time, vector& position, - label& cellOwner + label& cellOwner, + label& tetFaceI, + label& tetPtI ); //- Set the parcel properties diff --git a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C index d0c1ba984e35cf9b4304518d05b710aede6a7458..04413ad9cf6c0d92dac15cdfcc508c49950c9b00 100644 --- a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C +++ b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C @@ -80,7 +80,7 @@ bool Foam::ThermoSurfaceFilm<CloudType>::transferParcel { const polyPatch& pp = this->owner().mesh().boundaryMesh()[patchI]; - label faceI = pp.whichFace(p.face()); + const label faceI = pp.whichFace(p.face()); // Patch face normal const vector& nf = pp.faceNormals()[faceI]; @@ -137,7 +137,7 @@ void Foam::ThermoSurfaceFilm<CloudType>::cacheFilmFields filmModel ); - TFilmPatch_ = filmModel.T().boundaryField()[filmPatchI]; + TFilmPatch_ = filmModel.Ts().boundaryField()[filmPatchI]; distMap.distribute(TFilmPatch_); cpFilmPatch_ = filmModel.cp().boundaryField()[filmPatchI]; diff --git a/src/lagrangian/molecularDynamics/molecule/molecule/molecule.C b/src/lagrangian/molecularDynamics/molecule/molecule/molecule.C index 2af297c6ac4ac87f030b222bab838dfa5f4b933c..ef3b1395cc8e41dab90834f0c9c4815178437de0 100644 --- a/src/lagrangian/molecularDynamics/molecule/molecule/molecule.C +++ b/src/lagrangian/molecularDynamics/molecule/molecule/molecule.C @@ -260,7 +260,9 @@ bool Foam::molecule::hitPatch ( const polyPatch&, molecule::trackData&, - const label + const label, + const scalar, + const tetIndices& ) { return false; @@ -271,7 +273,9 @@ bool Foam::molecule::hitPatch ( const polyPatch&, int&, - const label + const label, + const scalar, + const tetIndices& ) { return false; @@ -299,10 +303,13 @@ void Foam::molecule::hitProcessorPatch void Foam::molecule::hitWallPatch ( const wallPolyPatch& wpp, - molecule::trackData& td + molecule::trackData& td, + const tetIndices& tetIs ) { - vector nw = wpp.faceAreas()[wpp.whichFace(face())]; + // Use of the normal from tetIs is not required as + // hasWallImpactDistance for a moleculeCloud is false. + vector nw = normal(); nw /= mag(nw); scalar vn = v_ & nw; @@ -318,7 +325,8 @@ void Foam::molecule::hitWallPatch void Foam::molecule::hitWallPatch ( const wallPolyPatch&, - int& + int&, + const tetIndices& ) {} diff --git a/src/lagrangian/molecularDynamics/molecule/molecule/molecule.H b/src/lagrangian/molecularDynamics/molecule/molecule/molecule.H index 448cb0955bee540ab4b931075de0f1bdf4aeebca..8df55ca8faf34c9f4647a7a31d4270cba2af81fe 100644 --- a/src/lagrangian/molecularDynamics/molecule/molecule/molecule.H +++ b/src/lagrangian/molecularDynamics/molecule/molecule/molecule.H @@ -228,7 +228,9 @@ public: ( const Cloud<molecule>& c, const vector& position, - const label celli, + const label cellI, + const label tetFaceI, + const label tetPtI, const tensor& Q, const vector& v, const vector& a, @@ -317,7 +319,9 @@ public: ( const polyPatch&, molecule::trackData& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ); //- Overridable function to handle the particle hitting a patch @@ -326,7 +330,9 @@ public: ( const polyPatch& p, int& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ); //- Overridable function to handle the particle hitting a processorPatch @@ -348,7 +354,8 @@ public: void hitWallPatch ( const wallPolyPatch&, - molecule::trackData& td + molecule::trackData& td, + const tetIndices& ); //- Overridable function to handle the particle hitting a wallPatch @@ -356,7 +363,8 @@ public: void hitWallPatch ( const wallPolyPatch&, - int& + int&, + const tetIndices& ); //- Overridable function to handle the particle hitting a polyPatch diff --git a/src/lagrangian/molecularDynamics/molecule/molecule/moleculeI.H b/src/lagrangian/molecularDynamics/molecule/molecule/moleculeI.H index b759d4731be0f0691bc4e4e17ed1e5c8e888ddc6..be0c19985e35a070606fab32f5b4ab721a431409 100644 --- a/src/lagrangian/molecularDynamics/molecule/molecule/moleculeI.H +++ b/src/lagrangian/molecularDynamics/molecule/molecule/moleculeI.H @@ -221,7 +221,9 @@ inline Foam::molecule::molecule ( const Cloud<molecule>& c, const vector& position, - const label celli, + const label cellI, + const label tetFaceI, + const label tetPtI, const tensor& Q, const vector& v, const vector& a, @@ -234,7 +236,7 @@ inline Foam::molecule::molecule ) : - Particle<molecule>(c, position, celli), + Particle<molecule>(c, position, cellI, tetFaceI, tetPtI), Q_(Q), v_(v), a_(a), diff --git a/src/lagrangian/molecularDynamics/molecule/moleculeCloud/moleculeCloud.C b/src/lagrangian/molecularDynamics/molecule/moleculeCloud/moleculeCloud.C index 5fef0b1d0d4edcf10d6293d6344c89ce3960f9d2..ef50886ebf227c63151d3188432aa87c9452d283 100644 --- a/src/lagrangian/molecularDynamics/molecule/moleculeCloud/moleculeCloud.C +++ b/src/lagrangian/molecularDynamics/molecule/moleculeCloud/moleculeCloud.C @@ -742,7 +742,17 @@ void Foam::moleculeCloud::initialiseMolecules globalPosition ); - label cell = mesh_.findCell(globalPosition); + label cell = -1; + label tetFace = -1; + label tetPt = -1; + + findCellFacePt + ( + globalPosition, + cell, + tetFace, + tetPt + ); if (findIndex(zone, cell) != -1) { @@ -750,6 +760,8 @@ void Foam::moleculeCloud::initialiseMolecules ( globalPosition, cell, + tetFace, + tetPt, id, tethered, temperature, @@ -818,9 +830,16 @@ void Foam::moleculeCloud::initialiseMolecules globalPosition ); - label cell = mesh_.findCell + label cell = -1; + label tetFace = -1; + label tetPt = -1; + + findCellFacePt ( - globalPosition + globalPosition, + cell, + tetFace, + tetPt ); if (findIndex(zone, cell) != -1) @@ -829,6 +848,8 @@ void Foam::moleculeCloud::initialiseMolecules ( globalPosition, cell, + tetFace, + tetPt, id, tethered, temperature, @@ -888,9 +909,16 @@ void Foam::moleculeCloud::initialiseMolecules globalPosition ); - label cell = mesh_.findCell + label cell = -1; + label tetFace = -1; + label tetPt = -1; + + findCellFacePt ( - globalPosition + globalPosition, + cell, + tetFace, + tetPt ); if (findIndex(zone, cell) != -1) @@ -899,6 +927,8 @@ void Foam::moleculeCloud::initialiseMolecules ( globalPosition, cell, + tetFace, + tetPt, id, tethered, temperature, @@ -962,6 +992,8 @@ void Foam::moleculeCloud::createMolecule ( const point& position, label cell, + label tetFace, + label tetPt, label id, bool tethered, scalar temperature, @@ -972,7 +1004,7 @@ void Foam::moleculeCloud::createMolecule if (cell == -1) { - cell = mesh_.findCell(position); + findCellFacePt(position, cell, tetFace, tetPt); } if (cell == -1) @@ -1034,6 +1066,8 @@ void Foam::moleculeCloud::createMolecule cloud, position, cell, + tetFace, + tetPt, Q, v, vector::zero, diff --git a/src/lagrangian/molecularDynamics/molecule/moleculeCloud/moleculeCloud.H b/src/lagrangian/molecularDynamics/molecule/moleculeCloud/moleculeCloud.H index b92f4e5e7b510d8b04c9ce694f17979bd183a9fa..7cf3359a3517588acea7bd474fe418af85204c91 100644 --- a/src/lagrangian/molecularDynamics/molecule/moleculeCloud/moleculeCloud.H +++ b/src/lagrangian/molecularDynamics/molecule/moleculeCloud/moleculeCloud.H @@ -114,6 +114,8 @@ private: ( const point& position, label cell, + label tetFace, + label tetPt, label id, bool tethered, scalar temperature, diff --git a/src/lagrangian/solidParticle/Make/options b/src/lagrangian/solidParticle/Make/options index 15874b7b55afc2cfae55d9550fd48451604ee3d4..9fe79c9220b60af2b5c87cc7e9f6974096372b1a 100644 --- a/src/lagrangian/solidParticle/Make/options +++ b/src/lagrangian/solidParticle/Make/options @@ -1,7 +1,9 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude LIB_LIBS = \ -llagrangian \ + -lmeshTools \ -lfiniteVolume diff --git a/src/lagrangian/solidParticle/solidParticle.C b/src/lagrangian/solidParticle/solidParticle.C index 37c8b4478c09a62eb9e29b4ac11f5593818af79b..e802e67d06a2f88858778a8911b6753574fe13b7 100644 --- a/src/lagrangian/solidParticle/solidParticle.C +++ b/src/lagrangian/solidParticle/solidParticle.C @@ -54,14 +54,14 @@ bool Foam::solidParticle::move(solidParticle::trackData& td) // remember which cell the parcel is in // since this will change if a face is hit - label celli = cell(); + label cellI = cell(); dt *= trackToFace(position() + dt*U_, td); tEnd -= dt; stepFraction() = 1.0 - tEnd/deltaT; - cellPointWeight cpw(mesh, position(), celli, face()); + cellPointWeight cpw(mesh, position(), cellI, face()); scalar rhoc = td.rhoInterp().interpolate(cpw); vector Uc = td.UInterp().interpolate(cpw); scalar nuc = td.nuInterp().interpolate(cpw); @@ -98,7 +98,9 @@ bool Foam::solidParticle::hitPatch ( const polyPatch&, solidParticle::trackData&, - const label + const label, + const scalar, + const tetIndices& ) { return false; @@ -109,7 +111,9 @@ bool Foam::solidParticle::hitPatch ( const polyPatch&, int&, - const label + const label, + const scalar, + const tetIndices& ) { return false; @@ -137,10 +141,11 @@ void Foam::solidParticle::hitProcessorPatch void Foam::solidParticle::hitWallPatch ( const wallPolyPatch& wpp, - solidParticle::trackData& td + solidParticle::trackData& td, + const tetIndices& tetIs ) { - vector nw = wpp.faceAreas()[wpp.whichFace(face())]; + vector nw = tetIs.faceTri(cloud().pMesh()).normal(); nw /= mag(nw); scalar Un = U_ & nw; @@ -158,7 +163,8 @@ void Foam::solidParticle::hitWallPatch void Foam::solidParticle::hitWallPatch ( const wallPolyPatch&, - int& + int&, + const tetIndices& ) {} diff --git a/src/lagrangian/solidParticle/solidParticle.H b/src/lagrangian/solidParticle/solidParticle.H index 842b0045325157cbc811d9705e1375117a4c511f..04ff8e9e51002b77e734394c3057b4a1122783f9 100644 --- a/src/lagrangian/solidParticle/solidParticle.H +++ b/src/lagrangian/solidParticle/solidParticle.H @@ -127,8 +127,10 @@ public: ( const Cloud<solidParticle>& c, const vector& position, - const label celli, - const scalar m, + const label cellI, + const label tetFaceI, + const label tetPtI, + const scalar d, const vector& U ); @@ -176,7 +178,9 @@ public: ( const polyPatch&, solidParticle::trackData& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ); //- Overridable function to handle the particle hitting a patch @@ -185,7 +189,9 @@ public: ( const polyPatch& p, int& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ); //- Overridable function to handle the particle hitting a @@ -208,7 +214,8 @@ public: void hitWallPatch ( const wallPolyPatch&, - solidParticle::trackData& td + solidParticle::trackData& td, + const tetIndices& ); //- Overridable function to handle the particle hitting a wallPatch @@ -216,7 +223,8 @@ public: void hitWallPatch ( const wallPolyPatch&, - int& + int&, + const tetIndices& ); //- Overridable function to handle the particle hitting a polyPatch diff --git a/src/lagrangian/solidParticle/solidParticleCloud.H b/src/lagrangian/solidParticle/solidParticleCloud.H index b4e87423b33507fd938885b0b4e0f07edd37b00e..7a1761593b2d65a7ad85d49287ad9cce9e8e8d5a 100644 --- a/src/lagrangian/solidParticle/solidParticleCloud.H +++ b/src/lagrangian/solidParticle/solidParticleCloud.H @@ -94,6 +94,8 @@ public: // Access + inline bool hasWallImpactDistance() const; + inline const fvMesh& mesh() const; inline scalar rhop() const; diff --git a/src/lagrangian/solidParticle/solidParticleCloudI.H b/src/lagrangian/solidParticle/solidParticleCloudI.H index db8b817901ad072314d8056bd0a9a0d91a0ee35e..3b830c0887c2c07d44f5aa70d3287d8a6d9ce1ce 100644 --- a/src/lagrangian/solidParticle/solidParticleCloudI.H +++ b/src/lagrangian/solidParticle/solidParticleCloudI.H @@ -25,6 +25,12 @@ License // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +inline bool Foam::solidParticleCloud::hasWallImpactDistance() const +{ + return true; +} + + inline const Foam::fvMesh& Foam::solidParticleCloud::mesh() const { return mesh_; diff --git a/src/lagrangian/solidParticle/solidParticleI.H b/src/lagrangian/solidParticle/solidParticleI.H index a0af6bfad532b42562b4a6b784e16a900e8a8fb1..5bc146941a105f594eba6d75075978a88cfa0fc1 100644 --- a/src/lagrangian/solidParticle/solidParticleI.H +++ b/src/lagrangian/solidParticle/solidParticleI.H @@ -46,12 +46,14 @@ inline Foam::solidParticle::solidParticle ( const Cloud<solidParticle>& c, const vector& position, - const label celli, + const label cellI, + const label tetFaceI, + const label tetPtI, const scalar d, const vector& U ) : - Particle<solidParticle>(c, position, celli), + Particle<solidParticle>(c, position, cellI, tetFaceI, tetPtI), d_(d), U_(U) {} @@ -64,18 +66,21 @@ inline Foam::solidParticleCloud& Foam::solidParticle::trackData::spc() return spc_; } + inline const Foam::interpolationCellPoint<Foam::scalar>& Foam::solidParticle::trackData::rhoInterp() const { return rhoInterp_; } + inline const Foam::interpolationCellPoint<Foam::vector>& Foam::solidParticle::trackData::UInterp() const { return UInterp_; } + inline const Foam::interpolationCellPoint<Foam::scalar>& Foam::solidParticle::trackData::nuInterp() const { @@ -93,11 +98,13 @@ inline Foam::scalar Foam::solidParticle::d() const return d_; } + inline Foam::scalar Foam::solidParticle::wallImpactDistance(const vector&) const { return 0.5*d_; } + inline const Foam::vector& Foam::solidParticle::U() const { return U_; diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C index 1c867ba760f6f9e5c63eb0b886f6d042cf50fd93..bda9fc6e8e9b1b14b7dc081112ea0721dfdbf067 100644 --- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C +++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C @@ -279,7 +279,11 @@ Foam::label Foam::meshRefinement::markFeatureRefinement Cloud<trackedParticle> cloud(mesh_, IDLList<trackedParticle>()); // Create particles on whichever processor holds the keepPoint. - label cellI = mesh_.findCell(keepPoint); + label cellI = -1; + label tetFaceI = -1; + label tetPtI = -1; + + cloud.findCellFacePt(keepPoint, cellI, tetFaceI, tetPtI); if (cellI != -1) { @@ -308,6 +312,8 @@ Foam::label Foam::meshRefinement::markFeatureRefinement cloud, keepPoint, cellI, + tetFaceI, + tetPtI, featureMesh.points()[pointI], // endpos featureLevels[featI], // level featI, // featureMesh diff --git a/src/mesh/autoMesh/autoHexMesh/trackedParticle/ExactParticle.C b/src/mesh/autoMesh/autoHexMesh/trackedParticle/ExactParticle.C deleted file mode 100644 index 8efba5dc0cc0d0429d3e9feed329c975847a5b9c..0000000000000000000000000000000000000000 --- a/src/mesh/autoMesh/autoHexMesh/trackedParticle/ExactParticle.C +++ /dev/null @@ -1,261 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 "ExactParticle.H" - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -template<class ParticleType> -template<class TrackingData> -Foam::label Foam::ExactParticle<ParticleType>::track -( - const vector& endPosition, - TrackingData& td -) -{ - this->facei_ = -1; - - // Tracks to endPosition or stop on boundary - while (!this->onBoundary() && this->stepFraction_ < 1.0 - SMALL) - { - this->stepFraction_ += - trackToFace(endPosition, td) - *(1.0 - this->stepFraction_); - } - - return this->facei_; -} - - -template<class ParticleType> -Foam::label Foam::ExactParticle<ParticleType>::track -( - const vector& endPosition -) -{ - int dummyTd; - return track(endPosition, dummyTd); -} - - -template<class ParticleType> -template<class TrackingData> -Foam::scalar Foam::ExactParticle<ParticleType>::trackToFace -( - const vector& endPosition, - TrackingData& td -) -{ - const polyMesh& mesh = this->cloud().pMesh(); - const labelList& cFaces = mesh.cells()[this->celli_]; - - point intersection(vector::zero); - scalar trackFraction = VGREAT; - label hitFacei = -1; - - const vector vec = endPosition-this->position_; - - forAll(cFaces, i) - { - label facei = cFaces[i]; - - if (facei != this->face()) - { - pointHit inter = mesh.faces()[facei].intersection - ( - this->position_, - vec, - mesh.faceCentres()[facei], - mesh.points(), - intersection::HALF_RAY - ); - - if (inter.hit() && inter.distance() < trackFraction) - { - trackFraction = inter.distance(); - hitFacei = facei; - intersection = inter.hitPoint(); - } - } - } - - if (hitFacei == -1) - { - // Did not find any intersection. Fall back to original approximate - // algorithm - return Particle<ParticleType>::trackToFace - ( - endPosition, - td - ); - } - - if (trackFraction >= (1.0-SMALL)) - { - // Nearest intersection beyond endPosition so we hit endPosition. - trackFraction = 1.0; - this->position_ = endPosition; - this->facei_ = -1; - return 1.0; - } - else - { - this->position_ = intersection; - this->facei_ = hitFacei; - } - - - // Normal situation (trackFraction 0..1). Straight copy - // of Particle::trackToFace. - - bool internalFace = this->cloud().internalFace(this->facei_); - - // change cell - if (internalFace) // Internal face - { - if (this->celli_ == mesh.faceOwner()[this->facei_]) - { - this->celli_ = mesh.faceNeighbour()[this->facei_]; - } - else if (this->celli_ == mesh.faceNeighbour()[this->facei_]) - { - this->celli_ = mesh.faceOwner()[this->facei_]; - } - else - { - FatalErrorIn - ( - "ExactParticle::trackToFace" - "(const vector&, TrackingData&)" - )<< "addressing failure" << nl - << abort(FatalError); - } - } - else - { - ParticleType& p = static_cast<ParticleType&>(*this); - - // Soft-sphere algorithm ignores the boundary - if (p.softImpact()) - { - trackFraction = 1.0; - this->position_ = endPosition; - } - - label patchi = patch(this->facei_); - const polyPatch& patch = mesh.boundaryMesh()[patchi]; - - if (isA<wedgePolyPatch>(patch)) - { - p.hitWedgePatch - ( - static_cast<const wedgePolyPatch&>(patch), td - ); - } - else if (isA<symmetryPolyPatch>(patch)) - { - p.hitSymmetryPatch - ( - static_cast<const symmetryPolyPatch&>(patch), td - ); - } - else if (isA<cyclicPolyPatch>(patch)) - { - p.hitCyclicPatch - ( - static_cast<const cyclicPolyPatch&>(patch), td - ); - } - else if (isA<processorPolyPatch>(patch)) - { - p.hitProcessorPatch - ( - static_cast<const processorPolyPatch&>(patch), td - ); - } - else if (isA<wallPolyPatch>(patch)) - { - p.hitWallPatch - ( - static_cast<const wallPolyPatch&>(patch), td - ); - } - else if (isA<polyPatch>(patch)) - { - p.hitPatch - ( - static_cast<const polyPatch&>(patch), td - ); - } - else - { - FatalErrorIn - ( - "ExactParticle::trackToFace" - "(const vector& endPosition, scalar& trackFraction)" - )<< "patch type " << patch.type() << " not suported" << nl - << abort(FatalError); - } - } - - // If the trackFraction = 0 something went wrong. - // Either the particle is flipping back and forth across a face perhaps - // due to velocity interpolation errors or it is in a "hole" in the mesh - // caused by face warpage. - // In both cases resolve the positional ambiguity by moving the particle - // slightly towards the cell-centre. - if (trackFraction < SMALL) - { - this->position_ += - 1.0e-6*(mesh.cellCentres()[this->celli_] - this->position_); - } - - return trackFraction; -} - - -template<class ParticleType> -Foam::scalar Foam::ExactParticle<ParticleType>::trackToFace -( - const vector& endPosition -) -{ - int dummyTd; - return trackToFace(endPosition, dummyTd); -} - - -template<class ParticleType> -Foam::Ostream& Foam::operator<< -( - Ostream& os, - const ExactParticle<ParticleType>& p -) -{ - return operator<<(os, static_cast<const Particle<ParticleType>&>(p)); -} - - -// ************************************************************************* // diff --git a/src/mesh/autoMesh/autoHexMesh/trackedParticle/ExactParticle.H b/src/mesh/autoMesh/autoHexMesh/trackedParticle/ExactParticle.H deleted file mode 100644 index 5965815d02f75f64269e06f65080ef793651abb8..0000000000000000000000000000000000000000 --- a/src/mesh/autoMesh/autoHexMesh/trackedParticle/ExactParticle.H +++ /dev/null @@ -1,191 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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::ExactParticle - -Description - Special version of Particle to do tracking on non-convex cells. - -\*---------------------------------------------------------------------------*/ - -#ifndef ExactParticle_H -#define ExactParticle_H - -#include "face.H" -#include "Particle.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -template<class ExactParticle> -class Cloud; - -// Forward declaration of friend functions and operators - -template<class ParticleType> -class ExactParticle; - -template<class ParticleType> -Ostream& operator<< -( - Ostream&, - const ExactParticle<ParticleType>& -); - - -/*---------------------------------------------------------------------------*\ - Class ExactParticle Declaration -\*---------------------------------------------------------------------------*/ - -template<class ParticleType> -class ExactParticle -: - public Particle<ParticleType> -{ - -public: - - friend class Cloud<ParticleType>; - - - // Constructors - - //- Construct from components - ExactParticle - ( - const Cloud<ParticleType>& cloud, - const vector& position, - const label celli - ) - : - Particle<ParticleType>(cloud, position, celli) - {} - - - //- Construct from Istream - ExactParticle - ( - const Cloud<ParticleType>& cloud, - Istream& is, - bool readFields = true - ) - : - Particle<ParticleType>(cloud, is, readFields) - {} - - - //- Factory class to read-construct particles used for parallel transfer - class iNew - { - - // Private data - - const Cloud<ParticleType>& cloud_; - - - public: - - iNew(const Cloud<ParticleType>& cloud) - : - cloud_(cloud) - {} - - autoPtr<ParticleType> operator()(Istream& is) const - { - return autoPtr<ParticleType> - ( - new ParticleType(cloud_, is) - ); - } - }; - - - //- Destructor - virtual ~ExactParticle() - {} - - - // Member Functions - - //- Track particle to end of trajectory - // or until it hits the boundary. - // On entry 'stepFraction()' should be set to the fraction of the - // time-step at which the tracking starts and on exit it contains - // the fraction of the time-step completed. - // Returns the boundary face index if the track stops at the - // boundary, -1 otherwise. - template<class TrackingData> - label track - ( - const vector& endPosition, - TrackingData& td - ); - - //- Calls the templated track with dummy TrackingData - label track(const vector& endPosition); - - //- Track particle to a given position and returns 1.0 if the - // trajectory is completed without hitting a face otherwise - // stops at the face and returns the fraction of the trajectory - // completed. - // on entry 'stepFraction()' should be set to the fraction of the - // time-step at which the tracking starts. - template<class TrackingData> - scalar trackToFace - ( - const vector& endPosition, - TrackingData& td - ); - - //- Calls the templated trackToFace with dummy TrackingData - scalar trackToFace(const vector& endPosition); - - - // Ostream Operator - - friend Ostream& operator<< <ParticleType> - ( - Ostream&, - const ExactParticle<ParticleType>& - ); -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#ifdef NoRepository -# include "ExactParticle.C" -#endif - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/mesh/autoMesh/autoHexMesh/trackedParticle/trackedParticle.C b/src/mesh/autoMesh/autoHexMesh/trackedParticle/trackedParticle.C index ad4a5079d57df02ee4d60480597211bf2f81715b..5714b3062eeb861ba34c4267b3678be7843ab2af 100644 --- a/src/mesh/autoMesh/autoHexMesh/trackedParticle/trackedParticle.C +++ b/src/mesh/autoMesh/autoHexMesh/trackedParticle/trackedParticle.C @@ -32,14 +32,16 @@ Foam::trackedParticle::trackedParticle ( const Cloud<trackedParticle>& c, const vector& position, - const label celli, + const label cellI, + const label tetFaceI, + const label tetPtI, const point& end, const label level, const label i, const label j ) : - ExactParticle<trackedParticle>(c, position, celli), + Particle<trackedParticle>(c, position, cellI, tetFaceI, tetPtI), end_(end), level_(level), i_(i), @@ -55,7 +57,7 @@ Foam::trackedParticle::trackedParticle bool readFields ) : - ExactParticle<trackedParticle>(c, is, readFields) + Particle<trackedParticle>(c, is, readFields) { if (readFields) { @@ -118,7 +120,9 @@ bool Foam::trackedParticle::hitPatch ( const polyPatch&, trackedParticle::trackData& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ) { return false; @@ -129,7 +133,9 @@ bool Foam::trackedParticle::hitPatch ( const polyPatch&, int&, - const label + const label, + const scalar trackFraction, + const tetIndices& tetIs ) { return false; @@ -215,7 +221,8 @@ void Foam::trackedParticle::hitProcessorPatch void Foam::trackedParticle::hitWallPatch ( const wallPolyPatch& wpp, - trackedParticle::trackData& td + trackedParticle::trackData& td, + const tetIndices& ) { // Remove particle @@ -226,7 +233,8 @@ void Foam::trackedParticle::hitWallPatch void Foam::trackedParticle::hitWallPatch ( const wallPolyPatch& wpp, - int& + int&, + const tetIndices& ) {} @@ -256,7 +264,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const trackedParticle& p) { if (os.format() == IOstream::ASCII) { - os << static_cast<const ExactParticle<trackedParticle>&>(p) + os << static_cast<const Particle<trackedParticle>&>(p) << token::SPACE << p.end_ << token::SPACE << p.level_ << token::SPACE << p.i_ @@ -264,7 +272,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const trackedParticle& p) } else { - os << static_cast<const ExactParticle<trackedParticle>&>(p); + os << static_cast<const Particle<trackedParticle>&>(p); os.write ( reinterpret_cast<const char*>(&p.end_), diff --git a/src/mesh/autoMesh/autoHexMesh/trackedParticle/trackedParticle.H b/src/mesh/autoMesh/autoHexMesh/trackedParticle/trackedParticle.H index ef0c2695e4b9cd760146018b2230bdc90cd1776b..1f62e6f37a575a55bb22e280b71da48c10004832 100644 --- a/src/mesh/autoMesh/autoHexMesh/trackedParticle/trackedParticle.H +++ b/src/mesh/autoMesh/autoHexMesh/trackedParticle/trackedParticle.H @@ -26,8 +26,7 @@ Class Description Particle class that marks cells it passes through. Used to mark cells - visited by feature edges. Uses ExactParticle tracking class so - will work on concave cells. + visited by feature edges. SourceFiles trackedParticle.C @@ -37,7 +36,7 @@ SourceFiles #ifndef trackedParticle_H #define trackedParticle_H -#include "ExactParticle.H" +#include "Particle.H" #include "autoPtr.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -53,7 +52,7 @@ class trackedParticleCloud; class trackedParticle : - public ExactParticle<trackedParticle> + public Particle<trackedParticle> { // Private data @@ -118,7 +117,9 @@ public: ( const Cloud<trackedParticle>& c, const vector& position, - const label celli, + const label cellI, + const label tetFaceI, + const label tetPtI, const point& end, const label level, const label i, @@ -174,13 +175,17 @@ public: ( const polyPatch&, trackedParticle::trackData& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ); bool hitPatch ( const polyPatch&, int&, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ); //- Overridable function to handle the particle hitting a wedge @@ -237,12 +242,14 @@ public: void hitWallPatch ( const wallPolyPatch&, - trackedParticle::trackData& td + trackedParticle::trackData& td, + const tetIndices& ); void hitWallPatch ( const wallPolyPatch&, - int& + int&, + const tetIndices& ); //- Overridable function to handle the particle hitting a polyPatch diff --git a/src/meshTools/Make/options b/src/meshTools/Make/options index ef1033b0e8e02532fad69152efae5ae8342f046a..45765759c16acadd0d907685d44e79783df5cc54 100644 --- a/src/meshTools/Make/options +++ b/src/meshTools/Make/options @@ -1,7 +1,5 @@ EXE_INC = \ - -I$(LIB_SRC)/triSurface/lnInclude \ - -I$(LIB_SRC)/lagrangian/basic/lnInclude + -I$(LIB_SRC)/triSurface/lnInclude LIB_LIBS = \ - -ltriSurface \ - -llagrangian + -ltriSurface diff --git a/src/meshTools/surfaceSets/surfaceSets.H b/src/meshTools/surfaceSets/surfaceSets.H index 3fd75716fac88baa117085ebfac99c4d1737511b..faeb38aa4d7c66cc2a4ddcab1749620cf700d0db 100644 --- a/src/meshTools/surfaceSets/surfaceSets.H +++ b/src/meshTools/surfaceSets/surfaceSets.H @@ -102,9 +102,8 @@ class surfaceSets //); ////- Select all points out of pointSet where the distance to - //// the surface is less - //// than a factor times a local length scale (minimum length of - //// connected edges) + //// the surface is less than a factor times a local length + //// scale (minimum length of connected edges) //static void getNearPoints //( // const primitiveMesh& mesh, diff --git a/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C b/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C index 9e164f73feb422f35f1bac5cc60bf2aec7b4236c..6602fbcf430385f0018ae9368381c946571cdd1f 100644 --- a/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C +++ b/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C @@ -30,8 +30,6 @@ License #include "HashSet.H" #include "triSurface.H" #include "pointIndexHit.H" -#include "octreeDataTriSurface.H" -#include "octree.H" #include "mergePoints.H" #include "plane.H" #include "edgeIntersections.H" diff --git a/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersectionFuncs.C b/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersectionFuncs.C index ec9f370553916cd33465e05c963620e3af5860e9..18ebd6988c075ae141024be6f81fe7076f4a89c2 100644 --- a/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersectionFuncs.C +++ b/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersectionFuncs.C @@ -30,8 +30,6 @@ License #include "HashSet.H" #include "triSurface.H" #include "pointIndexHit.H" -#include "octreeDataTriSurface.H" -#include "octree.H" #include "meshTools.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // diff --git a/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.C b/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.C index acfb6749144f6f8fcdb52e2f88a97f6405e99d14..3cbe1157a98a59cf4e70db908b88cdfd625af173 100644 --- a/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.C +++ b/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.C @@ -25,9 +25,9 @@ License #include "surfaceFeatures.H" #include "triSurface.H" -#include "octree.H" -#include "octreeDataEdges.H" -#include "octreeDataPoint.H" +#include "indexedOctree.H" +#include "treeDataEdge.H" +#include "treeDataPoint.H" #include "meshTools.H" #include "linePointRef.H" #include "OFstream.H" @@ -752,21 +752,21 @@ Foam::Map<Foam::label> Foam::surfaceFeatures::nearestSamples ( const labelList& pointLabels, const pointField& samples, - const scalarField& maxDist + const scalarField& maxDistSqr ) const { // Build tree out of all samples. - //Note: cannot be done one the fly - gcc4.4 compiler bug. + // Note: cannot be done one the fly - gcc4.4 compiler bug. treeBoundBox bb(samples); - octree<octreeDataPoint> ppTree + indexedOctree<treeDataPoint> ppTree ( - bb, // overall search domain - octreeDataPoint(samples), // all information needed to do checks - 1, // min levels - 20.0, // maximum ratio of cubes v.s. cells - 100.0 // max. duplicity; n/a since no bounding boxes. + treeDataPoint(samples), // all information needed to do checks + bb, // overall search domain + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity ); // From patch point to surface point @@ -780,31 +780,23 @@ Foam::Map<Foam::label> Foam::surfaceFeatures::nearestSamples const point& surfPt = surfPoints[surfPointI]; - point maxDistPt(maxDist[i], maxDist[i], maxDist[i]); - - treeBoundBox tightest(surfPt - maxDistPt, surfPt + maxDistPt); - scalar tightestDist = Foam::GREAT; - - label sampleI = ppTree.findNearest + pointIndexHit info = ppTree.findNearest ( surfPt, - tightest, - tightestDist + maxDistSqr[i] ); - if (sampleI == -1) + if (!info.hit()) { FatalErrorIn("surfaceFeatures::nearestSamples") << "Problem for point " - << surfPointI << " in tree " << ppTree.octreeBb() + << surfPointI << " in tree " << ppTree.bb() << abort(FatalError); } - if - ( - magSqr(samples[sampleI] - surfPt) - < Foam::sqr(maxDist[sampleI]) - ) + label sampleI = info.index(); + + if (magSqr(samples[sampleI] - surfPt) < maxDistSqr[sampleI]) { nearest.insert(sampleI, surfPointI); } @@ -845,26 +837,25 @@ Foam::Map<Foam::label> Foam::surfaceFeatures::nearestSamples const labelList& selectedEdges, const pointField& samples, const scalarField& sampleDist, - const scalarField& maxDist, + const scalarField& maxDistSqr, const scalar minSampleDist ) const { const pointField& surfPoints = surf_.localPoints(); const edgeList& surfEdges = surf_.edges(); - scalar maxSearch = max(maxDist); - vector span(maxSearch, maxSearch, maxSearch); + scalar maxSearchSqr = max(maxDistSqr); //Note: cannot be done one the fly - gcc4.4 compiler bug. treeBoundBox bb(samples); - octree<octreeDataPoint> ppTree + indexedOctree<treeDataPoint> ppTree ( + treeDataPoint(samples), // all information needed to do checks bb, // overall search domain - octreeDataPoint(samples), // all information needed to do checks - 1, // min levels - 20.0, // maximum ratio of cubes v.s. cells - 100.0 // max. duplicity; n/a since no bounding boxes. + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity ); // From patch point to surface edge. @@ -902,22 +893,21 @@ Foam::Map<Foam::label> Foam::surfaceFeatures::nearestSamples { point edgePoint(surfPoints[e.start()] + s*eVec); - treeBoundBox tightest(edgePoint - span, edgePoint + span); - scalar tightestDist = Foam::GREAT; - - label sampleI = ppTree.findNearest + pointIndexHit info = ppTree.findNearest ( edgePoint, - tightest, - tightestDist + maxSearchSqr ); - if (sampleI == -1) + if (!info.hit()) { // No point close enough to surface edge. break; } - if (tightestDist < maxDist[sampleI]) + + label sampleI = info.index(); + + if (magSqr(info.hitPoint() - edgePoint) < maxDistSqr[sampleI]) { nearest.insert(sampleI, surfEdgeI); } @@ -985,31 +975,30 @@ Foam::Map<Foam::pointIndexHit> Foam::surfaceFeatures::nearestEdges const labelList& selectedSampleEdges, const pointField& samplePoints, const scalarField& sampleDist, - const scalarField& maxDist, + const scalarField& maxDistSqr, const scalar minSampleDist ) const { // Build tree out of selected sample edges. - octree<octreeDataEdges> ppTree + indexedOctree<treeDataEdge> ppTree ( - treeBoundBox(samplePoints), // overall search domain - octreeDataEdges + treeDataEdge ( + false, sampleEdges, samplePoints, selectedSampleEdges ), // geometric info container for edges - 1, // min levels - 20.0, // maximum ratio of cubes v.s. cells - 10.0 // max. duplicity + treeBoundBox(samplePoints), // overall search domain + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity ); const pointField& surfPoints = surf_.localPoints(); const edgeList& surfEdges = surf_.edges(); - scalar maxSearch = max(maxDist); - vector span(maxSearch, maxSearch, maxSearch); - + scalar maxSearchSqr = max(maxDistSqr); Map<pointIndexHit> nearest(2*sampleEdges.size()); @@ -1050,27 +1039,25 @@ Foam::Map<Foam::pointIndexHit> Foam::surfaceFeatures::nearestEdges { point edgePoint(surfPoints[e.start()] + s*eVec); - treeBoundBox tightest(edgePoint - span, edgePoint + span); - scalar tightestDist = Foam::GREAT; - - label index = ppTree.findNearest + pointIndexHit info = ppTree.findNearest ( edgePoint, - tightest, - tightestDist + maxSearchSqr ); - if (index == -1) + if (!info.hit()) { // No edge close enough to surface edge. break; } + label index = info.index(); + label sampleEdgeI = ppTree.shapes().edgeLabels()[index]; const edge& e = sampleEdges[sampleEdgeI]; - if (tightestDist < maxDist[e.start()]) + if (magSqr(info.hitPoint() - edgePoint) < maxDistSqr[e.start()]) { nearest.insert ( @@ -1136,7 +1123,7 @@ void Foam::surfaceFeatures::nearestSurfEdge ( const labelList& selectedEdges, const pointField& samples, - const vector& searchSpan, // Search span + scalar searchSpanSqr, // Search span labelList& edgeLabel, labelList& edgeEndPoint, pointField& edgePoint @@ -1148,57 +1135,48 @@ void Foam::surfaceFeatures::nearestSurfEdge const pointField& localPoints = surf_.localPoints(); - octree<octreeDataEdges> ppTree + indexedOctree<treeDataEdge> ppTree ( - treeBoundBox(localPoints), // overall search domain - octreeDataEdges + treeDataEdge ( + false, surf_.edges(), localPoints, selectedEdges ), // all information needed to do geometric checks - 1, // min levels - 20.0, // maximum ratio of cubes v.s. cells - 10.0 // max. duplicity + treeBoundBox(localPoints), // overall search domain + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity ); - forAll(samples, i) { const point& sample = samples[i]; - treeBoundBox tightest(sample - searchSpan, sample + searchSpan); - - scalar tightestDist = magSqr(searchSpan); - - label index = - ppTree.findNearest - ( - sample, - tightest, - tightestDist - ); - + pointIndexHit info = ppTree.findNearest + ( + sample, + searchSpanSqr + ); - if (index == -1) + if (!info.hit()) { edgeLabel[i] = -1; } else { - edgeLabel[i] = selectedEdges[index]; + edgeLabel[i] = selectedEdges[info.index()]; - // Unfortunately findNearest does not return nearest point so - // recalculate + // Need to recalculate to classify edgeEndPoint const edge& e = surf_.edges()[edgeLabel[i]]; - pointIndexHit pHit = - edgeNearest - ( - localPoints[e.start()], - localPoints[e.end()], - sample - ); + pointIndexHit pHit = edgeNearest + ( + localPoints[e.start()], + localPoints[e.end()], + sample + ); edgePoint[i] = pHit.rawPoint(); edgeEndPoint[i] = pHit.index(); @@ -1226,22 +1204,21 @@ void Foam::surfaceFeatures::nearestSurfEdge pointOnEdge.setSize(selectedSampleEdges.size()); pointOnFeature.setSize(selectedSampleEdges.size()); - - octree<octreeDataEdges> ppTree + indexedOctree<treeDataEdge> ppTree ( - treeBoundBox(surf_.localPoints()), // overall search domain - octreeDataEdges + treeDataEdge ( + false, surf_.edges(), surf_.localPoints(), selectedEdges ), // all information needed to do geometric checks - 1, // min levels - 10.0, // maximum ratio of cubes v.s. cells - 10.0 // max. duplicity + treeBoundBox(surf_.localPoints()), // overall search domain + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity ); - forAll(selectedSampleEdges, i) { const edge& e = sampleEdges[selectedSampleEdges[i]]; @@ -1252,23 +1229,22 @@ void Foam::surfaceFeatures::nearestSurfEdge treeBoundBox tightest(eMid - searchSpan, eMid + searchSpan); - label index = - ppTree.findNearest - ( - edgeLine, - tightest, - pointOnEdge[i], - pointOnFeature[i] - ); - + pointIndexHit info = ppTree.findNearest + ( + edgeLine, + tightest, + pointOnEdge[i] + ); - if (index == -1) + if (!info.hit()) { edgeLabel[i] = -1; } else { - edgeLabel[i] = featureEdges_[index]; + edgeLabel[i] = selectedEdges[info.index()]; + + pointOnFeature[i] = info.hitPoint(); } } } diff --git a/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.H b/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.H index 60e9c470859f977ff99da9d6a34fbbaf5fb61259..a12fc0f76158ca93a4b762b8fbe6ec85cba23f73 100644 --- a/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.H +++ b/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.H @@ -268,28 +268,30 @@ public: // Find - //- Find nearest sample for selected surface points (usually the - // set of featurePoints). Return map from index in - // samples to surface point. Do not include points that are further - // than maxDist away (separate maxDist for every sample) + //- Find nearest sample for selected surface points + // (usually the set of featurePoints). Return map from + // index in samples to surface point. Do not include + // points that are further than maxDist away (separate + // maxDist for every sample). Supply maxDistSqr. Map<label> nearestSamples ( const labelList& selectedPoints, const pointField& samples, - const scalarField& maxDist + const scalarField& maxDistSqr ) const; - //- Find nearest sample for regularly sampled points along the - // selected (surface) edges. Return map from sample to edge. - // maxDist is distance below which gets snapped. - // Edge gets sampled at points sampleDist[sampleI] apart. - // (with a maximum of 10 samples per edge) + //- Find nearest sample for regularly sampled points along + // the selected (surface) edges. Return map from sample + // to edge. maxDistSqr is distance squared below which + // gets snapped. Edge gets sampled at points + // sampleDist[sampleI] apart. (with a maximum of 10 + // samples per edge) Map<label> nearestSamples ( const labelList& selectedEdges, const pointField& samples, const scalarField& sampleDist, - const scalarField& maxDist, + const scalarField& maxDistSqr, const scalar minSampleDist = 0.1 ) const; @@ -303,7 +305,7 @@ public: const labelList& selectedSampleEdges, const pointField& samplePoints, const scalarField& sampleDist, - const scalarField& maxDist, + const scalarField& maxDistSqr, const scalar minSampleDist = 0.1 ) const; @@ -319,7 +321,7 @@ public: ( const labelList& selectedEdges, const pointField& samples, - const vector& searchSpan, // search span + scalar searchSpanSqr, // search span labelList& edgeLabel, labelList& edgeEndPoint, pointField& edgePoint diff --git a/src/parallel/reconstruct/reconstruct/Make/options b/src/parallel/reconstruct/reconstruct/Make/options index 71546225cf549de3ffb95105271396bf163a8dfc..7a728f9dd7cf75800c9b44943a2964c781376576 100644 --- a/src/parallel/reconstruct/reconstruct/Make/options +++ b/src/parallel/reconstruct/reconstruct/Make/options @@ -1,7 +1,9 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude LIB_LIBS = \ -lfiniteVolume \ + -lmeshTools \ -llagrangian diff --git a/src/parallel/reconstruct/reconstruct/reconstructLagrangianPositions.C b/src/parallel/reconstruct/reconstruct/reconstructLagrangianPositions.C index d6e84638b99a1faa24ab5e7c9aa0c265c71134d1..2e001de610f1e3511e7ce6d0a895065085f821dc 100644 --- a/src/parallel/reconstruct/reconstruct/reconstructLagrangianPositions.C +++ b/src/parallel/reconstruct/reconstruct/reconstructLagrangianPositions.C @@ -50,19 +50,27 @@ void Foam::reconstructLagrangianPositions { const labelList& cellMap = cellProcAddressing[i]; + // faceProcAddressing not required currently. + // const labelList& faceMap = faceProcAddressing[i]; + Cloud<passiveParticle> lpi(meshes[i], cloudName, false); forAllConstIter(Cloud<passiveParticle>, lpi, iter) { const passiveParticle& ppi = iter(); + // // Inverting sign if necessary and subtracting 1 from + // // faceProcAddressing + // label mappedTetFace = mag(faceMap[ppi.tetFace()]) - 1; + lagrangianPositions.append ( new passiveParticle ( lagrangianPositions, ppi.position(), - cellMap[ppi.cell()] + cellMap[ppi.cell()], + false ) ); } diff --git a/src/postProcessing/functionObjects/field/streamLine/streamLine.C b/src/postProcessing/functionObjects/field/streamLine/streamLine.C index ebe01f1e8b48bbdf9f9e55cd425bbc20020efce1..8336fd8f9a9144b8f3465e144421547b81b63a1a 100644 --- a/src/postProcessing/functionObjects/field/streamLine/streamLine.C +++ b/src/postProcessing/functionObjects/field/streamLine/streamLine.C @@ -56,6 +56,7 @@ void Foam::streamLine::track() //Pout<< "Seeding particles." << endl; const sampledSet& seedPoints = sampledSetPtr_(); + forAll(seedPoints, i) { //Pout<< "Seeded particle at " << seedPoints[i] @@ -73,10 +74,10 @@ void Foam::streamLine::track() ) ); } + label nSeeds = returnReduce(particles.size(), sumOp<label>()); - Info<< "Seeded " << nSeeds - << " particles." << endl; + Info<< "Seeded " << nSeeds << " particles." << endl; // Read or lookup fields PtrList<volScalarField> vsFlds; @@ -84,7 +85,6 @@ void Foam::streamLine::track() PtrList<volVectorField> vvFlds; PtrList<interpolationCellPoint<vector> > vvInterp; - label UIndex = -1; if (loadFromFiles_) @@ -188,7 +188,6 @@ void Foam::streamLine::track() vectorNames_[i] = vvInterp[i].psi().name(); } - // Check that we know the index of U in the interpolators. if (UIndex == -1) @@ -202,8 +201,6 @@ void Foam::streamLine::track() << exit(FatalError); } - - // Sampled data // ~~~~~~~~~~~~ @@ -490,7 +487,6 @@ void Foam::streamLine::write() mkDir(vtkPath); - // Convert track positions PtrList<coordSet> tracks(allTracks_.size()); @@ -508,8 +504,6 @@ void Foam::streamLine::write() tracks[trackI].transfer(allTracks_[trackI]); } - - // Convert scalar values if (allScalars_.size() > 0) diff --git a/src/postProcessing/functionObjects/field/streamLine/streamLineParticle.C b/src/postProcessing/functionObjects/field/streamLine/streamLineParticle.C index 01d092c5ada24fb7c3a6c1ffeb9ee42083443689..78478222cb52c88e93e03e5806ed9c612fda08d3 100644 --- a/src/postProcessing/functionObjects/field/streamLine/streamLineParticle.C +++ b/src/postProcessing/functionObjects/field/streamLine/streamLineParticle.C @@ -88,11 +88,11 @@ Foam::streamLineParticle::streamLineParticle ( const Cloud<streamLineParticle>& c, const vector& position, - const label celli, + const label cellI, const label lifeTime ) : - Particle<streamLineParticle>(c, position, celli), + Particle<streamLineParticle>(c, position, cellI), lifeTime_(lifeTime) {} @@ -246,7 +246,9 @@ bool Foam::streamLineParticle::hitPatch ( const polyPatch&, streamLineParticle::trackData& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ) { // Disable generic patch interaction @@ -258,7 +260,9 @@ bool Foam::streamLineParticle::hitPatch ( const polyPatch&, int&, - const label + const label, + const scalar, + const tetIndices& ) { // Disable generic patch interaction @@ -345,7 +349,8 @@ void Foam::streamLineParticle::hitProcessorPatch void Foam::streamLineParticle::hitWallPatch ( const wallPolyPatch& wpp, - streamLineParticle::trackData& td + streamLineParticle::trackData& td, + const tetIndices& ) { // Remove particle @@ -356,7 +361,8 @@ void Foam::streamLineParticle::hitWallPatch void Foam::streamLineParticle::hitWallPatch ( const wallPolyPatch& wpp, - int& + int&, + const tetIndices& ) {} diff --git a/src/postProcessing/functionObjects/field/streamLine/streamLineParticle.H b/src/postProcessing/functionObjects/field/streamLine/streamLineParticle.H index eceb8a3f88e3c432595e42b51dc2cf3e201626c7..d556e4791decf15ab076f885143fe1adb7b3f1d1 100644 --- a/src/postProcessing/functionObjects/field/streamLine/streamLineParticle.H +++ b/src/postProcessing/functionObjects/field/streamLine/streamLineParticle.H @@ -141,7 +141,7 @@ public: ( const Cloud<streamLineParticle>& c, const vector& position, - const label celli, + const label cellI, const label lifeTime ); @@ -182,13 +182,18 @@ public: ( const polyPatch&, streamLineParticle::trackData& td, - const label patchI + const label patchI, + const scalar trackFraction, + const tetIndices& tetIs ); + bool hitPatch ( const polyPatch&, int&, - const label patchI + const label, + const scalar, + const tetIndices& ); //- Overridable function to handle the particle hitting a wedge @@ -245,12 +250,14 @@ public: void hitWallPatch ( const wallPolyPatch&, - streamLineParticle::trackData& td + streamLineParticle::trackData& td, + const tetIndices& ); void hitWallPatch ( const wallPolyPatch&, - int& + int&, + const tetIndices& ); //- Overridable function to handle the particle hitting a polyPatch diff --git a/src/postProcessing/functionObjects/forces/pointPatchFields/derived/sixDoFRigidBodyMotion/sixDoFRigidBodyMotion.C b/src/postProcessing/functionObjects/forces/pointPatchFields/derived/sixDoFRigidBodyMotion/sixDoFRigidBodyMotion.C index ed1e524bf6885545131d5fc1883ee8fb609ab357..1ab6cada871d4d2cc1792ce358219ffaba495129 100644 --- a/src/postProcessing/functionObjects/forces/pointPatchFields/derived/sixDoFRigidBodyMotion/sixDoFRigidBodyMotion.C +++ b/src/postProcessing/functionObjects/forces/pointPatchFields/derived/sixDoFRigidBodyMotion/sixDoFRigidBodyMotion.C @@ -374,7 +374,6 @@ void Foam::sixDoFRigidBodyMotion::updatePosition centreOfMass() += deltaT*v(); // Leapfrog orientation adjustment - rotate(Q(), pi(), deltaT); } diff --git a/src/postProcessing/functionObjects/forces/pointPatchFields/derived/sixDoFRigidBodyMotion/sixDoFRigidBodyMotionRestraint/linearSpring/linearSpring.C b/src/postProcessing/functionObjects/forces/pointPatchFields/derived/sixDoFRigidBodyMotion/sixDoFRigidBodyMotionRestraint/linearSpring/linearSpring.C index ffab7cc17e2757330dd8230d062549afb74dae16..7185e9784e71bf6df8e476fc8e12c0aa89b8ec6a 100644 --- a/src/postProcessing/functionObjects/forces/pointPatchFields/derived/sixDoFRigidBodyMotion/sixDoFRigidBodyMotionRestraint/linearSpring/linearSpring.C +++ b/src/postProcessing/functionObjects/forces/pointPatchFields/derived/sixDoFRigidBodyMotion/sixDoFRigidBodyMotionRestraint/linearSpring/linearSpring.C @@ -96,7 +96,7 @@ void Foam::sixDoFRigidBodyMotionRestraints::linearSpring::restrain if (motion.report()) { - Info<< " attachmentPt - anchor " << r + Info<< " attachmentPt - anchor " << r*magR << " spring length " << magR << " force " << restraintForce << " moment " << restraintMoment diff --git a/src/sampling/Make/options b/src/sampling/Make/options index 6629b3652c02317e37610ccc87b5ce0afcf52ca6..0e2c6780d2b4052888e065a1c709958c652c52b6 100644 --- a/src/sampling/Make/options +++ b/src/sampling/Make/options @@ -9,4 +9,5 @@ LIB_LIBS = \ -lfiniteVolume \ -lmeshTools \ -lsurfMesh \ - -ltriSurface + -ltriSurface \ + -llagrangian diff --git a/src/sampling/meshToMeshInterpolation/meshToMesh/calculateMeshToMeshAddressing.C b/src/sampling/meshToMeshInterpolation/meshToMesh/calculateMeshToMeshAddressing.C index 372ba4a1c63ffe1533e4b1d83ee28526e2cc1cd0..0248c41d30e6f03bb36b20c530318afeaaacfafe 100644 --- a/src/sampling/meshToMeshInterpolation/meshToMesh/calculateMeshToMeshAddressing.C +++ b/src/sampling/meshToMeshInterpolation/meshToMesh/calculateMeshToMeshAddressing.C @@ -31,9 +31,9 @@ Description #include "meshToMesh.H" #include "SubField.H" -#include "octree.H" -#include "octreeDataCell.H" -#include "octreeDataFace.H" +#include "indexedOctree.H" +#include "treeDataCell.H" +#include "treeDataFace.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -100,21 +100,18 @@ void Foam::meshToMesh::calcAddressing() Info<< " typical dimension :" << shiftedBb.typDim() << endl; } - // Wrap indices and mesh information into helper object - octreeDataCell shapes(fromMesh_); - - octree<octreeDataCell> oc + indexedOctree<treeDataCell> oc ( - shiftedBb, // overall bounding box - shapes, // all information needed to do checks on cells - 1, // min. levels - 10.0, // max. size of leaves - 10.0 // maximum ratio of cubes v.s. cells + treeDataCell(false, fromMesh_), + shiftedBb, // overall bounding box + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity ); if (debug) { - oc.printStats(Info); + oc.print(Pout, false, 0); } cellAddresses @@ -174,38 +171,29 @@ void Foam::meshToMesh::calcAddressing() wallBb.max() + vector(typDim, typDim, typDim) ); - // Wrap data for octree into container - octreeDataFace shapes(fromPatch); - - octree<octreeDataFace> oc + indexedOctree<treeDataFace> oc ( + treeDataFace(false, fromPatch), shiftedBb, // overall search domain - shapes, // all information needed to do checks on cells - 1, // min levels - 20.0, // maximum ratio of cubes v.s. cells - 2.0 + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity ); - const vectorField::subField centresToBoundary = toPatch.faceCentres(); boundaryAddressing_[patchi].setSize(toPatch.size()); - treeBoundBox tightest; - scalar tightestDist; + scalar distSqr = sqr(GREAT); forAll(toPatch, toi) { - tightest = wallBb; // starting search bb - tightestDist = Foam::GREAT; // starting max distance - boundaryAddressing_[patchi][toi] = oc.findNearest ( centresToBoundary[toi], - tightest, - tightestDist - ); + distSqr + ).index(); } } } @@ -225,7 +213,7 @@ void Foam::meshToMesh::cellAddresses const pointField& points, const fvMesh& fromMesh, const List<bool>& boundaryCell, - const octree<octreeDataCell>& oc + const indexedOctree<treeDataCell>& oc ) const { // the implemented search method is a simple neighbour array search. @@ -290,7 +278,7 @@ void Foam::meshToMesh::cellAddresses // the octree search to find it. if (boundaryCell[curCell]) { - cellAddressing_[toI] = oc.find(p); + cellAddressing_[toI] = oc.findInside(p); } else { @@ -342,7 +330,7 @@ void Foam::meshToMesh::cellAddresses if (!found) { // Still not found so us the octree - cellAddressing_[toI] = oc.find(p); + cellAddressing_[toI] = oc.findInside(p); } } } diff --git a/src/sampling/meshToMeshInterpolation/meshToMesh/meshToMesh.H b/src/sampling/meshToMeshInterpolation/meshToMesh/meshToMesh.H index 1edd13866ceebb2f5624a11cf0228e1dae95e150..a3e83a73e9b06287b0bdb63f9f853dc89f7593ba 100644 --- a/src/sampling/meshToMeshInterpolation/meshToMesh/meshToMesh.H +++ b/src/sampling/meshToMeshInterpolation/meshToMesh/meshToMesh.H @@ -50,9 +50,9 @@ namespace Foam { template<class Type> -class octree; +class indexedOctree; -class octreeDataCell; +class treeDataCell; /*---------------------------------------------------------------------------*\ Class meshToMesh Declaration @@ -99,7 +99,7 @@ class meshToMesh const pointField& points, const fvMesh& fromMesh, const List<bool>& boundaryCell, - const octree<octreeDataCell>& oc + const indexedOctree<treeDataCell>& oc ) const; void calculateInverseDistanceWeights() const; diff --git a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C index fc5c31911e851d4b347b4c7d379f484077a9cb9d..b117a4b2916e8ce97efac2759b293093e53dc366 100644 --- a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C +++ b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C @@ -24,7 +24,6 @@ License \*---------------------------------------------------------------------------*/ #include "sampledTriSurfaceMesh.H" -#include "treeDataPoint.H" #include "meshSearch.H" #include "Tuple2.H" #include "globalIndex.H" diff --git a/src/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.C b/src/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.C index a1993a7e33ee92304f1b38afb04ba2b50cdae620..0d9db92f1f8587f8917ba84b7128ef4971c221c9 100644 --- a/src/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.C +++ b/src/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.C @@ -72,12 +72,14 @@ Foam::surfaceFilmModels::cloudInjection::~cloudInjection() // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -void Foam::surfaceFilmModels::cloudInjection::correct +void Foam::surfaceFilmModels::cloudInjection::inject ( scalarField& massToInject, scalarField& diameterToInject ) { + correctDetachedFilm(massToInject); + const scalar pi = constant::mathematical::pi; const scalarField& rhoFilm = owner().rho(); diff --git a/src/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.H b/src/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.H index 01c9f5eedb9c40790a99cf2094b97df362aeea23..53c42769d3b20733f22908e178150fe6a765800f 100644 --- a/src/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.H +++ b/src/surfaceFilmModels/submodels/kinematic/injectionModel/cloudInjection/cloudInjection.H @@ -101,8 +101,8 @@ public: // Evolution - //- Correct - virtual void correct + //- Inject + virtual void inject ( scalarField& massToInject, scalarField& diameterToInject diff --git a/src/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.C b/src/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.C index fe3e0d9e771fe5dd2da36118631639f466d03eb4..5e5d7e4077c396487c192046725d6266cdd969c9 100644 --- a/src/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.C +++ b/src/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.C @@ -24,6 +24,7 @@ License \*---------------------------------------------------------------------------*/ #include "injectionModel.H" +#include "kinematicSingleLayer.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -37,6 +38,35 @@ namespace Foam } +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::surfaceFilmModels::injectionModel::correctDetachedFilm +( + scalarField& mass +) const +{ + mass = 0.0; + + const kinematicSingleLayer& film = + refCast<const kinematicSingleLayer>(owner_); + + const scalarField gNorm = film.gNorm(); + const scalarField& delta = film.delta(); + const scalarField& rho = film.rho(); + const scalarField& magSf = film.magSf(); + const scalarField& massPhaseChange = film.massPhaseChangeForPrimary(); + + forAll(gNorm, i) + { + if (gNorm[i] > SMALL) + { + const scalar ddelta = max(0.0, delta[i] - deltaStable_); + mass[i] = max(0.0, ddelta*rho[i]*magSf[i] - massPhaseChange[i]); + } + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::surfaceFilmModels::injectionModel::injectionModel @@ -45,7 +75,8 @@ Foam::surfaceFilmModels::injectionModel::injectionModel ) : owner_(owner), - coeffs_(dictionary::null) + coeffs_(dictionary::null), + injectedMass_(0.0) {} @@ -57,7 +88,9 @@ Foam::surfaceFilmModels::injectionModel::injectionModel ) : owner_(owner), - coeffs_(dict.subDict(type + "Coeffs")) + coeffs_(dict.subDict(type + "Coeffs")), + injectedMass_(0.0), + deltaStable_(readScalar(coeffs_.lookup("deltaStable"))) {} @@ -67,4 +100,27 @@ Foam::surfaceFilmModels::injectionModel::~injectionModel() {} +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::surfaceFilmModels::injectionModel::correct +( + volScalarField& massToInject, + volScalarField& diameterToInject +) +{ + inject(massToInject, diameterToInject); + massToInject.correctBoundaryConditions(); + diameterToInject.correctBoundaryConditions(); + + injectedMass_ += sum(massToInject.internalField()); +} + + +void Foam::surfaceFilmModels::injectionModel::info() const +{ + Info<< indent << "injected mass = " + << returnReduce<scalar>(injectedMass_, sumOp<scalar>()) << nl; +} + + // ************************************************************************* // diff --git a/src/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.H b/src/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.H index 539184c74580e7a6559a5620e2c51a1b503dea0a..ca5b265101e616f086e85dbc870fb17eadb71cca 100644 --- a/src/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.H +++ b/src/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModel.H @@ -82,6 +82,18 @@ protected: //- Model coefficients dictionary dictionary coeffs_; + //- Cumulative injected mass + scalar injectedMass_; + + //- Stable film thickness - film cannot detach until reached + scalar deltaStable_; + + + // Protected Member Functions + + //- Correct film detached mass + void correctDetachedFilm(scalarField& mass) const; + public: @@ -141,15 +153,31 @@ public: //- Return the model coefficients dictionary inline const dictionary& coeffs() const; + //- Return access to the injected mass [kg] + inline scalar injectedMass() const; + // Evolution - //- Correct + //- Correct - wrapper around inject(...) virtual void correct + ( + volScalarField& massToInject, + volScalarField& diameterToInject + ); + + //- Inject + virtual void inject ( scalarField& massToInject, scalarField& diameterToInject ) = 0; + + + // Input/output + + //- Output model statistics + virtual void info() const; }; diff --git a/src/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModelI.H b/src/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModelI.H index 2f3bf02ef1d04796d3696eb760e5022f0b58ceed..13455cee7bed240cc8f0c469e853e9166aee2cf2 100644 --- a/src/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModelI.H +++ b/src/surfaceFilmModels/submodels/kinematic/injectionModel/injectionModel/injectionModelI.H @@ -41,4 +41,11 @@ Foam::surfaceFilmModels::injectionModel::coeffs() const } +inline Foam::scalar Foam::surfaceFilmModels::injectionModel::injectedMass() +const +{ + return injectedMass_; +} + + // ************************************************************************* // diff --git a/src/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.C b/src/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.C index f696f1a1bcda2974eac9f531fa682c9d1445918f..da8ee087f64bd83fc52defead6f4033ade5b2465 100644 --- a/src/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.C +++ b/src/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.C @@ -58,7 +58,7 @@ Foam::surfaceFilmModels::noInjection::~noInjection() // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -void Foam::surfaceFilmModels::noInjection::correct +void Foam::surfaceFilmModels::noInjection::inject ( scalarField& massToInject, scalarField& diameterToInject @@ -66,6 +66,7 @@ void Foam::surfaceFilmModels::noInjection::correct { // no mass injected massToInject = 0.0; + diameterToInject = -1.0; } diff --git a/src/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.H b/src/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.H index 7b1446ebab431e44a811177fd70e9bd7971f5451..405b2ba0850a86b640a62ae20946151a3992a23f 100644 --- a/src/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.H +++ b/src/surfaceFilmModels/submodels/kinematic/injectionModel/noInjection/noInjection.H @@ -83,8 +83,8 @@ public: // Evolution - //- Correct - virtual void correct + //- Inject + virtual void inject ( scalarField& massToInject, scalarField& diameterToInject diff --git a/src/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.C b/src/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.C index 97d9bb00aae5dae4d48df16cfac7605235935da5..b7cf4d59529f50bc761da73bdb21f7d798de750c 100644 --- a/src/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.C +++ b/src/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.C @@ -58,13 +58,15 @@ Foam::surfaceFilmModels::removeInjection::~removeInjection() // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -void Foam::surfaceFilmModels::removeInjection::correct +void Foam::surfaceFilmModels::removeInjection::inject ( - scalarField&, - scalarField& + scalarField& massToInject, + scalarField& diameterToInject ) { - // do nothing - all mass available to be removed + // all mass available to be removed + correctDetachedFilm(massToInject); + diameterToInject = -1; } diff --git a/src/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.H b/src/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.H index 9c651560f826c2cd27b28c31c3d8e306b71fcaaa..c4b678e74cf5042837de92c44b9958b707802150 100644 --- a/src/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.H +++ b/src/surfaceFilmModels/submodels/kinematic/injectionModel/removeInjection/removeInjection.H @@ -83,8 +83,8 @@ public: // Evolution - //- Correct - virtual void correct + //- Inject + virtual void inject ( scalarField& massToInject, scalarField& diameterToInject diff --git a/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.C b/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.C index 8e023485b5bec24e7ad3de46382fa68c89a59e5e..99691237dc5ecdbfc0fc6e12875359d285281962 100644 --- a/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.C +++ b/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.C @@ -69,4 +69,10 @@ void Foam::surfaceFilmModels::noPhaseChange::correct } +void Foam::surfaceFilmModels::noPhaseChange::info() const +{ + // do nothing +} + + // ************************************************************************* // diff --git a/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.H b/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.H index e75a9f78c4a8ff306fba9e2702c22957da3f9f2c..e29cc4df4ae5ba3ef6ec4240611361bd9681accd 100644 --- a/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.H +++ b/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/noPhaseChange/noPhaseChange.H @@ -90,6 +90,12 @@ public: scalarField& dMass, scalarField& dEnergy ); + + + // Input/output + + //- Output model statistics + virtual void info() const; }; diff --git a/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/phaseChangeModel/phaseChangeModel.H b/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/phaseChangeModel/phaseChangeModel.H index 63f0c227c1951efcf52dec6377fb90637cb7a80d..716f010e10dd9cc57c5580a770a255a3b1a4926a 100644 --- a/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/phaseChangeModel/phaseChangeModel.H +++ b/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/phaseChangeModel/phaseChangeModel.H @@ -143,6 +143,12 @@ public: scalarField& dMass, scalarField& dEnergy ) = 0; + + + // Input/output + + //- Output model statistics + virtual void info() const = 0; }; diff --git a/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.C b/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.C index 4619a4a76a8825b3703de162226fddd2d6856191..df0eb7712ee16d53bb54aedece9674d5bab26416 100644 --- a/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.C +++ b/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.C @@ -74,8 +74,11 @@ Foam::surfaceFilmModels::standardPhaseChange::standardPhaseChange ) : phaseChangeModel(typeName, owner, dict), + Tb_(readScalar(coeffs_.lookup("Tb"))), deltaMin_(readScalar(coeffs_.lookup("deltaMin"))), - L_(readScalar(coeffs_.lookup("L"))) + L_(readScalar(coeffs_.lookup("L"))), + totalMass_(0.0), + vapourRate_(0.0) {} @@ -94,6 +97,9 @@ void Foam::surfaceFilmModels::standardPhaseChange::correct scalarField& dEnergy ) { + dMass = 0.0; + dEnergy = 0.0; + const thermoSingleLayer& film = refCast<const thermoSingleLayer>(owner_); // set local thermo properties @@ -107,76 +113,102 @@ void Foam::surfaceFilmModels::standardPhaseChange::correct const scalarField& YInf = film.YPrimary()[vapId]; const scalarField& pInf = film.pPrimary(); const scalarField& T = film.T(); - const scalarField& Ts = film.Ts(); const scalarField& Tw = film.Tw(); - const scalarField& TInf = film.TPrimary(); const scalarField& rho = film.rho(); - const scalarField& mu = film.mu(); + const scalarField& TInf = film.TPrimary(); + const scalarField& rhoInf = film.rhoPrimary(); + const scalarField& muInf = film.muPrimary(); const scalarField& magSf = film.magSf(); const scalarField hInf = film.htcs().h(); const scalarField hFilm = film.htcw().h(); const vectorField dU = film.UPrimary() - film.Us(); - const scalarField availableMass = delta*rho*magSf; - - // Reynolds number - const scalarField Re = rho*mag(dU)*L_/mu; - - // molecular weight of vapour - const scalar Wvap = thermo.carrier().W(vapId); + const scalarField availableMass = (delta - deltaMin_)*rho*magSf; - // molecular weight of liquid - const scalar Wliq = liq.W(); forAll(dMass, cellI) { if (delta[cellI] > deltaMin_) { - // cell pressure + // cell pressure [Pa] const scalar pc = pInf[cellI]; - // saturation pressure - const scalar pSat = liq.pv(pc, Ts[cellI]); + // local temperature - impose lower limit of 200 K for stability + const scalar Tloc = min(liq.Tc(), max(200.0, T[cellI])); - // latent heat - const scalar hVap = liq.hl(pc, Ts[cellI]); + // saturation pressure [Pa] + const scalar pSat = liq.pv(pc, Tloc); + + // latent heat [J/kg] + const scalar hVap = liq.hl(pc, Tloc); // calculate mass transfer - if (pSat > pc) + if (pSat >= 0.95*pc) { // boiling const scalar qDotInf = hInf[cellI]*(TInf[cellI] - T[cellI]); const scalar qDotFilm = hFilm[cellI]*(T[cellI] - Tw[cellI]); - dMass[cellI] = dt*magSf[cellI]/hVap*(qDotInf - qDotFilm); + + const scalar cp = liq.cp(pc, Tloc); + const scalar qCorr = availableMass[cellI]*cp*(T[cellI] - Tb_); + dMass[cellI] = + dt*magSf[cellI]/hVap*(qDotInf + qDotFilm) + + qCorr/hVap; + } else { + // Primary region density [kg/m3] + const scalar rhoInfc = rhoInf[cellI]; + + // Primary region viscosity [Pa.s] + const scalar muInfc = muInf[cellI]; + + // Reynolds number + const scalar Re = rhoInfc*mag(dU[cellI])*L_/muInfc; + + // molecular weight of vapour [kg/kmol] + const scalar Wvap = thermo.carrier().W(vapId); + + // molecular weight of liquid [kg/kmol] + const scalar Wliq = liq.W(); + // vapour mass fraction at interface const scalar Ys = Wliq*pSat/(Wliq*pSat + Wvap*(pc - pSat)); - // bulk gas average density - const scalar rhoAve = pc/(specie::RR*Ts[cellI]); - // vapour diffusivity [m2/s] - const scalar Dab = liq.D(pc, Ts[cellI]); + const scalar Dab = liq.D(pc, Tloc); // Schmidt number - const scalar Sc = mu[cellI]/(rho[cellI]*(Dab + ROOTVSMALL)); + const scalar Sc = muInfc/(rhoInfc*(Dab + ROOTVSMALL)); // Sherwood number - const scalar Sh = this->Sh(Re[cellI], Sc); + const scalar Sh = this->Sh(Re, Sc); // mass transfer coefficient [m/s] const scalar hm = Sh*Dab/L_; // add mass contribution to source dMass[cellI] = - dt*magSf[cellI]*rhoAve*hm*(Ys - YInf[cellI])/(1.0 - Ys); + dt*magSf[cellI]*rhoInfc*hm*(Ys - YInf[cellI])/(1.0 - Ys); } dMass[cellI] = min(availableMass[cellI], max(0.0, dMass[cellI])); dEnergy[cellI] = dMass[cellI]*hVap; } } + + const scalar sumdMass = sum(dMass); + totalMass_ += sumdMass; + vapourRate_ = sumdMass/owner().time().deltaTValue(); +} + + +void Foam::surfaceFilmModels::standardPhaseChange::info() const +{ + Info<< indent << "mass phase change = " + << returnReduce(totalMass_, sumOp<scalar>()) << nl + << indent << "vapourisation rate = " + << returnReduce(vapourRate_, sumOp<scalar>()) << nl; } diff --git a/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.H b/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.H index 726f36e2cc9f16fc3e5a213f6fdd832db303603d..bb9e69e4c62511ca1d317bf714b181125c156c81 100644 --- a/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.H +++ b/src/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.H @@ -67,12 +67,21 @@ protected: // Protected data + //- Boiling temperature / [K] + const scalar Tb_; + //- Minimum film height for model to be active const scalar deltaMin_; - //- Length scalae / [m] + //- Length scale / [m] const scalar L_; + //- Total mass evolved / [kg] + scalar totalMass_; + + //- Vapouristaion rate / kg/s + scalar vapourRate_; + // Protected member functions @@ -111,6 +120,12 @@ public: scalarField& dMass, scalarField& dEnergy ); + + + // Input/output + + //- Output model statistics + virtual void info() const; }; diff --git a/src/surfaceFilmModels/surfaceFilmModel/kinematicSingleLayer/kinematicSingleLayer.C b/src/surfaceFilmModels/surfaceFilmModel/kinematicSingleLayer/kinematicSingleLayer.C index bbba0b5371662a9385fe8b7557674bdce1d99a2c..5655c4b6e9e7f26a311257adefbf88bc55f6b68d 100644 --- a/src/surfaceFilmModels/surfaceFilmModel/kinematicSingleLayer/kinematicSingleLayer.C +++ b/src/surfaceFilmModels/surfaceFilmModel/kinematicSingleLayer/kinematicSingleLayer.C @@ -59,15 +59,12 @@ bool Foam::surfaceFilmModels::kinematicSingleLayer::read() { if (surfaceFilmModel::read()) { - const dictionary& solution = - filmRegion_.solutionDict().subDict("PISO"); - solution.lookup("momentumPredictor") >> momentumPredictor_; - solution.lookup("nOuterCorr") >> nOuterCorr_; - solution.lookup("nCorr") >> nCorr_; - solution.lookup("nNonOrthCorr") >> nNonOrthCorr_; + solution().lookup("momentumPredictor") >> momentumPredictor_; + solution().lookup("nOuterCorr") >> nOuterCorr_; + solution().lookup("nCorr") >> nCorr_; + solution().lookup("nNonOrthCorr") >> nNonOrthCorr_; coeffs_.lookup("Cf") >> Cf_; - coeffs_.lookup("deltaStable") >> deltaStable_; return true; } @@ -184,7 +181,7 @@ void Foam::surfaceFilmModels::kinematicSingleLayer::correctThermoFields() FatalErrorIn ( "void Foam::surfaceFilmModels::kinematicSingleLayer::" - "correctThermo()" + "correctThermoFields()" ) << "Kinematic surface film must use " << thermoModelTypeNames_[thermoModel_] << "thermodynamics" << endl; } @@ -203,10 +200,12 @@ resetPrimaryRegionSourceTerms() void Foam::surfaceFilmModels::kinematicSingleLayer:: transferPrimaryRegionFields() { - // Update pressure and velocity from primary region via direct mapped + // Update fields from primary region via direct mapped // (coupled) boundary conditions UPrimary_.correctBoundaryConditions(); pPrimary_.correctBoundaryConditions(); + rhoPrimary_.correctBoundaryConditions(); + muPrimary_.correctBoundaryConditions(); // Retrieve the source fields from the primary region via direct mapped // (coupled) boundary conditions @@ -269,47 +268,14 @@ Foam::surfaceFilmModels::kinematicSingleLayer::pp() } -void Foam::surfaceFilmModels::kinematicSingleLayer::correctDetachedFilm() -{ - massForPrimary_ == dimensionedScalar("zero", dimMass, 0.0); - diametersForPrimary_ == dimensionedScalar("zero", dimLength, -1.0); - - const scalarField gNorm = this->gNorm(); - - forAll(gNorm, i) - { - if (gNorm[i] > SMALL) - { - scalar ddelta = max(0.0, delta_[i] - deltaStable_.value()); - massForPrimary_[i] = - max - ( - 0.0, - ddelta*rho_[i]*magSf_[i] - massPhaseChangeForPrimary_[i] - ); - } - } -} - - void Foam::surfaceFilmModels::kinematicSingleLayer::updateSubmodels() { - correctDetachedFilm(); - // Update injection model - mass returned is actual mass injected injection_->correct(massForPrimary_, diametersForPrimary_); - // Update cumulative detached mass counter - detachedMass_ += sum(massForPrimary_.field()); - - // Push values to boundaries ready for transfer to the primary region - massForPrimary_.correctBoundaryConditions(); - diametersForPrimary_.correctBoundaryConditions(); - // Update source fields const dimensionedScalar deltaT = time_.deltaT(); - rhoSp_ -= massForPrimary_/magSf_/deltaT; - USp_ -= massForPrimary_*U_/magSf_/deltaT; + rhoSp_ -= (massForPrimary_ + massPhaseChangeForPrimary_)/magSf_/deltaT; } @@ -448,6 +414,12 @@ Foam::surfaceFilmModels::kinematicSingleLayer::solveMomentum updateSurfaceVelocities(); + volScalarField mLossCoeff + ( + "mLossCoeff", + (massForPrimary_ + massPhaseChangeForPrimary_)/magSf_/time_.deltaT() + ); + // Momentum tmp<fvVectorMatrix> tUEqn ( @@ -457,6 +429,7 @@ Foam::surfaceFilmModels::kinematicSingleLayer::solveMomentum USp_ + tau(U_) + fvc::grad(sigma_) + + fvm::SuSp(-mLossCoeff, U_) ); fvVectorMatrix& UEqn = tUEqn(); @@ -604,7 +577,7 @@ Foam::surfaceFilmModels::kinematicSingleLayer::kinematicSingleLayer time_.timeName(), filmRegion_, IOobject::NO_READ, - IOobject::NO_WRITE + IOobject::AUTO_WRITE ), filmRegion_, dimensionedVector("zero", dimless, vector::zero), @@ -618,7 +591,7 @@ Foam::surfaceFilmModels::kinematicSingleLayer::kinematicSingleLayer time_.timeName(), filmRegion_, IOobject::NO_READ, - IOobject::NO_WRITE + IOobject::AUTO_WRITE ), filmRegion_, dimensionedScalar("zero", dimArea, 0.0), @@ -628,32 +601,13 @@ Foam::surfaceFilmModels::kinematicSingleLayer::kinematicSingleLayer filmTopPatchIDs_(0), filmBottomPatchIDs_(0), - momentumPredictor_ - ( - filmRegion_.solutionDict().subDict("PISO").lookup("momentumPredictor") - ), - nOuterCorr_ - ( - readLabel - ( - filmRegion_.solutionDict().subDict("PISO").lookup("nOuterCorr") - ) - ), - nCorr_ - ( - readLabel(filmRegion_.solutionDict().subDict("PISO").lookup("nCorr")) - ), - nNonOrthCorr_ - ( - readLabel - ( - filmRegion_.solutionDict().subDict("PISO").lookup("nNonOrthCorr") - ) - ), + momentumPredictor_(solution().lookup("momentumPredictor")), + nOuterCorr_(readLabel(solution().lookup("nOuterCorr"))), + nCorr_(readLabel(solution().lookup("nCorr"))), + nNonOrthCorr_(readLabel(solution().lookup("nNonOrthCorr"))), cumulativeContErr_(0.0), Cf_(readScalar(coeffs_.lookup("Cf"))), - deltaStable_(coeffs_.lookup("deltaStable")), initialisedThermo_(false), rho_ @@ -817,7 +771,7 @@ Foam::surfaceFilmModels::kinematicSingleLayer::kinematicSingleLayer IOobject::NO_WRITE ), filmRegion_, - dimensionedScalar("zero", dimMass, 0), + dimensionedScalar("zero", dimMass, 0.0), zeroGradientFvPatchScalarField::typeName ), @@ -924,11 +878,38 @@ Foam::surfaceFilmModels::kinematicSingleLayer::kinematicSingleLayer ), filmRegion_ ), + rhoPrimary_ + ( + IOobject + ( + "rho", // must have same name as rho to enable mapping + time_.timeName(), + filmRegion_, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + filmRegion_, + dimensionedScalar("zero", dimDensity, 0.0), + pPrimary_.boundaryField().types() + ), + muPrimary_ + ( + IOobject + ( + "mu", // must have same name as mu to enable mapping + time_.timeName(), + filmRegion_, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + filmRegion_, + dimensionedScalar("zero", dimPressure*dimTime, 0.0), + pPrimary_.boundaryField().types() + ), injection_(injectionModel::New(*this, coeffs_)), - addedMass_(0.0), - detachedMass_(0.0) + addedMass_(0.0) { initialise(); } @@ -1187,23 +1168,23 @@ void Foam::surfaceFilmModels::kinematicSingleLayer::info() const // Output Courant number for info only - does not change time step CourantNumber(); - Info<< indent << "added mass = " + Info<< indent << "added mass = " << returnReduce<scalar>(addedMass_, sumOp<scalar>()) << nl - << indent << "current mass = " + << indent << "current mass = " << gSum((deltaRho_*magSf_)()) << nl - << indent << "detached mass = " - << returnReduce<scalar>(detachedMass_, sumOp<scalar>()) << nl - << indent << "min/max(mag(U)) = " << min(mag(U_)).value() << ", " + << indent << "min/max(mag(U)) = " << min(mag(U_)).value() << ", " << max(mag(U_)).value() << nl - << indent << "min/max(delta) = " << min(delta_).value() << ", " + << indent << "min/max(delta) = " << min(delta_).value() << ", " << max(delta_).value() << nl; + + injection_->info(); } Foam::tmp<Foam::DimensionedField<Foam::scalar, Foam::volMesh> > Foam::surfaceFilmModels::kinematicSingleLayer::Srho() const { - tmp<DimensionedField<scalar, volMesh> > tSrho + return tmp<DimensionedField<scalar, volMesh> > ( new DimensionedField<scalar, volMesh> ( @@ -1220,38 +1201,6 @@ Foam::surfaceFilmModels::kinematicSingleLayer::Srho() const dimensionedScalar("zero", dimMass/dimVolume/dimTime, 0.0) ) ); - - scalarField& Srho = tSrho(); - const scalarField& V = mesh_.V(); - const scalar dt = time_.deltaTValue(); - - forAll(filmBottomPatchIDs_, i) - { - const label primaryPatchI = primaryPatchIDs_[i]; - const directMappedWallPolyPatch& wpp = - refCast<const directMappedWallPolyPatch> - ( - mesh_.boundaryMesh()[primaryPatchI] - ); - - const mapDistribute& distMap = wpp.map(); - - const label filmPatchI = filmBottomPatchIDs_[i]; - - scalarField patchMass = - massPhaseChangeForPrimary().boundaryField()[filmPatchI]; - - distMap.distribute(patchMass); - - const unallocLabelList& cells = wpp.faceCells(); - - forAll(patchMass, j) - { - Srho[cells[j]] = patchMass[j]/(V[cells[j]]*dt); - } - } - - return tSrho; } diff --git a/src/surfaceFilmModels/surfaceFilmModel/kinematicSingleLayer/kinematicSingleLayer.H b/src/surfaceFilmModels/surfaceFilmModel/kinematicSingleLayer/kinematicSingleLayer.H index 89f83f5dd8b376cfe546bc9f1814e17496b11948..c6b1ed1b4e3a73b2ec89daa38b0f5c6771267859 100644 --- a/src/surfaceFilmModels/surfaceFilmModel/kinematicSingleLayer/kinematicSingleLayer.H +++ b/src/surfaceFilmModels/surfaceFilmModel/kinematicSingleLayer/kinematicSingleLayer.H @@ -120,9 +120,6 @@ protected: //- Skin frition coefficient for film/primary region interface scalar Cf_; - //- Stable film thickness - film cannot detach until reached - dimensionedScalar deltaStable_; - // Thermo properties @@ -212,6 +209,12 @@ protected: //- Pressure / [Pa] volScalarField pPrimary_; + //- Density / [kg/m3] + volScalarField rhoPrimary_; + + //- Viscosity / [Pa.s] + volScalarField muPrimary_; + // Sub-models @@ -225,12 +228,6 @@ protected: scalar addedMass_; - // Detached surface properties - - //- Cumulative mass detached [kg] - scalar detachedMass_; - - // Protected member functions //- Initialise the film model - called on construction @@ -248,9 +245,6 @@ protected: //- Transfer fields from the primary region to the film region virtual void transferPrimaryRegionFields(); - //- Correct the source terms for film that detaches from film region - virtual void correctDetachedFilm(); - // Explicit pressure source contribution virtual tmp<volScalarField> pu(); @@ -349,6 +343,9 @@ public: // Solution parameters + //- Return the film region solution dictionary + inline const dictionary& solution() const; + //- Return the momentum predictor inline const Switch& momentumPredictor() const; @@ -483,6 +480,12 @@ public: //- Pressure / [Pa] inline const volScalarField& pPrimary() const; + //- Density / [kg/m3] + inline const volScalarField& rhoPrimary() const; + + //- Viscosity / [Pa.s] + inline const volScalarField& muPrimary() const; + // Sub-models diff --git a/src/surfaceFilmModels/surfaceFilmModel/kinematicSingleLayer/kinematicSingleLayerI.H b/src/surfaceFilmModels/surfaceFilmModel/kinematicSingleLayer/kinematicSingleLayerI.H index c0f4a434678affa8702f6005f649dd48e30de5b9..765cdc0d790b7c7a032e667ac99cdaa0511eda23 100644 --- a/src/surfaceFilmModels/surfaceFilmModel/kinematicSingleLayer/kinematicSingleLayerI.H +++ b/src/surfaceFilmModels/surfaceFilmModel/kinematicSingleLayer/kinematicSingleLayerI.H @@ -41,6 +41,13 @@ Foam::surfaceFilmModels::kinematicSingleLayer::magSf() const } +inline const Foam::dictionary& +Foam::surfaceFilmModels::kinematicSingleLayer::solution() const +{ + return filmRegion_.solutionDict().subDict("PISO"); +} + + inline const Foam::Switch& Foam::surfaceFilmModels::kinematicSingleLayer::momentumPredictor() const { @@ -171,6 +178,20 @@ Foam::surfaceFilmModels::kinematicSingleLayer::pPrimary() const } +inline const Foam::volScalarField& +Foam::surfaceFilmModels::kinematicSingleLayer::rhoPrimary() const +{ + return rhoPrimary_; +} + + +inline const Foam::volScalarField& +Foam::surfaceFilmModels::kinematicSingleLayer::muPrimary() const +{ + return muPrimary_; +} + + inline Foam::surfaceFilmModels::injectionModel& Foam::surfaceFilmModels::kinematicSingleLayer::injection() { diff --git a/src/surfaceFilmModels/surfaceFilmModel/noFilm/noFilm.C b/src/surfaceFilmModels/surfaceFilmModel/noFilm/noFilm.C index 3565cf7c1256db0b3fe53aebcfb1f61e97402cbe..b277192e25870d2228f6f3c26cae68835c13f2a6 100644 --- a/src/surfaceFilmModels/surfaceFilmModel/noFilm/noFilm.C +++ b/src/surfaceFilmModels/surfaceFilmModel/noFilm/noFilm.C @@ -138,10 +138,8 @@ void Foam::surfaceFilmModels::noFilm::addSources const Foam::volVectorField& Foam::surfaceFilmModels::noFilm::U() const { - FatalErrorIn - ( - "const volScalarField& noFilm::U() const" - ) << "U field not available for " << type() << abort(FatalError); + FatalErrorIn("const volScalarField& noFilm::U() const") + << "U field not available for " << type() << abort(FatalError); return volVectorField::null(); } @@ -149,10 +147,8 @@ const Foam::volVectorField& Foam::surfaceFilmModels::noFilm::U() const const Foam::volVectorField& Foam::surfaceFilmModels::noFilm::Us() const { - FatalErrorIn - ( - "const volScalarField& noFilm::Us() const" - ) << "Us field not available for " << type() << abort(FatalError); + FatalErrorIn("const volScalarField& noFilm::Us() const") + << "Us field not available for " << type() << abort(FatalError); return volVectorField::null(); } @@ -160,10 +156,8 @@ const Foam::volVectorField& Foam::surfaceFilmModels::noFilm::Us() const const Foam::volVectorField& Foam::surfaceFilmModels::noFilm::Uw() const { - FatalErrorIn - ( - "const volScalarField& noFilm::Uw() const" - ) << "Uw field not available for " << type() << abort(FatalError); + FatalErrorIn("const volScalarField& noFilm::Uw() const") + << "Uw field not available for " << type() << abort(FatalError); return volVectorField::null(); } @@ -171,10 +165,8 @@ const Foam::volVectorField& Foam::surfaceFilmModels::noFilm::Uw() const const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::rho() const { - FatalErrorIn - ( - "const volScalarField& noFilm::rho() const" - ) << "rho field not available for " << type() << abort(FatalError); + FatalErrorIn("const volScalarField& noFilm::rho() const") + << "rho field not available for " << type() << abort(FatalError); return volScalarField::null(); } @@ -182,10 +174,8 @@ const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::rho() const const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::T() const { - FatalErrorIn - ( - "const Foam::volScalarField& Foam::noFilm::T() const" - ) << "T field not available for " << type() << abort(FatalError); + FatalErrorIn("const Foam::volScalarField& Foam::noFilm::T() const") + << "T field not available for " << type() << abort(FatalError); return volScalarField::null(); } @@ -193,10 +183,8 @@ const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::T() const const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::Ts() const { - FatalErrorIn - ( - "const Foam::volScalarField& Foam::noFilm::Ts() const" - ) << "Ts field not available for " << type() << abort(FatalError); + FatalErrorIn("const Foam::volScalarField& Foam::noFilm::Ts() const") + << "Ts field not available for " << type() << abort(FatalError); return volScalarField::null(); } @@ -204,10 +192,8 @@ const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::Ts() const const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::Tw() const { - FatalErrorIn - ( - "const Foam::volScalarField& Foam::noFilm::Tw() const" - ) << "Tw field not available for " << type() << abort(FatalError); + FatalErrorIn("const Foam::volScalarField& Foam::noFilm::Tw() const") + << "Tw field not available for " << type() << abort(FatalError); return volScalarField::null(); } @@ -215,10 +201,8 @@ const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::Tw() const const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::cp() const { - FatalErrorIn - ( - "const volScalarField& noFilm::cp() const" - ) << "cp field not available for " << type() << abort(FatalError); + FatalErrorIn("const volScalarField& noFilm::cp() const") + << "cp field not available for " << type() << abort(FatalError); return volScalarField::null(); } @@ -226,10 +210,8 @@ const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::cp() const const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::kappa() const { - FatalErrorIn - ( - "const volScalarField& noFilm::kappa() const" - ) << "kappa field not available for " << type() << abort(FatalError); + FatalErrorIn("const volScalarField& noFilm::kappa() const") + << "kappa field not available for " << type() << abort(FatalError); return volScalarField::null(); } @@ -238,10 +220,8 @@ const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::kappa() const const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::massForPrimary() const { - FatalErrorIn - ( - "const volScalarField& noFilm::massForPrimary() const" - ) << "massForPrimary field not available for " << type() + FatalErrorIn("const volScalarField& noFilm::massForPrimary() const") + << "massForPrimary field not available for " << type() << abort(FatalError); return volScalarField::null(); @@ -251,10 +231,8 @@ Foam::surfaceFilmModels::noFilm::massForPrimary() const const Foam::volScalarField& Foam::surfaceFilmModels::noFilm::diametersForPrimary() const { - FatalErrorIn - ( - "const volScalarField& noFilm::diametersForPrimary() const" - ) << "diametersForPrimary field not available for " << type() + FatalErrorIn("const volScalarField& noFilm::diametersForPrimary() const") + << "diametersForPrimary field not available for " << type() << abort(FatalError); return volScalarField::null(); @@ -267,13 +245,82 @@ Foam::surfaceFilmModels::noFilm::massPhaseChangeForPrimary() const FatalErrorIn ( "const volScalarField& noFilm::massPhaseChangeForPrimary() const" - ) << "massPhaseChangeForPrimary field not available for " << type() + ) << "massPhaseChange field not available for " << type() << abort(FatalError); return volScalarField::null(); } +Foam::tmp<Foam::DimensionedField<Foam::scalar, Foam::volMesh> > +Foam::surfaceFilmModels::noFilm::Srho() const +{ + return tmp<DimensionedField<scalar, volMesh> > + ( + new DimensionedField<scalar, volMesh> + ( + IOobject + ( + "noFilm::Srho", + time_.timeName(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + mesh_, + dimensionedScalar("zero", dimMass/dimVolume/dimTime, 0.0) + ) + ); +} + + +Foam::tmp<Foam::DimensionedField<Foam::scalar, Foam::volMesh> > +Foam::surfaceFilmModels::noFilm::Srho(const label) const +{ + return tmp<DimensionedField<scalar, volMesh> > + ( + new DimensionedField<scalar, volMesh> + ( + IOobject + ( + "kinematicSingleLayer::Srho(i)", + time_.timeName(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + mesh_, + dimensionedScalar("zero", dimMass/dimVolume/dimTime, 0.0) + ) + ); +} + + +Foam::tmp<Foam::DimensionedField<Foam::scalar, Foam::volMesh> > +Foam::surfaceFilmModels::noFilm::Sh() const +{ + return tmp<DimensionedField<scalar, volMesh> > + ( + new DimensionedField<scalar, volMesh> + ( + IOobject + ( + "kinematicSingleLayer::Sh", + time_.timeName(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + mesh_, + dimensionedScalar("zero", dimEnergy/dimVolume/dimTime, 0.0) + ) + ); +} + + void Foam::surfaceFilmModels::noFilm::info() const { // do nothing diff --git a/src/surfaceFilmModels/surfaceFilmModel/noFilm/noFilm.H b/src/surfaceFilmModels/surfaceFilmModel/noFilm/noFilm.H index 7d5fb40021b2aeca5f77debd834ec42e494de682..e4616151fdc3b39bfc6f5feabe1876ff90b7d541 100644 --- a/src/surfaceFilmModels/surfaceFilmModel/noFilm/noFilm.H +++ b/src/surfaceFilmModels/surfaceFilmModel/noFilm/noFilm.H @@ -175,6 +175,23 @@ public: virtual void evolveFilm(); + // Source fields + + // Mapped into primary region + + //- Return total mass source - Eulerian phase only + virtual tmp<DimensionedField<scalar, volMesh> > Srho() const; + + //- Return mass source for specie i - Eulerian phase only + virtual tmp<DimensionedField<scalar, volMesh> > Srho + ( + const label i + ) const; + + //- Return enthalpy source - Eulerian phase only + virtual tmp<DimensionedField<scalar, volMesh> > Sh() const; + + // I-O //- Provide some feedback diff --git a/src/surfaceFilmModels/surfaceFilmModel/surfaceFilmModel/surfaceFilmModel.C b/src/surfaceFilmModels/surfaceFilmModel/surfaceFilmModel/surfaceFilmModel.C index 9180c56658c82359bbfed4a72dd72853bb003dac..9ac01432fbb55efaf3bab9fcc5d8d993a55c92fe 100644 --- a/src/surfaceFilmModels/surfaceFilmModel/surfaceFilmModel/surfaceFilmModel.C +++ b/src/surfaceFilmModels/surfaceFilmModel/surfaceFilmModel/surfaceFilmModel.C @@ -128,10 +128,18 @@ Foam::surfaceFilmModels::surfaceFilmModel::surfaceFilmModel active_(lookup("active")), g_(g), - filmRegionName_(lookup("filmRegionName")), - coeffs_(subDict(type + "Coeffs")), - thermoModel_(thermoModelTypeNames_.read(coeffs_.lookup("thermoModel"))) -{} + filmRegionName_("none"), + coeffs_(dictionary::null), + thermoModel_(tmConstant) +{ + if (active_) + { + lookup("filmRegionName") >> filmRegionName_; + coeffs_ = subDict(type + "Coeffs"); + thermoModel_ = + thermoModelTypeNames_.read(coeffs_.lookup("thermoModel")); + } +} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // diff --git a/src/surfaceFilmModels/surfaceFilmModel/thermoSingleLayer/thermoSingleLayer.C b/src/surfaceFilmModels/surfaceFilmModel/thermoSingleLayer/thermoSingleLayer.C index 480759783cc37fdf006d3d51877871204ae4ca0d..aa9194942e1368eae04f16b0cf97036c0f5a16d7 100644 --- a/src/surfaceFilmModels/surfaceFilmModel/thermoSingleLayer/thermoSingleLayer.C +++ b/src/surfaceFilmModels/surfaceFilmModel/thermoSingleLayer/thermoSingleLayer.C @@ -126,19 +126,7 @@ void Foam::surfaceFilmModels::thermoSingleLayer::updateSurfaceTemperatures() Tw_.correctBoundaryConditions(); // Update film surface temperature - dimensionedScalar deltaSmall("SMALL", dimLength, SMALL); - volScalarField kappaDeltaBy2 = kappa_/(0.5*delta_ + deltaSmall); - Ts_ = - ( - // qRad - - energyPhaseChangeForPrimary_/(time_.deltaT()*magSf_) - + TPrimary_*htcs_->h() - + kappaDeltaBy2*T_ - ) - /( - htcs_->h() - + kappaDeltaBy2 - ); + Ts_ = T_; Ts_.correctBoundaryConditions(); } @@ -175,9 +163,6 @@ void Foam::surfaceFilmModels::thermoSingleLayer::updateSubmodels() htcw_->correct(); // Update phase change - massPhaseChangeForPrimary_ == dimensionedScalar("zero", dimMass, 0.0); - energyPhaseChangeForPrimary_ == dimensionedScalar("zero", dimEnergy, 0.0); - phaseChange_->correct ( time_.deltaTValue(), @@ -185,17 +170,12 @@ void Foam::surfaceFilmModels::thermoSingleLayer::updateSubmodels() energyPhaseChangeForPrimary_ ); massPhaseChangeForPrimary_.correctBoundaryConditions(); - totalMassPhaseChange_ += sum(massPhaseChangeForPrimary_).value(); // Update kinematic sub-models kinematicSingleLayer::updateSubmodels(); // Update source fields - const dimensionedScalar deltaT = time_.deltaT(); - rhoSp_ -= massPhaseChangeForPrimary_/magSf_/deltaT; - USp_ -= massPhaseChangeForPrimary_*U_/magSf_/deltaT; - hsSp_ -= - (massForPrimary_*hs_ + energyPhaseChangeForPrimary_)/magSf_/deltaT; + hsSp_ -= energyPhaseChangeForPrimary_/magSf_/time_.deltaT(); } @@ -208,7 +188,7 @@ Foam::tmp<Foam::fvScalarMatrix> Foam::surfaceFilmModels::thermoSingleLayer::q return ( - - fvm::Sp(htcs_->h()/cp_, hs) - htcs_->h()*(Tstd - Ts_) + - fvm::Sp(htcs_->h()/cp_, hs) - htcs_->h()*(Tstd - TPrimary_) - fvm::Sp(htcw_->h()/cp_, hs) - htcw_->h()*(Tstd - Tw_) ); } @@ -223,13 +203,21 @@ void Foam::surfaceFilmModels::thermoSingleLayer::solveEnergy() updateSurfaceTemperatures(); + volScalarField mLossCoeff + ( + "mLossCoeff", + massForPrimary_/magSf_/time_.deltaT() + ); + solve ( fvm::ddt(deltaRho_, hs_) + fvm::div(phi_, hs_) == +// fvm::Sp(hsSp_/hs_, hs_) hsSp_ + q(hs_) + - fvm::Sp(mLossCoeff, hs_) ); correctThermoFields(); @@ -388,7 +376,6 @@ Foam::surfaceFilmModels::thermoSingleLayer::thermoSingleLayer heatTransferModel::New(*this, coeffs_.subDict("lowerSurfaceModels")) ), phaseChange_(phaseChangeModel::New(*this, coeffs_)), - totalMassPhaseChange_(0.0), energyPhaseChangeForPrimary_ ( IOobject @@ -584,10 +571,65 @@ void Foam::surfaceFilmModels::thermoSingleLayer::info() const { kinematicSingleLayer::info(); - Info<< indent << "min/max(T) = " << min(T_).value() << ", " - << max(T_).value() << nl - << indent << "mass phase change = " - << returnReduce(totalMassPhaseChange_, sumOp<scalar>()) << nl; + Info<< indent << "min/max(T) = " << min(T_).value() << ", " + << max(T_).value() << nl; + + phaseChange_->info(); +} + + +Foam::tmp<Foam::DimensionedField<Foam::scalar, Foam::volMesh> > +Foam::surfaceFilmModels::thermoSingleLayer::Srho() const +{ + tmp<DimensionedField<scalar, volMesh> > tSrho + ( + new DimensionedField<scalar, volMesh> + ( + IOobject + ( + "thermoSingleLayer::Srho", + time_.timeName(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + mesh_, + dimensionedScalar("zero", dimMass/dimVolume/dimTime, 0.0) + ) + ); + + scalarField& Srho = tSrho(); + const scalarField& V = mesh_.V(); + const scalar dt = time_.deltaTValue(); + + forAll(filmBottomPatchIDs_, i) + { + const label primaryPatchI = primaryPatchIDs_[i]; + const directMappedWallPolyPatch& wpp = + refCast<const directMappedWallPolyPatch> + ( + mesh_.boundaryMesh()[primaryPatchI] + ); + + const mapDistribute& distMap = wpp.map(); + + const label filmPatchI = filmBottomPatchIDs_[i]; + + scalarField patchMass = + massPhaseChangeForPrimary_.boundaryField()[filmPatchI]; + + distMap.distribute(patchMass); + + const unallocLabelList& cells = wpp.faceCells(); + + forAll(patchMass, j) + { + Srho[cells[j]] = patchMass[j]/(V[cells[j]]*dt); + } + } + + return tSrho; } @@ -627,7 +669,7 @@ Foam::surfaceFilmModels::thermoSingleLayer::Srho(const label i) const const directMappedWallPolyPatch& wpp = refCast<const directMappedWallPolyPatch> ( - mesh_.boundaryMesh()[primaryPatchI] + mesh_.boundaryMesh()[primaryPatchI] ); const mapDistribute& distMap = wpp.map(); @@ -635,7 +677,7 @@ Foam::surfaceFilmModels::thermoSingleLayer::Srho(const label i) const const label filmPatchI = filmBottomPatchIDs_[i]; scalarField patchMass = - massPhaseChangeForPrimary().boundaryField()[filmPatchI]; + massPhaseChangeForPrimary_.boundaryField()[filmPatchI]; distMap.distribute(patchMass); @@ -673,6 +715,9 @@ Foam::surfaceFilmModels::thermoSingleLayer::Sh() const ) ); + // All of enthalpy change due to phase change added to film energy equation + +/* scalarField& Sh = tSh(); const scalarField& V = mesh_.V(); const scalar dt = time_.deltaTValue(); @@ -683,28 +728,25 @@ Foam::surfaceFilmModels::thermoSingleLayer::Sh() const const directMappedWallPolyPatch& wpp = refCast<const directMappedWallPolyPatch> ( - mesh_.boundaryMesh()[primaryPatchI] + mesh_.boundaryMesh()[primaryPatchI] ); const mapDistribute& distMap = wpp.map(); const label filmPatchI = filmBottomPatchIDs_[i]; - scalarField patchMass = - massPhaseChangeForPrimary().boundaryField()[filmPatchI]; - distMap.distribute(patchMass); - - scalarField patchEnthalpy = hs_.boundaryField()[filmPatchI]; - distMap.distribute(patchEnthalpy); + scalarField patchEnergy = + energyPhaseChangeForPrimary_.boundaryField()[filmPatchI]; + distMap.distribute(patchEnergy); const unallocLabelList& cells = wpp.faceCells(); forAll(patchMass, j) { - Sh[cells[j]] += patchMass[j]*patchEnthalpy[j]/(V[cells[j]]*dt); + Sh[cells[j]] += patchEnergy[j]/(V[cells[j]]*dt); } } - +*/ return tSh; } diff --git a/src/surfaceFilmModels/surfaceFilmModel/thermoSingleLayer/thermoSingleLayer.H b/src/surfaceFilmModels/surfaceFilmModel/thermoSingleLayer/thermoSingleLayer.H index a5c5b892e7c3053bd9a6f1d2e96145a6da298957..2cdf71f2e47772b7a0a33402e106ec28ffbfcfce 100644 --- a/src/surfaceFilmModels/surfaceFilmModel/thermoSingleLayer/thermoSingleLayer.H +++ b/src/surfaceFilmModels/surfaceFilmModel/thermoSingleLayer/thermoSingleLayer.H @@ -147,9 +147,6 @@ protected: //- Phase change autoPtr<phaseChangeModel> phaseChange_; - //- Total mass transferred to primary region [kg] - scalar totalMassPhaseChange_; - //- Film energy evolved via phase change volScalarField energyPhaseChangeForPrimary_; @@ -317,6 +314,9 @@ public: // Mapped into primary region + //- Return total mass source - Eulerian phase only + virtual tmp<DimensionedField<scalar, volMesh> > Srho() const; + //- Return mass source for specie i - Eulerian phase only virtual tmp<DimensionedField<scalar, volMesh> > Srho ( diff --git a/src/thermophysicalModels/pdfs/fixedValue/fixedValue.C b/src/thermophysicalModels/pdfs/fixedValue/fixedValue.C index 98634af06fe87edb848cf25c72c0ffd7e72356e9..b8afd67303645161d3941828b6bfd41dc1e8ff38 100644 --- a/src/thermophysicalModels/pdfs/fixedValue/fixedValue.C +++ b/src/thermophysicalModels/pdfs/fixedValue/fixedValue.C @@ -62,13 +62,13 @@ Foam::scalar Foam::pdfs::fixedValue::fixedValue::sample() const Foam::scalar Foam::pdfs::fixedValue::fixedValue::minValue() const { - return -VGREAT; + return value_; } Foam::scalar Foam::pdfs::fixedValue::fixedValue::maxValue() const { - return VGREAT; + return value_; } diff --git a/src/thermophysicalModels/pdfs/pdf/pdf.H b/src/thermophysicalModels/pdfs/pdf/pdf.H index b0c5ea671d107b9154b44e54ed7589ffa1bd9198..d6dbf8fb90fc3c41c9a20c3bd653850866bb3e51 100644 --- a/src/thermophysicalModels/pdfs/pdf/pdf.H +++ b/src/thermophysicalModels/pdfs/pdf/pdf.H @@ -77,7 +77,7 @@ protected: //- Coefficients dictionary const dictionary pdfDict_; - //- Reference to the randmo number generator + //- Reference to the random number generator Random& rndGen_; diff --git a/tutorials/combustion/dieselFoam/aachenBomb/constant/sprayProperties b/tutorials/combustion/dieselFoam/aachenBomb/constant/sprayProperties index de0933465ba08d5625c91f4828cc7539419a80d1..878439295f1d1812fb922c567ef144ae7b0fff36 100644 --- a/tutorials/combustion/dieselFoam/aachenBomb/constant/sprayProperties +++ b/tutorials/combustion/dieselFoam/aachenBomb/constant/sprayProperties @@ -17,7 +17,7 @@ FoamFile interpolationSchemes { - U cellPointFace; + U cellPoint; rho cell; p cell; T cell; diff --git a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict index 75432f06b993b2e78abfee09679d638a2bef12bb..6f09959210749fc2196206f99c1ca168c896ba19 100644 --- a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict +++ b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict @@ -358,11 +358,14 @@ meshQualityControls // Set to very negative number (e.g. -1E30) to disable. minVol 1e-13; - //- Minimum tet volume. Is absolute volume of the tet formed by the - // face-centre decomposition triangle and the cell centre. - // Set to a sensible fraction of the smallest cell volume expected. - // Set to very negative number (e.g. -1E30) to disable. - minTetVol 1e-20; + //- 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-9; //- Minimum face area. Set to <0 to disable. minArea -1; diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/system/snappyHexMeshDict b/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/system/snappyHexMeshDict index 1cc6ba8dbae81fd3935985842161cd08a9cb9922..f86acc422643d14970063f4831f0e4046e47d8bd 100644 --- a/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/system/snappyHexMeshDict +++ b/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/system/snappyHexMeshDict @@ -340,11 +340,14 @@ meshQualityControls // Set to very negative number (e.g. -1E30) to disable. minVol 0; - //- Minimum tet volume. Is absolute volume of the tet formed by the - // face-centre decomposition triangle and the cell centre. - // Set to a sensible fraction of the smallest cell volume expected. - // Set to very negative number (e.g. -1E30) to disable. - minTetVol 1e-20; + //- 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-9; //- Minimum face area. Set to <0 to disable. minArea -1; diff --git a/tutorials/incompressible/pimpleDyMFoam/wingMotion/wingMotion_snappyHexMesh/system/snappyHexMeshDict b/tutorials/incompressible/pimpleDyMFoam/wingMotion/wingMotion_snappyHexMesh/system/snappyHexMeshDict index 37b684ec9ab02a7b34dfa859ddd17813c9a28f44..78068461c3e79e8daad561dab43d5408bd5c3aed 100644 --- a/tutorials/incompressible/pimpleDyMFoam/wingMotion/wingMotion_snappyHexMesh/system/snappyHexMeshDict +++ b/tutorials/incompressible/pimpleDyMFoam/wingMotion/wingMotion_snappyHexMesh/system/snappyHexMeshDict @@ -272,11 +272,14 @@ meshQualityControls // Set to very negative number (e.g. -1E30) to disable. minVol 1e-13; - //- Minimum tet volume. Is absolute volume of the tet formed by the - // face-centre decomposition triangle and the cell centre. - // Set to a sensible fraction of the smallest cell volume expected. - // Set to very negative number (e.g. -1E30) to disable. - minTetVol 1e-20; + //- 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-9; //- Minimum face area. Set to <0 to disable. minArea -1; diff --git a/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict b/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict index 2cf5bad399989649588c1803e7e268e7ad867461..de5c2a8aa775fd08575783851321e756da414ffd 100644 --- a/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict +++ b/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict @@ -551,11 +551,14 @@ meshQualityControls // Set to very negative number (e.g. -1E30) to disable. minVol 1e-13; - //- Minimum tet volume. Is absolute volume of the tet formed by the - // face-centre decomposition triangle and the cell centre. - // Set to a sensible fraction of the smallest cell volume expected. - // Set to very negative number (e.g. -1E30) to disable. - minTetVol 1e-20; + //- 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-9; //- Minimum face area. Set to <0 to disable. minArea -1; diff --git a/tutorials/incompressible/simpleFoam/windTurbineTerrain/system/snappyHexMeshDict b/tutorials/incompressible/simpleFoam/windTurbineTerrain/system/snappyHexMeshDict index d32abbb74bc1eadf790c9c5362d7a0e068b9e865..7b7a4e571425abddc0a5c93e1a8b0194a2d713a2 100644 --- a/tutorials/incompressible/simpleFoam/windTurbineTerrain/system/snappyHexMeshDict +++ b/tutorials/incompressible/simpleFoam/windTurbineTerrain/system/snappyHexMeshDict @@ -362,11 +362,14 @@ meshQualityControls // Set to very negative number (e.g. -1E30) to disable. minVol 1e-13; - //- Minimum tet volume. Is absolute volume of the tet formed by the - // face-centre decomposition triangle and the cell centre. - // Set to a sensible fraction of the smallest cell volume expected. - // Set to very negative number (e.g. -1E30) to disable. - minTetVol 1e-20; + //- 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-9; //- Minimum face area. Set to <0 to disable. minArea -1; diff --git a/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/constant/coalCloud1Properties b/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/constant/coalCloud1Properties index b7eb5e23a7736089ab058170eebc4d164da81db5..5624bb507b4dc0a8cf3d918c7bc32f8462f619b0 100644 --- a/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/constant/coalCloud1Properties +++ b/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/constant/coalCloud1Properties @@ -73,7 +73,7 @@ constantProperties interpolationSchemes { rho cell; - U cellPointFace; + U cellPoint; mu cell; T cell; Cp cell; diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/constant/reactingCloud1Properties b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/constant/reactingCloud1Properties index 1e7431118eed4c403155bc2df33617a68c9c449c..4534388250f668bad6a0d659f9940c01751aed58 100644 --- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/constant/reactingCloud1Properties +++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/constant/reactingCloud1Properties @@ -74,7 +74,7 @@ constantProperties interpolationSchemes { rho cell; - U cellPointFace; + U cellPoint; mu cell; T cell; Cp cell; diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/parcelInBox/constant/reactingCloud1Properties b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/parcelInBox/constant/reactingCloud1Properties index b9e6be98a565c39dcd1ba4b907747255a1be139c..dc6f9aba8bd5a130216124b79a580a75c9934018 100644 --- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/parcelInBox/constant/reactingCloud1Properties +++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/parcelInBox/constant/reactingCloud1Properties @@ -73,7 +73,7 @@ constantProperties interpolationSchemes { rho cell; - U cellPointFace; + U cellPoint; mu cell; T cell; Cp cell; diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/verticalChannel/constant/reactingCloud1Properties b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/verticalChannel/constant/reactingCloud1Properties index f04e8560be729c627cf1ae454b2ff086ac6f602e..44a046965f7f8ded55ea953fc062c5315aa98bd7 100644 --- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/verticalChannel/constant/reactingCloud1Properties +++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/verticalChannel/constant/reactingCloud1Properties @@ -73,7 +73,7 @@ constantProperties interpolationSchemes { rho cell; - U cellPointFace; + U cellPoint; mu cell; T cell; Cp cell; diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/H2O b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/H2O new file mode 100644 index 0000000000000000000000000000000000000000..45bd7b237cdbde402b5ffa0029b1ef3991cbcb2e --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/H2O @@ -0,0 +1,36 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object H2O; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +dimensions [0 0 0 0 0 0 0]; + +internalField uniform 0.0; + +boundaryField +{ + "(.*)" + { + type zeroGradient; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type zeroGradient; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/N2 b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/N2 new file mode 100644 index 0000000000000000000000000000000000000000..f1ab7544ccc46ff2e73e4ed825c599adc95a515c --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/N2 @@ -0,0 +1,36 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object N2; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +dimensions [0 0 0 0 0 0 0]; + +internalField uniform 0.79; + +boundaryField +{ + "(.*)" + { + type zeroGradient; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type zeroGradient; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/O2 b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/O2 new file mode 100644 index 0000000000000000000000000000000000000000..2eed8c75a875e50d4cac11eaa06d960323a6c5b1 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/O2 @@ -0,0 +1,36 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object O2; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 0 0 0 0]; + +internalField uniform 0.21; + +boundaryField +{ + "(.*)" + { + type zeroGradient; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type zeroGradient; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/T b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/T new file mode 100644 index 0000000000000000000000000000000000000000..f34ddb4387f97c4256def6743a1c80fde4e38819 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/T @@ -0,0 +1,39 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + location "0"; + class volScalarField; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 500; + +boundaryField +{ + "(.*)" + { + type fixedValue; + value uniform 300; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedNamedFixedValue; + fieldName Tsf; + average 300; + setAverage no; + value uniform 300; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/U b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/U new file mode 100644 index 0000000000000000000000000000000000000000..4622cf8a48ed8e035cee8af6c8180fb5838a013b --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/U @@ -0,0 +1,40 @@ +/*--------------------------------*- 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 volVectorField; + location "0"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + "(.*)" + { + type fixedValue; + value uniform (0 0 0); + } + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedNamedFixedValue; + fieldName Usf; + average ( 0 0 0 ); + setAverage no; + value uniform (0 0 0); + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/alphat b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/alphat new file mode 100644 index 0000000000000000000000000000000000000000..51edd139e7aed891905cdadb0f713f1f09ee1476 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/alphat @@ -0,0 +1,39 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.7.x | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object alphat; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -1 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + "(.*)" + { + type alphatWallFunction; + Prt 0.85; + value uniform 0; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type alphatWallFunction; + Prt 0.85; + value uniform 0; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/epsilon b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/epsilon new file mode 100644 index 0000000000000000000000000000000000000000..2f05a9be403b980845bc7f3cea8ee0db3754aa8e --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/epsilon @@ -0,0 +1,43 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.7.x | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object epsilon; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -3 0 0 0 0]; + +internalField uniform 1e-07; + +boundaryField +{ + "(.*)" + { + type compressible::epsilonWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 1e-07; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type compressible::epsilonWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 1e-07; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/htcConv b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/htcConv new file mode 100644 index 0000000000000000000000000000000000000000..372f9728b0acc4aee78c5379cdb563921fd4115e --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/htcConv @@ -0,0 +1,39 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.7.x | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object htcConv; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 0 -1 1 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + "(.*)" + { + type calculated; + value uniform 0; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type htcConvection; + L 1.0; + value uniform 0; + } +} + + +// ************************************************************************* // +/* vim: set filetype=cpp : */ diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/k b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/k new file mode 100644 index 0000000000000000000000000000000000000000..73a28dd66dd35fdc787d95ade0a13966f7c6a6e6 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/k @@ -0,0 +1,37 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.7.x | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object k; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -2 0 0 0 0]; + +internalField uniform 1e-05; + +boundaryField +{ + "(.*)" + { + type compressible::kqRWallFunction; + value uniform 1e-05; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type compressible::kqRWallFunction; + value uniform 1e-05; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/mut b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/mut new file mode 100644 index 0000000000000000000000000000000000000000..8b027d9e3ca95fae8e237614528cc0cf03d8e0a4 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/mut @@ -0,0 +1,43 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.7.x | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object mut; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -1 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + "(.*)" + { + type mutWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 0; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type mutWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 0; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/p b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/p new file mode 100644 index 0000000000000000000000000000000000000000..4416257054197fab08512a5fc0d8f2c85dec25d2 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/p @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 100000; + +boundaryField +{ + "(.*)" + { + type zeroGradient; // buoyantPressure; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type zeroGradient; // buoyantPressure; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/T b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/T new file mode 100644 index 0000000000000000000000000000000000000000..fc3185b84b8076322f1f6d0aacbda2d9cacd7f3d --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/T @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0/wallFilmRegion"; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 300; + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedFixedInternalValue; + average 300; + setAverage no; + value uniform 300; + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/Tf b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/Tf new file mode 100644 index 0000000000000000000000000000000000000000..c6e2bcc2a294509cc81752fe4104fb05372ef31b --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/Tf @@ -0,0 +1,51 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0/wallFilmRegion"; + object Tf; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 288; + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type fixedValue; + value uniform 312.3; + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/U b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/U new file mode 100644 index 0000000000000000000000000000000000000000..5bed5414f81c60c96a9810ae6470748368b93f03 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/U @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + location "0/wallFilmRegion"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedFixedInternalValue; + average (0 0 0); + setAverage no; + value uniform (0 0 0); + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/USpf b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/USpf new file mode 100644 index 0000000000000000000000000000000000000000..c9a49b5c8df2ce0941df22ec79be297f26722d8e --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/USpf @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + location "0/wallFilmRegion"; + object USpf; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; // kg.m/s/(m2.s) + +internalField uniform (0 0 0); + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedFixedPushedInternalValue; + average (0 0 0); + setAverage no; + value uniform (0 0 0); + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/Uf b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/Uf new file mode 100644 index 0000000000000000000000000000000000000000..dfcb58aaec7a19cae27ac240ad2e7fbbd78a0031 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/Uf @@ -0,0 +1,54 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + location "0/wallFilmRegion"; + object Uf; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + wallFilmFaces_top + { + type slip; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type fixedValue; + value uniform (0 0 0); + } + + left + { + type fixedValue; + value uniform (0 0 0); + } + + right + { + type fixedValue; + value uniform (0 0 0); + } + + frontAndBack + { + type fixedValue; + value uniform (0 0 0); + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/deltaf b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/deltaf new file mode 100644 index 0000000000000000000000000000000000000000..75db44350a52179e57bf8af79bb3bf7d7e3eab7a --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/deltaf @@ -0,0 +1,50 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0/wallFilmRegion"; + object deltaf; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 0 0 0 0 0]; + +internalField uniform 0.00013; + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type zeroGradient; + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/p b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/p new file mode 100644 index 0000000000000000000000000000000000000000..8d2193ce1a692c56df7d4a53413b1bc20e32934e --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/p @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0/wallFilmRegion"; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 100000; + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedFixedInternalValue; + average 100000; + setAverage no; + value uniform 100000; + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/pSpf b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/pSpf new file mode 100644 index 0000000000000000000000000000000000000000..2c4181e52c78c040d7a4f549b7161bfa3a303ee9 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0.org/wallFilmRegion/pSpf @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0/wallFilmRegion"; + object pSpf; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; // Pa + +internalField uniform 0.0; + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedFixedPushedInternalValue; + average 0.0; + setAverage no; + value uniform 0.0; + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/H2O b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/H2O new file mode 100644 index 0000000000000000000000000000000000000000..45bd7b237cdbde402b5ffa0029b1ef3991cbcb2e --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/H2O @@ -0,0 +1,36 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object H2O; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +dimensions [0 0 0 0 0 0 0]; + +internalField uniform 0.0; + +boundaryField +{ + "(.*)" + { + type zeroGradient; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type zeroGradient; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/N2 b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/N2 new file mode 100644 index 0000000000000000000000000000000000000000..f1ab7544ccc46ff2e73e4ed825c599adc95a515c --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/N2 @@ -0,0 +1,36 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object N2; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +dimensions [0 0 0 0 0 0 0]; + +internalField uniform 0.79; + +boundaryField +{ + "(.*)" + { + type zeroGradient; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type zeroGradient; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/O2 b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/O2 new file mode 100644 index 0000000000000000000000000000000000000000..2eed8c75a875e50d4cac11eaa06d960323a6c5b1 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/O2 @@ -0,0 +1,36 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object O2; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 0 0 0 0]; + +internalField uniform 0.21; + +boundaryField +{ + "(.*)" + { + type zeroGradient; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type zeroGradient; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/T b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/T new file mode 100644 index 0000000000000000000000000000000000000000..f34ddb4387f97c4256def6743a1c80fde4e38819 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/T @@ -0,0 +1,39 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + location "0"; + class volScalarField; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 500; + +boundaryField +{ + "(.*)" + { + type fixedValue; + value uniform 300; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedNamedFixedValue; + fieldName Tsf; + average 300; + setAverage no; + value uniform 300; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/U b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/U new file mode 100644 index 0000000000000000000000000000000000000000..4622cf8a48ed8e035cee8af6c8180fb5838a013b --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/U @@ -0,0 +1,40 @@ +/*--------------------------------*- 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 volVectorField; + location "0"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + "(.*)" + { + type fixedValue; + value uniform (0 0 0); + } + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedNamedFixedValue; + fieldName Usf; + average ( 0 0 0 ); + setAverage no; + value uniform (0 0 0); + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/alphat b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/alphat new file mode 100644 index 0000000000000000000000000000000000000000..51edd139e7aed891905cdadb0f713f1f09ee1476 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/alphat @@ -0,0 +1,39 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.7.x | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object alphat; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -1 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + "(.*)" + { + type alphatWallFunction; + Prt 0.85; + value uniform 0; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type alphatWallFunction; + Prt 0.85; + value uniform 0; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/epsilon b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/epsilon new file mode 100644 index 0000000000000000000000000000000000000000..2f05a9be403b980845bc7f3cea8ee0db3754aa8e --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/epsilon @@ -0,0 +1,43 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.7.x | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object epsilon; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -3 0 0 0 0]; + +internalField uniform 1e-07; + +boundaryField +{ + "(.*)" + { + type compressible::epsilonWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 1e-07; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type compressible::epsilonWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 1e-07; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/htcConv b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/htcConv new file mode 100644 index 0000000000000000000000000000000000000000..372f9728b0acc4aee78c5379cdb563921fd4115e --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/htcConv @@ -0,0 +1,39 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.7.x | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object htcConv; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 0 -1 1 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + "(.*)" + { + type calculated; + value uniform 0; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type htcConvection; + L 1.0; + value uniform 0; + } +} + + +// ************************************************************************* // +/* vim: set filetype=cpp : */ diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/k b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/k new file mode 100644 index 0000000000000000000000000000000000000000..73a28dd66dd35fdc787d95ade0a13966f7c6a6e6 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/k @@ -0,0 +1,37 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.7.x | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object k; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -2 0 0 0 0]; + +internalField uniform 1e-05; + +boundaryField +{ + "(.*)" + { + type compressible::kqRWallFunction; + value uniform 1e-05; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type compressible::kqRWallFunction; + value uniform 1e-05; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/mut b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/mut new file mode 100644 index 0000000000000000000000000000000000000000..8b027d9e3ca95fae8e237614528cc0cf03d8e0a4 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/mut @@ -0,0 +1,43 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.7.x | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object mut; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -1 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + "(.*)" + { + type mutWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 0; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type mutWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 0; + } +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/p b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/p new file mode 100644 index 0000000000000000000000000000000000000000..4416257054197fab08512a5fc0d8f2c85dec25d2 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/p @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 100000; + +boundaryField +{ + "(.*)" + { + type zeroGradient; // buoyantPressure; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type zeroGradient; // buoyantPressure; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/T b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/T new file mode 100644 index 0000000000000000000000000000000000000000..fc3185b84b8076322f1f6d0aacbda2d9cacd7f3d --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/T @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0/wallFilmRegion"; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 300; + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedFixedInternalValue; + average 300; + setAverage no; + value uniform 300; + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/Tf b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/Tf new file mode 100644 index 0000000000000000000000000000000000000000..c6e2bcc2a294509cc81752fe4104fb05372ef31b --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/Tf @@ -0,0 +1,51 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0/wallFilmRegion"; + object Tf; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 288; + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type fixedValue; + value uniform 312.3; + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/U b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/U new file mode 100644 index 0000000000000000000000000000000000000000..5bed5414f81c60c96a9810ae6470748368b93f03 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/U @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + location "0/wallFilmRegion"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedFixedInternalValue; + average (0 0 0); + setAverage no; + value uniform (0 0 0); + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/USpf b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/USpf new file mode 100644 index 0000000000000000000000000000000000000000..c9a49b5c8df2ce0941df22ec79be297f26722d8e --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/USpf @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + location "0/wallFilmRegion"; + object USpf; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; // kg.m/s/(m2.s) + +internalField uniform (0 0 0); + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedFixedPushedInternalValue; + average (0 0 0); + setAverage no; + value uniform (0 0 0); + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/Uf b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/Uf new file mode 100644 index 0000000000000000000000000000000000000000..dfcb58aaec7a19cae27ac240ad2e7fbbd78a0031 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/Uf @@ -0,0 +1,54 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + location "0/wallFilmRegion"; + object Uf; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + wallFilmFaces_top + { + type slip; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type fixedValue; + value uniform (0 0 0); + } + + left + { + type fixedValue; + value uniform (0 0 0); + } + + right + { + type fixedValue; + value uniform (0 0 0); + } + + frontAndBack + { + type fixedValue; + value uniform (0 0 0); + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/deltaf b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/deltaf new file mode 100644 index 0000000000000000000000000000000000000000..75db44350a52179e57bf8af79bb3bf7d7e3eab7a --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/deltaf @@ -0,0 +1,50 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0/wallFilmRegion"; + object deltaf; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 0 0 0 0 0]; + +internalField uniform 0.00013; + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type zeroGradient; + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/p b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/p new file mode 100644 index 0000000000000000000000000000000000000000..8d2193ce1a692c56df7d4a53413b1bc20e32934e --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/p @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0/wallFilmRegion"; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 100000; + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedFixedInternalValue; + average 100000; + setAverage no; + value uniform 100000; + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/pSpf b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/pSpf new file mode 100644 index 0000000000000000000000000000000000000000..2c4181e52c78c040d7a4f549b7161bfa3a303ee9 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/0/wallFilmRegion/pSpf @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0/wallFilmRegion"; + object pSpf; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; // Pa + +internalField uniform 0.0; + +boundaryField +{ + wallFilmFaces_top + { + type zeroGradient; + } + + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedFixedPushedInternalValue; + average 0.0; + setAverage no; + value uniform 0.0; + } + + left + { + type zeroGradient; + } + + right + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/Allclean b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/Allclean new file mode 100755 index 0000000000000000000000000000000000000000..2c4c2c8e813128df3c6e59674d117783c4c9213d --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/Allclean @@ -0,0 +1,14 @@ +#!/bin/sh +# Source tutorial clean functions +. $WM_PROJECT_DIR/bin/tools/CleanFunctions + +cleanCase + +#rm -rf system/wallFilmRegion +rm -rf constant/wallFilmRegion +rm -rf 0 +cp -rf 0.org 0 +rm -rf mfr* + +rm -rf *.obj + diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/Allrun b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/Allrun new file mode 100755 index 0000000000000000000000000000000000000000..01302f3e31430d3506cfccaa348daea3c253eb62 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/Allrun @@ -0,0 +1,6 @@ +#!/bin/sh +. $WM_PROJECT_DIR/bin/tools/RunFunctions + +./Allrun.pre + +runApplication reactingParcelFilmFoam diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/Allrun.pre b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/Allrun.pre new file mode 100755 index 0000000000000000000000000000000000000000..a3c9718bf68071a89e78f1392c3291254a6e272e --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/Allrun.pre @@ -0,0 +1,15 @@ +#!/bin/sh +. $WM_PROJECT_DIR/bin/tools/RunFunctions + +rm -fr log.* + +runApplication blockMesh + +runApplication setSet -batch wallFilmRegion.setSet +mv log.setSet log.wallFilmRegion.setSet + +runApplication setsToZones -noFlipMap +mv log.setsToZones log.setsToZones.primaryRegion + +runApplication extrudeToRegionMesh wallFilmRegion '(wallFilmFaces)' 0.01 -overwrite + diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/chemkin/chem.inp b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/chemkin/chem.inp new file mode 100644 index 0000000000000000000000000000000000000000..e1c66808259097c7678e10a52072760041181bec --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/chemkin/chem.inp @@ -0,0 +1,6 @@ +ELEMENTS +O H N +END +SPECIES +N2 O2 H2O +END diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/chemkin/foam.dat b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/chemkin/foam.dat new file mode 100644 index 0000000000000000000000000000000000000000..36ef32431218784d9c10aa1609870debbbbb5924 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/chemkin/foam.dat @@ -0,0 +1,17 @@ +( +O2 O2 1 31.9988 + 200 5000 1000 + 3.69758 0.00061352 -1.25884e-07 1.77528e-11 -1.13644e-15 -1233.93 3.18917 + 3.21294 0.00112749 -5.75615e-07 1.31388e-09 -8.76855e-13 -1005.25 6.03474 + 1.67212e-06 170.672 +H2O H2O 1 18.0153 + 200 5000 1000 + 2.67215 0.00305629 -8.73026e-07 1.201e-10 -6.39162e-15 -29899.2 6.86282 + 3.38684 0.00347498 -6.3547e-06 6.96858e-09 -2.50659e-12 -30208.1 2.59023 + 1.67212e-06 170.672 +N2 N2 1 28.0134 + 200 5000 1000 + 2.92664 0.00148798 -5.68476e-07 1.0097e-10 -6.75335e-15 -922.798 5.98053 + 3.29868 0.00140824 -3.96322e-06 5.64152e-09 -2.44486e-12 -1020.9 3.95037 + 1.67212e-06 170.672 +) diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/chemkin/foam.inp b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/chemkin/foam.inp new file mode 100644 index 0000000000000000000000000000000000000000..80d66f62c04dbc0e5638ad8912f02619e526e7be --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/chemkin/foam.inp @@ -0,0 +1,11 @@ +species +( + O2 + H2O + N2 +) +; + +reactions +( +); diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/chemkin/therm.dat b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/chemkin/therm.dat new file mode 100644 index 0000000000000000000000000000000000000000..2a896be3987daf9b20db6bff6b4f7c67b8c6e4c8 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/chemkin/therm.dat @@ -0,0 +1,15 @@ +THERMO ALL + 200.000 1000.000 5000.000 +H2O 20387H 2O 1 G 0200.00 5000.00 1000.00 1 + 0.02672146E+02 0.03056293E-01-0.08730260E-05 0.01200996E-08-0.06391618E-13 2 +-0.02989921E+06 0.06862817E+02 0.03386842E+02 0.03474982E-01-0.06354696E-04 3 + 0.06968581E-07-0.02506588E-10-0.03020811E+06 0.02590233E+02 4 +N2 121286N 2 G 0200.00 5000.00 1000.00 1 + 0.02926640E+02 0.01487977E-01-0.05684761E-05 0.01009704E-08-0.06753351E-13 2 +-0.09227977E+04 0.05980528E+02 0.03298677E+02 0.01408240E-01-0.03963222E-04 3 + 0.05641515E-07-0.02444855E-10-0.01020900E+05 0.03950372E+02 4 +O2 121386O 2 G 0200.00 5000.00 1000.00 1 + 0.03697578E+02 0.06135197E-02-0.01258842E-05 0.01775281E-09-0.01136435E-13 2 +-0.01233930E+05 0.03189166E+02 0.03212936E+02 0.01127486E-01-0.05756150E-05 3 + 0.01313877E-07-0.08768554E-11-0.01005249E+05 0.06034738E+02 4 +END diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/RASProperties b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/RASProperties new file mode 100644 index 0000000000000000000000000000000000000000..2e9369e9b41a659e217a6f8bac7a7b0c162006db --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/RASProperties @@ -0,0 +1,26 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object RASProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +RASModel kEpsilon; + +turbulence on; + +printCoeffs on; + + +// ************************************************************************* // +/* vim: set filetype=cpp : */ diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/additionalControls b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/additionalControls new file mode 100644 index 0000000000000000000000000000000000000000..8d9db83624adf74adb3fa8aba97dae2af20ce630 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/additionalControls @@ -0,0 +1,20 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object additionalControls; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvePrimaryRegion false; // true; + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/chemistryProperties b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/chemistryProperties new file mode 100644 index 0000000000000000000000000000000000000000..80376d01fb24e82befcecfce0d25d6a5b78436f1 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/chemistryProperties @@ -0,0 +1,49 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object chemistryProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +psiChemistryModel ODEChemistryModel<gasThermoPhysics>; + +chemistry off; + +turbulentReaction off; + +chemistrySolver ode; + +initialChemicalTimeStep 1e-07; + +sequentialCoeffs +{ + cTauChem 0.001; +} + +EulerImplicitCoeffs +{ + cTauChem 0.05; + equilibriumRateLimiter off; +} + +odeCoeffs +{ + ODESolver RK; + eps 0.05; + scale 1; +} + +Cmix Cmix [ 0 0 0 0 0 0 0 ] 1; + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/g b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/g new file mode 100644 index 0000000000000000000000000000000000000000..faba76bef3dec42aa00d8127c822db075a593d7e --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/g @@ -0,0 +1,23 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class uniformDimensionedVectorField; + location "constant"; + object g; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -2 0 0 0 0]; + +value (0 0 -9.81); + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/polyMesh/blockMeshDict b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/polyMesh/blockMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..f295e7dcadd10835ffbbbecbcdb450964bd9915e --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/polyMesh/blockMeshDict @@ -0,0 +1,77 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.7.x | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant/polyMesh"; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +convertToMeters 1; + +vertices +( + //back + ( 0 0 0) + ( 1.22 0 0) + ( 0 0.51 0) + ( 1.22 0.51 0) + + // front + ( 0 0 0.2) + ( 1.22 0 0.2) + ( 0 0.51 0.2) + ( 1.22 0.51 0.2) +); + +blocks +( + hex (0 1 3 2 4 5 7 6 ) (80 40 1) simpleGrading (1 1 1) +); + +edges +( +); + +patches +( + wall right + ( + (1 5 7 3) + ) + + wall top + ( + (4 5 7 6) + ) + + wall left + ( + (4 0 2 6) + ) + + wall frontAndBack + ( + (7 3 2 6) + (0 4 5 1) + ) + + wall filmWalls + ( + (0 1 3 2) + ) +); + +mergePatchPairs +( +); + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/polyMesh/boundary b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/polyMesh/boundary new file mode 100644 index 0000000000000000000000000000000000000000..1a24a5c0000e38c055eec2b4fb2ce3ea8df582d0 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/polyMesh/boundary @@ -0,0 +1,3260 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class polyBoundaryMesh; + location "constant/polyMesh"; + object boundary; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +5 +( + right + { + type wall; + nFaces 40; + startFace 6280; + } + top + { + type wall; + nFaces 3200; + startFace 6320; + } + left + { + type wall; + nFaces 40; + startFace 9520; + } + frontAndBack + { + type wall; + nFaces 160; + startFace 9560; + } + region0_to_wallFilmRegion_wallFilmFaces + { + type directMappedWall; + nFaces 3200; + startFace 9720; + sampleMode nearestPatchFace; + sampleRegion wallFilmRegion; + samplePatch region0_to_wallFilmRegion_wallFilmFaces; + offsets +3200 +( +(-0 -8.67361738e-19 -0) +(-1.734723476e-18 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-8.67361738e-19 -0 -0) +(-8.67361738e-19 -1.387778781e-17 -0) +(-8.67361738e-19 -1.387778781e-17 -0) +(-0 -1.387778781e-17 -0) +(-8.67361738e-19 -4.163336342e-17 -0) +(-1.734723476e-18 -2.775557562e-17 -0) +(-1.734723476e-18 -0 -0) +(-1.734723476e-18 -0 -0) +(-1.734723476e-18 -2.775557562e-17 -0) +(-1.734723476e-18 -0 -0) +(-1.734723476e-18 -0 -0) +(-1.734723476e-18 -0 -0) +(-1.734723476e-18 -0 -0) +(-1.734723476e-18 -2.775557562e-17 -0) +(-1.734723476e-18 -0 -0) +(-8.67361738e-19 -5.551115123e-17 -0) +(-0 -0 -0) +(-8.67361738e-19 -5.551115123e-17 -0) +(-1.734723476e-18 5.551115123e-17 -0) +(-8.67361738e-19 -0 -0) +(-0 -5.551115123e-17 -0) +(-8.67361738e-19 -5.551115123e-17 -0) +(-1.734723476e-18 -0 -0) +(-0 -0 -0) +(-1.734723476e-18 -0 -0) +(-8.67361738e-19 -0 -0) +(-8.67361738e-19 -5.551115123e-17 -0) +(-0 -0 -0) +(-8.67361738e-19 -5.551115123e-17 -0) +(-1.734723476e-18 -0 -0) +(-0 -0 -0) +(-8.67361738e-19 -1.110223025e-16 -0) +(-8.67361738e-19 -5.551115123e-17 -0) +(-0 -0 -0) +(-8.67361738e-19 -0 -0) +(3.469446952e-18 -8.67361738e-19 -0) +(-3.469446952e-18 -0 -0) +(-0 6.938893904e-18 -0) +(-3.469446952e-18 -0 -0) +(-3.469446952e-18 1.387778781e-17 -0) +(-3.469446952e-18 -0 -0) +(-3.469446952e-18 -1.387778781e-17 -0) +(-3.469446952e-18 -1.387778781e-17 -0) +(-0 -1.387778781e-17 -0) +(-3.469446952e-18 -4.163336342e-17 -0) +(-3.469446952e-18 -2.775557562e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -2.775557562e-17 -0) +(-3.469446952e-18 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-3.469446952e-18 -0 -0) +(-0 -2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-3.469446952e-18 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-3.469446952e-18 -5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-3.469446952e-18 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-3.469446952e-18 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-3.469446952e-18 -0 -0) +(-0 -1.110223025e-16 -0) +(-0 -5.551115123e-17 -0) +(-3.469446952e-18 -0 -0) +(-0 -0 -0) +(-0 -8.67361738e-19 -0) +(-6.938893904e-18 -0 -0) +(-6.938893904e-18 6.938893904e-18 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-6.938893904e-18 -1.387778781e-17 -0) +(6.938893904e-18 -1.387778781e-17 -0) +(-0 -1.387778781e-17 -0) +(-0 -4.163336342e-17 -0) +(-0 -2.775557562e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -2.775557562e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(6.938893904e-18 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(6.938893904e-18 -0 -0) +(-0 -0 -0) +(6.938893904e-18 -0 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(6.938893904e-18 -0 -0) +(-0 -0 -0) +(-0 -1.110223025e-16 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-1.387778781e-17 -0 -0) +(-0 -0 -0) +(-6.938893904e-18 -0 -0) +(-0 -1.387778781e-17 -0) +(-0 -1.387778781e-17 -0) +(6.938893904e-18 -1.387778781e-17 -0) +(6.938893904e-18 -1.387778781e-17 -0) +(6.938893904e-18 -4.163336342e-17 -0) +(-0 -0 -0) +(6.938893904e-18 -0 -0) +(1.387778781e-17 2.775557562e-17 -0) +(-6.938893904e-18 -5.551115123e-17 -0) +(-0 -0 -0) +(6.938893904e-18 -0 -0) +(1.387778781e-17 2.775557562e-17 -0) +(-0 -0 -0) +(6.938893904e-18 2.775557562e-17 -0) +(1.387778781e-17 2.775557562e-17 -0) +(-1.387778781e-17 -0 -0) +(-6.938893904e-18 -0 -0) +(-1.387778781e-17 -5.551115123e-17 -0) +(-1.387778781e-17 -5.551115123e-17 -0) +(-1.387778781e-17 -5.551115123e-17 -0) +(-6.938893904e-18 -5.551115123e-17 -0) +(-1.387778781e-17 -5.551115123e-17 -0) +(-1.387778781e-17 -0 -0) +(-6.938893904e-18 -0 -0) +(-1.387778781e-17 -5.551115123e-17 -0) +(-1.387778781e-17 -5.551115123e-17 -0) +(-1.387778781e-17 -1.110223025e-16 -0) +(-6.938893904e-18 -0 -0) +(-1.387778781e-17 -1.110223025e-16 -0) +(-1.387778781e-17 -5.551115123e-17 -0) +(-6.938893904e-18 -0 -0) +(-1.387778781e-17 -5.551115123e-17 -0) +(-1.387778781e-17 -1.110223025e-16 -0) +(-6.938893904e-18 -0 -0) +(-1.387778781e-17 -0 -0) +(1.387778781e-17 1.734723476e-18 -0) +(1.387778781e-17 6.938893904e-18 -0) +(-1.387778781e-17 -0 -0) +(-0 6.938893904e-18 -0) +(-1.387778781e-17 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -1.387778781e-17 -0) +(-1.387778781e-17 1.387778781e-17 -0) +(-0 -2.775557562e-17 -0) +(-1.387778781e-17 -0 -0) +(1.387778781e-17 -2.775557562e-17 -0) +(-1.387778781e-17 -0 -0) +(1.387778781e-17 -0 -0) +(-1.387778781e-17 2.775557562e-17 -0) +(1.387778781e-17 -0 -0) +(-1.387778781e-17 2.775557562e-17 -0) +(-1.387778781e-17 -0 -0) +(1.387778781e-17 -5.551115123e-17 -0) +(-1.387778781e-17 -5.551115123e-17 -0) +(1.387778781e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.387778781e-17 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 -1.110223025e-16 -0) +(1.387778781e-17 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(1.387778781e-17 5.551115123e-17 -0) +(1.387778781e-17 -5.551115123e-17 -0) +(1.387778781e-17 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(1.387778781e-17 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.387778781e-17 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.387778781e-17 1.734723476e-18 -0) +(1.387778781e-17 6.938893904e-18 -0) +(-0 6.938893904e-18 -0) +(1.387778781e-17 6.938893904e-18 -0) +(-0 -0 -0) +(1.387778781e-17 1.387778781e-17 -0) +(1.387778781e-17 -0 -0) +(1.387778781e-17 -1.387778781e-17 -0) +(-0 -0 -0) +(1.387778781e-17 -2.775557562e-17 -0) +(-0 -0 -0) +(1.387778781e-17 -2.775557562e-17 -0) +(-0 -0 -0) +(1.387778781e-17 -2.775557562e-17 -0) +(-0 2.775557562e-17 -0) +(1.387778781e-17 -0 -0) +(-0 -2.775557562e-17 -0) +(-0 -0 -0) +(1.387778781e-17 -5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(1.387778781e-17 -5.551115123e-17 -0) +(1.387778781e-17 -0 -0) +(-0 -0 -0) +(1.387778781e-17 -0 -0) +(-0 -5.551115123e-17 -0) +(1.387778781e-17 -1.110223025e-16 -0) +(1.387778781e-17 -5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(1.387778781e-17 -0 -0) +(1.387778781e-17 -5.551115123e-17 -0) +(1.387778781e-17 -5.551115123e-17 -0) +(1.387778781e-17 -0 -0) +(1.387778781e-17 -0 -0) +(-0 -5.551115123e-17 -0) +(1.387778781e-17 -0 -0) +(1.387778781e-17 -0 -0) +(-0 -0 -0) +(1.387778781e-17 -5.551115123e-17 -0) +(1.387778781e-17 1.110223025e-16 -0) +(-0 -0 -0) +(-0 1.734723476e-18 -0) +(1.387778781e-17 6.938893904e-18 -0) +(-1.387778781e-17 6.938893904e-18 -0) +(-1.387778781e-17 6.938893904e-18 -0) +(-2.775557562e-17 -0 -0) +(-1.387778781e-17 1.387778781e-17 -0) +(-1.387778781e-17 -0 -0) +(-1.387778781e-17 -1.387778781e-17 -0) +(-1.387778781e-17 -0 -0) +(-1.387778781e-17 -2.775557562e-17 -0) +(-1.387778781e-17 -0 -0) +(-2.775557562e-17 -2.775557562e-17 -0) +(-1.387778781e-17 -0 -0) +(-4.163336342e-17 -2.775557562e-17 -0) +(-1.387778781e-17 2.775557562e-17 -0) +(-2.775557562e-17 -0 -0) +(-1.387778781e-17 -2.775557562e-17 -0) +(-1.387778781e-17 -0 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(-1.387778781e-17 -5.551115123e-17 -0) +(-4.163336342e-17 -5.551115123e-17 -0) +(-2.775557562e-17 -0 -0) +(-2.775557562e-17 -0 -0) +(-4.163336342e-17 -0 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(-2.775557562e-17 -1.110223025e-16 -0) +(-4.163336342e-17 -5.551115123e-17 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(-2.775557562e-17 -0 -0) +(-4.163336342e-17 -5.551115123e-17 -0) +(-4.163336342e-17 -5.551115123e-17 -0) +(-4.163336342e-17 -0 -0) +(-2.775557562e-17 -0 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(-4.163336342e-17 -0 -0) +(-2.775557562e-17 -0 -0) +(-2.775557562e-17 -0 -0) +(-4.163336342e-17 -5.551115123e-17 -0) +(-2.775557562e-17 1.110223025e-16 -0) +(-2.775557562e-17 -0 -0) +(1.387778781e-17 1.734723476e-18 -0) +(4.163336342e-17 6.938893904e-18 -0) +(2.775557562e-17 -0 -0) +(1.387778781e-17 -0 -0) +(-2.775557562e-17 -1.387778781e-17 -0) +(-2.775557562e-17 -0 -0) +(-2.775557562e-17 -1.387778781e-17 -0) +(-2.775557562e-17 -1.387778781e-17 -0) +(-0 -2.775557562e-17 -0) +(-2.775557562e-17 -1.387778781e-17 -0) +(2.775557562e-17 2.775557562e-17 -0) +(-0 -2.775557562e-17 -0) +(2.775557562e-17 2.775557562e-17 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(2.775557562e-17 -2.775557562e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -2.775557562e-17 -0) +(-2.775557562e-17 -0 -0) +(-1.387778781e-17 -0 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(-2.775557562e-17 -1.110223025e-16 -0) +(-2.775557562e-17 -1.110223025e-16 -0) +(-1.387778781e-17 -5.551115123e-17 -0) +(-2.775557562e-17 -1.110223025e-16 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(-1.387778781e-17 -0 -0) +(-2.775557562e-17 -1.110223025e-16 -0) +(-2.775557562e-17 -1.110223025e-16 -0) +(-2.775557562e-17 -1.110223025e-16 -0) +(-1.387778781e-17 -0 -0) +(-2.775557562e-17 -1.110223025e-16 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(-1.387778781e-17 -0 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(-2.775557562e-17 -2.220446049e-16 -0) +(-1.387778781e-17 1.110223025e-16 -0) +(-2.775557562e-17 -0 -0) +(-0 -0 -0) +(-2.775557562e-17 -0 -0) +(-0 -0 -0) +(-2.775557562e-17 -6.938893904e-18 -0) +(-2.775557562e-17 -1.387778781e-17 -0) +(-2.775557562e-17 -0 -0) +(-2.775557562e-17 -1.387778781e-17 -0) +(-2.775557562e-17 -2.775557562e-17 -0) +(-0 -2.775557562e-17 -0) +(-2.775557562e-17 -2.775557562e-17 -0) +(-0 -5.551115123e-17 -0) +(-2.775557562e-17 -2.775557562e-17 -0) +(2.775557562e-17 -2.775557562e-17 -0) +(-0 2.775557562e-17 -0) +(-0 -2.775557562e-17 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(2.775557562e-17 -0 -0) +(-0 -5.551115123e-17 -0) +(-2.775557562e-17 -8.326672685e-17 -0) +(2.775557562e-17 2.775557562e-17 -0) +(2.775557562e-17 5.551115123e-17 -0) +(-0 -1.110223025e-16 -0) +(-0 5.551115123e-17 -0) +(2.775557562e-17 1.110223025e-16 -0) +(-0 1.110223025e-16 -0) +(-0 -5.551115123e-17 -0) +(2.775557562e-17 -0 -0) +(-0 -0 -0) +(-0 -1.110223025e-16 -0) +(2.775557562e-17 5.551115123e-17 -0) +(2.775557562e-17 5.551115123e-17 -0) +(2.775557562e-17 1.110223025e-16 -0) +(-0 -5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(2.775557562e-17 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(2.775557562e-17 1.110223025e-16 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(2.775557562e-17 -0 -0) +(2.775557562e-17 6.938893904e-18 -0) +(-2.775557562e-17 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.775557562e-17 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(2.775557562e-17 -0 -0) +(2.775557562e-17 -0 -0) +(2.775557562e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(2.775557562e-17 -0 -0) +(2.775557562e-17 -0 -0) +(5.551115123e-17 -0 -0) +(2.775557562e-17 2.775557562e-17 -0) +(5.551115123e-17 -0 -0) +(2.775557562e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.775557562e-17 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(2.775557562e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.775557562e-17 5.551115123e-17 -0) +(2.775557562e-17 -5.551115123e-17 -0) +(2.775557562e-17 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.775557562e-17 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(2.775557562e-17 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-2.775557562e-17 -0 -0) +(-0 -0 -0) +(-2.775557562e-17 -6.938893904e-18 -0) +(-0 6.938893904e-18 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(2.775557562e-17 2.775557562e-17 -0) +(-0 -0 -0) +(2.775557562e-17 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -2.775557562e-17 -0) +(-0 -0 -0) +(2.775557562e-17 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -2.775557562e-17 -0) +(2.775557562e-17 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-8.326672685e-17 -1.110223025e-16 -0) +(-0 5.551115123e-17 -0) +(-2.775557562e-17 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-8.326672685e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(-8.326672685e-17 -1.665334537e-16 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-8.326672685e-17 -1.110223025e-16 -0) +(-0 -0 -0) +(-2.775557562e-17 -0 -0) +(-8.326672685e-17 -1.665334537e-16 -0) +(-0 -5.551115123e-17 -0) +(-0 -1.110223025e-16 -0) +(-8.326672685e-17 -2.220446049e-16 -0) +(-0 -0 -0) +(-0 -8.67361738e-19 -0) +(2.775557562e-17 -6.938893904e-18 -0) +(-2.775557562e-17 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -0 -0) +(2.775557562e-17 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-2.775557562e-17 1.387778781e-17 -0) +(-0 -0 -0) +(-2.775557562e-17 -0 -0) +(2.775557562e-17 -0 -0) +(-2.775557562e-17 -0 -0) +(-0 -0 -0) +(-2.775557562e-17 -0 -0) +(2.775557562e-17 -0 -0) +(-0 -0 -0) +(-2.775557562e-17 2.775557562e-17 -0) +(2.775557562e-17 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-2.775557562e-17 -0 -0) +(-0 -6.938893904e-18 -0) +(-0 -0 -0) +(-2.775557562e-17 -0 -0) +(-0 -0 -0) +(-5.551115123e-17 -0 -0) +(-2.775557562e-17 -0 -0) +(2.775557562e-17 -0 -0) +(-0 -0 -0) +(-0 -2.775557562e-17 -0) +(-0 2.775557562e-17 -0) +(2.775557562e-17 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.775557562e-17 2.775557562e-17 -0) +(-0 -2.775557562e-17 -0) +(-0 2.775557562e-17 -0) +(2.775557562e-17 5.551115123e-17 -0) +(-2.775557562e-17 -1.110223025e-16 -0) +(-2.775557562e-17 5.551115123e-17 -0) +(2.775557562e-17 1.110223025e-16 -0) +(-2.775557562e-17 1.110223025e-16 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(2.775557562e-17 5.551115123e-17 -0) +(-2.775557562e-17 -0 -0) +(-2.775557562e-17 -1.110223025e-16 -0) +(2.775557562e-17 5.551115123e-17 -0) +(2.775557562e-17 5.551115123e-17 -0) +(2.775557562e-17 1.110223025e-16 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(-2.775557562e-17 5.551115123e-17 -0) +(2.775557562e-17 5.551115123e-17 -0) +(-2.775557562e-17 -5.551115123e-17 -0) +(-2.775557562e-17 5.551115123e-17 -0) +(2.775557562e-17 1.110223025e-16 -0) +(-2.775557562e-17 -1.665334537e-16 -0) +(-2.775557562e-17 -0 -0) +(-5.551115123e-17 -8.67361738e-19 -0) +(-5.551115123e-17 -6.938893904e-18 -0) +(-0 -0 -0) +(2.775557562e-17 6.938893904e-18 -0) +(-2.775557562e-17 -0 -0) +(-2.775557562e-17 1.387778781e-17 -0) +(-0 -0 -0) +(-2.775557562e-17 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(2.775557562e-17 -0 -0) +(2.775557562e-17 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.775557562e-17 -0 -0) +(2.775557562e-17 -0 -0) +(-0 -0 -0) +(2.775557562e-17 -0 -0) +(2.775557562e-17 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(2.775557562e-17 -0 -0) +(-0 5.551115123e-17 -0) +(2.775557562e-17 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(2.775557562e-17 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(2.775557562e-17 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(2.775557562e-17 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.775557562e-17 1.110223025e-16 -0) +(2.775557562e-17 -0 -0) +(2.775557562e-17 -0 -0) +(-5.551115123e-17 -6.938893904e-18 -0) +(2.775557562e-17 6.938893904e-18 -0) +(-2.775557562e-17 -0 -0) +(2.775557562e-17 -0 -0) +(2.775557562e-17 1.387778781e-17 -0) +(2.775557562e-17 1.387778781e-17 -0) +(-0 2.775557562e-17 -0) +(2.775557562e-17 -0 -0) +(-2.775557562e-17 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -2.775557562e-17 -0) +(-0 -0 -0) +(-2.775557562e-17 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -2.775557562e-17 -0) +(-2.775557562e-17 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-5.551115123e-17 -1.110223025e-16 -0) +(-8.326672685e-17 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-8.326672685e-17 5.551115123e-17 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-8.326672685e-17 -5.551115123e-17 -0) +(-5.551115123e-17 -1.665334537e-16 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 -1.110223025e-16 -0) +(-8.326672685e-17 -0 -0) +(-0 -0 -0) +(-5.551115123e-17 -1.665334537e-16 -0) +(-8.326672685e-17 -5.551115123e-17 -0) +(-0 -1.110223025e-16 -0) +(-5.551115123e-17 -2.220446049e-16 -0) +(-8.326672685e-17 -0 -0) +(-8.326672685e-17 -8.67361738e-19 -0) +(-8.326672685e-17 -6.938893904e-18 -0) +(-0 -0 -0) +(2.775557562e-17 6.938893904e-18 -0) +(-2.775557562e-17 -0 -0) +(2.775557562e-17 1.387778781e-17 -0) +(2.775557562e-17 -0 -0) +(2.775557562e-17 -0 -0) +(-0 1.387778781e-17 -0) +(2.775557562e-17 1.387778781e-17 -0) +(-2.775557562e-17 -0 -0) +(-0 -0 -0) +(2.775557562e-17 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.775557562e-17 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(5.551115123e-17 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(-0 -0 -0) +(5.551115123e-17 6.938893904e-18 -0) +(-0 -0 -0) +(5.551115123e-17 1.387778781e-17 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 1.387778781e-17 -0) +(5.551115123e-17 1.387778781e-17 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 2.775557562e-17 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(5.551115123e-17 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-0 8.67361738e-19 -0) +(5.551115123e-17 3.469446952e-18 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -1.387778781e-17 -0) +(-0 -2.775557562e-17 -0) +(-0 -0 -0) +(-0 -1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -2.775557562e-17 -0) +(-0 -2.775557562e-17 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(-0 -2.775557562e-17 -0) +(-0 2.775557562e-17 -0) +(-5.551115123e-17 -1.110223025e-16 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-5.551115123e-17 -1.110223025e-16 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -5.551115123e-17 -0) +(-5.551115123e-17 -1.110223025e-16 -0) +(-0 1.110223025e-16 -0) +(-0 -1.110223025e-16 -0) +(-5.551115123e-17 -1.110223025e-16 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-5.551115123e-17 -1.110223025e-16 -0) +(5.551115123e-17 -8.67361738e-19 -0) +(5.551115123e-17 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-5.551115123e-17 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(5.551115123e-17 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 2.775557562e-17 -0) +(-0 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(5.551115123e-17 1.110223025e-16 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-5.551115123e-17 -8.67361738e-19 -0) +(-5.551115123e-17 -6.938893904e-18 -0) +(-5.551115123e-17 -0 -0) +(1.110223025e-16 6.938893904e-18 -0) +(-5.551115123e-17 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 1.387778781e-17 -0) +(1.110223025e-16 1.387778781e-17 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 2.775557562e-17 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(5.551115123e-17 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-5.551115123e-17 -8.67361738e-19 -0) +(-5.551115123e-17 -6.938893904e-18 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-5.551115123e-17 1.387778781e-17 -0) +(-0 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(1.110223025e-16 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 2.775557562e-17 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(5.551115123e-17 1.110223025e-16 -0) +(-5.551115123e-17 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(-0 5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(-0 1.110223025e-16 -0) +(-0 8.67361738e-19 -0) +(5.551115123e-17 3.469446952e-18 -0) +(-5.551115123e-17 -0 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -1.387778781e-17 -0) +(-0 -2.775557562e-17 -0) +(-0 -0 -0) +(-5.551115123e-17 -1.387778781e-17 -0) +(-0 -2.775557562e-17 -0) +(-5.551115123e-17 -0 -0) +(-0 -2.775557562e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(5.551115123e-17 -0 -0) +(-5.551115123e-17 2.775557562e-17 -0) +(-0 -2.775557562e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-5.551115123e-17 -2.775557562e-17 -0) +(-0 2.775557562e-17 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-5.551115123e-17 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-5.551115123e-17 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 -1.110223025e-16 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-5.551115123e-17 -8.67361738e-19 -0) +(-5.551115123e-17 -6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(5.551115123e-17 6.938893904e-18 -0) +(-5.551115123e-17 -0 -0) +(-0 1.387778781e-17 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(5.551115123e-17 1.387778781e-17 -0) +(5.551115123e-17 1.387778781e-17 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 2.775557562e-17 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-0 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(5.551115123e-17 1.110223025e-16 -0) +(-0 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(5.551115123e-17 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(-0 -0 -0) +(-5.551115123e-17 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-5.551115123e-17 1.387778781e-17 -0) +(-5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(-5.551115123e-17 1.387778781e-17 -0) +(-5.551115123e-17 1.387778781e-17 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 2.775557562e-17 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(5.551115123e-17 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(-5.551115123e-17 -0 -0) +(-0 6.938893904e-18 -0) +(-5.551115123e-17 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(5.551115123e-17 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-5.551115123e-17 -0 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-5.551115123e-17 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-5.551115123e-17 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-5.551115123e-17 1.110223025e-16 -0) +(-5.551115123e-17 8.67361738e-19 -0) +(-0 3.469446952e-18 -0) +(-1.665334537e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-5.551115123e-17 6.938893904e-18 -0) +(-1.110223025e-16 -1.387778781e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-1.665334537e-16 -0 -0) +(-5.551115123e-17 -1.387778781e-17 -0) +(-1.665334537e-16 -2.775557562e-17 -0) +(5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(-5.551115123e-17 -2.775557562e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(5.551115123e-17 -2.775557562e-17 -0) +(-5.551115123e-17 2.775557562e-17 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 1.110223025e-16 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(5.551115123e-17 1.110223025e-16 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-5.551115123e-17 -1.110223025e-16 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-5.551115123e-17 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-5.551115123e-17 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(5.551115123e-17 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(-5.551115123e-17 2.775557562e-17 -0) +(1.110223025e-16 -0 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-5.551115123e-17 5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(-5.551115123e-17 1.110223025e-16 -0) +(-5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(-5.551115123e-17 5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(-5.551115123e-17 -0 -0) +(-5.551115123e-17 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(5.551115123e-17 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-5.551115123e-17 -0 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-1.110223025e-16 -0 -0) +(-5.551115123e-17 -0 -0) +(-0 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-5.551115123e-17 5.551115123e-17 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-5.551115123e-17 1.110223025e-16 -0) +(-5.551115123e-17 -8.67361738e-19 -0) +(-5.551115123e-17 -6.938893904e-18 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 6.938893904e-18 -0) +(-5.551115123e-17 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(1.110223025e-16 8.67361738e-19 -0) +(1.110223025e-16 3.469446952e-18 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 6.938893904e-18 -0) +(-1.110223025e-16 -1.387778781e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-1.110223025e-16 -0 -0) +(-5.551115123e-17 -1.387778781e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-5.551115123e-17 -0 -0) +(-5.551115123e-17 -2.775557562e-17 -0) +(-0 -2.775557562e-17 -0) +(-0 -0 -0) +(-5.551115123e-17 2.775557562e-17 -0) +(-5.551115123e-17 -2.775557562e-17 -0) +(-0 -5.551115123e-17 -0) +(-5.551115123e-17 -2.775557562e-17 -0) +(-5.551115123e-17 2.775557562e-17 -0) +(-0 -1.110223025e-16 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 -0 -0) +(-1.665334537e-16 -5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-1.665334537e-16 -0 -0) +(-5.551115123e-17 -0 -0) +(-0 -0 -0) +(-1.665334537e-16 -1.110223025e-16 -0) +(-5.551115123e-17 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(-1.665334537e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 -1.110223025e-16 -0) +(-1.665334537e-16 -1.110223025e-16 -0) +(-0 5.551115123e-17 -0) +(-5.551115123e-17 -5.551115123e-17 -0) +(-1.665334537e-16 -1.110223025e-16 -0) +(-5.551115123e-17 -8.67361738e-19 -0) +(-1.665334537e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-5.551115123e-17 1.387778781e-17 -0) +(-0 -0 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(5.551115123e-17 -0 -0) +(1.110223025e-16 -0 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -0 -0) +(-0 2.775557562e-17 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(-0 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-0 -0 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(5.551115123e-17 -5.551115123e-17 -0) +(5.551115123e-17 1.110223025e-16 -0) +(-0 -0 -0) +(5.551115123e-17 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(-0 -0 -0) +(5.551115123e-17 5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(5.551115123e-17 1.110223025e-16 -0) +(-5.551115123e-17 -8.67361738e-19 -0) +(-5.551115123e-17 -6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-0 6.938893904e-18 -0) +(-5.551115123e-17 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-5.551115123e-17 -0 -0) +(-0 1.387778781e-17 -0) +(-5.551115123e-17 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-5.551115123e-17 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-5.551115123e-17 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-5.551115123e-17 -0 -0) +(-0 -5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(5.551115123e-17 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(5.551115123e-17 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(5.551115123e-17 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(5.551115123e-17 -0 -0) +(-0 1.110223025e-16 -0) +(-5.551115123e-17 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(-5.551115123e-17 -0 -0) +(5.551115123e-17 6.938893904e-18 -0) +(-0 -0 -0) +(1.665334537e-16 1.387778781e-17 -0) +(1.665334537e-16 -0 -0) +(1.665334537e-16 -0 -0) +(-1.110223025e-16 1.387778781e-17 -0) +(1.665334537e-16 1.387778781e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 2.775557562e-17 -0) +(-0 -0 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -6.938893904e-18 -0) +(-0 6.938893904e-18 -0) +(-1.110223025e-16 -1.387778781e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -1.387778781e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-1.110223025e-16 -8.326672685e-17 -0) +(-1.110223025e-16 -8.326672685e-17 -0) +(-1.110223025e-16 -8.326672685e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -1.665334537e-16 -0) +(-0 -1.110223025e-16 -0) +(-1.110223025e-16 -0 -0) +(-0 -1.110223025e-16 -0) +(-1.110223025e-16 -1.665334537e-16 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -1.665334537e-16 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-1.110223025e-16 5.551115123e-17 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-1.110223025e-16 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(-1.110223025e-16 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-2.220446049e-16 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-1.110223025e-16 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(1.110223025e-16 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(1.110223025e-16 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 2.775557562e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-2.220446049e-16 -1.387778781e-17 -0) +(-2.220446049e-16 6.938893904e-18 -0) +(-2.220446049e-16 -1.387778781e-17 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 -1.387778781e-17 -0) +(-2.220446049e-16 -2.775557562e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-2.220446049e-16 -2.775557562e-17 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-3.330669074e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-2.220446049e-16 -2.775557562e-17 -0) +(-2.220446049e-16 -8.326672685e-17 -0) +(-1.110223025e-16 -8.326672685e-17 -0) +(-2.220446049e-16 2.775557562e-17 -0) +(-2.220446049e-16 -8.326672685e-17 -0) +(-3.330669074e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-2.220446049e-16 -1.110223025e-16 -0) +(-3.330669074e-16 -5.551115123e-17 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-3.330669074e-16 -1.110223025e-16 -0) +(-2.220446049e-16 -1.110223025e-16 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-3.330669074e-16 -1.110223025e-16 -0) +(-3.330669074e-16 -1.665334537e-16 -0) +(-3.330669074e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-3.330669074e-16 -1.665334537e-16 -0) +(-1.110223025e-16 -1.665334537e-16 -0) +(-2.220446049e-16 -1.665334537e-16 -0) +(-3.330669074e-16 -1.665334537e-16 -0) +(-1.110223025e-16 -1.665334537e-16 -0) +(-2.220446049e-16 -1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-1.110223025e-16 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 1.387778781e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(-1.110223025e-16 1.387778781e-17 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 2.775557562e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-0 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-1.110223025e-16 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(1.110223025e-16 -0 -0) +(-0 6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(1.110223025e-16 6.938893904e-18 -0) +(-0 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(1.110223025e-16 -0 -0) +(2.220446049e-16 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(1.110223025e-16 1.387778781e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(1.110223025e-16 6.938893904e-18 -0) +(-1.110223025e-16 -1.387778781e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-2.220446049e-16 -1.387778781e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-0 -2.775557562e-17 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-3.330669074e-16 -5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-2.220446049e-16 -2.775557562e-17 -0) +(-1.110223025e-16 -8.326672685e-17 -0) +(-0 -8.326672685e-17 -0) +(-2.220446049e-16 -2.775557562e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-3.330669074e-16 -5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-3.330669074e-16 -5.551115123e-17 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-3.330669074e-16 -1.110223025e-16 -0) +(-2.220446049e-16 -1.110223025e-16 -0) +(-2.220446049e-16 -0 -0) +(-3.330669074e-16 -1.110223025e-16 -0) +(-3.330669074e-16 -1.665334537e-16 -0) +(-3.330669074e-16 -1.110223025e-16 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(-3.330669074e-16 -1.665334537e-16 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 -1.665334537e-16 -0) +(-3.330669074e-16 -1.110223025e-16 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-2.220446049e-16 -1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-0 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-1.110223025e-16 1.387778781e-17 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 2.775557562e-17 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 1.387778781e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(-1.110223025e-16 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 6.938893904e-18 -0) +(-3.330669074e-16 -0 -0) +(-0 1.387778781e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(1.110223025e-16 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 1.387778781e-17 -0) +(1.110223025e-16 1.387778781e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 2.775557562e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 1.110223025e-16 -0) +(-2.220446049e-16 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 2.775557562e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(2.220446049e-16 1.387778781e-17 -0) +(-0 -0 -0) +(3.330669074e-16 -0 -0) +(-0 -0 -0) +(3.330669074e-16 -0 -0) +(-0 -0 -0) +(3.330669074e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(3.330669074e-16 2.775557562e-17 -0) +(-0 -0 -0) +(3.330669074e-16 -5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(3.330669074e-16 -0 -0) +(3.330669074e-16 5.551115123e-17 -0) +(3.330669074e-16 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(3.330669074e-16 -5.551115123e-17 -0) +(3.330669074e-16 -0 -0) +(1.110223025e-16 -0 -0) +(3.330669074e-16 5.551115123e-17 -0) +(3.330669074e-16 -5.551115123e-17 -0) +(3.330669074e-16 1.110223025e-16 -0) +(1.110223025e-16 -0 -0) +(3.330669074e-16 -0 -0) +(3.330669074e-16 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(3.330669074e-16 5.551115123e-17 -0) +(3.330669074e-16 -0 -0) +(1.110223025e-16 -0 -0) +(3.330669074e-16 1.110223025e-16 -0) +(-2.220446049e-16 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(2.220446049e-16 -0 -0) +(1.110223025e-16 -0 -0) +(2.220446049e-16 -0 -0) +(1.110223025e-16 -0 -0) +(2.220446049e-16 -0 -0) +(1.110223025e-16 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(1.110223025e-16 2.775557562e-17 -0) +(2.220446049e-16 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-3.330669074e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-3.330669074e-16 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-3.330669074e-16 -0 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-3.330669074e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(-3.330669074e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-3.330669074e-16 -0 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(-1.110223025e-16 -1.387778781e-17 -0) +(-0 6.938893904e-18 -0) +(-3.330669074e-16 -1.387778781e-17 -0) +(-1.110223025e-16 -0 -0) +(-3.330669074e-16 -0 -0) +(-2.220446049e-16 -1.387778781e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -2.775557562e-17 -0) +(-2.220446049e-16 -8.326672685e-17 -0) +(-1.110223025e-16 -8.326672685e-17 -0) +(-1.110223025e-16 2.775557562e-17 -0) +(-2.220446049e-16 -8.326672685e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-0 -5.551115123e-17 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-1.110223025e-16 -1.665334537e-16 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -1.665334537e-16 -0) +(-0 -1.665334537e-16 -0) +(-1.110223025e-16 -1.665334537e-16 -0) +(-1.110223025e-16 -1.665334537e-16 -0) +(-0 -1.665334537e-16 -0) +(-1.110223025e-16 -1.110223025e-16 -0) +(-3.330669074e-16 -8.67361738e-19 -0) +(-3.330669074e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(1.110223025e-16 6.938893904e-18 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(1.110223025e-16 1.387778781e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(2.220446049e-16 -5.551115123e-17 -0) +(2.220446049e-16 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(1.110223025e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-2.220446049e-16 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-2.220446049e-16 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-2.220446049e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 2.775557562e-17 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(3.330669074e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(3.330669074e-16 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(3.330669074e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-2.220446049e-16 -0 -0) +(3.330669074e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(3.330669074e-16 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(3.330669074e-16 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(-2.220446049e-16 6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(2.220446049e-16 1.387778781e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(3.330669074e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(3.330669074e-16 -0 -0) +(1.110223025e-16 2.775557562e-17 -0) +(3.330669074e-16 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 2.775557562e-17 -0) +(1.110223025e-16 -0 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-1.110223025e-16 -5.551115123e-17 -0) +(-1.110223025e-16 1.110223025e-16 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-2.220446049e-16 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(-0 -0 -0) +(1.110223025e-16 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(1.110223025e-16 1.387778781e-17 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 1.387778781e-17 -0) +(1.110223025e-16 1.387778781e-17 -0) +(2.220446049e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(1.110223025e-16 -0 -0) +(2.220446049e-16 -0 -0) +(1.110223025e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(1.110223025e-16 2.775557562e-17 -0) +(-0 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -5.551115123e-17 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-2.220446049e-16 -0 -0) +(1.110223025e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(1.110223025e-16 5.551115123e-17 -0) +(1.110223025e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(1.110223025e-16 1.110223025e-16 -0) +(-1.110223025e-16 -8.67361738e-19 -0) +(-1.110223025e-16 -6.938893904e-18 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 6.938893904e-18 -0) +(-1.110223025e-16 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(-1.110223025e-16 1.387778781e-17 -0) +(2.220446049e-16 1.387778781e-17 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 -0 -0) +(-1.110223025e-16 2.775557562e-17 -0) +(-1.110223025e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-2.220446049e-16 2.775557562e-17 -0) +(-0 -0 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-2.220446049e-16 1.110223025e-16 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-2.220446049e-16 6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-2.220446049e-16 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(-0 -0 -0) +(2.220446049e-16 6.938893904e-18 -0) +(-0 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(2.220446049e-16 1.387778781e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(-0 2.775557562e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-4.440892099e-16 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 1.387778781e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 2.775557562e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 5.551115123e-17 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.220446049e-16 1.110223025e-16 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 -2.081668171e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -1.387778781e-17 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -2.775557562e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 1.665334537e-16 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -1.110223025e-16 -0) +(-0 -0 -0) +(-2.220446049e-16 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 1.110223025e-16 -0) +(-2.220446049e-16 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(2.220446049e-16 -0 -0) +(-0 6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(-0 2.775557562e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(2.220446049e-16 -0 -0) +(-0 6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(2.220446049e-16 -5.551115123e-17 -0) +(2.220446049e-16 1.110223025e-16 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 1.110223025e-16 -0) +(-2.220446049e-16 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-2.220446049e-16 6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(-0 1.387778781e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(2.220446049e-16 1.387778781e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 2.775557562e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 1.110223025e-16 -0) +(-2.220446049e-16 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(2.220446049e-16 6.938893904e-18 -0) +(-0 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(4.440892099e-16 -0 -0) +(2.220446049e-16 -0 -0) +(-0 1.387778781e-17 -0) +(4.440892099e-16 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-2.220446049e-16 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(-0 -0 -0) +(-0 6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-2.220446049e-16 2.775557562e-17 -0) +(2.220446049e-16 -0 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(-2.220446049e-16 -5.551115123e-17 -0) +(-2.220446049e-16 1.110223025e-16 -0) +(-0 -0 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(-0 -0 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-2.220446049e-16 1.110223025e-16 -0) +(-4.440892099e-16 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(2.220446049e-16 -0 -0) +(-0 6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-2.220446049e-16 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(4.440892099e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(4.440892099e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 2.775557562e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(4.440892099e-16 5.551115123e-17 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 -0 -0) +(4.440892099e-16 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(2.220446049e-16 -0 -0) +(-2.220446049e-16 -0 -0) +(4.440892099e-16 5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-2.220446049e-16 5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-2.220446049e-16 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-0 -6.938893904e-18 -0) +(2.220446049e-16 -0 -0) +(-0 6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.220446049e-16 1.387778781e-17 -0) +(-0 1.387778781e-17 -0) +(4.440892099e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(4.440892099e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(4.440892099e-16 -0 -0) +(-0 2.775557562e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -5.551115123e-17 -0) +(-0 1.110223025e-16 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 5.551115123e-17 -0) +(-0 -0 -0) +(-0 -0 -0) +(-0 1.110223025e-16 -0) +(-0 -8.67361738e-19 -0) +(-2.220446049e-16 -6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(-2.220446049e-16 6.938893904e-18 -0) +(-2.220446049e-16 -0 -0) +(-0 1.387778781e-17 -0) +(-2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 1.387778781e-17 -0) +(-2.220446049e-16 1.387778781e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(-0 -0 -0) +(2.220446049e-16 2.775557562e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 -5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(2.220446049e-16 -5.551115123e-17 -0) +(2.220446049e-16 1.110223025e-16 -0) +(-0 -0 -0) +(2.220446049e-16 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(-0 -0 -0) +(2.220446049e-16 5.551115123e-17 -0) +(2.220446049e-16 -0 -0) +(-0 -0 -0) +(2.220446049e-16 1.110223025e-16 -0) +) +; + } +) + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/radiationProperties b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/radiationProperties new file mode 100644 index 0000000000000000000000000000000000000000..82dd1f0fef7920062dbb82043a12b65be6931cbc --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/radiationProperties @@ -0,0 +1,23 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object radiationProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +radiation off; + +radiationModel none; + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/reactingCloud1Properties b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/reactingCloud1Properties new file mode 100644 index 0000000000000000000000000000000000000000..3f3b7a8aac97e8a4427f5e4c6e5608d44d280312 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/reactingCloud1Properties @@ -0,0 +1,111 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object reactingCloud1Properties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +active false; // true; + +InjectionModel none; + +DragModel SphereDrag; + +DispersionModel none; + +PatchInteractionModel StandardWallInteraction; + +CollisionModel none; + +HeatTransferModel none; + +CompositionModel SinglePhaseMixture; + +PhaseChangeModel none; + +PostProcessingModel none; + +SurfaceFilmModel ThermoSurfaceFilm; + +radiation off; + +coupled true; + +cellValueSourceCorrection on; + +parcelTypeId 1; + +constantProperties +{ + rhoMin rhoMin [ 1 -3 0 0 0 ] 1e-15; + TMin TMin [ 0 0 0 1 0 ] 200; + pMin pMin [ 1 -1 2 0 0 ] 1000; + rho0 rho0 [ 1 -3 0 0 0 ] 1000; + minParticleMass minParticleMass [ 1 0 0 0 0 ] 1e-15; + T0 T0 [ 0 0 0 1 0 ] 300; + cp0 cp0 [ 0 2 -2 -1 0 ] 4187; + epsilon0 epsilon0 [ 0 0 0 0 0 ] 1; + f0 f0 [ 0 0 0 0 0 ] 0.5; + Pr Pr [ 0 0 0 0 0 ] 0.7; + Tvap Tvap [ 0 0 0 1 0 ] 273; + Tbp Tvap [ 0 0 0 1 0 ] 373; + constantVolume false; + youngsModulus youngsModulus [ 0 0 0 0 0 ] 0; + poissonsRatio poissonsRatio [ 0 0 0 0 0 ] 0; +} + +interpolationSchemes +{ + rho cell; + U cell; // cellPoint; + mu cell; + T cell; + Cp cell; + p cell; +} + +integrationSchemes +{ + U Euler; + T Analytical; +} + +particleForces +{ + gravity on; + virtualMass off; + pressureGradient off; + paramagnetic off; +} + +StandardWallInteractionCoeffs +{ + type rebound; +} + +SinglePhaseMixtureCoeffs +{ + phases + ( + liquid + { + H2O 1; + } + ); +} + +ThermoSurfaceFilmCoeffs +{} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/surfaceFilmProperties b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/surfaceFilmProperties new file mode 100644 index 0000000000000000000000000000000000000000..83ef5e9e8dfba2e460f6313ab78157105ebf8f16 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/surfaceFilmProperties @@ -0,0 +1,90 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object SurfaceFilmProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +surfaceFilmModel thermoSingleLayer; + +filmRegionName wallFilmRegion; + +active true; + +kinematicSingleLayerCoeffs +{ + thermoModel constant; + rho0 rho0 [1 -3 0 0 0] 1000; + mu0 mu0 [1 -1 -1 0 0] 1e-3; + sigma0 sigma0 [1 0 -2 0 0] 0.07; + + deltaStable deltaStable [0 1 0 0 0] 0; + Cf 0.005; + + injectionModel none; +} + +thermoSingleLayerCoeffs +{ + thermoModel singleComponent; // constant +// thermoModel constant; // constant + liquid H2O; +// rho0 rho0 [1 -3 0 0 0] 1000; +// mu0 mu0 [1 -1 -1 0 0] 1e-3; +// sigma0 sigma0 [1 0 -2 0 0] 0.07; +// cp0 cp0 [0 2 -2 -1 0] 4187; + + deltaStable deltaStable [0 1 0 0 0] 0; + Cf 0.005; + htcw htcw [1 0 -3 -1 0] 1e3; // 0.0; + htcs htcs [1 0 -3 -1 0] 1e-8; // 0.0; + + rho0 rho [1 -3 0 0 0] 1000; + mu0 mu [1 -1 -1 0 0] 1e-3; + sigma0 sigma [1 0 -2 0 0] 0.07; + cp0 cp [0 2 -2 -1 0] 4187; + kappa0 kappa0 [1 1 -3 -1 0] 0.6; + + injectionModel none; + + phaseChangeModel standardPhaseChange; // only option currently available + //phaseChangeModel none; // only option currently available + standardPhaseChangeCoeffs + { + Tb 374.8; + deltaMin 1e-8; // mass transfer turned off when film thickness below this value + L 1; // length scale used in mean Nusselt and Sherwood correlation + } + + upperSurfaceModels + { + //heatTransferModel mappedConvectiveHeatTransfer; // gets htc from gas-phase calculation + heatTransferModel constant; // submodels/thermo/heatTransferModel/constantHeatTransfer/constantHeatTransfer.C + constantCoeffs + { + c0 1000; + } + } + + lowerSurfaceModels + { + heatTransferModel constant; // submodels/thermo/heatTransferModel/constantHeatTransfer/constantHeatTransfer.C + constantCoeffs + { +// c0 50; + c0 1000; + } + } + +} + diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/thermophysicalProperties b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/thermophysicalProperties new file mode 100644 index 0000000000000000000000000000000000000000..01f72e1ffe25584cd9f7ed7958b0d37e6f917769 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/thermophysicalProperties @@ -0,0 +1,47 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +thermoType hsPsiMixtureThermo<reactingMixture<gasThermoPhysics>>; + +chemistryReader foamChemistryReader; + +foamChemistryFile "$FOAM_CASE/chemkin/foam.inp"; + +foamChemistryThermoFile "$FOAM_CASE/chemkin/foam.dat"; + +inertSpecie N2; + + +liquids +{ + liquidComponents + ( + H2O + ); + + H2O H2O defaultCoeffs; +} + + +solids +{ + solidComponents + (); +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/turbulenceProperties b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/turbulenceProperties new file mode 100644 index 0000000000000000000000000000000000000000..9cfc50a3d927937cf2ce96c64d3c9d6bd3144e2c --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/constant/turbulenceProperties @@ -0,0 +1,21 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType laminar; + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/controlDict b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/controlDict new file mode 100644 index 0000000000000000000000000000000000000000..2e84d85b10565b63e68995ef8c038c3050575a8a --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/controlDict @@ -0,0 +1,55 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.7.x | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application reactingParcelFoam; + +startFrom latestTime; + +startTime 0; + +stopAt endTime; + +endTime 10; + +deltaT 1e-02; + +writeControl adjustableRunTime; + +writeInterval 0.05; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 10; + +writeCompression uncompressed; + +timeFormat general; + +timePrecision 6; + +runTimeModifiable yes; + +adjustTimeStep no; + +maxCo 0.5; + +maxDeltaT 1e-03; + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/decomposeParDict b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/decomposeParDict new file mode 100644 index 0000000000000000000000000000000000000000..c9ff16db1b345392a1182e12fe586f41286ea851 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/decomposeParDict @@ -0,0 +1,50 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object decomposeParDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +numberOfSubdomains 8; + +method metis; + +simpleCoeffs +{ + n ( 2 2 1 ); + delta 0.001; +} + +hierarchicalCoeffs +{ + n ( 1 1 1 ); + delta 0.001; + order xyz; +} + +metisCoeffs +{ + processorWeights ( 1 1 1 1 1 1 1 1 ); +} + +manualCoeffs +{ + dataFile ""; +} + +distributed no; + +roots ( ); + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/fvSchemes b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/fvSchemes new file mode 100644 index 0000000000000000000000000000000000000000..8b3b34e9f04f336e4175eb5d0f07a21038362343 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/fvSchemes @@ -0,0 +1,64 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + default Gauss linear; + grad(p) Gauss linear; +} + +divSchemes +{ + default none; + div(phi,U) Gauss upwind; + div(phiU,p) Gauss upwind; + div(phi,h) Gauss upwind; + div(phi,k) Gauss upwind; + div(phi,epsilon) Gauss upwind; + div(U) Gauss linear; + div((muEff*dev2(grad(U).T()))) Gauss linear; + div(phi,Yi_h) Gauss upwind; +} + +laplacianSchemes +{ + default Gauss linear limited 0.5; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default limited 0.5; +} + +fluxRequired +{ + default no; + p; +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/fvSolution b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/fvSolution new file mode 100644 index 0000000000000000000000000000000000000000..4f2b05997984cbf4e39cdcbb6ae0d45544703a8d --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/fvSolution @@ -0,0 +1,62 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + "(rho|G)" + { + solver PCG; + preconditioner DIC; + tolerance 1e-05; + relTol 0; + } + + "(U|h|k|epsilon)" + { + solver PBiCG; + preconditioner DILU; + tolerance 1e-05; + relTol 0; + } + + p + { + solver PCG; + preconditioner DIC; + tolerance 1e-06; + relTol 0; + } + + "(hs|Yi|O2|N2|H2O)" + { + solver PBiCG; + preconditioner DILU; + tolerance 1e-06; + relTol 0; + } +} + +PISO +{ + transonic no; + nCorrectors 2; + nNonOrthogonalCorrectors 0; + momentumPredictor yes; +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/wallFilmRegion/decomposeParDict b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/wallFilmRegion/decomposeParDict new file mode 100644 index 0000000000000000000000000000000000000000..c9ff16db1b345392a1182e12fe586f41286ea851 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/wallFilmRegion/decomposeParDict @@ -0,0 +1,50 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object decomposeParDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +numberOfSubdomains 8; + +method metis; + +simpleCoeffs +{ + n ( 2 2 1 ); + delta 0.001; +} + +hierarchicalCoeffs +{ + n ( 1 1 1 ); + delta 0.001; + order xyz; +} + +metisCoeffs +{ + processorWeights ( 1 1 1 1 1 1 1 1 ); +} + +manualCoeffs +{ + dataFile ""; +} + +distributed no; + +roots ( ); + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/wallFilmRegion/fvSchemes b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/wallFilmRegion/fvSchemes new file mode 100644 index 0000000000000000000000000000000000000000..4e8738031a55438b3e8ff1f6c7a4d66beab31acc --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/wallFilmRegion/fvSchemes @@ -0,0 +1,67 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev.FMGlobal | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system/wallFilmRegion"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default none; + ddt(deltaf*rhof) Euler; + ddt(rhof,deltaf) Euler; + ddt(deltaf*rhof,Uf) Euler; + ddt(deltaf*rhof,hsf) Euler; +} + +divSchemes +{ + default none; + div(phi,Uf) Gauss upwind; + div(phid,deltaf) Gauss upwind; + div(phi,hsf) Gauss upwind; +} + +gradSchemes +{ + default none; + grad(pL) Gauss linear; + grad(sigmaf) Gauss linear; + grad(omega) Gauss linear; + snGradCorr(deltaf) Gauss linear; + snGradCorr(pp) Gauss linear; + snGradCorr(pu) Gauss linear; +} + +laplacianSchemes +{ + default none; + laplacian(sigmaf,deltaf) Gauss linear uncorrected; + laplacian((((interpolate(deltaf)*interpolate((deltaf*(1|A(Uf)))))*interpolate(rhof))*interpolate(pp)),deltaf) Gauss linear uncorrected; +} + +snGradSchemes +{ + snGrad(p) uncorrected; + snGrad(deltaf) uncorrected; + snGrad(omega) uncorrected; +} + +fluxRequired +{ + default no; + deltaf; +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/wallFilmRegion/fvSolution b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/wallFilmRegion/fvSolution new file mode 100644 index 0000000000000000000000000000000000000000..5657bcce0d577d8412a0fdfa9ea7237b91d523fa --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/system/wallFilmRegion/fvSolution @@ -0,0 +1,49 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev.FMGlobal | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system/wallFilmRegion"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + "(Uf|hsf|deltaf\*rhof)" + { + solver PBiCG; + preconditioner DILU; + tolerance 1e-10; + relTol 0; + } + deltaf + { + solver PBiCG; // PCG; + preconditioner DILU; // DIC; + tolerance 1e-10; + relTol 0; + } +} + + +PISO +{ + momentumPredictor true; + nOuterCorr 2; + nCorr 1; + nNonOrthCorr 0; +} + + +relaxationFactors +{} + +// ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/wallFilmRegion.setSet b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/wallFilmRegion.setSet new file mode 100644 index 0000000000000000000000000000000000000000..fcbff76dabcb6a0038caafcba36a265a7e48cf59 --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFilmFoam/evaporationTest/wallFilmRegion.setSet @@ -0,0 +1,2 @@ +# Create face set +faceSet wallFilmFaces new patchToFace filmWalls diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/constant/reactingCloud1Properties b/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/constant/reactingCloud1Properties index ce8c2019aaca8754d6a0f5809de3e3b8cb5c29af..072f100d499507eb64674ab6c5477d10d384cfb6 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/constant/reactingCloud1Properties +++ b/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/constant/reactingCloud1Properties @@ -67,7 +67,7 @@ constantProperties interpolationSchemes { rho cell; - U cell; // cellPointFace; + U cell; // cellPoint; mu cell; T cell; Cp cell; diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/constant/surfaceFilmProperties b/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/constant/surfaceFilmProperties index 7ff3b3bae83f220e031481a4d81985f885707df1..1045475fae4b87b8e76af20d6b99e26b66ce4ad8 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/constant/surfaceFilmProperties +++ b/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/constant/surfaceFilmProperties @@ -94,6 +94,7 @@ thermoSingleLayerCoeffs standardPhaseChangeCoeffs { + Tb 374.8; deltaMin 1e-8; L 1.0; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/T b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/T index d24c726015c5a8186b69bcb13a05fc8b1ee76c9e..8d97198ebb20856de4af3e5ece6cabcc54d34e42 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/T +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/T @@ -21,10 +21,10 @@ internalField uniform 300; boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -43,7 +43,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/Tf b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/Tf index 54d6217d84c3738d0669c234b3af1aa030ec3e83..28df167bde67c6d9f464544c65d34e874e94ccc2 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/Tf +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/Tf @@ -21,10 +21,10 @@ internalField uniform 300; boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -40,7 +40,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/U b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/U index 58758a96352861d44f773b7665e27d61c9b58a9f..aea8e929a044ba06a448357f48740483af355f7b 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/U +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/U @@ -21,10 +21,10 @@ internalField uniform (0 0 0); boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -43,7 +43,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/USpf b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/USpf index cc16f1f92a97abe714a7f81b97410550f1662007..11cf721fc7d60e090910c4daf41d9219fdcec85a 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/USpf +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/USpf @@ -21,10 +21,10 @@ internalField uniform (0 0 0); boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -43,7 +43,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/Uf b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/Uf index 948421f545a8c305b924a61257f408ea1ca91a91..1a0a93ba1822fd956442639edb88c532ecbfed0c 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/Uf +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/Uf @@ -21,10 +21,10 @@ internalField uniform (0 0 0); boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -40,7 +40,7 @@ boundaryField } // floor sides - floor_side + walls { type fixedValue; value uniform (0 0 0); diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/deltaf b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/deltaf index 46b4a2c1fbc57ed669e1b9b6970ed79bab2b6e5d..f7a6ddb6144bc8345accf8e2438ab94497c8c4d2 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/deltaf +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/deltaf @@ -21,10 +21,10 @@ internalField uniform 0.0; boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -40,7 +40,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/p b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/p index 76715b65d81f9837fda074bb1bb77dca21e05bfa..84b66303edcba20ce0ee826400459e8a57e8b455 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/p +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/p @@ -21,10 +21,10 @@ internalField uniform 100000; boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -43,7 +43,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/pSpf b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/pSpf index eedc444d303c1a12e06ef05743e6b67f0f54fd06..1d61b6e6f248e517b97b58408a1c607813ee46ee 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/pSpf +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0.org/wallFilmRegion/pSpf @@ -21,10 +21,10 @@ internalField uniform 0.0; boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -43,7 +43,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/T b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/T index d24c726015c5a8186b69bcb13a05fc8b1ee76c9e..8d97198ebb20856de4af3e5ece6cabcc54d34e42 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/T +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/T @@ -21,10 +21,10 @@ internalField uniform 300; boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -43,7 +43,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/Tf b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/Tf index 54d6217d84c3738d0669c234b3af1aa030ec3e83..28df167bde67c6d9f464544c65d34e874e94ccc2 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/Tf +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/Tf @@ -21,10 +21,10 @@ internalField uniform 300; boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -40,7 +40,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/U b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/U index 58758a96352861d44f773b7665e27d61c9b58a9f..aea8e929a044ba06a448357f48740483af355f7b 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/U +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/U @@ -21,10 +21,10 @@ internalField uniform (0 0 0); boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -43,7 +43,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/USpf b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/USpf index cc16f1f92a97abe714a7f81b97410550f1662007..11cf721fc7d60e090910c4daf41d9219fdcec85a 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/USpf +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/USpf @@ -21,10 +21,10 @@ internalField uniform (0 0 0); boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -43,7 +43,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/Uf b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/Uf index 948421f545a8c305b924a61257f408ea1ca91a91..1a0a93ba1822fd956442639edb88c532ecbfed0c 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/Uf +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/Uf @@ -21,10 +21,10 @@ internalField uniform (0 0 0); boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -40,7 +40,7 @@ boundaryField } // floor sides - floor_side + walls { type fixedValue; value uniform (0 0 0); diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/deltaf b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/deltaf index 46b4a2c1fbc57ed669e1b9b6970ed79bab2b6e5d..f7a6ddb6144bc8345accf8e2438ab94497c8c4d2 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/deltaf +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/deltaf @@ -21,10 +21,10 @@ internalField uniform 0.0; boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -40,7 +40,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/p b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/p index 76715b65d81f9837fda074bb1bb77dca21e05bfa..84b66303edcba20ce0ee826400459e8a57e8b455 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/p +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/p @@ -21,10 +21,10 @@ internalField uniform 100000; boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -43,7 +43,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/pSpf b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/pSpf index eedc444d303c1a12e06ef05743e6b67f0f54fd06..1d61b6e6f248e517b97b58408a1c607813ee46ee 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/pSpf +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/0/wallFilmRegion/pSpf @@ -21,10 +21,10 @@ internalField uniform 0.0; boundaryField { - // cyclic boundaries between film patches - "(cube[0-9][0-9]_side[0-9]_cube[0-9][0-9]_side[0-9])" + // nonuniformTransformCyclic boundaries between film patches + "(cube[0-9][0-9]_side[0-9]_to_cube[0-9][0-9]_side[0-9])" { - type cyclic; + type nonuniformTransformCyclic; } // top film surface @@ -43,7 +43,7 @@ boundaryField } // floor sides - floor_side + walls { type zeroGradient; } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/constant/reactingCloud1Properties b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/constant/reactingCloud1Properties index a148c74674bdfb5cf5ed33a7e12a7f500ff660e3..51f281bdad5a247698442a79c39e9333b19e724e 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/constant/reactingCloud1Properties +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/constant/reactingCloud1Properties @@ -67,7 +67,7 @@ constantProperties interpolationSchemes { rho cell; - U cell; // cellPointFace; + U cell; // cellPoint; mu cell; T cell; Cp cell; diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/constant/surfaceFilmProperties b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/constant/surfaceFilmProperties index c39d47cb3e93e5606de72582fad02202f142b2b7..c54f41c6e7a76267e5b9ff2db68be0c833741ba2 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/constant/surfaceFilmProperties +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/constant/surfaceFilmProperties @@ -24,12 +24,13 @@ active true; kinematicSingleLayerCoeffs { - deltaStable deltaStable [0 1 0 0 0] 0.0005; + thermoModel constant; + Cf 0.005; - rho rho [1 -3 0 0 0] 1000; - mu mu [1 -1 -1 0 0] 1e-3; - sigma sigma [1 0 -2 0 0] 0.07; + rho0 rho0 [1 -3 0 0 0] 1000; + mu0 mu0 [1 -1 -1 0 0] 1e-3; + sigma0 sigma0 [1 0 -2 0 0] 0.07; injectionModel remove; // none; // cloudInjection; } @@ -37,15 +38,16 @@ kinematicSingleLayerCoeffs thermoSingleLayerCoeffs { - deltaStable deltaStable [0 1 0 0 0] 0; + thermoModel constant; + liquid H2O; + Cf 0.005; - htcw htcw [1 0 -3 -1 0] 1e-8; // 0.0; - htcs htcs [1 0 -3 -1 0] 1e-8; // 0.0; - rho rho [1 -3 0 0 0] 1000; - mu mu [1 -1 -1 0 0] 1e-3; - sigma sigma [1 0 -2 0 0] 0.07; - cp cp [0 2 -2 -1 0] 4187; + rho0 rho0 [1 -3 0 0 0] 1000; + mu0 mu0 [1 -1 -1 0 0] 1e-3; + sigma0 sigma0 [1 0 -2 0 0] 0.07; + cp0 cp0 [0 2 -2 -1 0] 4187; + kappa0 kappa0 [1 1 -3 -1 0] 0.58; injectionModel cloudInjection; // remove; // none; // cloudInjection; @@ -55,6 +57,8 @@ thermoSingleLayerCoeffs { cloudName reactingCloud1; + deltaStable 0; + particlesPerParcel 100.0; parcelPDF @@ -69,5 +73,23 @@ thermoSingleLayerCoeffs } } } + + upperSurfaceModels + { + heatTransferModel constant; + constantCoeffs + { + c0 1e-8; + } + } + + lowerSurfaceModels + { + heatTransferModel constant; + constantCoeffs + { + c0 1e-8; + } + } } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/constant/thermophysicalProperties b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/constant/thermophysicalProperties index acfbe00bcea125abcf24f0a993155be4985adec8..bddd3c54584a951cc24ad95c5883b79a96d1ab38 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/constant/thermophysicalProperties +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/constant/thermophysicalProperties @@ -23,17 +23,23 @@ foamChemistryFile "$FOAM_CASE/chemkin/foam.inp"; foamChemistryThermoFile "$FOAM_CASE/chemkin/foam.dat"; -liquidComponents -( - H2O -); +inertSpecie N2; -solidComponents -(); +liquids +{ + liquidComponents + ( + H2O + ); -inertSpecie N2; + H2O H2O defaultCoeffs; +} -H2O H2O defaultCoeffs; +solids +{ + solidComponents + (); +} // ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/system/wallFilmRegion.org/fvSchemes b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/system/wallFilmRegion.org/fvSchemes index c4de9c3c182edcf63cd655b5cba78bc2838967df..d164ec0424eb0a39a7db8e39326ae4a24b32c2a5 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/system/wallFilmRegion.org/fvSchemes +++ b/tutorials/lagrangian/reactingParcelFilmFoam/multipleBoxes/system/wallFilmRegion.org/fvSchemes @@ -36,6 +36,7 @@ gradSchemes { default none; grad(pL) Gauss linear; + grad(sigmaf) Gauss linear; snGradCorr(deltaf) Gauss linear; snGradCorr(pp) Gauss linear; snGradCorr(pu) Gauss linear; diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/panel/constant/reactingCloud1Properties b/tutorials/lagrangian/reactingParcelFilmFoam/panel/constant/reactingCloud1Properties index 27a63e876a1c048ef39683cce9476648e25253d2..73494b022dae79cb6ca285f96558796e338d1b47 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/panel/constant/reactingCloud1Properties +++ b/tutorials/lagrangian/reactingParcelFilmFoam/panel/constant/reactingCloud1Properties @@ -67,7 +67,7 @@ constantProperties interpolationSchemes { rho cell; - U cell; // cellPointFace; + U cell; // cellPoint; mu cell; T cell; Cp cell; diff --git a/tutorials/lagrangian/reactingParcelFoam/evaporationTest/constant/reactingCloud1Properties b/tutorials/lagrangian/reactingParcelFoam/evaporationTest/constant/reactingCloud1Properties index 49e1a85b97c35fe160da1741bfd582e93a97556a..ca70790376d0c31c99c5e77f44c5e7dad734d3a1 100644 --- a/tutorials/lagrangian/reactingParcelFoam/evaporationTest/constant/reactingCloud1Properties +++ b/tutorials/lagrangian/reactingParcelFoam/evaporationTest/constant/reactingCloud1Properties @@ -67,7 +67,7 @@ constantProperties interpolationSchemes { rho cell; - U cellPointFace; + U cellPoint; mu cell; T cell; Cp cell; diff --git a/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/0.org/pointDisplacement b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/0.org/pointDisplacement new file mode 100644 index 0000000000000000000000000000000000000000..d2b845620a516e4b0fe75dac9535d4fae1b436e5 --- /dev/null +++ b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/0.org/pointDisplacement @@ -0,0 +1,88 @@ +/*--------------------------------*- 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 pointVectorField; + location "0.01"; + object pointDisplacement; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 0 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + stationaryWalls + { + type fixedValue; + value uniform (0 0 0); + } + movingBlock + { + type uncoupledSixDoFRigidBodyDisplacement; + centreOfMass (0.5 0.5 0.5); + momentOfInertia (0.1052 0.1052 0.1778); + mass 9.6; + velocity (0 0 0); + orientation (1 0 0 0 1 0 0 0 1); + acceleration (0 0 0); + angularMomentum (0 0 0); + torque (0 0 0); + gravity (0 0 0); + rhoInf 1; + report on; + restraints + { + topSpring + { + sixDoFRigidBodyMotionRestraint linearSpring; + + linearSpringCoeffs + { + anchor (0.5 0.5 1); + refAttachmentPt $centreOfMass; + stiffness 5000; + damping 50; + restLength 0.4; + } + } + } + constraints + { + maxIterations 500; + + fixedAxes1 + { + sixDoFRigidBodyMotionConstraint fixedOrientation; + tolerance 1e-6; + relaxationFactor 1.0; + fixedOrientationCoeffs {} + } + + fixedLine1 + { + sixDoFRigidBodyMotionConstraint fixedLine; + tolerance 1e-6; + relaxationFactor 1.0; + fixedLineCoeffs + { + refPoint $centreOfMass; + direction (0 0 1); + } + } + } + value uniform (0 0 0); + } +} + + +// ************************************************************************* // diff --git a/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/Allclean b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/Allclean new file mode 100755 index 0000000000000000000000000000000000000000..b134761b23196a7e95da25393256db8cbe304bb5 --- /dev/null +++ b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/Allclean @@ -0,0 +1,11 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory + +# Source tutorial clean functions +. $WM_PROJECT_DIR/bin/tools/CleanFunctions + +rm -rf 0 t_vs_cm t_vs_lv shm.eps > /dev/null 2>&1 + +cleanCase + +# ----------------------------------------------------------------- end-of-file diff --git a/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/Allrun b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/Allrun new file mode 100755 index 0000000000000000000000000000000000000000..f7afb77a5bababbdc23a5b332dae00b3e90ab7cc --- /dev/null +++ b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/Allrun @@ -0,0 +1,19 @@ +#!/bin/sh + +cd ${0%/*} || exit 1 # run from this directory + +# Source tutorial run functions +. $WM_PROJECT_DIR/bin/tools/RunFunctions + +# Set application name +application="moveDynamicMesh" + +runApplication blockMesh +runApplication topoSet +runApplication subsetMesh -overwrite c0 -patch movingBlock +cp -r 0.org 0 > /dev/null 2>&1 +runApplication $application +./extractData log.$application +gnuplot shm.gnuplot + +# ----------------------------------------------------------------- end-of-file diff --git a/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/constant/dynamicMeshDict b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/constant/dynamicMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..329480c68d677eace7d2818c15cb2adb118f773a --- /dev/null +++ b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/constant/dynamicMeshDict @@ -0,0 +1,26 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object motionProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dynamicFvMesh dynamicMotionSolverFvMesh; + +motionSolverLibs ("libfvMotionSolvers.so"); + +solver displacementLaplacian; + +diffusivity inverseDistance (movingBlock); + + +// ************************************************************************* // diff --git a/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/constant/polyMesh/blockMeshDict b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/constant/polyMesh/blockMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..c2ae0e3bfe871ddefc9a3a6595c475a39e4634ff --- /dev/null +++ b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/constant/polyMesh/blockMeshDict @@ -0,0 +1,59 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: http://www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +convertToMeters 1; + +vertices +( + (0 0 0) + (1 0 0) + (1 1 0) + (0 1 0) + (0 0 1) + (1 0 1) + (1 1 1) + (0 1 1) +); + +blocks +( + hex (0 1 2 3 4 5 6 7) (9 9 14) simpleGrading (1 1 1) +); + +edges +( +); + +patches +( + patch stationaryWalls + ( + (0 3 2 1) + (2 6 5 1) + (1 5 4 0) + (3 7 6 2) + (0 4 7 3) + (4 5 6 7) + ) + patch movingBlock + () +); + +mergePatchPairs +( +); + +// ************************************************************************* // diff --git a/tutorials/discreteMethods/molecularDynamics/mdEquilibrationFoam/periodicCubeWater/0/U b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/constant/polyMesh/boundary similarity index 71% rename from tutorials/discreteMethods/molecularDynamics/mdEquilibrationFoam/periodicCubeWater/0/U rename to tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/constant/polyMesh/boundary index c7bc8234a29fe33e1e33d6860629e259b3db5642..eef245f9f4c246818e8811e5fad2f2dd1ed42dc5 100644 --- a/tutorials/discreteMethods/molecularDynamics/mdEquilibrationFoam/periodicCubeWater/0/U +++ b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/constant/polyMesh/boundary @@ -9,29 +9,26 @@ FoamFile { version 2.0; format ascii; - class volVectorField; - object U; + class polyBoundaryMesh; + location "constant/polyMesh"; + object boundary; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -dimensions [0 1 -1 0 0 0 0]; - -internalField uniform (0 0 0); - -boundaryField -{ - periodicX +2 +( + stationaryWalls { - type cyclic; + type wall; + nFaces 666; + startFace 2994; } - periodicY + movingBlock { - type cyclic; + type patch; + nFaces 42; + startFace 3660; } - periodicZ - { - type cyclic; - } -} +) // ************************************************************************* // diff --git a/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/extractData b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/extractData new file mode 100755 index 0000000000000000000000000000000000000000..784f45c5fc5b4c5210b993202eb2d14914ed2da1 --- /dev/null +++ b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/extractData @@ -0,0 +1,42 @@ +#!/bin/sh +#------------------------------------------------------------------------------ +# ========= | +# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox +# \\ / O peration | +# \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. +# \\/ M anipulation | +#------------------------------------------------------------------------------- +# License +# This file is part of OpenFOAM. +# +# OpenFOAM is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 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/>. +# +# Script +# extractData +# +# Description +# Extracts motion data from a simple harmonic motion dynamicMesh case +# +#------------------------------------------------------------------------------ + +grep "Centre of mass" $1 | cut -d ":" -f 2 | cut -d " " -f 4 | tr -d ")" > cM +grep "Linear velocity" $1 | cut -d ":" -f 2 | cut -d " " -f 4 | tr -d ")" > lV +grep -e "^Time = " $1 | cut -d " " -f 3 > times + +paste times cM > t_vs_cm +paste times lV > t_vs_lv + +rm cM lV times + +#------------------------------------------------------------------------------ \ No newline at end of file diff --git a/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/shm.gnuplot b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/shm.gnuplot new file mode 100644 index 0000000000000000000000000000000000000000..8027230526ebe20ea8aa0d2c9075d77088fee4ed --- /dev/null +++ b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/shm.gnuplot @@ -0,0 +1,76 @@ +#------------------------------------------------------------------------------ +# ========= | +# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox +# \\ / O peration | +# \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. +# \\/ M anipulation | +#------------------------------------------------------------------------------- +# License +# This file is part of OpenFOAM. +# +# OpenFOAM is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 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/>. +# +# Script +# shm.gnuplot +# +# Description +# Creates an .eps graph of OpenFOAM results vs analytical solution +# for a simple harmonic motion dynamicMesh case +# +#------------------------------------------------------------------------------ + +reset + +set samples 2000 + +k = 5000.0 +m = 9.6 +c = 50.0 +a = -0.1 + +omega = sqrt(k/m) +zeta = c/(2.0*m*omega) + +phi = atan((sqrt(1.0 - zeta**2))/zeta) +A = a/sin(phi) + +pos(A, t, omega, phi, zeta) = A*exp(-zeta*omega*t)*sin(sqrt(1-zeta**2)*omega*t + phi) +vel(A, t, omega, phi, zeta) = \ +A*exp(-zeta*omega*t)*\ +( \ + sqrt(1-zeta**2)*omega*cos(sqrt(1-zeta**2)*omega*t + phi) \ +- zeta*omega*sin(sqrt(1-zeta**2)*omega*t + phi) \ +) + +set xlabel "Time/[s]" +set ylabel "Position" + +set ytics nomirror +set y2tics + +set yrange [-0.1:0.1] +set y2range [-2:2] + +set xzeroaxis + +set terminal postscript eps color enhanced solid +set output "shm.eps" + +plot \ + "t_vs_cm" u 1:($2 - 0.6) w l t "Simulation, centre of mass relative to start", \ + pos(A, x, omega, phi, zeta) w l t "Analytical solution, centre of mass", \ + "t_vs_lv" u 1:2 w l axes x1y2 t "Simulation, vertical velocity", \ + vel(A, x, omega, phi, zeta) w l axes x1y2 t "Analytical solution, vertical velocity" + +#------------------------------------------------------------------------------ diff --git a/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/system/controlDict b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/system/controlDict new file mode 100644 index 0000000000000000000000000000000000000000..2d71827bb43c766f572f270e302d476e6e2b55c2 --- /dev/null +++ b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/system/controlDict @@ -0,0 +1,68 @@ +/*--------------------------------*- 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; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application interDyMFoam; + +startFrom startTime; + +startTime 0; + +stopAt endTime; + +endTime 4; + +deltaT 0.002; + +writeControl adjustableRunTime; + +writeInterval 0.25; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 12; + +writeCompression uncompressed; + +timeFormat general; + +timePrecision 6; + +runTimeModifiable yes; + +adjustTimeStep yes; + +maxCo 0.2; + +maxDeltaT 0.025; + +libs +( + "libincompressibleRASModels.so" + "libforces.so" +); + + +// libs +// ( +// "libgenericPatchFields.so" +// "libincompressibleRASModels.so" +// "libforces.so" +// ); + +// ************************************************************************* // diff --git a/tutorials/compressible/rhoPorousMRFPimpleFoam/mixerVessel2D/constant/dynamicMeshDict b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/system/fvSchemes similarity index 59% rename from tutorials/compressible/rhoPorousMRFPimpleFoam/mixerVessel2D/constant/dynamicMeshDict rename to tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/system/fvSchemes index 36f5458ddffdf40ab537d24d4f3f3c5b72a8afba..9b11d59f3d38f5b6962db895469efa21e45ce610 100644 --- a/tutorials/compressible/rhoPorousMRFPimpleFoam/mixerVessel2D/constant/dynamicMeshDict +++ b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/system/fvSchemes @@ -2,7 +2,7 @@ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: dev | -| \\ / A nd | Web: www.OpenFOAM.com | +| \\ / A nd | Web: www.OpenFOAM.org | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile @@ -10,32 +10,40 @@ FoamFile version 2.0; format ascii; class dictionary; - location "constant"; - object dynamicMeshDict; + location "system"; + object fvSchemes; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -dynamicFvMeshLib "libtopoChangerFvMesh.so"; +ddtSchemes +{ +} + +gradSchemes +{ + default Gauss linear; +} + +divSchemes +{ +} -dynamicFvMesh mixerFvMesh; +laplacianSchemes +{ + default Gauss linear corrected; +} -mixerFvMeshCoeffs +interpolationSchemes { - coordinateSystem - { - type cylindrical; - origin ( 0 0 0 ); - axis ( 0 0 1 ); - direction ( 1 0 0 ); - } + default linear; +} - rpm 10; +snGradSchemes +{ +} - slider - { - inside insideSlider; - outside outsideSlider; - } +fluxRequired +{ } diff --git a/tutorials/incompressible/MRFSimpleFoam/mixerVessel2D/constant/dynamicMeshDict b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/system/fvSolution similarity index 59% rename from tutorials/incompressible/MRFSimpleFoam/mixerVessel2D/constant/dynamicMeshDict rename to tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/system/fvSolution index 36f5458ddffdf40ab537d24d4f3f3c5b72a8afba..209b3b035f8827e08258ce1c67a84dee0c45a7f0 100644 --- a/tutorials/incompressible/MRFSimpleFoam/mixerVessel2D/constant/dynamicMeshDict +++ b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/system/fvSolution @@ -2,7 +2,7 @@ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: dev | -| \\ / A nd | Web: www.OpenFOAM.com | +| \\ / A nd | Web: www.OpenFOAM.org | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile @@ -10,31 +10,23 @@ FoamFile version 2.0; format ascii; class dictionary; - location "constant"; - object dynamicMeshDict; + location "system"; + object fvSolution; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -dynamicFvMeshLib "libtopoChangerFvMesh.so"; - -dynamicFvMesh mixerFvMesh; - -mixerFvMeshCoeffs +solvers { - coordinateSystem - { - type cylindrical; - origin ( 0 0 0 ); - axis ( 0 0 1 ); - direction ( 1 0 0 ); - } - - rpm 10; - - slider + cellDisplacement { - inside insideSlider; - outside outsideSlider; + solver GAMG; + tolerance 1e-06; + relTol 0; + smoother GaussSeidel; + cacheAgglomeration true; + nCellsInCoarsestLevel 10; + agglomerator faceAreaPair; + mergeLevels 1; } } diff --git a/tutorials/discreteMethods/molecularDynamics/mdEquilibrationFoam/periodicCubeArgon/0/U b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/system/topoSetDict similarity index 72% rename from tutorials/discreteMethods/molecularDynamics/mdEquilibrationFoam/periodicCubeArgon/0/U rename to tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/system/topoSetDict index c7bc8234a29fe33e1e33d6860629e259b3db5642..91b2397d23b567b64d6d25ae7a1a33dfb76681d0 100644 --- a/tutorials/discreteMethods/molecularDynamics/mdEquilibrationFoam/periodicCubeArgon/0/U +++ b/tutorials/mesh/moveDynamicMesh/simpleHarmonicMotion/system/topoSetDict @@ -9,29 +9,30 @@ FoamFile { version 2.0; format ascii; - class volVectorField; - object U; + class dictionary; + object topoSetDict; } -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -dimensions [0 1 -1 0 0 0 0]; -internalField uniform (0 0 0); +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -boundaryField -{ - periodicX +actions +( { - type cyclic; + name c0; + type cellSet; + action new; + source boxToCell; + sourceInfo + { + box (0.35 0.35 0.44) (0.65 0.65 0.56); + } } - periodicY - { - type cyclic; - } - periodicZ + { - type cyclic; + name c0; + type cellSet; + action invert; } -} +); // ************************************************************************* // diff --git a/tutorials/multiphase/interPhaseChangeFoam/cavitatingBullet/system/snappyHexMeshDict b/tutorials/multiphase/interPhaseChangeFoam/cavitatingBullet/system/snappyHexMeshDict index d2c7fee5e424060bb6adb0966ced9375bb0a76bd..456bd93ea0df6638cd98e28ef076a701743e3faa 100644 --- a/tutorials/multiphase/interPhaseChangeFoam/cavitatingBullet/system/snappyHexMeshDict +++ b/tutorials/multiphase/interPhaseChangeFoam/cavitatingBullet/system/snappyHexMeshDict @@ -292,11 +292,14 @@ meshQualityControls // Set to very negative number (e.g. -1E30) to disable. minVol 1e-20; - //- Minimum tet volume. Is absolute volume of the tet formed by the - // face-centre decomposition triangle and the cell centre. - // Set to a sensible fraction of the smallest cell volume expected. - // Set to very negative number (e.g. -1E30) to disable. - minTetVol 1e-20; + //- 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-9; //- Minimum face area. Set to <0 to disable. minArea -1;