mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'cvm'
This commit is contained in:
@ -3,4 +3,3 @@
|
||||
|
||||
const int nNonOrthCorr =
|
||||
potentialFlow.lookupOrDefault<int>("nNonOrthogonalCorrectors", 0);
|
||||
|
||||
|
||||
@ -13,4 +13,3 @@ EXE_LIBS = \
|
||||
-lmolecule \
|
||||
-lpotential \
|
||||
-lmolecularMeasurements
|
||||
|
||||
|
||||
@ -13,4 +13,3 @@ EXE_LIBS = \
|
||||
-lmolecule \
|
||||
-lpotential \
|
||||
-lmolecularMeasurements
|
||||
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
Info<< "\nReading field U\n" << endl;
|
||||
volVectorField U
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"U",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
word polyatomicCloudName("polyatomicCloud");
|
||||
|
||||
potential polyPot
|
||||
(
|
||||
mesh,
|
||||
IOdictionary
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
polyatomicCloudName + "Properties",
|
||||
mesh.time().constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
polyatomicCloud polyatomics(polyatomicCloudName, mesh, polyPot);
|
||||
|
||||
word monoatomicCloudName("monoatomicCloud");
|
||||
|
||||
potential monoPot
|
||||
(
|
||||
mesh,
|
||||
IOdictionary
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
monoatomicCloudName + "Properties",
|
||||
mesh.time().constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
monoatomicCloud monoatomics(monoatomicCloudName, mesh, monoPot);
|
||||
@ -0,0 +1,3 @@
|
||||
mdEquilibrationFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/mdEquilibrationFoam
|
||||
@ -0,0 +1,16 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/lagrangian/molecularDynamics/molecule/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/molecularDynamics/potential/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/molecularDynamics/molecularMeasurements/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools \
|
||||
-lfiniteVolume \
|
||||
-llagrangian \
|
||||
-lmolecule \
|
||||
-lpotential \
|
||||
-lmolecularMeasurements
|
||||
|
||||
@ -0,0 +1,101 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2011 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
|
||||
mdEquilibrationFoam
|
||||
|
||||
Description
|
||||
Equilibrates and/or preconditions molecular dynamics systems
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "md.H"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Info<< "\nReading field U\n" << endl;
|
||||
volVectorField U
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"U",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
potential pot(mesh);
|
||||
|
||||
moleculeCloud molecules(mesh, pot);
|
||||
|
||||
#include "temperatureAndPressureVariables.H"
|
||||
|
||||
#include "readmdEquilibrationDict.H"
|
||||
|
||||
label nAveragingSteps = 0;
|
||||
|
||||
Info<< "\nStarting time loop\n" << endl;
|
||||
|
||||
while (runTime.loop())
|
||||
{
|
||||
nAveragingSteps++;
|
||||
|
||||
Info<< "Time = " << runTime.timeName() << endl;
|
||||
|
||||
molecules.evolve();
|
||||
|
||||
#include "meanMomentumEnergyAndNMols.H"
|
||||
|
||||
#include "temperatureAndPressure.H"
|
||||
|
||||
#include "temperatureEquilibration.H"
|
||||
|
||||
runTime.write();
|
||||
|
||||
if (runTime.outputTime())
|
||||
{
|
||||
nAveragingSteps = 0;
|
||||
}
|
||||
|
||||
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,18 @@
|
||||
Info<< nl << "Reading MD Equilibration Dictionary" << nl << endl;
|
||||
|
||||
IOdictionary mdEquilibrationDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"mdEquilibrationDict",
|
||||
runTime.system(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
scalar targetTemperature = readScalar
|
||||
(
|
||||
mdEquilibrationDict.lookup("targetTemperature")
|
||||
);
|
||||
@ -16,4 +16,3 @@
|
||||
{
|
||||
solve(UEqn == -fvc::grad(p));
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -26,7 +26,7 @@ Application
|
||||
|
||||
Description
|
||||
Calculates the inertia tensor and principal axes and moments of a
|
||||
test face, tetrahedron and mesh.
|
||||
test face, tetrahedron and cell.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
3
applications/utilities/mesh/generation/cvMesh/Make/files
Normal file
3
applications/utilities/mesh/generation/cvMesh/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
cvMesh.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/cvMesh
|
||||
26
applications/utilities/mesh/generation/cvMesh/Make/options
Normal file
26
applications/utilities/mesh/generation/cvMesh/Make/options
Normal file
@ -0,0 +1,26 @@
|
||||
EXE_DEBUG = -DFULLDEBUG -g -O0
|
||||
EXE_FROUNDING_MATH = -frounding-math
|
||||
EXE_NDEBUG = -DNDEBUG
|
||||
|
||||
include $(GENERAL_RULES)/CGAL
|
||||
|
||||
EXE_INC = \
|
||||
${EXE_FROUNDING_MATH} \
|
||||
${EXE_NDEBUG} \
|
||||
${CGAL_INC} \
|
||||
-I$(LIB_SRC)/mesh/conformalVoronoiMesh/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
|
||||
-I$(LIB_SRC)/edgeMesh/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
$(CGAL_LIBS) \
|
||||
-lconformalVoronoiMesh \
|
||||
-lmeshTools \
|
||||
-ldecompositionMethods -L$(FOAM_LIBBIN)/dummy -lscotchDecomp \
|
||||
-ledgeMesh \
|
||||
-ltriSurface \
|
||||
-ldynamicMesh
|
||||
82
applications/utilities/mesh/generation/cvMesh/cvMesh.C
Normal file
82
applications/utilities/mesh/generation/cvMesh/cvMesh.C
Normal file
@ -0,0 +1,82 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2011 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
|
||||
cvMesh
|
||||
|
||||
Description
|
||||
Conformal Voronoi automatic mesh generator
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "conformalVoronoiMesh.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
runTime.functionObjects().off();
|
||||
|
||||
IOdictionary cvMeshDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cvMeshDict",
|
||||
runTime.system(),
|
||||
runTime,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
conformalVoronoiMesh mesh(runTime, cvMeshDict);
|
||||
|
||||
while (runTime.loop())
|
||||
{
|
||||
Info<< nl << "Time = " << runTime.timeName() << endl;
|
||||
|
||||
mesh.move();
|
||||
|
||||
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
mesh.writeMesh(runTime.constant());
|
||||
|
||||
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
|
||||
Info<< nl << "End" << nl << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
496
applications/utilities/mesh/generation/cvMesh/cvMeshDict
Normal file
496
applications/utilities/mesh/generation/cvMesh/cvMeshDict
Normal file
@ -0,0 +1,496 @@
|
||||
/*--------------------------------*- 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 dictionary;
|
||||
object cvMeshDict;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Control dictionary for cvMesh - polyhedral mesh generator.
|
||||
|
||||
cvMesh phases:
|
||||
1. fill volume with initial points (initialPoints subdictionary). An option
|
||||
is to reread from previous set of points.
|
||||
|
||||
2. internal point motion (motionControl subdictionary)
|
||||
|
||||
3. every once in a while add point duplets/triplets to conform to
|
||||
surfaces and features (surfaceConformation subdictionary)
|
||||
|
||||
4. back to 2
|
||||
|
||||
5. construct polyMesh.
|
||||
- filter (polyMeshFiltering subdictionary)
|
||||
- check (meshQualityControls subdictionary) and undo filtering
|
||||
|
||||
|
||||
See also cvControls.H in the conformalVoronoiMesh library
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// Important:
|
||||
// ----------
|
||||
// Any scalar with a name <name>Coeff specifies a value that will be implemented
|
||||
// as a faction of the local target cell size
|
||||
// Any scalar with a name <name>Size specifies an absolute size.
|
||||
|
||||
|
||||
// Geometry. Definition of all surfaces. All surfaces are of class
|
||||
// searchableSurface.
|
||||
// Surfaces need to be (almost) closed - use closedTriSurfaceMesh
|
||||
// if they are not topologically closed. Surfaces need to be oriented so
|
||||
// the space to be meshed is always on the inside of all surfaces. Use e.g.
|
||||
// surfaceOrient.
|
||||
geometry
|
||||
{
|
||||
// Surface to conform to
|
||||
flange.obj
|
||||
{
|
||||
type triSurfaceMesh;
|
||||
}
|
||||
|
||||
// Surface used for cell size control
|
||||
ref7.stl
|
||||
{
|
||||
name ref7;
|
||||
type triSurfaceMesh;
|
||||
}
|
||||
|
||||
// Surface used for cell size control
|
||||
tunnel_APPROACH_INLET.obj
|
||||
{
|
||||
type triSurfaceMesh;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Controls for conforming to the surfaces.
|
||||
surfaceConformation
|
||||
{
|
||||
// A point inside surfaces that is inside mesh.
|
||||
locationInMesh (0 0 0);
|
||||
|
||||
// How far apart are point-duplets generated. Balance this between
|
||||
// - very low distance: little chance of interference from other
|
||||
// surfaces
|
||||
// - largish distance: less non-orthogonality in final cell
|
||||
// (circumcentre far away from centroid)
|
||||
pointPairDistanceCoeff 0.1;
|
||||
|
||||
// Mixed feature points - connected to both inside and outside edges.
|
||||
// Recreated by inserting triplets of points to recreate a single edge.
|
||||
// Done for all edges emanating from point. triplets of points get inserted
|
||||
// mixedFeaturePointPPDistanceCoeff distance away from feature point.
|
||||
// Set to a negative number to disable.
|
||||
mixedFeaturePointPPDistanceCoeff 5.0; //-1;
|
||||
|
||||
// Distance to a feature point within which surface and edge
|
||||
// conformation points are excluded - fraction of the local target
|
||||
// cell size
|
||||
featurePointExclusionDistanceCoeff 0.4;
|
||||
|
||||
// Distance to an existing feature edge conformation location
|
||||
// within which other edge conformation location are excluded -
|
||||
// fraction of the local target cell size
|
||||
featureEdgeExclusionDistanceCoeff 0.2;
|
||||
|
||||
// Optimisation: do not check for surface intersection (of dual edges)
|
||||
// for points near to surface.
|
||||
surfaceSearchDistanceCoeff 2.5;
|
||||
|
||||
// Maximum allowable protrusion through the surface before
|
||||
// conformation points are added - fraction of the local target
|
||||
// cell size. These small protusions are (hopefully) done by mesh filtering
|
||||
// instead.
|
||||
maxSurfaceProtrusionCoeff 0.1;
|
||||
|
||||
// If feature edge with large angle (so more than 125 degrees) introduce
|
||||
// additional points to create two half angled cells (= mitering).
|
||||
maxQuadAngle 125;
|
||||
|
||||
// Frequency to redo surface conformation (expensive).
|
||||
surfaceConformationRebuildFrequency 10;
|
||||
|
||||
// Initial and intermediate controls
|
||||
coarseConformationControls
|
||||
{
|
||||
// Initial conformation
|
||||
initial
|
||||
{
|
||||
// We've got a point poking through the surface. Don't do any
|
||||
// surface conformation if near feature edge (since feature edge
|
||||
// conformation should have priority)
|
||||
|
||||
// distance to search for near feature edges
|
||||
edgeSearchDistCoeff 1.1;
|
||||
|
||||
// Proximity to a feature edge where a surface hit is
|
||||
// not created, only the edge conformation is created
|
||||
// - fraction of the local target cell size. Coarse
|
||||
// conformation, initial protrusion tests.
|
||||
surfacePtReplaceDistCoeff 0.5;
|
||||
}
|
||||
|
||||
// Same for iterations
|
||||
iteration
|
||||
{
|
||||
edgeSearchDistCoeff 1.25;
|
||||
surfacePtReplaceDistCoeff 0.7;
|
||||
}
|
||||
|
||||
// Stop either at maxIterations or if the number of surface pokes
|
||||
// is very small (iterationToInitialHitRatioLimit * initial number)
|
||||
// Note: perhaps iterationToInitialHitRatioLimit should be absolute
|
||||
// count?
|
||||
maxIterations 15;
|
||||
|
||||
iterationToInitialHitRatioLimit 0.001;
|
||||
}
|
||||
|
||||
// Final (at endTime) controls
|
||||
fineConformationControls
|
||||
{
|
||||
initial
|
||||
{
|
||||
edgeSearchDistCoeff 1.1;
|
||||
surfacePtReplaceDistCoeff 0.5;
|
||||
}
|
||||
|
||||
iteration
|
||||
{
|
||||
edgeSearchDistCoeff 1.25;
|
||||
surfacePtReplaceDistCoeff 0.7;
|
||||
}
|
||||
|
||||
maxIterations 15;
|
||||
|
||||
iterationToInitialHitRatioLimit 0.001;
|
||||
}
|
||||
|
||||
// Geometry to mesh to
|
||||
geometryToConformTo
|
||||
{
|
||||
flange.obj
|
||||
{
|
||||
featureMethod extendedFeatureEdgeMesh; // or none;
|
||||
extendedFeatureEdgeMesh "flange.extendedFeatureEdgeMesh";
|
||||
}
|
||||
}
|
||||
|
||||
// Additional features.
|
||||
additionalFeatures
|
||||
{
|
||||
//line
|
||||
//{
|
||||
// featureMethod extendedFeatureEdgeMesh; // or none;
|
||||
// extendedFeatureEdgeMesh "line.extendedFeatureEdgeMesh";
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Controls for seeding initial points and general control of the target
|
||||
// cell size (used everywhere)
|
||||
initialPoints
|
||||
{
|
||||
// Do not place point closer than minimumSurfaceDistanceCoeff
|
||||
// to the surface. Is fraction of local target cell size (see below)
|
||||
minimumSurfaceDistanceCoeff 0.55;
|
||||
|
||||
initialPointsMethod autoDensity;
|
||||
// initialPointsMethod uniformGrid;
|
||||
// initialPointsMethod bodyCentredCubic;
|
||||
// initialPointsMethod pointFile;
|
||||
|
||||
|
||||
// Take boundbox of all geometry. Sample with this box. If too much
|
||||
// samples in box (due to target cell size) split box.
|
||||
autoDensityDetails
|
||||
{
|
||||
// Initial number of refinement levels. Needs to be enough to pick
|
||||
// up features due to size ratio. If not enough it will take longer
|
||||
// to determine point seeding.
|
||||
minLevels 4;
|
||||
// Split box if ratio of min to max cell size larger than maxSizeRatio
|
||||
maxSizeRatio 5.0;
|
||||
// Per box sample 5x5x5 internally
|
||||
sampleResolution 5;
|
||||
// Additionally per face of the box sample 5x5
|
||||
surfaceSampleResolution 5;
|
||||
}
|
||||
|
||||
uniformGridDetails
|
||||
{
|
||||
// Absolute cell size.
|
||||
initialCellSize 0.0015;
|
||||
randomiseInitialGrid yes;
|
||||
randomPerturbationCoeff 0.02;
|
||||
}
|
||||
|
||||
bodyCentredCubicDetails
|
||||
{
|
||||
initialCellSize 0.0015;
|
||||
randomiseInitialGrid no;
|
||||
randomPerturbationCoeff 0.1;
|
||||
}
|
||||
|
||||
pointFileDetails
|
||||
{
|
||||
// Reads points from file. Still rejects points that are too
|
||||
// close to the surface (minimumSurfaceDistanceCoeff) or on the
|
||||
// wrong side of the surfaces.
|
||||
pointFile "constant/internalDelaunayVertices";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Control size of voronoi cells i.e. distance between points. This
|
||||
// determines the target cell size which is used everywhere.
|
||||
// It determines the cell size given a location. It then uses all
|
||||
// the rules
|
||||
// - defaultCellSize
|
||||
// - cellSizeControlGeometry
|
||||
// to determine target cell size. Rule with highest priority wins. If same
|
||||
// priority smallest cell size wins.
|
||||
motionControl
|
||||
{
|
||||
// Absolute cell size of back ground mesh. This is the maximum cell size.
|
||||
defaultCellSize 0.00075;
|
||||
|
||||
// Assign a priority to all requests for cell sizes, the highest overrules.
|
||||
defaultPriority 0;
|
||||
|
||||
cellSizeControlGeometry
|
||||
{
|
||||
ref7_outside
|
||||
{
|
||||
// optional name of geometry
|
||||
surface ref7;
|
||||
priority 1;
|
||||
mode outside;//inside/bothSides
|
||||
cellSizeFunction linearDistance;
|
||||
|
||||
// cellSizeFunctions:
|
||||
// uniform : uniform size
|
||||
// uniformDistance : fixed size for all within distance
|
||||
// linearSpatial : grading in specified direction only
|
||||
// linearDistance : vary linearly as distance to surface
|
||||
// surfaceOffsetLinearDistance : constant close to surface then
|
||||
// fade like linearDistance
|
||||
|
||||
// Vary from surfaceCellSize (close to the surface) to
|
||||
// distanceCellSize (further than 'distance')
|
||||
linearDistanceCoeffs
|
||||
{
|
||||
surfaceCellSize 1e-5; // absolute size
|
||||
distanceCellSize $defaultCellSize;
|
||||
distance 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
tunnel_APPROACH_INLET.obj
|
||||
{
|
||||
priority 1;
|
||||
mode bothSides;
|
||||
cellSizeFunction surfaceOffsetLinearDistance;
|
||||
// Constant within a certain distance then linear fade away.
|
||||
// Good for layers.
|
||||
surfaceOffsetLinearDistanceCoeffs
|
||||
{
|
||||
surfaceCellSize 1e-5;
|
||||
distanceCellSize $defaultCellSize;
|
||||
surfaceOffset 0.1;
|
||||
totalDistance 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Underrelaxation for point motion. Simulated annealing: starts off at 1
|
||||
// and lowers to 0 (at simulation endTime) to converge points.
|
||||
// adaptiveLinear is preferred choice.
|
||||
// Points move by e.g. 10% of tet size.
|
||||
relaxationModel adaptiveLinear; //rampHoldFall
|
||||
|
||||
adaptiveLinearCoeffs
|
||||
{
|
||||
relaxationStart 1.0;
|
||||
relaxationEnd 0.0;
|
||||
}
|
||||
|
||||
// Output lots and lots of .obj files
|
||||
objOutput no;
|
||||
|
||||
// Timing and memory usage.
|
||||
timeChecks yes;
|
||||
|
||||
// Number of rays in plane parallel to nearest surface. Used to detect
|
||||
// next closest surfaces. Used to work out alignment (three vectors)
|
||||
// to surface.
|
||||
// Note that only the initial points (from the seeding) calculate this
|
||||
// information so if these are not fine enough the alignment will
|
||||
// not be correct. (any points added during the running will lookup
|
||||
// this information from the nearest initial point since it is
|
||||
// expensive)
|
||||
alignmentSearchSpokes 36;
|
||||
|
||||
// For each delaunay edge (between two vertices, becomes
|
||||
// the Voronoi face normal) snap to the alignment direction if within
|
||||
// alignmentAcceptanceAngle. Slightly > 45 is a good choice - prevents
|
||||
// flipping.
|
||||
alignmentAcceptanceAngle 48;
|
||||
|
||||
// How often to rebuild the alignment info (expensive)
|
||||
sizeAndAlignmentRebuildFrequency 20;
|
||||
|
||||
// When to insert points. Not advisable change to
|
||||
// these settings.
|
||||
pointInsertionCriteria
|
||||
{
|
||||
// If edge larger than 1.75 target cell size
|
||||
// (so tets too large/stretched) insert point
|
||||
cellCentreDistCoeff 1.75;
|
||||
// Do not insert point if voronoi face (on edge) very small.
|
||||
faceAreaRatioCoeff 0.0025;
|
||||
// Insert point only if edge closely aligned to local alignment
|
||||
// direction.
|
||||
acceptanceAngle 21.5;
|
||||
}
|
||||
|
||||
// Opposite: remove point if mesh too compressed. Do not change these
|
||||
// settings.
|
||||
pointRemovalCriteria
|
||||
{
|
||||
cellCentreDistCoeff 0.65;
|
||||
}
|
||||
|
||||
// How to determine the point motion. All edges got some direction.
|
||||
// Sum all edge contributions to determine point motion. Weigh by
|
||||
// face area so motion is preferentially determined by large faces
|
||||
// (or more importantly ignore contribution from small faces).
|
||||
// Do not change these settings.
|
||||
faceAreaWeightModel piecewiseLinearRamp;
|
||||
|
||||
piecewiseLinearRampCoeffs
|
||||
{
|
||||
lowerAreaFraction 0.5;
|
||||
upperAreaFraction 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// After simulation, when converting to polyMesh, filter out small faces/edges.
|
||||
// Do not change. See cvControls.H
|
||||
polyMeshFiltering
|
||||
{
|
||||
// Write the underlying Delaunay tet mesh at output time
|
||||
writeTetDualMesh false; //true;
|
||||
|
||||
// Upper limit on the size of faces to be filtered.
|
||||
// fraction of the local target cell size
|
||||
filterSizeCoeff 0.2;
|
||||
|
||||
// Upper limit on how close two dual vertices can be before
|
||||
// being merged, fraction of the local target cell size
|
||||
mergeClosenessCoeff 1e-9;
|
||||
|
||||
// To not filter: set maxNonOrtho to 1 (so check fails) and then
|
||||
// set continueFilteringOnBadInitialPolyMesh to false.
|
||||
continueFilteringOnBadInitialPolyMesh true;
|
||||
|
||||
// When a face is "bad", what fraction should the filterSizeCoeff be
|
||||
// reduced by. Recursive, so for a filterCount value of fC, the
|
||||
// filterSizeCoeff is reduced by pow(filterErrorReductionCoeff, fC)
|
||||
filterErrorReductionCoeff 0.5;
|
||||
|
||||
// Maximum number of filterCount applications before a face
|
||||
// is not attempted to be filtered
|
||||
filterCountSkipThreshold 4;
|
||||
|
||||
// Maximum number of permissible iterations of the face collapse
|
||||
// algorithm. The value to choose will be related the maximum number
|
||||
// of points on a face that is to be collapsed and how many faces
|
||||
// around it need to be collapsed.
|
||||
maxCollapseIterations 25;
|
||||
|
||||
// Maximum number of times an to allow an equal faceSet to be
|
||||
// returned from the face quality assessment before stopping iterations
|
||||
// to break an infinitie loop.
|
||||
maxConsecutiveEqualFaceSets 5;
|
||||
// Remove little steps (almost perp to surface) by collapsing face.
|
||||
surfaceStepFaceAngle 80;
|
||||
// Do not collapse face to edge if should become edges
|
||||
edgeCollapseGuardFraction 0.3;
|
||||
// Only collapse face to point if high aspect ratio
|
||||
maxCollapseFaceToPointSideLengthCoeff 0.35;
|
||||
}
|
||||
|
||||
|
||||
// Generic mesh quality settings. At any undoable phase these determine
|
||||
// where to undo. Same as in snappyHexMeshDict
|
||||
meshQualityControls
|
||||
{
|
||||
//- Maximum non-orthogonality allowed. Set to 180 to disable.
|
||||
maxNonOrtho 65;
|
||||
|
||||
//- Max skewness allowed. Set to <0 to disable.
|
||||
maxBoundarySkewness 50;
|
||||
maxInternalSkewness 10;
|
||||
|
||||
//- Max concaveness allowed. Is angle (in degrees) below which concavity
|
||||
// is allowed. 0 is straight face, <0 would be convex face.
|
||||
// Set to 180 to disable.
|
||||
maxConcave 80;
|
||||
|
||||
//- Minimum pyramid volume. Is absolute volume of cell pyramid.
|
||||
// Set to a sensible fraction of the smallest cell volume expected.
|
||||
// Set to very negative number (e.g. -1E30) to disable.
|
||||
minVol -1E30;
|
||||
|
||||
//- Minimum quality of the tet formed by the
|
||||
// variable base point minimum decomposition triangles and
|
||||
// the cell centre (so not face-centre decomposition).
|
||||
// This has to be a positive number for tracking
|
||||
// to work. Set to very negative number (e.g. -1E30) to
|
||||
// disable.
|
||||
// <0 = inside out tet,
|
||||
// 0 = flat tet
|
||||
// 1 = regular tet
|
||||
minTetQuality 1e-30;
|
||||
|
||||
//- Minimum absolute face area. Set to <0 to disable.
|
||||
minArea -1;
|
||||
|
||||
//- Minimum face twist. Set to <-1 to disable. dot product of face normal
|
||||
//- and face centre triangles normal
|
||||
minTwist 0.02;
|
||||
|
||||
//- minimum normalised cell determinant
|
||||
//- 1 = hex, <= 0 = folded or flattened illegal cell
|
||||
minDeterminant 0.001;
|
||||
|
||||
//- minFaceWeight (0 -> 0.5)
|
||||
minFaceWeight 0.02;
|
||||
|
||||
//- minVolRatio (0 -> 1)
|
||||
minVolRatio 0.01;
|
||||
|
||||
//must be >0 for Fluent compatibility
|
||||
minTriangleTwist -1;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -91,6 +91,26 @@ int main(int argc, char *argv[])
|
||||
// Clear mesh before checking
|
||||
mesh.clearOut();
|
||||
|
||||
pointIOField overrideCCs
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cellCentres",
|
||||
mesh.pointsInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
runTime,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
if (overrideCCs.headerOk())
|
||||
{
|
||||
Info<< "Read " << overrideCCs.size() << " cell centres" << endl;
|
||||
|
||||
mesh.overrideCellCentres(overrideCCs);
|
||||
}
|
||||
|
||||
// Reconstruct globalMeshData
|
||||
mesh.globalData();
|
||||
|
||||
|
||||
@ -208,7 +208,8 @@ int main(int argc, char *argv[])
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
Info<< "Read set " << setName << " with size "
|
||||
<< currentSet().size() << endl;
|
||||
<< returnReduce(currentSet().size(), sumOp<label>())
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
@ -292,7 +293,8 @@ int main(int argc, char *argv[])
|
||||
if (currentSet.valid())
|
||||
{
|
||||
Info<< " Set " << currentSet().name()
|
||||
<< " now size " << currentSet().size()
|
||||
<< " now size "
|
||||
<< returnReduce(currentSet().size(), sumOp<label>())
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
|
||||
foamToTetDualMesh.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/foamToTetDualMesh
|
||||
@ -0,0 +1,5 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume
|
||||
@ -0,0 +1,313 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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
|
||||
foamToTetDualMesh
|
||||
|
||||
Description
|
||||
Converts polyMesh results to tetDualMesh.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "argList.H"
|
||||
#include "fvMesh.H"
|
||||
#include "volFields.H"
|
||||
#include "pointFields.H"
|
||||
#include "Time.H"
|
||||
#include "IOobjectList.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class ReadGeoField, class MappedGeoField>
|
||||
void ReadAndMapFields
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const IOobjectList& objects,
|
||||
const fvMesh& tetDualMesh,
|
||||
const labelList& map,
|
||||
const typename MappedGeoField::value_type& nullValue,
|
||||
PtrList<MappedGeoField>& tetFields
|
||||
)
|
||||
{
|
||||
typedef typename MappedGeoField::value_type Type;
|
||||
|
||||
// Search list of objects for wanted type
|
||||
IOobjectList fieldObjects(objects.lookupClass(ReadGeoField::typeName));
|
||||
|
||||
tetFields.setSize(fieldObjects.size());
|
||||
|
||||
label i = 0;
|
||||
forAllConstIter(IOobjectList, fieldObjects, iter)
|
||||
{
|
||||
Info<< "Converting " << ReadGeoField::typeName << ' ' << iter.key()
|
||||
<< endl;
|
||||
|
||||
ReadGeoField readField(*iter(), mesh);
|
||||
|
||||
tetFields.set
|
||||
(
|
||||
i,
|
||||
new MappedGeoField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
readField.name(),
|
||||
readField.instance(),
|
||||
readField.local(),
|
||||
tetDualMesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE,
|
||||
readField.registerObject()
|
||||
),
|
||||
pointMesh::New(tetDualMesh),
|
||||
dimensioned<Type>
|
||||
(
|
||||
"zero",
|
||||
readField.dimensions(),
|
||||
pTraits<Type>::zero
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
Field<Type>& fld = tetFields[i].internalField();
|
||||
|
||||
// Map from read field. Set unmapped entries to nullValue.
|
||||
fld.setSize(map.size(), nullValue);
|
||||
forAll(map, pointI)
|
||||
{
|
||||
label index = map[pointI];
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
label cellI = index-1;
|
||||
fld[pointI] = readField[cellI];
|
||||
}
|
||||
else if (index < 0)
|
||||
{
|
||||
label faceI = -index-1;
|
||||
label bFaceI = faceI - mesh.nInternalFaces();
|
||||
if (bFaceI >= 0)
|
||||
{
|
||||
label patchI = mesh.boundaryMesh().patchID()[bFaceI];
|
||||
label localFaceI = mesh.boundaryMesh()[patchI].whichFace
|
||||
(
|
||||
faceI
|
||||
);
|
||||
fld[pointI] = readField.boundaryField()[patchI][localFaceI];
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// FatalErrorIn("ReadAndMapFields(..)")
|
||||
// << "Face " << faceI << " from index " << index
|
||||
// << " is not a boundary face." << abort(FatalError);
|
||||
//}
|
||||
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// WarningIn("ReadAndMapFields(..)")
|
||||
// << "Point " << pointI << " at "
|
||||
// << tetDualMesh.points()[pointI]
|
||||
// << " has no dual correspondence." << endl;
|
||||
//}
|
||||
}
|
||||
tetFields[i].correctBoundaryConditions();
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
# include "addOverwriteOption.H"
|
||||
# include "addTimeOptions.H"
|
||||
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
// Get times list
|
||||
instantList Times = runTime.times();
|
||||
# include "checkTimeOptions.H"
|
||||
runTime.setTime(Times[startTime], startTime);
|
||||
|
||||
|
||||
// Read the mesh
|
||||
# include "createMesh.H"
|
||||
|
||||
// Read the tetDualMesh
|
||||
Info<< "Create tetDualMesh for time = "
|
||||
<< runTime.timeName() << nl << endl;
|
||||
|
||||
fvMesh tetDualMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"tetDualMesh",
|
||||
runTime.timeName(),
|
||||
runTime,
|
||||
IOobject::MUST_READ
|
||||
)
|
||||
);
|
||||
// From tet vertices to poly cells/faces
|
||||
const labelIOList pointDualAddressing
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"pointDualAddressing",
|
||||
tetDualMesh.facesInstance(),
|
||||
tetDualMesh.meshSubDir,
|
||||
tetDualMesh,
|
||||
IOobject::MUST_READ
|
||||
)
|
||||
);
|
||||
|
||||
if (pointDualAddressing.size() != tetDualMesh.nPoints())
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Size " << pointDualAddressing.size()
|
||||
<< " of addressing map " << pointDualAddressing.objectPath()
|
||||
<< " differs from number of points in mesh "
|
||||
<< tetDualMesh.nPoints()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
// Some stats on addressing
|
||||
label nCells = 0;
|
||||
label nPatchFaces = 0;
|
||||
label nUnmapped = 0;
|
||||
forAll(pointDualAddressing, pointI)
|
||||
{
|
||||
label index = pointDualAddressing[pointI];
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
nCells++;
|
||||
}
|
||||
else if (index == 0)
|
||||
{
|
||||
nUnmapped++;
|
||||
}
|
||||
else
|
||||
{
|
||||
label faceI = -index-1;
|
||||
if (faceI < mesh.nInternalFaces())
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Face " << faceI << " from index " << index
|
||||
<< " is not a boundary face."
|
||||
<< " nInternalFaces:" << mesh.nInternalFaces()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
else
|
||||
{
|
||||
nPatchFaces++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reduce(nCells, sumOp<label>());
|
||||
reduce(nPatchFaces, sumOp<label>());
|
||||
reduce(nUnmapped, sumOp<label>());
|
||||
Info<< "tetDualMesh points : " << tetDualMesh.nPoints()
|
||||
<< " of which mapped to" << nl
|
||||
<< " cells : " << nCells << nl
|
||||
<< " patch faces : " << nPatchFaces << nl
|
||||
<< " not mapped : " << nUnmapped << nl
|
||||
<< endl;
|
||||
|
||||
|
||||
// Read objects in time directory
|
||||
IOobjectList objects(mesh, runTime.timeName());
|
||||
|
||||
// Read vol fields, interpolate onto tet points
|
||||
PtrList<pointScalarField> psFlds;
|
||||
ReadAndMapFields<volScalarField, pointScalarField>
|
||||
(
|
||||
mesh,
|
||||
objects,
|
||||
tetDualMesh,
|
||||
pointDualAddressing,
|
||||
pTraits<scalar>::zero, // nullValue
|
||||
psFlds
|
||||
);
|
||||
|
||||
PtrList<pointVectorField> pvFlds;
|
||||
ReadAndMapFields<volVectorField, pointVectorField>
|
||||
(
|
||||
mesh,
|
||||
objects,
|
||||
tetDualMesh,
|
||||
pointDualAddressing,
|
||||
pTraits<vector>::zero, // nullValue
|
||||
pvFlds
|
||||
);
|
||||
|
||||
PtrList<pointSphericalTensorField> pstFlds;
|
||||
ReadAndMapFields<volSphericalTensorField, pointSphericalTensorField>
|
||||
(
|
||||
mesh,
|
||||
objects,
|
||||
tetDualMesh,
|
||||
pointDualAddressing,
|
||||
pTraits<sphericalTensor>::zero, // nullValue
|
||||
pstFlds
|
||||
);
|
||||
|
||||
PtrList<pointSymmTensorField> psymmtFlds;
|
||||
ReadAndMapFields<volSymmTensorField, pointSymmTensorField>
|
||||
(
|
||||
mesh,
|
||||
objects,
|
||||
tetDualMesh,
|
||||
pointDualAddressing,
|
||||
pTraits<symmTensor>::zero, // nullValue
|
||||
psymmtFlds
|
||||
);
|
||||
|
||||
PtrList<pointTensorField> ptFlds;
|
||||
ReadAndMapFields<volTensorField, pointTensorField>
|
||||
(
|
||||
mesh,
|
||||
objects,
|
||||
tetDualMesh,
|
||||
pointDualAddressing,
|
||||
pTraits<tensor>::zero, // nullValue
|
||||
ptFlds
|
||||
);
|
||||
|
||||
tetDualMesh.objectRegistry::write();
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
surfaceBooleanFeatures.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/surfaceBooleanFeatures
|
||||
@ -0,0 +1,9 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/edgeMesh/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-ltriSurface \
|
||||
-ledgeMesh \
|
||||
-lmeshTools
|
||||
@ -0,0 +1,462 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2010-2011 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
|
||||
surfaceBooleanFeatures
|
||||
|
||||
Description
|
||||
|
||||
Generates the extendedFeatureEdgeMesh for the interface between a boolean
|
||||
operation on two surfaces. Assumes that the orientation of the surfaces is
|
||||
correct:
|
||||
|
||||
+ if the operation is union or intersection, that both surface's normals
|
||||
(n) have the same orientation with respect to a point, i.e. surfaces and b
|
||||
are orientated the same with respect to point x:
|
||||
|
||||
@verbatim
|
||||
_______
|
||||
| |--> n
|
||||
| ___|___ x
|
||||
|a | | |--> n
|
||||
|___|___| b|
|
||||
| |
|
||||
|_______|
|
||||
|
||||
@endverbatim
|
||||
|
||||
+ if the operation is a subtraction, the surfaces should be oppositely
|
||||
oriented with respect to a point, i.e. for (a - b), then b's orientation
|
||||
should be such that x is "inside", and a's orientation such that x is
|
||||
"outside"
|
||||
|
||||
@verbatim
|
||||
_______
|
||||
| |--> n
|
||||
| ___|___ x
|
||||
|a | | |
|
||||
|___|___| b|
|
||||
| n <--|
|
||||
|_______|
|
||||
|
||||
@endverbatim
|
||||
|
||||
When the operation is peformed - for union, all of the edges generates where
|
||||
one surfaces cuts another are all "internal" for union, and "external" for
|
||||
intersection, b - a and a - b. This has been assumed, formal (dis)proof is
|
||||
invited.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "triSurface.H"
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "extendedFeatureEdgeMesh.H"
|
||||
#include "triSurfaceSearch.H"
|
||||
#include "OFstream.H"
|
||||
#include "booleanSurface.H"
|
||||
#include "edgeIntersections.H"
|
||||
#include "meshTools.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Keep on shuffling surface points until no more degenerate intersections.
|
||||
// Moves both surfaces and updates set of edge cuts.
|
||||
bool intersectSurfaces
|
||||
(
|
||||
triSurface& surf1,
|
||||
edgeIntersections& edgeCuts1,
|
||||
triSurface& surf2,
|
||||
edgeIntersections& edgeCuts2
|
||||
)
|
||||
{
|
||||
bool hasMoved1 = false;
|
||||
bool hasMoved2 = false;
|
||||
|
||||
for (label iter = 0; iter < 10; iter++)
|
||||
{
|
||||
Info<< "Determining intersections of surf1 edges with surf2"
|
||||
<< " faces" << endl;
|
||||
|
||||
// Determine surface1 edge intersections. Allow surface to be moved.
|
||||
|
||||
// Number of iterations needed to resolve degenerates
|
||||
label nIters1 = 0;
|
||||
{
|
||||
triSurfaceSearch querySurf2(surf2);
|
||||
|
||||
scalarField surf1PointTol
|
||||
(
|
||||
1e-3*edgeIntersections::minEdgeLength(surf1)
|
||||
);
|
||||
|
||||
// Determine raw intersections
|
||||
edgeCuts1 = edgeIntersections
|
||||
(
|
||||
surf1,
|
||||
querySurf2,
|
||||
surf1PointTol
|
||||
);
|
||||
|
||||
// Shuffle a bit to resolve degenerate edge-face hits
|
||||
{
|
||||
pointField points1(surf1.points());
|
||||
|
||||
nIters1 =
|
||||
edgeCuts1.removeDegenerates
|
||||
(
|
||||
5, // max iterations
|
||||
surf1,
|
||||
querySurf2,
|
||||
surf1PointTol,
|
||||
points1 // work array
|
||||
);
|
||||
|
||||
if (nIters1 != 0)
|
||||
{
|
||||
// Update geometric quantities
|
||||
surf1.movePoints(points1);
|
||||
hasMoved1 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Determining intersections of surf2 edges with surf1"
|
||||
<< " faces" << endl;
|
||||
|
||||
label nIters2 = 0;
|
||||
{
|
||||
triSurfaceSearch querySurf1(surf1);
|
||||
|
||||
scalarField surf2PointTol
|
||||
(
|
||||
1e-3*edgeIntersections::minEdgeLength(surf2)
|
||||
);
|
||||
|
||||
// Determine raw intersections
|
||||
edgeCuts2 = edgeIntersections
|
||||
(
|
||||
surf2,
|
||||
querySurf1,
|
||||
surf2PointTol
|
||||
);
|
||||
|
||||
// Shuffle a bit to resolve degenerate edge-face hits
|
||||
{
|
||||
pointField points2(surf2.points());
|
||||
|
||||
nIters2 =
|
||||
edgeCuts2.removeDegenerates
|
||||
(
|
||||
5, // max iterations
|
||||
surf2,
|
||||
querySurf1,
|
||||
surf2PointTol,
|
||||
points2 // work array
|
||||
);
|
||||
|
||||
if (nIters2 != 0)
|
||||
{
|
||||
// Update geometric quantities
|
||||
surf2.movePoints(points2);
|
||||
hasMoved2 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nIters1 == 0 && nIters2 == 0)
|
||||
{
|
||||
Info<< "** Resolved all intersections to be proper edge-face pierce"
|
||||
<< endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasMoved1)
|
||||
{
|
||||
fileName newFile("surf1.obj");
|
||||
Info<< "Surface 1 has been moved. Writing to " << newFile
|
||||
<< endl;
|
||||
surf1.write(newFile);
|
||||
}
|
||||
|
||||
if (hasMoved2)
|
||||
{
|
||||
fileName newFile("surf2.obj");
|
||||
Info<< "Surface 2 has been moved. Writing to " << newFile
|
||||
<< endl;
|
||||
surf2.write(newFile);
|
||||
}
|
||||
|
||||
return hasMoved1 || hasMoved2;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::validArgs.clear();
|
||||
argList::noParallel();
|
||||
argList::validArgs.append("action");
|
||||
argList::validArgs.append("surface file");
|
||||
argList::validArgs.append("surface file");
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
"perturb",
|
||||
"Perturb surface points to escape degenerate intersections"
|
||||
);
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
"invertedSpace",
|
||||
"do the surfaces have inverted space orientation, "
|
||||
"i.e. a point at infinity is considered inside. "
|
||||
"This is only sensible for union and intersection."
|
||||
);
|
||||
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
|
||||
word action(args.args()[1]);
|
||||
|
||||
HashTable<booleanSurface::booleanOpType> validActions;
|
||||
validActions.insert("intersection", booleanSurface::INTERSECTION);
|
||||
validActions.insert("union", booleanSurface::UNION);
|
||||
validActions.insert("difference", booleanSurface::DIFFERENCE);
|
||||
|
||||
if (!validActions.found(action))
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Unsupported action " << action << endl
|
||||
<< "Supported actions:" << validActions.toc() << exit(FatalError);
|
||||
}
|
||||
|
||||
fileName surf1Name(args[2]);
|
||||
Info<< "Reading surface " << surf1Name << endl;
|
||||
triSurface surf1(surf1Name);
|
||||
|
||||
Info<< surf1Name << " statistics:" << endl;
|
||||
surf1.writeStats(Info);
|
||||
Info<< endl;
|
||||
|
||||
fileName surf2Name(args[3]);
|
||||
Info<< "Reading surface " << surf2Name << endl;
|
||||
triSurface surf2(surf2Name);
|
||||
|
||||
Info<< surf2Name << " statistics:" << endl;
|
||||
surf2.writeStats(Info);
|
||||
Info<< endl;
|
||||
|
||||
edgeIntersections edge1Cuts;
|
||||
edgeIntersections edge2Cuts;
|
||||
|
||||
bool invertedSpace = args.optionFound("invertedSpace");
|
||||
|
||||
if (invertedSpace && validActions[action] == booleanSurface::DIFFERENCE)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Inverted space only makes sense for union or intersection."
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
if (args.optionFound("perturb"))
|
||||
{
|
||||
intersectSurfaces
|
||||
(
|
||||
surf1,
|
||||
edge1Cuts,
|
||||
surf2,
|
||||
edge2Cuts
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
triSurfaceSearch querySurf2(surf2);
|
||||
|
||||
Info<< "Determining intersections of surf1 edges with surf2 faces"
|
||||
<< endl;
|
||||
|
||||
edge1Cuts = edgeIntersections
|
||||
(
|
||||
surf1,
|
||||
querySurf2,
|
||||
1e-3*edgeIntersections::minEdgeLength(surf1)
|
||||
);
|
||||
|
||||
triSurfaceSearch querySurf1(surf1);
|
||||
|
||||
Info<< "Determining intersections of surf2 edges with surf1 faces"
|
||||
<< endl;
|
||||
|
||||
edge2Cuts = edgeIntersections
|
||||
(
|
||||
surf2,
|
||||
querySurf1,
|
||||
1e-3*edgeIntersections::minEdgeLength(surf2)
|
||||
);
|
||||
}
|
||||
|
||||
// Determine intersection edges
|
||||
surfaceIntersection inter(surf1, edge1Cuts, surf2, edge2Cuts);
|
||||
|
||||
fileName sFeatFileName =
|
||||
surf1Name.lessExt().name()
|
||||
+ "_"
|
||||
+ surf2Name.lessExt().name()
|
||||
+ "_"
|
||||
+ action;
|
||||
|
||||
label nFeatEds = inter.cutEdges().size();
|
||||
|
||||
vectorField normals(2*nFeatEds, vector::zero);
|
||||
vectorField edgeDirections(nFeatEds, vector::zero);
|
||||
labelListList edgeNormals(nFeatEds, labelList(2, -1));
|
||||
|
||||
triSurfaceSearch querySurf1(surf1);
|
||||
triSurfaceSearch querySurf2(surf2);
|
||||
|
||||
OFstream normalFile(sFeatFileName + "_normals.obj");
|
||||
|
||||
scalar scale = 0.05*min
|
||||
(
|
||||
querySurf1.tree().bb().mag(),
|
||||
querySurf2.tree().bb().mag()
|
||||
);
|
||||
|
||||
forAll(inter.cutEdges(), i)
|
||||
{
|
||||
const edge& fE(inter.cutEdges()[i]);
|
||||
|
||||
point fEC = fE.centre(inter.cutPoints());
|
||||
|
||||
pointIndexHit nearest1 = querySurf1.tree().findNearest(fEC, sqr(GREAT));
|
||||
pointIndexHit nearest2 = querySurf2.tree().findNearest(fEC, sqr(GREAT));
|
||||
|
||||
normals[2*i] = surf1.faceNormals()[nearest1.index()];
|
||||
normals[2*i + 1] = surf2.faceNormals()[nearest2.index()];
|
||||
|
||||
edgeNormals[i][0] = 2*i;
|
||||
edgeNormals[i][1] = 2*i + 1;
|
||||
|
||||
edgeDirections[i] = fE.vec(inter.cutPoints());
|
||||
|
||||
{
|
||||
meshTools::writeOBJ(normalFile, inter.cutPoints()[fE.start()]);
|
||||
meshTools::writeOBJ(normalFile, inter.cutPoints()[fE.end()]);
|
||||
|
||||
normalFile<< "l " << (5*i) + 1 << " " << (5*i) + 2<< endl;
|
||||
|
||||
meshTools::writeOBJ(normalFile, fEC);
|
||||
meshTools::writeOBJ(normalFile, fEC + scale*normals[2*i]);
|
||||
meshTools::writeOBJ(normalFile, fEC + scale*normals[2*i + 1]);
|
||||
|
||||
normalFile<< "l " << (5*i) + 3 << " " << (5*i) + 4 << endl;
|
||||
normalFile<< "l " << (5*i) + 3 << " " << (5*i) + 5 << endl;
|
||||
}
|
||||
}
|
||||
|
||||
label internalStart = -1;
|
||||
|
||||
if (validActions[action] == booleanSurface::UNION)
|
||||
{
|
||||
if (!invertedSpace)
|
||||
{
|
||||
// All edges are internal
|
||||
internalStart = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// All edges are external
|
||||
internalStart = nFeatEds;
|
||||
}
|
||||
}
|
||||
else if (validActions[action] == booleanSurface::INTERSECTION)
|
||||
{
|
||||
if (!invertedSpace)
|
||||
{
|
||||
// All edges are external
|
||||
internalStart = nFeatEds;
|
||||
}
|
||||
else
|
||||
{
|
||||
// All edges are internal
|
||||
internalStart = 0;
|
||||
}
|
||||
}
|
||||
else if (validActions[action] == booleanSurface::DIFFERENCE)
|
||||
{
|
||||
// All edges are external
|
||||
internalStart = nFeatEds;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Unsupported booleanSurface:booleanOpType and space "
|
||||
<< action << " " << invertedSpace
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// There are no feature points supported by surfaceIntersection
|
||||
// Flat, open or multiple edges are assumed to be impossible
|
||||
// Region edges are not explicitly supported by surfaceIntersection
|
||||
|
||||
extendedFeatureEdgeMesh feMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
sFeatFileName + ".extendedFeatureEdgeMesh",
|
||||
runTime.constant(),
|
||||
"featureEdgeMesh",
|
||||
runTime,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
inter.cutPoints(),
|
||||
inter.cutEdges(),
|
||||
0, // concaveStart,
|
||||
0, // mixedStart,
|
||||
0, // nonFeatureStart,
|
||||
internalStart, // internalStart,
|
||||
nFeatEds, // flatStart,
|
||||
nFeatEds, // openStart,
|
||||
nFeatEds, // multipleStart,
|
||||
normals,
|
||||
edgeDirections,
|
||||
edgeNormals,
|
||||
labelListList(0), // featurePointNormals,
|
||||
labelList(0) // regionEdges
|
||||
);
|
||||
|
||||
feMesh.write();
|
||||
|
||||
feMesh.writeObj(sFeatFileName);
|
||||
|
||||
Info << "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -314,25 +314,6 @@ int main(int argc, char *argv[])
|
||||
// << " coords " << f.points(surf.points()) << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
triPointRef tri
|
||||
(
|
||||
surf.points()[f[0]],
|
||||
surf.points()[f[1]],
|
||||
surf.points()[f[2]]
|
||||
);
|
||||
|
||||
vector ba(tri.b() - tri.a());
|
||||
ba /= mag(ba) + VSMALL;
|
||||
|
||||
vector ca(tri.c() - tri.a());
|
||||
ca /= mag(ca) + VSMALL;
|
||||
|
||||
if (mag(ba&ca) > 1-1E-3)
|
||||
{
|
||||
triQ[faceI] = SMALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
triQ[faceI] = triPointRef
|
||||
(
|
||||
@ -342,7 +323,6 @@ int main(int argc, char *argv[])
|
||||
).quality();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
labelList binCount = countBins(0, 1, 20, triQ);
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -66,8 +66,8 @@ static void writeRegionOBJ
|
||||
|
||||
triSurface regionSurf(surf.subsetMesh(include, pointMap, faceMap));
|
||||
|
||||
//Pout<< "Region " << regionI << " surface:" << nl;
|
||||
//regionSurf.writeStats(Pout);
|
||||
Pout<< "Region " << regionI << " surface:" << nl;
|
||||
regionSurf.writeStats(Pout);
|
||||
|
||||
regionSurf.write(regionName);
|
||||
|
||||
@ -97,7 +97,7 @@ static void splitTri
|
||||
DynamicList<labelledTri>& tris
|
||||
)
|
||||
{
|
||||
label oldNTris = tris.size();
|
||||
//label oldNTris = tris.size();
|
||||
|
||||
label fp = findIndex(f, e[0]);
|
||||
label fp1 = f.fcIndex(fp);
|
||||
@ -175,7 +175,7 @@ static void splitTri
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn("splitTri")
|
||||
FatalErrorIn("splitTri(..)")
|
||||
<< "Edge " << e << " not part of triangle " << f
|
||||
<< " fp:" << fp
|
||||
<< " fp1:" << fp1
|
||||
@ -183,13 +183,13 @@ static void splitTri
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
Pout<< "Split face " << f << " along edge " << e
|
||||
<< " into triangles:" << endl;
|
||||
|
||||
for (label i = oldNTris; i < tris.size(); i++)
|
||||
{
|
||||
Pout<< " " << tris[i] << nl;
|
||||
}
|
||||
//Pout<< "Split face " << f << " along edge " << e
|
||||
// << " into triangles:" << endl;
|
||||
//
|
||||
//for (label i = oldNTris; i < tris.size(); i++)
|
||||
//{
|
||||
// Pout<< " " << tris[i] << nl;
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
@ -206,14 +206,14 @@ static bool insertSorted
|
||||
{
|
||||
if (findIndex(sortedVerts, vertI) != -1)
|
||||
{
|
||||
FatalErrorIn("insertSorted") << "Trying to insert vertex " << vertI
|
||||
FatalErrorIn("insertSorted(..)") << "Trying to insert vertex " << vertI
|
||||
<< " which is already in list of sorted vertices "
|
||||
<< sortedVerts << abort(FatalError);
|
||||
}
|
||||
|
||||
if (weight <= 0 || weight >= 1)
|
||||
{
|
||||
FatalErrorIn("insertSorted") << "Trying to insert vertex " << vertI
|
||||
FatalErrorIn("insertSorted(..)") << "Trying to insert vertex " << vertI
|
||||
<< " with illegal weight " << weight
|
||||
<< " into list of sorted vertices "
|
||||
<< sortedVerts << abort(FatalError);
|
||||
@ -228,7 +228,7 @@ static bool insertSorted
|
||||
|
||||
if (mag(w - weight) < SMALL)
|
||||
{
|
||||
WarningIn("insertSorted")
|
||||
WarningIn("insertSorted(..)")
|
||||
<< "Trying to insert weight " << weight << " which is close to"
|
||||
<< " existing weight " << w << " in " << sortedWeights
|
||||
<< endl;
|
||||
@ -263,32 +263,23 @@ static bool insertSorted
|
||||
}
|
||||
|
||||
|
||||
// Mark all faces that are going to be collapsed.
|
||||
// faceToEdge: per face -1 or the base edge of the face.
|
||||
static void markCollapsedFaces
|
||||
// Is triangle candidate for collapse? Small height or small quality
|
||||
bool isSliver
|
||||
(
|
||||
const triSurface& surf,
|
||||
const scalar minLen,
|
||||
labelList& faceToEdge
|
||||
const scalar minQuality,
|
||||
const label faceI,
|
||||
const label edgeI
|
||||
)
|
||||
{
|
||||
faceToEdge.setSize(surf.size());
|
||||
faceToEdge = -1;
|
||||
|
||||
const pointField& localPoints = surf.localPoints();
|
||||
const labelListList& edgeFaces = surf.edgeFaces();
|
||||
|
||||
forAll(edgeFaces, edgeI)
|
||||
{
|
||||
const edge& e = surf.edges()[edgeI];
|
||||
// Check
|
||||
// - opposite vertex projects onto base edge
|
||||
// - normal distance is small
|
||||
// - or triangle quality is small
|
||||
|
||||
const labelList& eFaces = surf.edgeFaces()[edgeI];
|
||||
|
||||
forAll(eFaces, i)
|
||||
{
|
||||
label faceI = eFaces[i];
|
||||
|
||||
// Check distance of vertex to edge.
|
||||
label opposite0 =
|
||||
triSurfaceTools::oppositeVertex
|
||||
(
|
||||
@ -297,30 +288,78 @@ static void markCollapsedFaces
|
||||
edgeI
|
||||
);
|
||||
|
||||
const edge& e = surf.edges()[edgeI];
|
||||
const labelledTri& f = surf[faceI];
|
||||
|
||||
pointHit pHit =
|
||||
e.line(localPoints).nearestDist
|
||||
(
|
||||
localPoints[opposite0]
|
||||
);
|
||||
|
||||
if (pHit.hit() && pHit.distance() < minLen)
|
||||
if
|
||||
(
|
||||
pHit.hit()
|
||||
&& (
|
||||
pHit.distance() < minLen
|
||||
|| f.tri(surf.points()).quality() < minQuality
|
||||
)
|
||||
)
|
||||
{
|
||||
// Remove faceI and split all other faces using this
|
||||
// edge. This is done by 'replacing' the edgeI with the
|
||||
// opposite0 vertex
|
||||
Pout<< "Splitting face " << faceI << " since distance "
|
||||
<< pHit.distance()
|
||||
<< " from vertex " << opposite0
|
||||
<< " to edge " << edgeI
|
||||
<< " points "
|
||||
<< localPoints[e[0]]
|
||||
<< localPoints[e[1]]
|
||||
<< " is too small" << endl;
|
||||
//Pout<< "Splitting face " << faceI << " since distance "
|
||||
// << pHit.distance()
|
||||
// << " from vertex " << opposite0
|
||||
// << " to edge " << edgeI
|
||||
// << " points "
|
||||
// << localPoints[e[0]]
|
||||
// << localPoints[e[1]]
|
||||
// << " is too small or triangle quality "
|
||||
// << f.tri(surf.points()).quality()
|
||||
// << " too small." << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Mark all faces that are going to be collapsed.
|
||||
// faceToEdge: per face -1 or the base edge of the face.
|
||||
static void markCollapsedFaces
|
||||
(
|
||||
const triSurface& surf,
|
||||
const scalar minLen,
|
||||
const scalar minQuality,
|
||||
labelList& faceToEdge
|
||||
)
|
||||
{
|
||||
faceToEdge.setSize(surf.size());
|
||||
faceToEdge = -1;
|
||||
|
||||
const labelListList& edgeFaces = surf.edgeFaces();
|
||||
|
||||
forAll(edgeFaces, edgeI)
|
||||
{
|
||||
const labelList& eFaces = surf.edgeFaces()[edgeI];
|
||||
|
||||
forAll(eFaces, i)
|
||||
{
|
||||
label faceI = eFaces[i];
|
||||
|
||||
bool isCandidate = isSliver(surf, minLen, minQuality, faceI, edgeI);
|
||||
|
||||
if (isCandidate)
|
||||
{
|
||||
// Mark face as being collapsed
|
||||
if (faceToEdge[faceI] != -1)
|
||||
{
|
||||
FatalErrorIn("markCollapsedFaces")
|
||||
FatalErrorIn("markCollapsedFaces(..)")
|
||||
<< "Cannot collapse face " << faceI << " since "
|
||||
<< " is marked to be collapsed both to edge "
|
||||
<< faceToEdge[faceI] << " and " << edgeI
|
||||
@ -347,7 +386,7 @@ static void markRegion
|
||||
{
|
||||
if (faceToEdge[faceI] == -1 || collapseRegion[faceI] != -1)
|
||||
{
|
||||
FatalErrorIn("markRegion")
|
||||
FatalErrorIn("markRegion(..)")
|
||||
<< "Problem : crossed into uncollapsed/regionized face"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
@ -383,7 +422,7 @@ static void markRegion
|
||||
}
|
||||
else if (collapseRegion[nbrFaceI] != regionI)
|
||||
{
|
||||
FatalErrorIn("markRegion")
|
||||
FatalErrorIn("markRegion(..)")
|
||||
<< "Edge:" << edgeI << " between face " << faceI
|
||||
<< " with region " << regionI
|
||||
<< " and face " << nbrFaceI
|
||||
@ -411,8 +450,8 @@ static label markRegions
|
||||
{
|
||||
if (collapseRegion[faceI] == -1 && faceToEdge[faceI] != -1)
|
||||
{
|
||||
Pout<< "markRegions : Marking region:" << regionI
|
||||
<< " starting from face " << faceI << endl;
|
||||
//Pout<< "markRegions : Marking region:" << regionI
|
||||
// << " starting from face " << faceI << endl;
|
||||
|
||||
// Collapsed face. Mark connected region with current region number
|
||||
markRegion(surf, faceToEdge, regionI++, faceI, collapseRegion);
|
||||
@ -728,7 +767,12 @@ static void getSplitVerts
|
||||
}
|
||||
|
||||
|
||||
label collapseBase(triSurface& surf, const scalar minLen)
|
||||
label collapseBase
|
||||
(
|
||||
triSurface& surf,
|
||||
const scalar minLen,
|
||||
const scalar minQuality
|
||||
)
|
||||
{
|
||||
label nTotalSplit = 0;
|
||||
|
||||
@ -743,7 +787,7 @@ label collapseBase(triSurface& surf, const scalar minLen)
|
||||
labelList faceToEdge(surf.size(), -1);
|
||||
|
||||
// Calculate faceToEdge (face collapses)
|
||||
markCollapsedFaces(surf, minLen, faceToEdge);
|
||||
markCollapsedFaces(surf, minLen, minQuality, faceToEdge);
|
||||
|
||||
|
||||
// Find regions of connected collapsed faces
|
||||
@ -754,8 +798,8 @@ label collapseBase(triSurface& surf, const scalar minLen)
|
||||
|
||||
label nRegions = markRegions(surf, faceToEdge, collapseRegion);
|
||||
|
||||
Pout<< "Detected " << nRegions << " regions of faces to be collapsed"
|
||||
<< nl << endl;
|
||||
//Pout<< "Detected " << nRegions << " regions of faces to be collapsed"
|
||||
// << nl << endl;
|
||||
|
||||
// Pick up all vertices on outside of region
|
||||
labelListList outsideVerts
|
||||
@ -772,10 +816,10 @@ label collapseBase(triSurface& surf, const scalar minLen)
|
||||
{
|
||||
spanPoints[regionI] = getSpanPoints(surf, outsideVerts[regionI]);
|
||||
|
||||
Pout<< "For region " << regionI << " found extrema at points "
|
||||
<< surf.localPoints()[spanPoints[regionI][0]]
|
||||
<< surf.localPoints()[spanPoints[regionI][1]]
|
||||
<< endl;
|
||||
//Pout<< "For region " << regionI << " found extrema at points "
|
||||
// << surf.localPoints()[spanPoints[regionI][0]]
|
||||
// << surf.localPoints()[spanPoints[regionI][1]]
|
||||
// << endl;
|
||||
|
||||
// Project all non-span points onto the span edge.
|
||||
projectNonSpanPoints
|
||||
@ -787,21 +831,21 @@ label collapseBase(triSurface& surf, const scalar minLen)
|
||||
orderedWeights[regionI]
|
||||
);
|
||||
|
||||
Pout<< "For region:" << regionI
|
||||
<< " span:" << spanPoints[regionI]
|
||||
<< " orderedVerts:" << orderedVertices[regionI]
|
||||
<< " orderedWeights:" << orderedWeights[regionI]
|
||||
<< endl;
|
||||
//Pout<< "For region:" << regionI
|
||||
// << " span:" << spanPoints[regionI]
|
||||
// << " orderedVerts:" << orderedVertices[regionI]
|
||||
// << " orderedWeights:" << orderedWeights[regionI]
|
||||
// << endl;
|
||||
|
||||
writeRegionOBJ
|
||||
(
|
||||
surf,
|
||||
regionI,
|
||||
collapseRegion,
|
||||
outsideVerts[regionI]
|
||||
);
|
||||
//writeRegionOBJ
|
||||
//(
|
||||
// surf,
|
||||
// regionI,
|
||||
// collapseRegion,
|
||||
// outsideVerts[regionI]
|
||||
//);
|
||||
|
||||
Pout<< endl;
|
||||
//Pout<< endl;
|
||||
}
|
||||
|
||||
|
||||
@ -864,20 +908,19 @@ label collapseBase(triSurface& surf, const scalar minLen)
|
||||
// Split edge using splitVerts. All non-collapsed triangles
|
||||
// using edge will get split.
|
||||
|
||||
|
||||
{
|
||||
const pointField& localPoints = surf.localPoints();
|
||||
Pout<< "edge " << edgeI << ' ' << e
|
||||
<< " points "
|
||||
<< localPoints[e[0]] << ' ' << localPoints[e[1]]
|
||||
<< " split into edges with extra points:"
|
||||
<< endl;
|
||||
forAll(splitVerts, i)
|
||||
{
|
||||
Pout<< " " << splitVerts[i] << " weight "
|
||||
<< splitWeights[i] << nl;
|
||||
}
|
||||
}
|
||||
//{
|
||||
// const pointField& localPoints = surf.localPoints();
|
||||
// Pout<< "edge " << edgeI << ' ' << e
|
||||
// << " points "
|
||||
// << localPoints[e[0]] << ' ' << localPoints[e[1]]
|
||||
// << " split into edges with extra points:"
|
||||
// << endl;
|
||||
// forAll(splitVerts, i)
|
||||
// {
|
||||
// Pout<< " " << splitVerts[i] << " weight "
|
||||
// << splitWeights[i] << nl;
|
||||
// }
|
||||
//}
|
||||
|
||||
const labelList& eFaces = surf.edgeFaces()[edgeI];
|
||||
|
||||
@ -914,7 +957,8 @@ label collapseBase(triSurface& surf, const scalar minLen)
|
||||
}
|
||||
}
|
||||
|
||||
Pout<< "collapseBase : splitting " << nSplit << " triangles"
|
||||
Info<< "collapseBase : collapsing " << nSplit
|
||||
<< " triangles by splitting their base edge."
|
||||
<< endl;
|
||||
|
||||
nTotalSplit += nSplit;
|
||||
@ -927,15 +971,15 @@ label collapseBase(triSurface& surf, const scalar minLen)
|
||||
// Pack the triangles
|
||||
newTris.shrink();
|
||||
|
||||
Pout<< "Resetting surface from " << surf.size() << " to "
|
||||
<< newTris.size() << " triangles" << endl;
|
||||
//Pout<< "Resetting surface from " << surf.size() << " to "
|
||||
// << newTris.size() << " triangles" << endl;
|
||||
surf = triSurface(newTris, surf.patches(), surf.localPoints());
|
||||
|
||||
{
|
||||
fileName fName("bla" + name(iter) + ".obj");
|
||||
Pout<< "Writing surf to " << fName << endl;
|
||||
surf.write(fName);
|
||||
}
|
||||
//{
|
||||
// fileName fName("bla" + name(iter) + ".obj");
|
||||
// Pout<< "Writing surf to " << fName << endl;
|
||||
// surf.write(fName);
|
||||
//}
|
||||
|
||||
iter++;
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -41,9 +41,14 @@ using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Keep collapsing all triangles whose height is < minLen.
|
||||
//- Keep collapsing all triangles whose height is < minLen or quality < minQ.
|
||||
// Returns number of triangles collapsed.
|
||||
label collapseBase(triSurface& surf, const scalar minLen);
|
||||
label collapseBase
|
||||
(
|
||||
triSurface& surf,
|
||||
const scalar minLen,
|
||||
const scalar minQuality
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -121,8 +121,8 @@ label collapseEdge(triSurface& surf, const scalar minLen)
|
||||
pointMap[v1] = v;
|
||||
newPoints[v] = 0.5*(localPoints[v1] + localPoints[v]);
|
||||
|
||||
Pout<< "Collapsing triange " << faceI << " to edge mid "
|
||||
<< newPoints[v] << endl;
|
||||
//Pout<< "Collapsing triange " << faceI
|
||||
// << " to edge mid " << newPoints[v] << endl;
|
||||
|
||||
nCollapsed++;
|
||||
okToCollapse[faceI] = false;
|
||||
@ -136,7 +136,8 @@ label collapseEdge(triSurface& surf, const scalar minLen)
|
||||
}
|
||||
}
|
||||
|
||||
Pout<< "collapseEdge : collapsing " << nCollapsed << " triangles"
|
||||
Info<< "collapseEdge : collapsing " << nCollapsed
|
||||
<< " triangles to a single edge."
|
||||
<< endl;
|
||||
|
||||
nTotalCollapsed += nCollapsed;
|
||||
|
||||
@ -50,6 +50,7 @@ int main(int argc, char *argv[])
|
||||
argList::noParallel();
|
||||
argList::validArgs.append("surfaceFile");
|
||||
argList::validArgs.append("min length");
|
||||
argList::validArgs.append("min quality");
|
||||
argList::validArgs.append("output surfaceFile");
|
||||
argList::addBoolOption
|
||||
(
|
||||
@ -60,10 +61,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
const fileName inFileName = args[1];
|
||||
const scalar minLen = args.argRead<scalar>(2);
|
||||
const fileName outFileName = args[3];
|
||||
const scalar minQuality = args.argRead<scalar>(3);
|
||||
const fileName outFileName = args[4];
|
||||
|
||||
Info<< "Reading surface " << inFileName << nl
|
||||
<< "Collapsing all triangles with edges or heights < " << minLen << nl
|
||||
<< "Collapsing all triangles with" << nl
|
||||
<< " edges or heights < " << minLen << nl
|
||||
<< " quality < " << minQuality << nl
|
||||
<< "Writing result to " << outFileName << nl << endl;
|
||||
|
||||
|
||||
@ -90,7 +94,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
label nSplitEdge = collapseBase(surf, minLen);
|
||||
label nSplitEdge = collapseBase(surf, minLen, minQuality);
|
||||
|
||||
if (nSplitEdge == 0)
|
||||
{
|
||||
|
||||
@ -0,0 +1,203 @@
|
||||
#ifndef CGAL_PSURF_RINGS_H_
|
||||
#define CGAL_PSURF_RINGS_H_
|
||||
|
||||
// This file adapted from
|
||||
// CGAL-3.7/examples/Jet_fitting_3//PolyhedralSurf_rings.h
|
||||
// Licensed under CGAL-3.7/LICENSE.FREE_USE
|
||||
|
||||
// Copyright (c) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007
|
||||
// Utrecht University (The Netherlands), ETH Zurich (Switzerland), Freie
|
||||
// Universitaet Berlin (Germany), INRIA Sophia-Antipolis (France),
|
||||
// Martin-Luther-University Halle-Wittenberg (Germany), Max-Planck-Institute
|
||||
// Saarbruecken (Germany), RISC Linz (Austria), and Tel-Aviv University
|
||||
// (Israel). All rights reserved.
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
|
||||
#include <cassert>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template
|
||||
<
|
||||
class TPoly,
|
||||
class VertexPropertyMap
|
||||
>
|
||||
|
||||
class T_PolyhedralSurf_rings
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
//Polyhedron
|
||||
typedef typename TPoly::Vertex Vertex;
|
||||
typedef typename TPoly::Halfedge Halfedge;
|
||||
typedef typename TPoly::Facet Facet;
|
||||
typedef typename TPoly::Halfedge_around_vertex_circulator
|
||||
Halfedge_around_vertex_circulator;
|
||||
typedef typename TPoly::Vertex_iterator Vertex_iterator;
|
||||
|
||||
//vertex indices are initialised to -1
|
||||
static void reset_ring_indices(std::vector < Vertex * >&vces,
|
||||
VertexPropertyMap& vpm);
|
||||
|
||||
// i >= 1; from a start vertex on the current i-1 ring, push non-visited
|
||||
// neighbors of start in the nextRing and set indices to i. Also add these
|
||||
// vertices in all.
|
||||
static void push_neighbours_of(Vertex * start, int ith,
|
||||
std::vector < Vertex * >&nextRing,
|
||||
std::vector < Vertex * >&all,
|
||||
VertexPropertyMap& vpm);
|
||||
|
||||
// i >= 1, from a currentRing i-1, collect all neighbors, set indices
|
||||
// to i and store them in nextRing and all.
|
||||
static void collect_ith_ring(int ith,
|
||||
std::vector < Vertex * >¤tRing,
|
||||
std::vector < Vertex * >&nextRing,
|
||||
std::vector < Vertex * >&all,
|
||||
VertexPropertyMap& vpm);
|
||||
|
||||
public:
|
||||
|
||||
// collect i>=1 rings : all neighbours up to the ith ring,
|
||||
static void
|
||||
collect_i_rings(Vertex* v,
|
||||
int ring_i,
|
||||
std::vector < Vertex * >& all,
|
||||
VertexPropertyMap& vpm);
|
||||
|
||||
//collect enough rings (at least 1), to get at least min_nb of neighbors
|
||||
static void
|
||||
collect_enough_rings(Vertex* v,
|
||||
unsigned int min_nb,
|
||||
std::vector < Vertex * >& all,
|
||||
VertexPropertyMap& vpm);
|
||||
};
|
||||
|
||||
|
||||
////IMPLEMENTATION////////////////////////////////////////////////////
|
||||
|
||||
template < class TPoly , class VertexPropertyMap>
|
||||
void T_PolyhedralSurf_rings <TPoly, VertexPropertyMap>::
|
||||
push_neighbours_of(Vertex * start, int ith,
|
||||
std::vector < Vertex * >&nextRing,
|
||||
std::vector < Vertex * >&all,
|
||||
VertexPropertyMap& vpm)
|
||||
{
|
||||
Vertex *v;
|
||||
Halfedge_around_vertex_circulator
|
||||
hedgeb = start->vertex_begin(), hedgee = hedgeb;
|
||||
|
||||
CGAL_For_all(hedgeb, hedgee)
|
||||
{
|
||||
v = &*(hedgeb->opposite()->vertex());
|
||||
if(get(vpm, v) != -1) continue;//if visited: next
|
||||
|
||||
put(vpm, v, ith);
|
||||
nextRing.push_back(v);
|
||||
all.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class TPoly, class VertexPropertyMap>
|
||||
void T_PolyhedralSurf_rings <TPoly, VertexPropertyMap>::
|
||||
collect_ith_ring(int ith, std::vector < Vertex * >¤tRing,
|
||||
std::vector < Vertex * >&nextRing,
|
||||
std::vector < Vertex * >&all,
|
||||
VertexPropertyMap& vpm)
|
||||
{
|
||||
typename std::vector < Vertex * >::iterator
|
||||
itb = currentRing.begin(), ite = currentRing.end();
|
||||
|
||||
CGAL_For_all(itb, ite) push_neighbours_of(*itb, ith, nextRing, all, vpm);
|
||||
}
|
||||
|
||||
|
||||
template <class TPoly, class VertexPropertyMap>
|
||||
void T_PolyhedralSurf_rings <TPoly, VertexPropertyMap>::
|
||||
reset_ring_indices(std::vector < Vertex * >&vces,
|
||||
VertexPropertyMap& vpm)
|
||||
{
|
||||
typename std::vector < Vertex * >::iterator
|
||||
itb = vces.begin(), ite = vces.end();
|
||||
CGAL_For_all(itb, ite) put(vpm, *itb, -1);
|
||||
}
|
||||
|
||||
|
||||
template <class TPoly, class VertexPropertyMap>
|
||||
void T_PolyhedralSurf_rings <TPoly, VertexPropertyMap>::
|
||||
collect_i_rings(Vertex* v,
|
||||
int ring_i,
|
||||
std::vector < Vertex * >& all,
|
||||
VertexPropertyMap& vpm)
|
||||
{
|
||||
std::vector<Vertex*> current_ring, next_ring;
|
||||
std::vector<Vertex*> *p_current_ring, *p_next_ring;
|
||||
assert(ring_i >= 1);
|
||||
//initialize
|
||||
p_current_ring = ¤t_ring;
|
||||
p_next_ring = &next_ring;
|
||||
put(vpm, v, 0);
|
||||
current_ring.push_back(v);
|
||||
all.push_back(v);
|
||||
|
||||
for (int i=1; i<=ring_i; i++)
|
||||
{
|
||||
collect_ith_ring(i, *p_current_ring, *p_next_ring, all, vpm);
|
||||
//next round must be launched from p_nextRing...
|
||||
p_current_ring->clear();
|
||||
std::swap(p_current_ring, p_next_ring);
|
||||
}
|
||||
//clean up
|
||||
reset_ring_indices(all, vpm);
|
||||
}
|
||||
|
||||
|
||||
template <class TPoly, class VertexPropertyMap>
|
||||
void T_PolyhedralSurf_rings <TPoly, VertexPropertyMap>::
|
||||
collect_enough_rings(Vertex* v,
|
||||
unsigned int min_nb,
|
||||
std::vector < Vertex * >& all,
|
||||
VertexPropertyMap& vpm)
|
||||
{
|
||||
std::vector<Vertex*> current_ring, next_ring;
|
||||
std::vector<Vertex*> *p_current_ring, *p_next_ring;
|
||||
|
||||
//initialize
|
||||
p_current_ring = ¤t_ring;
|
||||
p_next_ring = &next_ring;
|
||||
put(vpm, v, 0);
|
||||
current_ring.push_back(v);
|
||||
all.push_back(v);
|
||||
|
||||
int i = 1;
|
||||
|
||||
while ( (all.size() < min_nb) && (p_current_ring->size() != 0) )
|
||||
{
|
||||
collect_ith_ring(i, *p_current_ring, *p_next_ring, all, vpm);
|
||||
//next round must be launched from p_nextRing...
|
||||
p_current_ring->clear();
|
||||
std::swap(p_current_ring, p_next_ring);
|
||||
i++;
|
||||
}
|
||||
//clean up
|
||||
reset_ring_indices(all, vpm);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,89 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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 "buildCGALPolyhedron.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::buildCGALPolyhedron::buildCGALPolyhedron
|
||||
(
|
||||
const Foam::triSurface& surf
|
||||
)
|
||||
:
|
||||
CGAL::Modifier_base<HalfedgeDS>(),
|
||||
surf_(surf)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::buildCGALPolyhedron::~buildCGALPolyhedron()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::buildCGALPolyhedron::operator()
|
||||
(
|
||||
HalfedgeDS& hds
|
||||
)
|
||||
{
|
||||
typedef HalfedgeDS::Traits Traits;
|
||||
typedef Traits::Point_3 Point;
|
||||
|
||||
// Postcondition: `hds' is a valid polyhedral surface.
|
||||
CGAL::Polyhedron_incremental_builder_3<HalfedgeDS> B(hds, false);
|
||||
|
||||
B.begin_surface
|
||||
(
|
||||
surf_.points().size(), // n points
|
||||
surf_.size(), // n facets
|
||||
2*surf_.edges().size() // n halfedges
|
||||
);
|
||||
|
||||
forAll(surf_.points(), pI)
|
||||
{
|
||||
const Foam::point& p = surf_.points()[pI];
|
||||
|
||||
B.add_vertex(Point(p.x(), p.y(), p.z()));
|
||||
}
|
||||
|
||||
forAll(surf_, fI)
|
||||
{
|
||||
B.begin_facet();
|
||||
|
||||
B.add_vertex_to_facet(surf_[fI][0]);
|
||||
B.add_vertex_to_facet(surf_[fI][1]);
|
||||
B.add_vertex_to_facet(surf_[fI][2]);
|
||||
|
||||
B.end_facet();
|
||||
}
|
||||
|
||||
B.end_surface();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,106 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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::buildCGALPolyhedron
|
||||
|
||||
Description
|
||||
Convert a triSurface into a CGAL Polyhedron
|
||||
|
||||
SourceFiles
|
||||
buildCGALPolyhedron.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef buildCGALPolyhedron_H
|
||||
#define buildCGALPolyhedron_H
|
||||
|
||||
#include "triSurface.H"
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Polyhedron_incremental_builder_3.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
|
||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
|
||||
typedef Polyhedron::HalfedgeDS HalfedgeDS;
|
||||
typedef Polyhedron::Vertex Vertex;
|
||||
typedef Polyhedron::Vertex_iterator Vertex_iterator;
|
||||
typedef Kernel::Point_3 Point_3;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class buildCGALPolyhedron Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class buildCGALPolyhedron
|
||||
:
|
||||
public CGAL::Modifier_base<HalfedgeDS>
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Reference to triSurface to convert
|
||||
const Foam::triSurface& surf_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
buildCGALPolyhedron(const buildCGALPolyhedron&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const buildCGALPolyhedron&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct with reference to triSurface
|
||||
buildCGALPolyhedron(const triSurface& surf);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~buildCGALPolyhedron();
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- operator() of this `modifier' called by delegate function of
|
||||
// Polyhedron
|
||||
void operator()(HalfedgeDS& hds);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,3 +1,4 @@
|
||||
surfaceFeatureExtract.C
|
||||
CGALPolyhedron/buildCGALPolyhedron.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/surfaceFeatureExtract
|
||||
|
||||
@ -1,9 +1,29 @@
|
||||
EXE_FROUNDING_MATH = -frounding-math
|
||||
EXE_NDEBUG = -DNDEBUG
|
||||
USE_F2C = -DCGAL_USE_F2C
|
||||
|
||||
include $(GENERAL_RULES)/CGAL
|
||||
|
||||
EXE_INC = \
|
||||
${EXE_FROUNDING_MATH} \
|
||||
${EXE_NDEBUG} \
|
||||
${USE_F2C} \
|
||||
${CGAL_INC} \
|
||||
-ICGALPolyhedron \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/edgeMesh/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/surfMesh/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
$(CGAL_LIBS) \
|
||||
-L$(CGAL_ARCH_PATH)/lib \
|
||||
-llapack \
|
||||
-lblas \
|
||||
-lCGAL \
|
||||
-lmeshTools \
|
||||
-ledgeMesh \
|
||||
-ltriSurface
|
||||
-ltriSurface \
|
||||
-lsampling
|
||||
|
||||
@ -40,7 +40,19 @@ Description
|
||||
#include "treeBoundBox.H"
|
||||
#include "meshTools.H"
|
||||
#include "OFstream.H"
|
||||
#include "triSurfaceMesh.H"
|
||||
#include "vtkSurfaceWriter.H"
|
||||
#include "triSurfaceFields.H"
|
||||
#include "unitConversion.H"
|
||||
#include "indexedOctree.H"
|
||||
#include "treeDataEdge.H"
|
||||
#include "unitConversion.H"
|
||||
|
||||
#include "buildCGALPolyhedron.H"
|
||||
#include "CGALPolyhedronRings.H"
|
||||
#include <CGAL/Monge_via_jet_fitting.h>
|
||||
#include <CGAL/Lapack/Linear_algebra_lapack.h>
|
||||
#include <CGAL/property_map.h>
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -91,6 +103,201 @@ void deleteBox
|
||||
}
|
||||
|
||||
|
||||
void drawHitProblem
|
||||
(
|
||||
label fI,
|
||||
const triSurface& surf,
|
||||
const pointField& start,
|
||||
const pointField& faceCentres,
|
||||
const pointField& end,
|
||||
const List<pointIndexHit>& hitInfo
|
||||
)
|
||||
{
|
||||
Info<< nl << "# findLineAll did not hit its own face."
|
||||
<< nl << "# fI " << fI
|
||||
<< nl << "# start " << start[fI]
|
||||
<< nl << "# f centre " << faceCentres[fI]
|
||||
<< nl << "# end " << end[fI]
|
||||
<< nl << "# hitInfo " << hitInfo
|
||||
<< endl;
|
||||
|
||||
meshTools::writeOBJ(Info, start[fI]);
|
||||
meshTools::writeOBJ(Info, faceCentres[fI]);
|
||||
meshTools::writeOBJ(Info, end[fI]);
|
||||
|
||||
Info<< "l 1 2 3" << endl;
|
||||
|
||||
meshTools::writeOBJ(Info, surf.points()[surf[fI][0]]);
|
||||
meshTools::writeOBJ(Info, surf.points()[surf[fI][1]]);
|
||||
meshTools::writeOBJ(Info, surf.points()[surf[fI][2]]);
|
||||
|
||||
Info<< "f 4 5 6" << endl;
|
||||
|
||||
forAll(hitInfo, hI)
|
||||
{
|
||||
label hFI = hitInfo[hI].index();
|
||||
|
||||
meshTools::writeOBJ(Info, surf.points()[surf[hFI][0]]);
|
||||
meshTools::writeOBJ(Info, surf.points()[surf[hFI][1]]);
|
||||
meshTools::writeOBJ(Info, surf.points()[surf[hFI][2]]);
|
||||
|
||||
Info<< "f "
|
||||
<< 3*hI + 7 << " "
|
||||
<< 3*hI + 8 << " "
|
||||
<< 3*hI + 9
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
scalarField calcCurvature(const triSurface& surf)
|
||||
{
|
||||
scalarField k(surf.points().size(), 0);
|
||||
|
||||
Polyhedron P;
|
||||
|
||||
buildCGALPolyhedron convert(surf);
|
||||
P.delegate(convert);
|
||||
|
||||
// Info<< "Created CGAL Polyhedron with " << label(P.size_of_vertices())
|
||||
// << " vertices and " << label(P.size_of_facets())
|
||||
// << " facets. " << endl;
|
||||
|
||||
// The rest of this function adapted from
|
||||
// CGAL-3.7/examples/Jet_fitting_3/Mesh_estimation.cpp
|
||||
// Licensed under CGAL-3.7/LICENSE.FREE_USE
|
||||
|
||||
// Copyright (c) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007
|
||||
// Utrecht University (The Netherlands), ETH Zurich (Switzerland), Freie
|
||||
// Universitaet Berlin (Germany), INRIA Sophia-Antipolis (France),
|
||||
// Martin-Luther-University Halle-Wittenberg (Germany), Max-Planck-Institute
|
||||
// Saarbruecken (Germany), RISC Linz (Austria), and Tel-Aviv University
|
||||
// (Israel). All rights reserved.
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
|
||||
// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
|
||||
// THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
//Vertex property map, with std::map
|
||||
typedef std::map<Vertex*, int> Vertex2int_map_type;
|
||||
typedef boost::associative_property_map< Vertex2int_map_type >
|
||||
Vertex_PM_type;
|
||||
typedef T_PolyhedralSurf_rings<Polyhedron, Vertex_PM_type > Poly_rings;
|
||||
|
||||
typedef CGAL::Monge_via_jet_fitting<Kernel> Monge_via_jet_fitting;
|
||||
typedef Monge_via_jet_fitting::Monge_form Monge_form;
|
||||
|
||||
std::vector<Point_3> in_points; //container for data points
|
||||
|
||||
// default parameter values and global variables
|
||||
unsigned int d_fitting = 2;
|
||||
unsigned int d_monge = 2;
|
||||
unsigned int min_nb_points = (d_fitting + 1)*(d_fitting + 2)/2;
|
||||
|
||||
//initialize the tag of all vertices to -1
|
||||
Vertex_iterator vitb = P.vertices_begin();
|
||||
Vertex_iterator vite = P.vertices_end();
|
||||
|
||||
Vertex2int_map_type vertex2props;
|
||||
Vertex_PM_type vpm(vertex2props);
|
||||
|
||||
CGAL_For_all(vitb, vite)
|
||||
{
|
||||
put(vpm, &(*vitb), -1);
|
||||
}
|
||||
|
||||
vite = P.vertices_end();
|
||||
|
||||
label vertI = 0;
|
||||
|
||||
for (vitb = P.vertices_begin(); vitb != vite; vitb++)
|
||||
{
|
||||
//initialize
|
||||
Vertex* v = &(*vitb);
|
||||
|
||||
//gather points around the vertex using rings
|
||||
// From: gather_fitting_points(v, in_points, vpm);
|
||||
{
|
||||
std::vector<Vertex*> gathered;
|
||||
in_points.clear();
|
||||
|
||||
Poly_rings::collect_enough_rings(v, min_nb_points, gathered, vpm);
|
||||
|
||||
//store the gathered points
|
||||
std::vector<Vertex*>::iterator itb = gathered.begin();
|
||||
std::vector<Vertex*>::iterator ite = gathered.end();
|
||||
|
||||
CGAL_For_all(itb, ite)
|
||||
{
|
||||
in_points.push_back((*itb)->point());
|
||||
}
|
||||
}
|
||||
|
||||
//skip if the nb of points is to small
|
||||
if ( in_points.size() < min_nb_points )
|
||||
{
|
||||
std::cerr
|
||||
<< "not enough pts for fitting this vertex"
|
||||
<< in_points.size()
|
||||
<< std::endl;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// perform the fitting
|
||||
Monge_via_jet_fitting monge_fit;
|
||||
|
||||
Monge_form monge_form = monge_fit
|
||||
(
|
||||
in_points.begin(),
|
||||
in_points.end(),
|
||||
d_fitting,
|
||||
d_monge
|
||||
);
|
||||
|
||||
// std::cout<< monge_form << std::endl;
|
||||
|
||||
// std::cout<< "k1 " << monge_form.principal_curvatures(0) << std::endl;
|
||||
// std::cout<< "k2 " << monge_form.principal_curvatures(1) << std::endl;
|
||||
|
||||
// std::vector<Point_3>::iterator itbp = in_points.begin();
|
||||
// std::vector<Point_3>::iterator itep = in_points.end();
|
||||
|
||||
// std::cout << "in_points list : " << std::endl;
|
||||
|
||||
// for (; itbp != itep; itbp++)
|
||||
// {
|
||||
// std::cout << *itbp << std::endl;
|
||||
// }
|
||||
|
||||
// std::cout << "--- vertex " << vertI
|
||||
// << " : " << v->point() << std::endl
|
||||
// << "number of points used : " << in_points.size()
|
||||
// << std::endl;
|
||||
|
||||
k[vertI++] = Foam::sqrt
|
||||
(
|
||||
sqr(monge_form.principal_curvatures(0))
|
||||
+ sqr(monge_form.principal_curvatures(1))
|
||||
);
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
// Unmark non-manifold edges if individual triangles are not features
|
||||
void unmarkBaffles
|
||||
(
|
||||
@ -111,7 +318,7 @@ void unmarkBaffles
|
||||
{
|
||||
label i0 = eFaces[0];
|
||||
//const labelledTri& f0 = surf[i0];
|
||||
const vector& n0 = surf.faceNormals()[i0];
|
||||
const Foam::vector& n0 = surf.faceNormals()[i0];
|
||||
|
||||
//Pout<< "edge:" << edgeI << " n0:" << n0 << endl;
|
||||
|
||||
@ -120,7 +327,7 @@ void unmarkBaffles
|
||||
for (label i = 1; i < eFaces.size(); i++)
|
||||
{
|
||||
//const labelledTri& f = surf[i];
|
||||
const vector& n = surf.faceNormals()[eFaces[i]];
|
||||
const Foam::vector& n = surf.faceNormals()[eFaces[i]];
|
||||
|
||||
//Pout<< " mag(n&n0): " << mag(n&n0) << endl;
|
||||
|
||||
@ -193,15 +400,63 @@ int main(int argc, char *argv[])
|
||||
"writeObj",
|
||||
"write extendedFeatureEdgeMesh obj files"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"writeVTK",
|
||||
"write extendedFeatureEdgeMesh vtk files"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"calcCurvature",
|
||||
"calculate curvature and closeness fields"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"closeness",
|
||||
"scalar",
|
||||
"span to look for surface closeness"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"featureProximity",
|
||||
"scalar",
|
||||
"distance to look for close features"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"writeVTK",
|
||||
"write surface property VTK files"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"manifoldEdgesOnly",
|
||||
"remove any non-manifold (open or more than two connected faces) edges"
|
||||
);
|
||||
|
||||
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
|
||||
Info<< "Feature line extraction is only valid on closed manifold surfaces."
|
||||
<< endl;
|
||||
bool writeVTK = args.optionFound("writeVTK");
|
||||
|
||||
bool writeObj = args.optionFound("writeObj");
|
||||
|
||||
bool curvature = args.optionFound("curvature");
|
||||
|
||||
if (curvature && env("FOAM_SIGFPE"))
|
||||
{
|
||||
WarningIn(args.executable())
|
||||
<< "Detected floating point exception trapping (FOAM_SIGFPE)."
|
||||
<< " This might give" << nl
|
||||
<< " problems when calculating curvature on straight angles"
|
||||
<< " (infinite curvature)" << nl
|
||||
<< " Switch it off in case of problems." << endl;
|
||||
}
|
||||
|
||||
|
||||
Info<< "Feature line extraction is only valid on closed manifold surfaces."
|
||||
<< endl;
|
||||
|
||||
const fileName surfFileName = args[1];
|
||||
const fileName outFileName = args[2];
|
||||
|
||||
@ -221,6 +476,12 @@ int main(int argc, char *argv[])
|
||||
surf.writeStats(Info);
|
||||
Info<< endl;
|
||||
|
||||
faceList faces(surf.size());
|
||||
|
||||
forAll(surf, fI)
|
||||
{
|
||||
faces[fI] = surf[fI].triFaceFace();
|
||||
}
|
||||
|
||||
// Either construct features from surface&featureangle or read set.
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -334,11 +595,25 @@ int main(int argc, char *argv[])
|
||||
);
|
||||
}
|
||||
|
||||
if (args.optionFound("manifoldEdgesOnly"))
|
||||
{
|
||||
Info<< "Removing all non-manifold edges" << endl;
|
||||
|
||||
forAll(edgeStat, edgeI)
|
||||
{
|
||||
if (surf.edgeFaces()[edgeI].size() != 2)
|
||||
{
|
||||
edgeStat[edgeI] = surfaceFeatures::NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
surfaceFeatures newSet(surf);
|
||||
newSet.setFromStatus(edgeStat);
|
||||
|
||||
Info<< endl << "Writing trimmed features to " << outFileName << endl;
|
||||
newSet.write(outFileName);
|
||||
//Info<< endl << "Writing trimmed features to " << outFileName << endl;
|
||||
//newSet.write(outFileName);
|
||||
|
||||
// Info<< endl << "Writing edge objs." << endl;
|
||||
// newSet.writeObj("final");
|
||||
@ -397,6 +672,358 @@ int main(int argc, char *argv[])
|
||||
bfeMesh.regIOobject::write();
|
||||
}
|
||||
|
||||
triSurfaceMesh searchSurf
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
sFeatFileName + ".closeness",
|
||||
runTime.constant(),
|
||||
"extendedFeatureEdgeMesh",
|
||||
runTime,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
surf
|
||||
);
|
||||
|
||||
if (!curvature)
|
||||
{
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Find close features
|
||||
|
||||
// // Dummy trim operation to mark features
|
||||
// labelList featureEdgeIndexing = newSet.trimFeatures(-GREAT, 0);
|
||||
|
||||
// scalarField surfacePtFeatureIndex(surf.points().size(), -1);
|
||||
|
||||
// forAll(newSet.featureEdges(), eI)
|
||||
// {
|
||||
// const edge& e = surf.edges()[newSet.featureEdges()[eI]];
|
||||
|
||||
// surfacePtFeatureIndex[surf.meshPoints()[e.start()]] =
|
||||
// featureEdgeIndexing[newSet.featureEdges()[eI]];
|
||||
|
||||
// surfacePtFeatureIndex[surf.meshPoints()[e.end()]] =
|
||||
// featureEdgeIndexing[newSet.featureEdges()[eI]];
|
||||
// }
|
||||
|
||||
// if (writeVTK)
|
||||
// {
|
||||
// vtkSurfaceWriter().write
|
||||
// (
|
||||
// runTime.constant()/"triSurface", // outputDir
|
||||
// sFeatFileName, // surfaceName
|
||||
// surf.points(),
|
||||
// faces,
|
||||
// "surfacePtFeatureIndex", // fieldName
|
||||
// surfacePtFeatureIndex,
|
||||
// true, // isNodeValues
|
||||
// true // verbose
|
||||
// );
|
||||
// }
|
||||
|
||||
// Random rndGen(343267);
|
||||
|
||||
// treeBoundBox surfBB
|
||||
// (
|
||||
// treeBoundBox(searchSurf.bounds()).extend(rndGen, 1e-4)
|
||||
// );
|
||||
|
||||
// surfBB.min() -= Foam::point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
|
||||
// surfBB.max() += Foam::point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
|
||||
|
||||
// indexedOctree<treeDataEdge> ftEdTree
|
||||
// (
|
||||
// treeDataEdge
|
||||
// (
|
||||
// false,
|
||||
// surf.edges(),
|
||||
// surf.localPoints(),
|
||||
// newSet.featureEdges()
|
||||
// ),
|
||||
// surfBB,
|
||||
// 8, // maxLevel
|
||||
// 10, // leafsize
|
||||
// 3.0 // duplicity
|
||||
// );
|
||||
|
||||
// labelList nearPoints = ftEdTree.findBox
|
||||
// (
|
||||
// treeBoundBox
|
||||
// (
|
||||
// sPt - featureSearchSpan*Foam::vector::one,
|
||||
// sPt + featureSearchSpan*Foam::vector::one
|
||||
// )
|
||||
// );
|
||||
|
||||
Info<< "Examine curvature, feature proximity and internal and "
|
||||
<< "external closeness." << endl;
|
||||
|
||||
// Internal and external closeness
|
||||
|
||||
// Prepare start and end points for intersection tests
|
||||
|
||||
const vectorField& normals = searchSurf.faceNormals();
|
||||
|
||||
scalar span = searchSurf.bounds().mag();
|
||||
|
||||
args.optionReadIfPresent("closeness", span);
|
||||
|
||||
scalar externalAngleTolerance = 10;
|
||||
scalar externalToleranceCosAngle = Foam::cos
|
||||
(
|
||||
degToRad(180 - externalAngleTolerance)
|
||||
);
|
||||
|
||||
scalar internalAngleTolerance = 45;
|
||||
scalar internalToleranceCosAngle = Foam::cos
|
||||
(
|
||||
degToRad(180 - internalAngleTolerance)
|
||||
);
|
||||
|
||||
Info<< "externalToleranceCosAngle: " << externalToleranceCosAngle << nl
|
||||
<< "internalToleranceCosAngle: " << internalToleranceCosAngle
|
||||
<< endl;
|
||||
|
||||
// Info<< "span " << span << endl;
|
||||
|
||||
pointField start = searchSurf.faceCentres() - span*normals;
|
||||
pointField end = searchSurf.faceCentres() + span*normals;
|
||||
const pointField& faceCentres = searchSurf.faceCentres();
|
||||
|
||||
List<List<pointIndexHit> > allHitInfo;
|
||||
|
||||
// Find all intersections (in order)
|
||||
searchSurf.findLineAll(start, end, allHitInfo);
|
||||
|
||||
scalarField internalCloseness(start.size(), GREAT);
|
||||
scalarField externalCloseness(start.size(), GREAT);
|
||||
|
||||
forAll(allHitInfo, fI)
|
||||
{
|
||||
const List<pointIndexHit>& hitInfo = allHitInfo[fI];
|
||||
|
||||
if (hitInfo.size() < 1)
|
||||
{
|
||||
drawHitProblem(fI, surf, start, faceCentres, end, hitInfo);
|
||||
|
||||
// FatalErrorIn(args.executable())
|
||||
// << "findLineAll did not hit its own face."
|
||||
// << exit(FatalError);
|
||||
}
|
||||
else if (hitInfo.size() == 1)
|
||||
{
|
||||
if (!hitInfo[0].hit())
|
||||
{
|
||||
// FatalErrorIn(args.executable())
|
||||
// << "findLineAll did not hit any face."
|
||||
// << exit(FatalError);
|
||||
}
|
||||
else if (hitInfo[0].index() != fI)
|
||||
{
|
||||
drawHitProblem(fI, surf, start, faceCentres, end, hitInfo);
|
||||
|
||||
// FatalErrorIn(args.executable())
|
||||
// << "findLineAll did not hit its own face."
|
||||
// << exit(FatalError);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
label ownHitI = -1;
|
||||
|
||||
forAll(hitInfo, hI)
|
||||
{
|
||||
// Find the hit on the triangle that launched the ray
|
||||
|
||||
if (hitInfo[hI].index() == fI)
|
||||
{
|
||||
ownHitI = hI;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ownHitI < 0)
|
||||
{
|
||||
drawHitProblem(fI, surf, start, faceCentres, end, hitInfo);
|
||||
|
||||
// FatalErrorIn(args.executable())
|
||||
// << "findLineAll did not hit its own face."
|
||||
// << exit(FatalError);
|
||||
}
|
||||
else if (ownHitI == 0)
|
||||
{
|
||||
// There are no internal hits, the first hit is the closest
|
||||
// external hit
|
||||
|
||||
if
|
||||
(
|
||||
(normals[fI] & normals[hitInfo[ownHitI + 1].index()])
|
||||
< externalToleranceCosAngle
|
||||
)
|
||||
{
|
||||
externalCloseness[fI] = mag
|
||||
(
|
||||
faceCentres[fI] - hitInfo[ownHitI + 1].hitPoint()
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (ownHitI == hitInfo.size() - 1)
|
||||
{
|
||||
// There are no external hits, the last but one hit is the
|
||||
// closest internal hit
|
||||
|
||||
if
|
||||
(
|
||||
(normals[fI] & normals[hitInfo[ownHitI - 1].index()])
|
||||
< internalToleranceCosAngle
|
||||
)
|
||||
{
|
||||
internalCloseness[fI] = mag
|
||||
(
|
||||
faceCentres[fI] - hitInfo[ownHitI - 1].hitPoint()
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if
|
||||
(
|
||||
(normals[fI] & normals[hitInfo[ownHitI + 1].index()])
|
||||
< externalToleranceCosAngle
|
||||
)
|
||||
{
|
||||
externalCloseness[fI] = mag
|
||||
(
|
||||
faceCentres[fI] - hitInfo[ownHitI + 1].hitPoint()
|
||||
);
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
(normals[fI] & normals[hitInfo[ownHitI - 1].index()])
|
||||
< internalToleranceCosAngle
|
||||
)
|
||||
{
|
||||
internalCloseness[fI] = mag
|
||||
(
|
||||
faceCentres[fI] - hitInfo[ownHitI - 1].hitPoint()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
triSurfaceScalarField internalClosenessField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
sFeatFileName + ".internalCloseness",
|
||||
runTime.constant(),
|
||||
"extendedFeatureEdgeMesh",
|
||||
runTime,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
surf,
|
||||
dimLength,
|
||||
internalCloseness
|
||||
);
|
||||
|
||||
internalClosenessField.write();
|
||||
|
||||
triSurfaceScalarField externalClosenessField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
sFeatFileName + ".externalCloseness",
|
||||
runTime.constant(),
|
||||
"extendedFeatureEdgeMesh",
|
||||
runTime,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
surf,
|
||||
dimLength,
|
||||
externalCloseness
|
||||
);
|
||||
|
||||
externalClosenessField.write();
|
||||
|
||||
scalarField k = calcCurvature(surf);
|
||||
|
||||
// Modify the curvature values on feature edges and points to be zero.
|
||||
|
||||
forAll(newSet.featureEdges(), fEI)
|
||||
{
|
||||
const edge& e = surf.edges()[newSet.featureEdges()[fEI]];
|
||||
|
||||
k[surf.meshPoints()[e.start()]] = 0.0;
|
||||
k[surf.meshPoints()[e.end()]] = 0.0;
|
||||
}
|
||||
|
||||
triSurfacePointScalarField kField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
sFeatFileName + ".curvature",
|
||||
runTime.constant(),
|
||||
"extendedFeatureEdgeMesh",
|
||||
runTime,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
surf,
|
||||
dimLength,
|
||||
k
|
||||
);
|
||||
|
||||
kField.write();
|
||||
|
||||
if (writeVTK)
|
||||
{
|
||||
vtkSurfaceWriter().write
|
||||
(
|
||||
runTime.constant()/"triSurface", // outputDir
|
||||
sFeatFileName, // surfaceName
|
||||
surf.points(),
|
||||
faces,
|
||||
"internalCloseness", // fieldName
|
||||
internalCloseness,
|
||||
false, // isNodeValues
|
||||
true // verbose
|
||||
);
|
||||
|
||||
vtkSurfaceWriter().write
|
||||
(
|
||||
runTime.constant()/"triSurface", // outputDir
|
||||
sFeatFileName, // surfaceName
|
||||
surf.points(),
|
||||
faces,
|
||||
"externalCloseness", // fieldName
|
||||
externalCloseness,
|
||||
false, // isNodeValues
|
||||
true // verbose
|
||||
);
|
||||
|
||||
vtkSurfaceWriter().write
|
||||
(
|
||||
runTime.constant()/"triSurface", // outputDir
|
||||
sFeatFileName, // surfaceName
|
||||
surf.points(),
|
||||
faces,
|
||||
"curvature", // fieldName
|
||||
k,
|
||||
true, // isNodeValues
|
||||
true // verbose
|
||||
);
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
|
||||
surfaceSplitByTopology.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/surfaceSplitByTopology
|
||||
@ -0,0 +1,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools \
|
||||
-ltriSurface
|
||||
|
||||
@ -0,0 +1,220 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Description
|
||||
|
||||
Strips any baffle parts of a surface. A baffle region is one which is
|
||||
reached by walking from an open edge, and stopping when a multiply connected
|
||||
edge is reached.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "triSurface.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
argList::validArgs.clear();
|
||||
argList::validArgs.append("input surface file");
|
||||
argList::validArgs.append("output surface file");
|
||||
argList args(argc, argv);
|
||||
|
||||
fileName surfFileName(args.additionalArgs()[0]);
|
||||
Info<< "Reading surface from " << surfFileName << endl;
|
||||
|
||||
fileName outFileName(args.additionalArgs()[1]);
|
||||
fileName outFileBaseName = outFileName.lessExt();
|
||||
word outExtension = outFileName.ext();
|
||||
|
||||
// Load surface
|
||||
triSurface surf(surfFileName);
|
||||
|
||||
bool anyZoneRemoved = false;
|
||||
|
||||
label iterationNo = 0;
|
||||
label iterationLimit = 10;
|
||||
|
||||
Info<< "Splitting off baffle parts " << endl;
|
||||
|
||||
do
|
||||
{
|
||||
anyZoneRemoved = false;
|
||||
|
||||
labelList faceZone;
|
||||
|
||||
const labelListList& edFaces = surf.edgeFaces();
|
||||
const labelListList& faceEds = surf.faceEdges();
|
||||
|
||||
boolList multipleEdges(edFaces.size(), false);
|
||||
|
||||
forAll(multipleEdges, i)
|
||||
{
|
||||
if (edFaces[i].size() > 2)
|
||||
{
|
||||
multipleEdges[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
label nZones = surf.markZones(multipleEdges, faceZone);
|
||||
|
||||
if (nZones < 2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
boolList nonBaffle(faceZone.size(), true);
|
||||
boolList baffle(faceZone.size(), true);
|
||||
labelList pointMap;
|
||||
labelList faceMap;
|
||||
|
||||
|
||||
for (label z = 0; z < nZones; z++)
|
||||
{
|
||||
bool keepZone = true;
|
||||
|
||||
forAll(faceZone, f)
|
||||
{
|
||||
if (faceZone[f] == z)
|
||||
{
|
||||
forAll (faceEds[f], fe)
|
||||
{
|
||||
if (edFaces[faceEds[f][fe]].size() < 2)
|
||||
{
|
||||
keepZone = false;
|
||||
|
||||
anyZoneRemoved = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!keepZone)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
forAll(faceZone, f)
|
||||
{
|
||||
if (faceZone[f] == z)
|
||||
{
|
||||
nonBaffle[f] = keepZone;
|
||||
baffle[f] = !keepZone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Info<< " Iteration " << iterationNo << endl;
|
||||
|
||||
triSurface baffleSurf = surf.subsetMesh(baffle, pointMap, faceMap);
|
||||
|
||||
if (baffleSurf.size())
|
||||
{
|
||||
fileName bafflePartFileName =
|
||||
outFileBaseName
|
||||
+ "_bafflePart_"
|
||||
+ name(iterationNo)
|
||||
+ "." + outExtension;
|
||||
|
||||
Info<< " Writing baffle part to " << bafflePartFileName << endl;
|
||||
|
||||
baffleSurf.write(bafflePartFileName);
|
||||
}
|
||||
|
||||
surf = surf.subsetMesh(nonBaffle, pointMap, faceMap);
|
||||
|
||||
if (iterationNo == iterationLimit)
|
||||
{
|
||||
WarningIn("surfaceSplitByTopology")
|
||||
<< "Iteration limit of " << iterationLimit << "reached" << endl;
|
||||
}
|
||||
|
||||
iterationNo++;
|
||||
|
||||
} while (anyZoneRemoved && iterationNo < iterationLimit);
|
||||
|
||||
Info<< "Writing new surface to " << outFileName << endl;
|
||||
|
||||
surf.write(outFileName);
|
||||
|
||||
labelList faceZone;
|
||||
|
||||
const labelListList& edFaces = surf.edgeFaces();
|
||||
|
||||
boolList multipleEdges(edFaces.size(), false);
|
||||
|
||||
forAll(multipleEdges, i)
|
||||
{
|
||||
if (edFaces[i].size() > 2)
|
||||
{
|
||||
multipleEdges[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
label nZones = surf.markZones(multipleEdges, faceZone);
|
||||
|
||||
Info<< "Splitting remaining multiply connected parts" << endl;
|
||||
|
||||
for (label z = 0; z < nZones; z++)
|
||||
{
|
||||
|
||||
boolList include(faceZone.size(), false);
|
||||
labelList pointMap;
|
||||
labelList faceMap;
|
||||
|
||||
forAll(faceZone, f)
|
||||
{
|
||||
if (faceZone[f] == z)
|
||||
{
|
||||
include[f] = true;
|
||||
}
|
||||
}
|
||||
|
||||
triSurface zoneSurf = surf.subsetMesh(include, pointMap, faceMap);
|
||||
|
||||
|
||||
fileName remainingPartFileName =
|
||||
outFileBaseName
|
||||
+ "_multiplePart_"
|
||||
+ name(z)
|
||||
+ "." + outExtension;
|
||||
|
||||
Info<< " Writing mulitple part "
|
||||
<< z << " to " << remainingPartFileName << endl;
|
||||
|
||||
zoneSurf.write(remainingPartFileName);
|
||||
}
|
||||
|
||||
Info << "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
135
differencesWrtDev.txt
Normal file
135
differencesWrtDev.txt
Normal file
@ -0,0 +1,135 @@
|
||||
src/
|
||||
|
||||
mesh/conformalVoronoiMesh
|
||||
- all the meshing. See separate section below.
|
||||
|
||||
polyMeshGeometry:
|
||||
- disabled tetquality check on face-center decomp tet.
|
||||
Check only minTetDecomp tet.
|
||||
|
||||
limits face filtering if enabled. So cv3d can generate neg.
|
||||
(face-centre decomp) tets but pyramid volumes are still positive!
|
||||
|
||||
indexedOctree:
|
||||
- findSphere routine
|
||||
|
||||
closedTriSurfaceMesh :
|
||||
triSurface which is defined closed even though topologically it isn't.
|
||||
|
||||
searchableSurface :
|
||||
- bounds_ member data
|
||||
- bool overlaps() const routine
|
||||
searchableSurfaces, searhcableSurfacesQueries :
|
||||
- findNearestIntersection routine
|
||||
- bounds routines
|
||||
|
||||
surfaceFeatures:
|
||||
- trimFeatures function returns trimmed bits
|
||||
|
||||
triSurfaceTools:
|
||||
- surfaceSide.
|
||||
|
||||
the edge code is irrelevant. Use dev bits.
|
||||
|
||||
indexedOctree:
|
||||
- findSphere
|
||||
|
||||
polyMeshTetDecomposition:
|
||||
- disabled face-centre tet quality check (but kept minTetDecomp)
|
||||
|
||||
polyMesh.C:
|
||||
- read cell centres if present.
|
||||
|
||||
Can be scrapped. Not useful. Does not write cell centres, does not
|
||||
do decomposition, reconstruction, moving meshes.
|
||||
|
||||
primitiveMesh:
|
||||
- overrideCellCentres
|
||||
|
||||
triangleI.H:
|
||||
- stabilised triangle quality. Ok.
|
||||
|
||||
memInfo:
|
||||
- added I/O operators. Useful.
|
||||
|
||||
distributedTrisurfaceMesh:
|
||||
- additional reduce on boundBox. Can be removed only on the one
|
||||
constructed from boundBox (line 2300)
|
||||
|
||||
|
||||
Utilities/
|
||||
|
||||
cvMesh:
|
||||
- top level mesher
|
||||
|
||||
checkMesh:
|
||||
- override cellCentres. Remove if the polyMesh stuff gets removed.
|
||||
|
||||
surfaceCheck:
|
||||
- moved triSurface quality into triangle. Use cvm.
|
||||
|
||||
surfaceBooleanFeatures:
|
||||
- new application. Determines features straight from intersection.
|
||||
More stable than surfaceBooleanOp. Used to e.g. get the features
|
||||
between the wheels and wind tunnel.
|
||||
So if surfaceBooleanOp fails:
|
||||
- use this to extract features
|
||||
- use snappyHexMesh to defeature
|
||||
- use cvMesh with extracted features
|
||||
This does not work very well! Since there might still be overlapping
|
||||
bits of triSurface that will be meshed.
|
||||
|
||||
surfaceFeatureExtract:
|
||||
- uses cgal only for curvature calculation. See cgal.
|
||||
- writes a triSurfaceField of 'curvature' and 'internal closeness'
|
||||
and 'external closeness'. This is just a normal intersection, not
|
||||
a nearest point. These fields get used by cvMesh. Or not yet - is part
|
||||
of proposal to seed points according to curvature.
|
||||
- detects features that are near?
|
||||
|
||||
surfaceSplitByTopology:
|
||||
- for fuel tank of Brawn. Detects baffles (markZones) and splits
|
||||
it accordingly.
|
||||
|
||||
|
||||
|
||||
conformalVoronoiMesh/
|
||||
--------------------
|
||||
- Make sure the surface does not have any sliver triangles. These are
|
||||
hard to get the surface normal correct for so might cause bleeding.
|
||||
- Use surfaceCheck to find out triangle quality and size of smallest edges
|
||||
- Use surfaceClean .. 1e-5 .. to get rid of any edges < 1e-5m.
|
||||
|
||||
- If you get bleeding you might see in face filtering:
|
||||
|
||||
...
|
||||
cells with with zero or one non-boundary face : 1
|
||||
...
|
||||
Initial check before face collapse, found 48 bad quality faces
|
||||
|
||||
but this was real - the cell that got created inside the cone and sphere by the
|
||||
bad triangle was actually attached to a lot of faces. This screwed up the
|
||||
subsequent filtering as it stopped too early.
|
||||
|
||||
I ran:
|
||||
|
||||
surfaceClean coneAndSphere.obj 1e-5 coneAndSphere_clean.obj
|
||||
|
||||
and re-ran with that surface and got
|
||||
|
||||
...
|
||||
cells with with zero or one non-boundary face : 0
|
||||
...
|
||||
Initial check before face collapse, found 0 bad quality faces
|
||||
|
||||
and the bad cells inside are gone.
|
||||
|
||||
That group of cells would be picked up at the end of the meshing as the
|
||||
|
||||
cvMesh_remainingProtrusions
|
||||
|
||||
cellSet which can be deleted.
|
||||
|
||||
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
export WM_PROJECT=OpenFOAM
|
||||
export WM_PROJECT_VERSION=dev
|
||||
export WM_PROJECT_VERSION=dev.cvm
|
||||
|
||||
################################################################################
|
||||
# USER EDITABLE PART: Changes made here may be lost with the next upgrade
|
||||
|
||||
@ -302,11 +302,13 @@ DebugSwitches
|
||||
ash 0;
|
||||
atomizationModel 0;
|
||||
attachDetach 0;
|
||||
autoDensity 0;
|
||||
autoHexMeshDriver 0;
|
||||
autoLayerDriver 0;
|
||||
autoRefineDriver 0;
|
||||
autoSnapDriver 0;
|
||||
bC11H10 0;
|
||||
backgroundMeshDecomposition 0;
|
||||
backward 0;
|
||||
basePatch 0;
|
||||
basicKinematicCloud 0;
|
||||
@ -345,6 +347,7 @@ DebugSwitches
|
||||
cellPointFace 0;
|
||||
cellPointWeight 0;
|
||||
cellSet 0;
|
||||
cellSizeControlSurfaces 0;
|
||||
cellToCell 0;
|
||||
cellToFace 0;
|
||||
cellToPoint 0;
|
||||
@ -406,7 +409,7 @@ DebugSwitches
|
||||
displacementLaplacian 0;
|
||||
displacementSBRStress 0;
|
||||
distanceSurface 0;
|
||||
distribution 0;
|
||||
Distribution 0;
|
||||
downwind 0;
|
||||
dragModel 0;
|
||||
duplicatePoints 0;
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
setenv WM_PROJECT OpenFOAM
|
||||
setenv WM_PROJECT_VERSION dev
|
||||
setenv WM_PROJECT_VERSION dev.cvm #dev
|
||||
|
||||
################################################################################
|
||||
# USER EDITABLE PART: Changes made here may be lost with the next upgrade
|
||||
|
||||
70
src/OSspecific/POSIX/memInfo/memInfoIO.C
Normal file
70
src/OSspecific/POSIX/memInfo/memInfoIO.C
Normal file
@ -0,0 +1,70 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "memInfo.H"
|
||||
#include "IOstreams.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::memInfo::memInfo(Istream& is)
|
||||
:
|
||||
base1(is),
|
||||
base2(is),
|
||||
member1(is),
|
||||
member2(is)
|
||||
{
|
||||
// Check state of Istream
|
||||
is.check("Foam::memInfo::memInfo(Foam::Istream&)");
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||
|
||||
Foam::Istream& Foam::operator>>(Istream& is, memInfo&)
|
||||
{
|
||||
// Check state of Istream
|
||||
is.check
|
||||
(
|
||||
"Foam::Istream& Foam::operator>>(Foam::Istream&, Foam::memInfo&)"
|
||||
);
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const memInfo&)
|
||||
{
|
||||
// Check state of Ostream
|
||||
os.check
|
||||
(
|
||||
"Foam::Ostream& Foam::operator<<(Foam::Ostream&, "
|
||||
"const Foam::memInfo&)"
|
||||
);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -2054,6 +2054,54 @@ void Foam::indexedOctree<Type>::findBox
|
||||
}
|
||||
|
||||
|
||||
template <class Type>
|
||||
void Foam::indexedOctree<Type>::findSphere
|
||||
(
|
||||
const label nodeI,
|
||||
const point& centre,
|
||||
const scalar radiusSqr,
|
||||
labelHashSet& elements
|
||||
) const
|
||||
{
|
||||
const node& nod = nodes_[nodeI];
|
||||
const treeBoundBox& nodeBb = nod.bb_;
|
||||
|
||||
for (direction octant = 0; octant < nod.subNodes_.size(); octant++)
|
||||
{
|
||||
labelBits index = nod.subNodes_[octant];
|
||||
|
||||
if (isNode(index))
|
||||
{
|
||||
const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
|
||||
|
||||
if (subBb.overlaps(centre, radiusSqr))
|
||||
{
|
||||
findSphere(getNode(index), centre, radiusSqr, elements);
|
||||
}
|
||||
}
|
||||
else if (isContent(index))
|
||||
{
|
||||
const treeBoundBox subBb(nodeBb.subBbox(octant));
|
||||
|
||||
if (subBb.overlaps(centre, radiusSqr))
|
||||
{
|
||||
const labelList& indices = contents_[getContent(index)];
|
||||
|
||||
forAll(indices, i)
|
||||
{
|
||||
label shapeI = indices[i];
|
||||
|
||||
if (shapes_.overlaps(shapeI, centre, radiusSqr))
|
||||
{
|
||||
elements.insert(shapeI);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Type>
|
||||
template <class CompareOp>
|
||||
void Foam::indexedOctree<Type>::findNear
|
||||
@ -2614,6 +2662,25 @@ Foam::labelList Foam::indexedOctree<Type>::findBox
|
||||
}
|
||||
|
||||
|
||||
template <class Type>
|
||||
Foam::labelList Foam::indexedOctree<Type>::findSphere
|
||||
(
|
||||
const point& centre,
|
||||
const scalar radiusSqr
|
||||
) const
|
||||
{
|
||||
// Storage for labels of shapes inside bb. Size estimate.
|
||||
labelHashSet elements(shapes_.size() / 100);
|
||||
|
||||
if (nodes_.size())
|
||||
{
|
||||
findSphere(0, centre, radiusSqr, elements);
|
||||
}
|
||||
|
||||
return elements.toc();
|
||||
}
|
||||
|
||||
|
||||
// Find node (as parent+octant) containing point
|
||||
template <class Type>
|
||||
Foam::labelBits Foam::indexedOctree<Type>::findNode
|
||||
|
||||
@ -337,6 +337,16 @@ private:
|
||||
) const;
|
||||
|
||||
|
||||
//- Find all elements intersecting sphere.
|
||||
void findSphere
|
||||
(
|
||||
const label nodeI,
|
||||
const point& centre,
|
||||
const scalar radiusSqr,
|
||||
labelHashSet& elements
|
||||
) const;
|
||||
|
||||
|
||||
template <class CompareOp>
|
||||
static void findNear
|
||||
(
|
||||
@ -565,6 +575,15 @@ public:
|
||||
// overlapping bounding box (i.e. all shapes not outside box)
|
||||
labelList findBox(const treeBoundBox& bb) const;
|
||||
|
||||
//- Find (in no particular order) indices of all shapes inside or
|
||||
// overlapping a bounding sphere (i.e. all shapes not outside
|
||||
// sphere)
|
||||
labelList findSphere
|
||||
(
|
||||
const point& centre,
|
||||
const scalar radiusSqr
|
||||
) const;
|
||||
|
||||
//- Find deepest node (as parent+octant) containing point. Starts
|
||||
// off from starting index in nodes_ (use 0 to start from top)
|
||||
// Use getNode and getOctant to extract info, or call findIndices.
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -295,6 +295,31 @@ Foam::polyMesh::polyMesh(const IOobject& io)
|
||||
neighbour_.write();
|
||||
}
|
||||
|
||||
// Read cell centres if present
|
||||
pointIOField cellCentres
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cellCentres",
|
||||
time().findInstance
|
||||
(
|
||||
meshDir(),
|
||||
"cellCentres",
|
||||
IOobject::READ_IF_PRESENT
|
||||
),
|
||||
meshSubDir,
|
||||
*this,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
if (cellCentres.headerOk())
|
||||
{
|
||||
Pout<< "Reading cell centres" << endl;
|
||||
overrideCellCentres(cellCentres);
|
||||
}
|
||||
|
||||
// Calculate topology for the patches (processor-processor comms etc.)
|
||||
boundary_.updateMesh();
|
||||
|
||||
|
||||
@ -380,11 +380,11 @@ bool Foam::polyMeshTetDecomposition::checkFaceTets
|
||||
)
|
||||
{
|
||||
const labelList& own = mesh.faceOwner();
|
||||
const labelList& nei = mesh.faceNeighbour();
|
||||
// const labelList& nei = mesh.faceNeighbour();
|
||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||
|
||||
const vectorField& cc = mesh.cellCentres();
|
||||
const vectorField& fc = mesh.faceCentres();
|
||||
// const vectorField& fc = mesh.faceCentres();
|
||||
|
||||
// Calculate coupled cell centre
|
||||
pointField neiCc(mesh.nFaces() - mesh.nInternalFaces());
|
||||
@ -398,62 +398,62 @@ bool Foam::polyMeshTetDecomposition::checkFaceTets
|
||||
|
||||
const faceList& fcs = mesh.faces();
|
||||
|
||||
const pointField& p = mesh.points();
|
||||
// const pointField& p = mesh.points();
|
||||
|
||||
label nErrorTets = 0;
|
||||
|
||||
forAll(fcs, faceI)
|
||||
{
|
||||
const face& f = 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();
|
||||
// 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);
|
||||
}
|
||||
// if (tetQual > -tol)
|
||||
// {
|
||||
// if (setPtr)
|
||||
// {
|
||||
// setPtr->insert(faceI);
|
||||
// }
|
||||
|
||||
nErrorTets++;
|
||||
break; // no need to check other tets
|
||||
}
|
||||
}
|
||||
// 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];
|
||||
// const face& f = fcs[faceI];
|
||||
|
||||
forAll(f, fPtI)
|
||||
{
|
||||
scalar tetQual = tetPointRef
|
||||
(
|
||||
p[f[fPtI]],
|
||||
p[f.nextLabel(fPtI)],
|
||||
fc[faceI],
|
||||
cc[nei[faceI]]
|
||||
).quality();
|
||||
// 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);
|
||||
}
|
||||
// if (tetQual < tol)
|
||||
// {
|
||||
// if (setPtr)
|
||||
// {
|
||||
// setPtr->insert(faceI);
|
||||
// }
|
||||
|
||||
nErrorTets++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// nErrorTets++;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (findSharedBasePoint(mesh, faceI, tol, report) == -1)
|
||||
{
|
||||
|
||||
@ -201,10 +201,34 @@ void Foam::processorPolyPatch::calcGeometry(PstreamBuffers& pBufs)
|
||||
boundaryMesh().mesh().time().path()
|
||||
/name()+"_faces.obj"
|
||||
);
|
||||
Pout<< "processorPolyPatch::order : Writing my " << size()
|
||||
|
||||
Pout<< "processorPolyPatch::calcGeometry : Writing my "
|
||||
<< size()
|
||||
<< " faces to OBJ file " << nm << endl;
|
||||
|
||||
writeOBJ(nm, *this, points());
|
||||
|
||||
OFstream ccStr
|
||||
(
|
||||
boundaryMesh().mesh().time().path()
|
||||
/name() + "_faceCentresConnections.obj"
|
||||
);
|
||||
|
||||
Pout<< "processorPolyPatch::calcGeometry :"
|
||||
<< " Dumping cell centre lines between"
|
||||
<< " corresponding face centres to OBJ file" << ccStr.name()
|
||||
<< endl;
|
||||
|
||||
label vertI = 0;
|
||||
|
||||
forAll(faceCentres(), faceI)
|
||||
{
|
||||
const point& c0 = neighbFaceCentres_[faceI];
|
||||
const point& c1 = faceCentres()[faceI];
|
||||
|
||||
writeOBJ(ccStr, c0, c1, vertI);
|
||||
}
|
||||
|
||||
FatalErrorIn
|
||||
(
|
||||
"processorPolyPatch::calcGeometry()"
|
||||
|
||||
@ -496,6 +496,12 @@ public:
|
||||
const scalarField& cellVolumes() const;
|
||||
const vectorField& faceAreas() const;
|
||||
|
||||
// Override cell centres with supplied positions
|
||||
void overrideCellCentres
|
||||
(
|
||||
const vectorField& cellCtrs
|
||||
) const;
|
||||
|
||||
|
||||
// Mesh motion
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ Description
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "primitiveMesh.H"
|
||||
#include "demandDrivenData.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
@ -168,4 +169,66 @@ const Foam::scalarField& Foam::primitiveMesh::cellVolumes() const
|
||||
}
|
||||
|
||||
|
||||
void Foam::primitiveMesh::overrideCellCentres
|
||||
(
|
||||
const vectorField& newCellCtrs
|
||||
) const
|
||||
{
|
||||
if (newCellCtrs.size() != nCells())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void Foam::primitiveMesh::overrideCellCentres"
|
||||
"("
|
||||
"const vectorField& newCellCtrs"
|
||||
") const"
|
||||
)
|
||||
<< "Size of new cell centres for override " << newCellCtrs.size()
|
||||
<< " not equal to the number of cells in the mesh " << nCells()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "void Foam::primitiveMesh::overrideCellCentres"
|
||||
<< "(const vectorField& newCellCtrs) const : "
|
||||
<< "overriding cell centres." << endl;
|
||||
}
|
||||
|
||||
deleteDemandDrivenData(cellCentresPtr_);
|
||||
deleteDemandDrivenData(cellVolumesPtr_);
|
||||
|
||||
// Calculate the cell volumes - these are invariant with respect
|
||||
// to the centre.
|
||||
calcCellCentresAndVols();
|
||||
|
||||
*cellCentresPtr_ = newCellCtrs;
|
||||
|
||||
// Set internal face centres to the midpoint of the cell-centre delta vector
|
||||
|
||||
// if (debug)
|
||||
// {
|
||||
// Pout<< "void Foam::primitiveMesh::overrideCellCentres"
|
||||
// << "(const vectorField& newCellCtrs) const : "
|
||||
// << "overriding internal face centres." << endl;
|
||||
// }
|
||||
|
||||
// deleteDemandDrivenData(faceCentresPtr_);
|
||||
// deleteDemandDrivenData(faceAreasPtr_);
|
||||
|
||||
// calcFaceCentresAndAreas();
|
||||
|
||||
// vectorField& fCtrs = *faceCentresPtr_;
|
||||
|
||||
// const vectorField& C = cellCentres();
|
||||
// const labelUList& owner = faceOwner();
|
||||
// const labelUList& neighbour = faceNeighbour();
|
||||
|
||||
// forAll(neighbour, faceI)
|
||||
// {
|
||||
// fCtrs[faceI] = 0.5*(C[neighbour[faceI]] + C[owner[faceI]]);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -701,7 +701,8 @@ bool Foam::primitiveMesh::checkFaceSkewness
|
||||
|
||||
|
||||
// Skewness vector
|
||||
vector sv = Cpf - ((fAreas[faceI]&Cpf)/((fAreas[faceI]&d)+VSMALL))*d;
|
||||
vector sv =
|
||||
Cpf - ((fAreas[faceI] & Cpf)/((fAreas[faceI] & d) + VSMALL))*d;
|
||||
vector svHat = sv/(mag(sv) + VSMALL);
|
||||
|
||||
// Normalisation distance calculated as the approximate distance
|
||||
|
||||
@ -191,7 +191,7 @@ public:
|
||||
// - point : centre of sphere
|
||||
// - distance : radius of sphere
|
||||
// - eligiblemiss: false
|
||||
// Tol (small compared to 1, e.g. 1E-9) is used to determine
|
||||
// Tol (small compared to 1, e.g. 1e-9) is used to determine
|
||||
// whether point is inside: mag(pt - ctr) < (1+tol)*radius.
|
||||
pointHit containmentSphere(const scalar tol) const;
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -160,7 +160,15 @@ inline Foam::scalar Foam::triangle<Point, PointRef>::circumRadius() const
|
||||
template<class Point, class PointRef>
|
||||
inline Foam::scalar Foam::triangle<Point, PointRef>::quality() const
|
||||
{
|
||||
return mag()/(Foam::sqr(circumRadius())*3.0*sqrt(3.0)/4.0 + VSMALL);
|
||||
scalar c = circumRadius();
|
||||
|
||||
if (c < ROOTVSMALL)
|
||||
{
|
||||
// zero circumRadius, something has gone wrong.
|
||||
return SMALL;
|
||||
}
|
||||
|
||||
return mag()/(Foam::sqr(c)*3.0*sqrt(3.0)/4.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -174,7 +174,6 @@ Foam::tmp<Foam::pointField> Foam::treeBoundBox::points() const
|
||||
forAll(points, octant)
|
||||
{
|
||||
points[octant] = corner(octant);
|
||||
|
||||
}
|
||||
|
||||
return tPts;
|
||||
|
||||
@ -309,7 +309,6 @@ Foam::scalar Foam::polyMeshGeometry::calcSkewness
|
||||
}
|
||||
|
||||
|
||||
// Create the neighbour pyramid - it will have positive volume
|
||||
bool Foam::polyMeshGeometry::checkFaceTet
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
@ -788,7 +787,7 @@ bool Foam::polyMeshGeometry::checkFaceTets
|
||||
// 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 labelList& nei = mesh.faceNeighbour();
|
||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||
|
||||
// Calculate coupled cell centre
|
||||
@ -803,48 +802,50 @@ bool Foam::polyMeshGeometry::checkFaceTets
|
||||
|
||||
label nErrorTets = 0;
|
||||
|
||||
// bool tetError = false
|
||||
|
||||
forAll(checkFaces, i)
|
||||
{
|
||||
label faceI = checkFaces[i];
|
||||
|
||||
// Create the owner pyramid - note: exchange cell and face centre
|
||||
// to get positive volume.
|
||||
bool tetError = checkFaceTet
|
||||
(
|
||||
mesh,
|
||||
report,
|
||||
minTetQuality,
|
||||
p,
|
||||
faceI,
|
||||
cellCentres[own[faceI]], // face centre
|
||||
faceCentres[faceI], // cell centre
|
||||
setPtr
|
||||
);
|
||||
// tetError = checkFaceTet
|
||||
// (
|
||||
// mesh,
|
||||
// report,
|
||||
// minTetQuality,
|
||||
// p,
|
||||
// faceI,
|
||||
// cellCentres[own[faceI]], // face centre
|
||||
// faceCentres[faceI], // cell centre
|
||||
// setPtr
|
||||
// );
|
||||
|
||||
if (tetError)
|
||||
{
|
||||
nErrorTets++;
|
||||
}
|
||||
// if (tetError)
|
||||
// {
|
||||
// nErrorTets++;
|
||||
// }
|
||||
|
||||
if (mesh.isInternalFace(faceI))
|
||||
{
|
||||
// Create the neighbour tets - they will have positive volume
|
||||
bool tetError = checkFaceTet
|
||||
(
|
||||
mesh,
|
||||
report,
|
||||
minTetQuality,
|
||||
p,
|
||||
faceI,
|
||||
faceCentres[faceI], // face centre
|
||||
cellCentres[nei[faceI]], // cell centre
|
||||
setPtr
|
||||
);
|
||||
// tetError = checkFaceTet
|
||||
// (
|
||||
// mesh,
|
||||
// report,
|
||||
// minTetQuality,
|
||||
// p,
|
||||
// faceI,
|
||||
// faceCentres[faceI], // face centre
|
||||
// cellCentres[nei[faceI]], // cell centre
|
||||
// setPtr
|
||||
// );
|
||||
|
||||
if (tetError)
|
||||
{
|
||||
nErrorTets++;
|
||||
}
|
||||
// if (tetError)
|
||||
// {
|
||||
// nErrorTets++;
|
||||
// }
|
||||
|
||||
if
|
||||
(
|
||||
@ -920,40 +921,40 @@ bool Foam::polyMeshGeometry::checkFaceTets
|
||||
label face0 = baffles[i].first();
|
||||
label face1 = baffles[i].second();
|
||||
|
||||
bool tetError = checkFaceTet
|
||||
(
|
||||
mesh,
|
||||
report,
|
||||
minTetQuality,
|
||||
p,
|
||||
face0,
|
||||
cellCentres[own[face0]], // face centre
|
||||
faceCentres[face0], // cell centre
|
||||
setPtr
|
||||
);
|
||||
// tetError = checkFaceTet
|
||||
// (
|
||||
// mesh,
|
||||
// report,
|
||||
// minTetQuality,
|
||||
// p,
|
||||
// face0,
|
||||
// cellCentres[own[face0]], // face centre
|
||||
// faceCentres[face0], // cell centre
|
||||
// setPtr
|
||||
// );
|
||||
|
||||
if (tetError)
|
||||
{
|
||||
nErrorTets++;
|
||||
}
|
||||
// if (tetError)
|
||||
// {
|
||||
// nErrorTets++;
|
||||
// }
|
||||
|
||||
// Create the neighbour tets - they will have positive volume
|
||||
tetError = checkFaceTet
|
||||
(
|
||||
mesh,
|
||||
report,
|
||||
minTetQuality,
|
||||
p,
|
||||
face0,
|
||||
faceCentres[face0], // face centre
|
||||
cellCentres[own[face1]], // cell centre
|
||||
setPtr
|
||||
);
|
||||
// // Create the neighbour tets - they will have positive volume
|
||||
// tetError = checkFaceTet
|
||||
// (
|
||||
// mesh,
|
||||
// report,
|
||||
// minTetQuality,
|
||||
// p,
|
||||
// face0,
|
||||
// faceCentres[face0], // face centre
|
||||
// cellCentres[own[face1]], // cell centre
|
||||
// setPtr
|
||||
// );
|
||||
|
||||
if (tetError)
|
||||
{
|
||||
nErrorTets++;
|
||||
}
|
||||
// if (tetError)
|
||||
// {
|
||||
// nErrorTets++;
|
||||
// }
|
||||
|
||||
if
|
||||
(
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -584,10 +584,7 @@ void Foam::InteractionLists<ParticleType>::buildInteractionLists()
|
||||
);
|
||||
|
||||
// Find all cells intersecting extendedBb
|
||||
labelList interactingElems
|
||||
(
|
||||
allCellsTree.findBox(extendedBb)
|
||||
);
|
||||
labelList interactingElems(allCellsTree.findBox(extendedBb));
|
||||
|
||||
// Reserve space to avoid multiple resizing
|
||||
DynamicList<label> cellDIL(interactingElems.size());
|
||||
@ -660,10 +657,7 @@ void Foam::InteractionLists<ParticleType>::findExtendedProcBbsInRange
|
||||
|
||||
if (procBb.overlaps(extendedReferredProcBb))
|
||||
{
|
||||
tmpExtendedProcBbsInRange.append
|
||||
(
|
||||
extendedReferredProcBb
|
||||
);
|
||||
tmpExtendedProcBbsInRange.append(extendedReferredProcBb);
|
||||
|
||||
// Dummy index, there are no transforms, so there will
|
||||
// be no resultant transform when this is decoded.
|
||||
@ -903,7 +897,6 @@ void Foam::InteractionLists<ParticleType>::buildMap
|
||||
(
|
||||
new mapDistribute
|
||||
(
|
||||
|
||||
constructSize,
|
||||
sendMap.xfer(),
|
||||
constructMap.xfer()
|
||||
@ -921,7 +914,6 @@ void Foam::InteractionLists<ParticleType>::prepareParticlesToRefer
|
||||
const globalIndexAndTransform& globalTransforms =
|
||||
mesh_.globalData().globalTransforms();
|
||||
|
||||
|
||||
referredParticles_.setSize(cellIndexAndTransformToDistribute_.size());
|
||||
|
||||
// Clear all existing referred particles
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,252 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2011 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::MoleculeCloud
|
||||
|
||||
Description
|
||||
|
||||
SourceFiles
|
||||
MoleculeCloudI.H
|
||||
MoleculeCloud.C
|
||||
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef MoleculeCloud_H
|
||||
#define MoleculeCloud_H
|
||||
|
||||
#include "Cloud.H"
|
||||
#include "moleculeCloud.H"
|
||||
#include "IOdictionary.H"
|
||||
#include "potential.H"
|
||||
#include "InteractionLists.H"
|
||||
#include "labelVector.H"
|
||||
#include "Random.H"
|
||||
#include "fileName.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class MoleculeCloud Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class MoleculeType>
|
||||
class MoleculeCloud
|
||||
:
|
||||
public Cloud<MoleculeType>,
|
||||
public moleculeCloud
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
// Private data
|
||||
|
||||
//-
|
||||
const polyMesh& mesh_;
|
||||
|
||||
//-
|
||||
const potential& pot_;
|
||||
|
||||
//-
|
||||
List<DynamicList<MoleculeType*> > cellOccupancy_;
|
||||
|
||||
//-
|
||||
InteractionLists<MoleculeType> il_;
|
||||
|
||||
//-
|
||||
List<typename MoleculeType::constantProperties> constPropList_;
|
||||
|
||||
//-
|
||||
Random rndGen_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//-
|
||||
void buildConstProps();
|
||||
|
||||
//-
|
||||
void setSiteSizesAndPositions();
|
||||
|
||||
//- Determine which molecules are in which cells
|
||||
void buildCellOccupancy();
|
||||
|
||||
//-
|
||||
void calculatePairForce();
|
||||
|
||||
//-
|
||||
inline void evaluatePair
|
||||
(
|
||||
MoleculeType& molI,
|
||||
MoleculeType& molJ
|
||||
);
|
||||
|
||||
//-
|
||||
inline bool evaluatePotentialLimit
|
||||
(
|
||||
MoleculeType& molI,
|
||||
MoleculeType& molJ
|
||||
) const;
|
||||
|
||||
//-
|
||||
void calculateTetherForce();
|
||||
|
||||
//-
|
||||
void calculateExternalForce();
|
||||
|
||||
//-
|
||||
void removeHighEnergyOverlaps();
|
||||
|
||||
//-
|
||||
void initialiseMolecules(const dictionary& mdInitialiseDict);
|
||||
|
||||
//-
|
||||
void createMolecule
|
||||
(
|
||||
const point& position,
|
||||
label cell,
|
||||
label tetFace,
|
||||
label tetPt,
|
||||
label id,
|
||||
bool tethered,
|
||||
scalar temperature,
|
||||
const vector& bulkVelocity
|
||||
);
|
||||
|
||||
//-
|
||||
label nSites() const;
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
MoleculeCloud(const MoleculeCloud&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const MoleculeCloud&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given mesh and potential references
|
||||
MoleculeCloud
|
||||
(
|
||||
const word& cloudName,
|
||||
const polyMesh& mesh,
|
||||
const potential& pot,
|
||||
bool readFields = true
|
||||
);
|
||||
|
||||
//- Construct given mesh, potential and mdInitialiseDict
|
||||
MoleculeCloud
|
||||
(
|
||||
const word& cloudName,
|
||||
const polyMesh& mesh,
|
||||
const potential& pot,
|
||||
const dictionary& mdInitialiseDict,
|
||||
bool readFields = true
|
||||
);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Evolve the molecules (move, calculate forces, control state etc)
|
||||
void evolve();
|
||||
|
||||
//-
|
||||
void calculateForce();
|
||||
|
||||
//- Print cloud information
|
||||
void info();
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
//-
|
||||
inline const polyMesh& mesh() const;
|
||||
|
||||
//-
|
||||
inline const potential& pot() const;
|
||||
|
||||
//-
|
||||
inline const List<DynamicList<MoleculeType*> >&
|
||||
cellOccupancy() const;
|
||||
|
||||
//-
|
||||
inline const InteractionLists<MoleculeType>& il() const;
|
||||
|
||||
//-
|
||||
inline const List<typename MoleculeType::constantProperties>
|
||||
constProps() const;
|
||||
|
||||
//-
|
||||
inline const typename MoleculeType::constantProperties&
|
||||
constProps(label id) const;
|
||||
|
||||
//-
|
||||
inline Random& rndGen();
|
||||
|
||||
//-
|
||||
inline vector equipartitionLinearVelocity
|
||||
(
|
||||
scalar temperature,
|
||||
scalar mass
|
||||
);
|
||||
|
||||
//-
|
||||
inline vector equipartitionAngularMomentum
|
||||
(
|
||||
scalar temperature,
|
||||
const typename MoleculeType::constantProperties& cP
|
||||
);
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- Write molecule sites in XYZ format
|
||||
void writeXYZ(const fileName& fName) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "MoleculeCloudI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "MoleculeCloud.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,416 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2011 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 "constants.H"
|
||||
|
||||
using namespace Foam::constant;
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class MoleculeType>
|
||||
inline void Foam::MoleculeCloud<MoleculeType>::evaluatePair
|
||||
(
|
||||
MoleculeType& molI,
|
||||
MoleculeType& molJ
|
||||
)
|
||||
{
|
||||
const pairPotentialList& pairPot = pot_.pairPotentials();
|
||||
|
||||
const pairPotential& electrostatic = pairPot.electrostatic();
|
||||
|
||||
label idI = molI.id();
|
||||
|
||||
label idJ = molJ.id();
|
||||
|
||||
const typename MoleculeType::constantProperties& constPropI
|
||||
(
|
||||
constProps(idI)
|
||||
);
|
||||
|
||||
const typename MoleculeType::constantProperties& constPropJ
|
||||
(
|
||||
constProps(idJ)
|
||||
);
|
||||
|
||||
forAll(constPropI.pairPotSites(), pI)
|
||||
{
|
||||
label sI = constPropI.pairPotSites()[pI];
|
||||
|
||||
label idsI = constPropI.sites()[sI].siteId();
|
||||
|
||||
forAll(constPropJ.pairPotSites(), pJ)
|
||||
{
|
||||
label sJ = constPropJ.pairPotSites()[pJ];
|
||||
|
||||
label idsJ = constPropJ.sites()[sJ].siteId();
|
||||
|
||||
vector rsIsJ =
|
||||
molI.sitePositions()[sI] - molJ.sitePositions()[sJ];
|
||||
|
||||
scalar rsIsJMagSq = magSqr(rsIsJ);
|
||||
|
||||
if (pairPot.rCutSqr(idsI, idsJ, rsIsJMagSq))
|
||||
{
|
||||
scalar rsIsJMag = mag(rsIsJ);
|
||||
|
||||
vector fsIsJ =
|
||||
(rsIsJ/rsIsJMag)
|
||||
*pairPot.force(idsI, idsJ, rsIsJMag);
|
||||
|
||||
molI.siteForces()[sI] += fsIsJ;
|
||||
|
||||
molJ.siteForces()[sJ] += -fsIsJ;
|
||||
|
||||
scalar potentialEnergy
|
||||
(
|
||||
pairPot.energy(idsI, idsJ, rsIsJMag)
|
||||
);
|
||||
|
||||
molI.potentialEnergy() += 0.5*potentialEnergy;
|
||||
|
||||
molJ.potentialEnergy() += 0.5*potentialEnergy;
|
||||
|
||||
vector rIJ = molI.position() - molJ.position();
|
||||
|
||||
tensor virialContribution =
|
||||
(rsIsJ*fsIsJ)*(rsIsJ & rIJ)/rsIsJMagSq;
|
||||
|
||||
molI.rf() += virialContribution;
|
||||
|
||||
molJ.rf() += virialContribution;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
forAll(constPropI.electrostaticSites(), pI)
|
||||
{
|
||||
label sI = constPropI.electrostaticSites()[pI];
|
||||
|
||||
forAll(constPropJ.electrostaticSites(), pJ)
|
||||
{
|
||||
label sJ = constPropJ.electrostaticSites()[pJ];
|
||||
|
||||
vector rsIsJ =
|
||||
molI.sitePositions()[sI] - molJ.sitePositions()[sJ];
|
||||
|
||||
scalar rsIsJMagSq = magSqr(rsIsJ);
|
||||
|
||||
if (rsIsJMagSq <= electrostatic.rCutSqr())
|
||||
{
|
||||
scalar rsIsJMag = mag(rsIsJ);
|
||||
|
||||
scalar chargeI = constPropI.sites()[sI].siteCharge();
|
||||
|
||||
scalar chargeJ = constPropJ.sites()[sJ].siteCharge();
|
||||
|
||||
vector fsIsJ =
|
||||
(rsIsJ/rsIsJMag)
|
||||
*chargeI*chargeJ*electrostatic.force(rsIsJMag);
|
||||
|
||||
molI.siteForces()[sI] += fsIsJ;
|
||||
|
||||
molJ.siteForces()[sJ] += -fsIsJ;
|
||||
|
||||
scalar potentialEnergy =
|
||||
chargeI*chargeJ
|
||||
*electrostatic.energy(rsIsJMag);
|
||||
|
||||
molI.potentialEnergy() += 0.5*potentialEnergy;
|
||||
|
||||
molJ.potentialEnergy() += 0.5*potentialEnergy;
|
||||
|
||||
vector rIJ = molI.position() - molJ.position();
|
||||
|
||||
tensor virialContribution =
|
||||
(rsIsJ*fsIsJ)*(rsIsJ & rIJ)/rsIsJMagSq;
|
||||
|
||||
molI.rf() += virialContribution;
|
||||
|
||||
molJ.rf() += virialContribution;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class MoleculeType>
|
||||
inline bool Foam::MoleculeCloud<MoleculeType>::evaluatePotentialLimit
|
||||
(
|
||||
MoleculeType& molI,
|
||||
MoleculeType& molJ
|
||||
) const
|
||||
{
|
||||
const pairPotentialList& pairPot = pot_.pairPotentials();
|
||||
|
||||
const pairPotential& electrostatic = pairPot.electrostatic();
|
||||
|
||||
label idI = molI.id();
|
||||
|
||||
label idJ = molJ.id();
|
||||
|
||||
const typename MoleculeType::constantProperties& constPropI
|
||||
(
|
||||
constProps(idI)
|
||||
);
|
||||
|
||||
const typename MoleculeType::constantProperties& constPropJ
|
||||
(
|
||||
constProps(idJ)
|
||||
);
|
||||
|
||||
forAll(constPropI.pairPotSites(), pI)
|
||||
{
|
||||
label sI = constPropI.pairPotSites()[pI];
|
||||
|
||||
label idsI = constPropI.sites()[sI].siteId();
|
||||
|
||||
forAll(constPropJ.pairPotSites(), pJ)
|
||||
{
|
||||
label sJ = constPropJ.pairPotSites()[pJ];
|
||||
|
||||
label idsJ = constPropJ.sites()[sJ].siteId();
|
||||
|
||||
vector rsIsJ =
|
||||
molI.sitePositions()[sI] - molJ.sitePositions()[sJ];
|
||||
|
||||
scalar rsIsJMagSq = magSqr(rsIsJ);
|
||||
|
||||
if (pairPot.rCutSqr(idsI, idsJ, rsIsJMagSq))
|
||||
{
|
||||
scalar rsIsJMag = mag(rsIsJ);
|
||||
|
||||
// Guard against pairPot.energy being evaluated
|
||||
// if rIJMag < SMALL. A floating point exception will
|
||||
// happen otherwise.
|
||||
|
||||
if (rsIsJMag < SMALL)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"MoleculeCloud<MoleculeType>::"
|
||||
"removeHighEnergyOverlaps()"
|
||||
)
|
||||
<< "Molecule site pair closer than "
|
||||
<< SMALL
|
||||
<< ": mag separation = " << rsIsJMag
|
||||
<< ". These may have been placed on top of each"
|
||||
<< " other by a rounding error in mdInitialise in"
|
||||
<< " parallel or a block filled with moleculess"
|
||||
<< " twice. Removing one of the molecules."
|
||||
<< endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Guard against pairPot.energy being evaluated if rIJMag <
|
||||
// rMin. A tabulation lookup error will occur otherwise.
|
||||
|
||||
if (rsIsJMag < pairPot.rMin(idsI, idsJ))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
mag(pairPot.energy(idsI, idsJ, rsIsJMag))
|
||||
> pot_.potentialEnergyLimit()
|
||||
)
|
||||
{
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forAll(constPropI.electrostaticSites(), pI)
|
||||
{
|
||||
label sI = constPropI.electrostaticSites()[pI];
|
||||
|
||||
forAll(constPropJ.electrostaticSites(), pJ)
|
||||
{
|
||||
label sJ = constPropJ.electrostaticSites()[pJ];
|
||||
|
||||
vector rsIsJ =
|
||||
molI.sitePositions()[sI] - molJ.sitePositions()[sJ];
|
||||
|
||||
scalar rsIsJMagSq = magSqr(rsIsJ);
|
||||
|
||||
if (pairPot.rCutMaxSqr(rsIsJMagSq))
|
||||
{
|
||||
scalar rsIsJMag = mag(rsIsJ);
|
||||
|
||||
// Guard against pairPot.energy being evaluated
|
||||
// if rIJMag < SMALL. A floating point exception will
|
||||
// happen otherwise.
|
||||
|
||||
if (rsIsJMag < SMALL)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"MoleculeCloud<MoleculeType>::"
|
||||
"removeHighEnergyOverlaps()"
|
||||
)
|
||||
<< "Molecule site pair closer than "
|
||||
<< SMALL
|
||||
<< ": mag separation = " << rsIsJMag
|
||||
<< ". These may have been placed on top of each"
|
||||
<< " other by a rounding error in mdInitialise in"
|
||||
<< " parallel or a block filled with molecules"
|
||||
<< " twice. Removing one of the molecules."
|
||||
<< endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rsIsJMag < electrostatic.rMin())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
scalar chargeI = constPropI.sites()[sI].siteCharge();
|
||||
|
||||
scalar chargeJ = constPropJ.sites()[sJ].siteCharge();
|
||||
|
||||
if
|
||||
(
|
||||
mag(chargeI*chargeJ*electrostatic.energy(rsIsJMag))
|
||||
> pot_.potentialEnergyLimit()
|
||||
)
|
||||
{
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class MoleculeType>
|
||||
inline const Foam::polyMesh& Foam::MoleculeCloud<MoleculeType>::mesh() const
|
||||
{
|
||||
return mesh_;
|
||||
}
|
||||
|
||||
|
||||
template<class MoleculeType>
|
||||
inline const Foam::potential& Foam::MoleculeCloud<MoleculeType>::pot() const
|
||||
{
|
||||
return pot_;
|
||||
}
|
||||
|
||||
|
||||
template<class MoleculeType>
|
||||
inline const Foam::List<Foam::DynamicList<MoleculeType*> >&
|
||||
Foam::MoleculeCloud<MoleculeType>::cellOccupancy() const
|
||||
{
|
||||
return cellOccupancy_;
|
||||
}
|
||||
|
||||
|
||||
template<class MoleculeType>
|
||||
inline const Foam::InteractionLists<MoleculeType>&
|
||||
Foam::MoleculeCloud<MoleculeType>::il() const
|
||||
{
|
||||
return il_;
|
||||
}
|
||||
|
||||
|
||||
template<class MoleculeType>
|
||||
inline const Foam::List<typename MoleculeType::constantProperties>
|
||||
Foam::MoleculeCloud<MoleculeType>::constProps() const
|
||||
{
|
||||
return constPropList_;
|
||||
}
|
||||
|
||||
|
||||
template<class MoleculeType>
|
||||
inline const typename MoleculeType::constantProperties&
|
||||
Foam::MoleculeCloud<MoleculeType>::constProps(label id) const
|
||||
{
|
||||
return constPropList_[id];
|
||||
}
|
||||
|
||||
|
||||
template<class MoleculeType>
|
||||
inline Foam::Random& Foam::MoleculeCloud<MoleculeType>::rndGen()
|
||||
{
|
||||
return rndGen_;
|
||||
}
|
||||
|
||||
|
||||
template<class MoleculeType>
|
||||
inline Foam::vector
|
||||
Foam::MoleculeCloud<MoleculeType>::equipartitionLinearVelocity
|
||||
(
|
||||
scalar temperature,
|
||||
scalar mass
|
||||
)
|
||||
{
|
||||
return sqrt(physicoChemical::k.value()*temperature/mass)*vector
|
||||
(
|
||||
rndGen_.GaussNormal(),
|
||||
rndGen_.GaussNormal(),
|
||||
rndGen_.GaussNormal()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class MoleculeType>
|
||||
inline Foam::vector
|
||||
Foam::MoleculeCloud<MoleculeType>::equipartitionAngularMomentum
|
||||
(
|
||||
scalar temperature,
|
||||
const typename MoleculeType::constantProperties& cP
|
||||
)
|
||||
{
|
||||
scalar sqrtKbT = sqrt(physicoChemical::k.value()*temperature);
|
||||
|
||||
if (cP.linearMolecule())
|
||||
{
|
||||
return sqrtKbT*vector
|
||||
(
|
||||
0.0,
|
||||
sqrt(cP.momentOfInertia().yy())*rndGen_.GaussNormal(),
|
||||
sqrt(cP.momentOfInertia().zz())*rndGen_.GaussNormal()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return sqrtKbT*vector
|
||||
(
|
||||
sqrt(cP.momentOfInertia().xx())*rndGen_.GaussNormal(),
|
||||
sqrt(cP.momentOfInertia().yy())*rndGen_.GaussNormal(),
|
||||
sqrt(cP.momentOfInertia().zz())*rndGen_.GaussNormal()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,48 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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 "moleculeCloud.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(moleculeCloud, 0);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::moleculeCloud::moleculeCloud()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::moleculeCloud::~moleculeCloud()
|
||||
{}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,83 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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::moleculeCloud
|
||||
|
||||
Description
|
||||
Virtual abstract base class for templated moleculeCloud
|
||||
|
||||
SourceFiles
|
||||
moleculeCloud.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef moleculeCloud_H
|
||||
#define moleculeCloud_H
|
||||
|
||||
#include "volFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class moleculeCloud Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class moleculeCloud
|
||||
{
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
moleculeCloud(const moleculeCloud&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const moleculeCloud&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("moleculeCloud");
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Null constructor
|
||||
moleculeCloud();
|
||||
|
||||
//- Destructor
|
||||
virtual ~moleculeCloud();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,52 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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::monoatomicCloud
|
||||
|
||||
Description
|
||||
Cloud class to simulate monoatomic molecules
|
||||
|
||||
SourceFiles
|
||||
monoatomicCloud.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef monoatomicCloud_H
|
||||
#define monoatomicCloud_H
|
||||
|
||||
#include "MoleculeCloud.H"
|
||||
#include "monoatomic.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
typedef MoleculeCloud<monoatomic> monoatomicCloud;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,52 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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::polyatomicCloud
|
||||
|
||||
Description
|
||||
Cloud class to simulate polyatomic molecules
|
||||
|
||||
SourceFiles
|
||||
polyatomicCloud.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef polyatomicCloud_H
|
||||
#define polyatomicCloud_H
|
||||
|
||||
#include "MoleculeCloud.H"
|
||||
#include "polyatomic.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
typedef MoleculeCloud<polyatomic> polyatomicCloud;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,573 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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 "controllers.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::controllers::controllers
|
||||
(
|
||||
const polyMesh& mesh
|
||||
)
|
||||
:
|
||||
time_(mesh.time()),
|
||||
controllersDict_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"controllersDict",
|
||||
time_.system(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
),
|
||||
stateControllersList_(),
|
||||
sCNames_(),
|
||||
sCIds_(),
|
||||
sCFixedPathNames_(),
|
||||
stateControllers_(),
|
||||
fluxControllersList_(),
|
||||
fCNames_(),
|
||||
fCIds_(),
|
||||
fCFixedPathNames_(),
|
||||
fluxControllers_()
|
||||
{}
|
||||
|
||||
|
||||
Foam::controllers::controllers
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
polyatomicCloud& cloud
|
||||
)
|
||||
:
|
||||
time_(mesh.time()),
|
||||
controllersDict_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"controllersDict",
|
||||
time_.system(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
),
|
||||
stateControllersList_(controllersDict_.lookup("stateControllers")),
|
||||
sCNames_(stateControllersList_.size()),
|
||||
sCIds_(stateControllersList_.size()),
|
||||
sCFixedPathNames_(stateControllersList_.size()),
|
||||
stateControllers_(stateControllersList_.size()),
|
||||
fluxControllersList_(controllersDict_.lookup("fluxControllers")),
|
||||
fCNames_(fluxControllersList_.size()),
|
||||
fCIds_(fluxControllersList_.size()),
|
||||
fCFixedPathNames_(fluxControllersList_.size()),
|
||||
fluxControllers_(fluxControllersList_.size())
|
||||
{
|
||||
|
||||
Info << nl << "Creating controllers" << nl << endl;
|
||||
|
||||
// state controllers
|
||||
|
||||
if (!stateControllers_.empty())
|
||||
{
|
||||
forAll(stateControllers_, sC)
|
||||
{
|
||||
const entry& controllersI = stateControllersList_[sC];
|
||||
|
||||
const dictionary& controllersIDict = controllersI.dict();
|
||||
|
||||
stateControllers_[sC] = autoPtr<stateController>
|
||||
(
|
||||
stateController::New(time_, cloud, controllersIDict)
|
||||
);
|
||||
|
||||
sCNames_[sC] = stateControllers_[sC]->type();
|
||||
|
||||
sCIds_[sC] = sC;
|
||||
}
|
||||
}
|
||||
|
||||
//- flux controllers
|
||||
|
||||
if (!fluxControllers_.empty())
|
||||
{
|
||||
forAll(fluxControllers_, fC)
|
||||
{
|
||||
const entry& controllersI = fluxControllersList_[fC];
|
||||
|
||||
const dictionary& controllersIDict = controllersI.dict();
|
||||
|
||||
fluxControllers_[fC] = autoPtr<fluxController>
|
||||
(
|
||||
fluxController::New(time_, cloud, controllersIDict)
|
||||
);
|
||||
|
||||
fCNames_[fC] = fluxControllers_[fC]->type();
|
||||
fCIds_[fC] = fC;
|
||||
}
|
||||
}
|
||||
|
||||
// creating directories for state controllers
|
||||
if (!nStateControllers_.empty())
|
||||
{
|
||||
// case/controllers
|
||||
fileName controllersPath(time_.path()/"controllers");
|
||||
|
||||
if (!isDir(controllersPath))
|
||||
{
|
||||
mkDir(controllersPath);
|
||||
}
|
||||
|
||||
// case/controllers/<cloudName>
|
||||
fileName controllersPath(controllersPath/cloud.name());
|
||||
|
||||
if (!isDir(controllersPath))
|
||||
{
|
||||
mkDir(controllersPath);
|
||||
}
|
||||
|
||||
// case/controllers/<cloudName>/stateControllers
|
||||
fileName stateControllersPath(controllersPath/"stateControllers");
|
||||
|
||||
if (!isDir(stateControllersPath))
|
||||
{
|
||||
mkDir(stateControllersPath);
|
||||
}
|
||||
|
||||
forAll(stateControllers_, sC)
|
||||
{
|
||||
if (stateControllers_[sC]->writeInCase())
|
||||
{
|
||||
// case/controllers/<cloudName>/
|
||||
// stateControllers/<stateControllerModel>
|
||||
fileName stateControllerPath(stateControllersPath/sCNames_[sC]);
|
||||
|
||||
if (!isDir(stateControllerPath))
|
||||
{
|
||||
mkDir(stateControllerPath);
|
||||
}
|
||||
|
||||
const word& regionName = stateControllers_[sC]->regionName();
|
||||
|
||||
// case/controllers/<cloudName>/
|
||||
// stateControllers/<stateControllerModel>/<cellZoneName>
|
||||
fileName zonePath(stateControllerPath/regionName);
|
||||
|
||||
if (!isDir(zonePath))
|
||||
{
|
||||
mkDir(zonePath);
|
||||
}
|
||||
|
||||
sCFixedPathNames_[sC] = zonePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// creating directories for flux controllers
|
||||
if (nFluxControllers_ > 0)
|
||||
{
|
||||
// case/controllers
|
||||
fileName controllersPath(time_.path()/"controllers");
|
||||
|
||||
if ( !isDir(controllersPath) )
|
||||
{
|
||||
mkDir(controllersPath);
|
||||
}
|
||||
|
||||
// case/controllers/<cloudName>
|
||||
fileName controllersPath(time_.path()/cloud.name());
|
||||
|
||||
if ( !isDir(controllersPath) )
|
||||
{
|
||||
mkDir(controllersPath);
|
||||
}
|
||||
|
||||
// case/controllers/<cloudName>/fluxControllers
|
||||
fileName fluxControllersPath(controllersPath/"fluxControllers");
|
||||
|
||||
if (!isDir(fluxControllersPath))
|
||||
{
|
||||
mkDir(fluxControllersPath);
|
||||
}
|
||||
|
||||
forAll(fluxControllers_, fC)
|
||||
{
|
||||
if (fluxControllers_[fC]->writeInCase())
|
||||
{
|
||||
// case/controllers/<cloudName>/
|
||||
// fluxControllers/<fluxControllerModel>
|
||||
fileName fluxControllerPath(fluxControllersPath/fCNames_[fC]);
|
||||
|
||||
if (!isDir(fluxControllerPath))
|
||||
{
|
||||
mkDir(fluxControllerPath);
|
||||
}
|
||||
|
||||
const word& regionName = fluxControllers_[fC]->regionName();
|
||||
|
||||
// case/controllers/<cloudName>/
|
||||
// fluxControllers/<fluxControllerModel>/<faceZoneName>
|
||||
fileName zonePath(fluxControllerPath/regionName);
|
||||
|
||||
if (!isDir(zonePath))
|
||||
{
|
||||
mkDir(zonePath);
|
||||
}
|
||||
|
||||
fCFixedPathNames_[fC] = zonePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
controllers::~controllers()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void controllers::initialConfig()
|
||||
{
|
||||
forAll(stateControllers_, sC)
|
||||
{
|
||||
stateControllers_[sC]->initialConfiguration();
|
||||
}
|
||||
|
||||
forAll(fluxControllers_, fC)
|
||||
{
|
||||
fluxControllers_[fC]->initialConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void controllers::updateTimeInfo()
|
||||
{
|
||||
forAll(stateControllers_, sC)
|
||||
{
|
||||
stateControllers_[sC]->updateTime();
|
||||
}
|
||||
|
||||
forAll(fluxControllers_, fC)
|
||||
{
|
||||
fluxControllers_[fC]->updateTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void controllers::controlState()
|
||||
{
|
||||
forAll(stateControllers_, sC)
|
||||
{
|
||||
stateControllers_[sC]->controlMols();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void controllers::controlVelocitiesI()
|
||||
{
|
||||
forAll(stateControllers_, sC)
|
||||
{
|
||||
stateControllers_[sC]->controlMolsBeg();
|
||||
}
|
||||
}
|
||||
|
||||
void controllers::controlVelocitiesII()
|
||||
{
|
||||
forAll(stateControllers_, sC)
|
||||
{
|
||||
stateControllers_[sC]->controlMolsEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void controllers::controlPriorToForces()
|
||||
{
|
||||
forAll(stateControllers_, sC)
|
||||
{
|
||||
stateControllers_[sC]->controlBeforeForces();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void controllers::calculateStateProps()
|
||||
{
|
||||
forAll(stateControllers_, sC)
|
||||
{
|
||||
stateControllers_[sC]->calculateProperties();
|
||||
}
|
||||
|
||||
forAll(fluxControllers_, fC)
|
||||
{
|
||||
fluxControllers_[fC]->calculateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void controllers::outputStateResults()
|
||||
{
|
||||
const Time& runTime = time_;
|
||||
|
||||
if (runTime.outputTime())
|
||||
{
|
||||
// creating a set of directories in the current time directory
|
||||
{
|
||||
List<fileName> timePathNames(sCFixedPathNames_.size());
|
||||
|
||||
if (nStateControllers_ > 0)
|
||||
{
|
||||
if (Pstream::master())
|
||||
{
|
||||
// case/<timeDir>/uniform
|
||||
fileName uniformTimePath
|
||||
(
|
||||
runTime.path()/runTime.timeName()/"uniform"
|
||||
);
|
||||
|
||||
if (!isDir(uniformTimePath))
|
||||
{
|
||||
mkDir(uniformTimePath);
|
||||
}
|
||||
|
||||
if (!stateControllers_.empty())
|
||||
{
|
||||
// case/<timeDir>/uniform/controllers
|
||||
fileName controllersTimePath
|
||||
(
|
||||
uniformTimePath/"controllers"
|
||||
);
|
||||
|
||||
if (!isDir(controllersTimePath))
|
||||
{
|
||||
mkDir(controllersTimePath);
|
||||
}
|
||||
|
||||
// case/<timeDir>/uniform/controllers/<cloudName>
|
||||
fileName cloudTimePath
|
||||
(
|
||||
controllersTimePath/cloud.name()
|
||||
);
|
||||
|
||||
if (!isDir(cloudTimePath))
|
||||
{
|
||||
mkDir(cloudTimePath);
|
||||
}
|
||||
|
||||
// case/<timeDir>/uniform/controllers/<cloudName>/
|
||||
fileName stateControllersTimePath
|
||||
(
|
||||
cloudTimePath/"stateControllers"
|
||||
);
|
||||
|
||||
if (!isDir(stateControllersTimePath))
|
||||
{
|
||||
mkDir(stateControllersTimePath);
|
||||
}
|
||||
|
||||
forAll(stateControllers_, sC)
|
||||
{
|
||||
if (stateControllers_[sC]->writeInTimeDir())
|
||||
{
|
||||
// case/<timeDir>/uniform/controllers/
|
||||
// <cloudName>/<stateControllerModel>
|
||||
fileName sCTimePath
|
||||
(
|
||||
stateControllersTimePath/sCNames_[sC]
|
||||
);
|
||||
|
||||
if (!isDir(sCTimePath))
|
||||
{
|
||||
mkDir(sCTimePath);
|
||||
}
|
||||
|
||||
// Creating directory for different zones but
|
||||
// of the same model
|
||||
const word& regionName =
|
||||
stateControllers_[sC]->regionName();
|
||||
|
||||
// case/<timeDir>/uniform/controllers/
|
||||
// <cloudName>/<stateControllerModel>/
|
||||
// <cellZoneName>
|
||||
fileName zoneTimePath(sCTimePath/regionName);
|
||||
|
||||
if (!isDir(zoneTimePath))
|
||||
{
|
||||
mkDir(zoneTimePath);
|
||||
}
|
||||
|
||||
timePathNames[sC] = zoneTimePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write out data
|
||||
forAll(stateControllers_, sC)
|
||||
{
|
||||
stateControllers_[sC]->output
|
||||
(
|
||||
sCFixedPathNames_[sC],
|
||||
timePathNames[sC]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
List<fileName> timePathNames(fCFixedPathNames_.size());
|
||||
|
||||
if (nFluxControllers_ > 0)
|
||||
{
|
||||
if (Pstream::master())
|
||||
{
|
||||
// case/<timeDir>/uniform
|
||||
fileName uniformTimePath
|
||||
(
|
||||
runTime.path()/runTime.timeName()/"uniform"
|
||||
);
|
||||
|
||||
if (!isDir(uniformTimePath))
|
||||
{
|
||||
mkDir(uniformTimePath);
|
||||
}
|
||||
|
||||
if (!fluxControllers_.empty())
|
||||
{
|
||||
// case/<timeDir>/uniform/controllers
|
||||
fileName controllersTimePath
|
||||
(
|
||||
uniformTimePath/"controllers"
|
||||
);
|
||||
|
||||
if (!isDir(controllersTimePath))
|
||||
{
|
||||
mkDir(controllersTimePath);
|
||||
}
|
||||
|
||||
// case/<timeDir>/uniform/controllers/<cloudName>
|
||||
fileName cloudTimePath
|
||||
(
|
||||
controllersTimePath/cloud.name()
|
||||
);
|
||||
|
||||
if (!isDir(cloudTimePath))
|
||||
{
|
||||
mkDir(cloudTimePath);
|
||||
}
|
||||
|
||||
// case/<timeDir>/uniform/fluxControllers
|
||||
fileName controllersTimePath
|
||||
(
|
||||
cloudTimePath/"fluxControllers"
|
||||
);
|
||||
|
||||
if (!isDir(controllersTimePath))
|
||||
{
|
||||
mkDir(controllersTimePath);
|
||||
}
|
||||
|
||||
forAll(fluxControllers_, fC)
|
||||
{
|
||||
if (stateControllers_[fC]->writeInTimeDir())
|
||||
{
|
||||
// case/<timeDir>/uniform/controllers/
|
||||
// <cloudName>/<fluxControllerModel>
|
||||
fileName fCTimePath
|
||||
(
|
||||
controllersTimePath/fCNames_[fC]
|
||||
);
|
||||
|
||||
if (!isDir(fCTimePath))
|
||||
{
|
||||
mkDir(fCTimePath);
|
||||
}
|
||||
|
||||
const word& regionName =
|
||||
fluxControllers_[fC]->regionName();
|
||||
|
||||
// case/<timeDir>/uniform/controllers/
|
||||
// <cloudName>/<fluxControllerModel>/
|
||||
// <faceZoneName>
|
||||
fileName zoneTimePath(fCTimePath/regionName);
|
||||
|
||||
if (!isDir(zoneTimePath))
|
||||
{
|
||||
mkDir(zoneTimePath);
|
||||
}
|
||||
|
||||
timePathNames[fC] = zoneTimePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write out data
|
||||
forAll(fluxControllers_, fC)
|
||||
{
|
||||
fluxControllers_[fC]->output
|
||||
(
|
||||
fCFixedPathNames_[fC],
|
||||
timePathNames[fC]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Re-read dictionaries for modified properties (run-time selection)
|
||||
{
|
||||
stateControllersList_.clear();
|
||||
|
||||
stateControllersList_ = controllersDict_.lookup("stateControllers");
|
||||
|
||||
forAll(stateControllers_, sC)
|
||||
{
|
||||
const entry& controllersI = stateControllersList_[sC];
|
||||
const dictionary& controllersIDict = controllersI.dict();
|
||||
|
||||
stateControllers_[sC]->updateProperties(controllersIDict);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
fluxControllersList_.clear();
|
||||
|
||||
fluxControllersList_ = controllersDict_.lookup("fluxControllers");
|
||||
|
||||
forAll(fluxControllers_, fC)
|
||||
{
|
||||
const entry& controllersI = fluxControllersList_[fC];
|
||||
const dictionary& controllersIDict = controllersI.dict();
|
||||
|
||||
fluxControllers_[fC]->updateProperties(controllersIDict);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,163 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2011 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
|
||||
|
||||
controllers
|
||||
|
||||
Description
|
||||
|
||||
Stores all the information for the controllers models defined within
|
||||
the controllersDict, and selects & builds the models automatically.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef controllers_H
|
||||
#define controllers_H
|
||||
|
||||
#include "List.H"
|
||||
#include "IOdictionary.H"
|
||||
#include "autoPtr.H"
|
||||
#include "polyMesh.H"
|
||||
#include "timeData.H"
|
||||
#include "stateController.H"
|
||||
#include "fluxController.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class controllers Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class controllers
|
||||
{
|
||||
// Private data
|
||||
|
||||
Time& time_;
|
||||
|
||||
//- The entire dictionary (containing multiple subDictionaries)
|
||||
IOdictionary controllersDict_;
|
||||
|
||||
//- state controllers
|
||||
PtrList<entry> stateControllersList_;
|
||||
List<word> sCNames_;
|
||||
List<label> sCIds_;
|
||||
List<fileName> sCFixedPathNames_;
|
||||
List< autoPtr<stateController> > stateControllers_;
|
||||
|
||||
//- flux controllers
|
||||
PtrList<entry> fluxControllersList_;
|
||||
List<word> fCNames_;
|
||||
List<label> fCIds_;
|
||||
List<fileName> fCFixedPathNames_;
|
||||
List< autoPtr<fluxController> > fluxControllers_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Null Constructor
|
||||
controllers
|
||||
(
|
||||
const polyMesh& mesh
|
||||
);
|
||||
|
||||
//- Constructor for with cloud
|
||||
controllers
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
polyatomicCloud& cloud
|
||||
);
|
||||
|
||||
//- Destructor
|
||||
~controllers();
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Initial configuration call this function after the polyatomicCloud
|
||||
// is completely initialised
|
||||
void initialConfig();
|
||||
|
||||
//- this function is to be called at the beginning of the MD time-step.
|
||||
// since we have placed a non-referenced time-data class in the
|
||||
// state-controller class.
|
||||
void updateTimeInfo();
|
||||
|
||||
//- control molecular state -- call this after the intermolecular force
|
||||
// calulation
|
||||
void controlState();
|
||||
|
||||
//-
|
||||
void controlVelocitiesI();
|
||||
|
||||
//-
|
||||
void controlVelocitiesII();
|
||||
|
||||
//-
|
||||
void controlPriorToForces();
|
||||
|
||||
//- calculate properties -- call this at the end of the MD time-step.
|
||||
void calculateStateProps();
|
||||
|
||||
//- output -- call this function at the end of the MD time-step
|
||||
void outputStateResults();
|
||||
|
||||
// Access
|
||||
|
||||
//-
|
||||
inline List< autoPtr<stateController> >& stateControllers();
|
||||
|
||||
//-
|
||||
inline const List< autoPtr<stateController> >&
|
||||
stateControllers() const;
|
||||
|
||||
//-
|
||||
inline List< autoPtr<fluxController> >& fluxControllers();
|
||||
|
||||
//-
|
||||
inline const List< autoPtr<fluxController> >&
|
||||
fluxControllers() const;
|
||||
|
||||
//-
|
||||
inline const List<word>& stateControllersNames() const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "controllersI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,64 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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::List<Foam::autoPtr<Foam::stateController> >&
|
||||
Foam::controllers::stateControllers()
|
||||
{
|
||||
return stateControllers_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::List<Foam::autoPtr<Foam::stateController> >&
|
||||
Foam::controllers::stateControllers() const
|
||||
{
|
||||
return stateControllers_;
|
||||
}
|
||||
|
||||
|
||||
Foam::List<Foam::autoPtr<Foam::fluxController> >&
|
||||
Foam::controllers::fluxControllers()
|
||||
{
|
||||
return fluxControllers_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::List< autoPtr<fluxController> >&
|
||||
Foam::controllers::fluxControllers() const
|
||||
{
|
||||
return fluxControllers_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::List<Foam::word>& Foam::controllers::stateControllersNames() const
|
||||
{
|
||||
return sCNames_;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,524 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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 "waterFluxController.H"
|
||||
#include "IFstream.H"
|
||||
#include "graph.H"
|
||||
#include "polyatomicCloud.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(waterFluxController, 0);
|
||||
|
||||
defineRunTimeSelectionTable(waterFluxController, dictionary);
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
// Construct from components
|
||||
waterFluxController::waterFluxController
|
||||
(
|
||||
Time& t,
|
||||
polyatomicCloud& cloud,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
mesh_(refCast<const fvMesh>(cloud.mesh())),
|
||||
cloud_(cloud),
|
||||
rndGen_(clock::getTime()),
|
||||
controllerDict_(dict.subDict("controllerProperties")),
|
||||
timeDict_(controllerDict_.subDict("timeProperties")),
|
||||
time_(t, timeDict_),
|
||||
regionName_(controllerDict_.lookup("zoneName")),
|
||||
regionId_(-1),
|
||||
zoneSurfaceArea_(0.0),
|
||||
internalFaces_(),
|
||||
processorFaces_(),
|
||||
control_(true),
|
||||
readStateFromFile_(true),
|
||||
singleValueController_(false),
|
||||
density_(0.0),
|
||||
velocity_(vector::zero),
|
||||
temperature_(0.0),
|
||||
pressure_(0.0),
|
||||
strainRate_(tensor::zero),
|
||||
tempGradient_(vector::zero),
|
||||
fieldController_(false),
|
||||
densities_(),
|
||||
velocities_(),
|
||||
temperatures_(),
|
||||
pressures_(),
|
||||
writeInTimeDir_(true),
|
||||
writeInCase_(true)
|
||||
{
|
||||
const faceZoneMesh& faceZones = mesh_.faceZones();
|
||||
regionId_ = faceZones.findZoneID(regionName_);
|
||||
|
||||
if (regionId_ == -1)
|
||||
{
|
||||
FatalErrorIn("waterFluxController::waterFluxController()")
|
||||
<< "Cannot find region (faceZone): " << regionName_ << nl << "in: "
|
||||
<< t.time().system()/"controllersDict"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
control_ = Switch(controllerDict_.lookup("controlSwitch"));
|
||||
readStateFromFile_ = Switch(controllerDict_.lookup("readStateFromFile"));
|
||||
|
||||
setFacesInfo();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
|
||||
autoPtr<waterFluxController> waterFluxController::New
|
||||
(
|
||||
Time& t,
|
||||
polyatomicCloud& cloud,
|
||||
const dictionary& dict
|
||||
)
|
||||
{
|
||||
word waterFluxControllerName
|
||||
(
|
||||
dict.lookup("fluxControllerModel")
|
||||
);
|
||||
|
||||
Info<< "Selecting fluxController "
|
||||
<< waterFluxControllerName << endl;
|
||||
|
||||
dictionaryConstructorTable::iterator cstrIter =
|
||||
dictionaryConstructorTablePtr_->find(waterFluxControllerName);
|
||||
|
||||
if (cstrIter == dictionaryConstructorTablePtr_->end())
|
||||
{
|
||||
FatalError
|
||||
<< "waterFluxController::New(const dictionary&) : " << endl
|
||||
<< " unknown waterFluxController type "
|
||||
<< waterFluxControllerName
|
||||
<< ", constructor not in hash table" << endl << endl
|
||||
<< " Valid injector types are :" << endl;
|
||||
Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<waterFluxController>
|
||||
(
|
||||
cstrIter()(t, cloud, dict)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
waterFluxController::~waterFluxController()
|
||||
{}
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
// void waterFluxController::updateTime()
|
||||
// {
|
||||
// time_++;
|
||||
//
|
||||
// const scalar& t = time_.time().timeOutputValue();
|
||||
//
|
||||
// if ((t - initialTime_) < timePeriod_)
|
||||
// {
|
||||
// time_.controlTimeInterval().endTime() = false;
|
||||
// // control_ = false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // control_ = true;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
void waterFluxController::setFacesInfo()
|
||||
{
|
||||
const labelList& faces = controlZone();
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
DynamicList<label> processorFaces(0);
|
||||
|
||||
forAll(mesh_.boundaryMesh(), patchI)
|
||||
{
|
||||
const polyPatch& patch = mesh_.boundaryMesh()[patchI];
|
||||
|
||||
if (isA<processorPolyPatch>(patch))
|
||||
{
|
||||
for (label p = 0; p < patch.size(); p++)
|
||||
{
|
||||
label patchFaceI = p + patch.start();
|
||||
label faceId = findIndex (faces, patchFaceI);
|
||||
|
||||
if (faceId != -1)
|
||||
{
|
||||
processorFaces.append(patchFaceI);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processorFaces.shrink();
|
||||
|
||||
processorFaces_.setSize(processorFaces.size(), -1);
|
||||
|
||||
forAll(processorFaces, f)
|
||||
{
|
||||
processorFaces_[f] = processorFaces[f];
|
||||
}
|
||||
|
||||
label nInternalFaces = faces.size() - processorFaces.size();
|
||||
internalFaces_.setSize(nInternalFaces, -1);
|
||||
|
||||
label counter = 0;
|
||||
|
||||
forAll(faces, f)
|
||||
{
|
||||
const label& faceI = faces[f];
|
||||
|
||||
if (findIndex(processorFaces, faceI) == -1)
|
||||
{
|
||||
internalFaces_[counter] = faceI;
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
// Pout << "processorFaces: " << processorFaces_ << endl;
|
||||
// Pout << "internalFaces: " << internalFaces_ << endl;
|
||||
|
||||
forAll(internalFaces_, f)
|
||||
{
|
||||
const label& faceI = internalFaces_[f];
|
||||
zoneSurfaceArea_ += mag(mesh_.faceAreas()[faceI]);
|
||||
}
|
||||
|
||||
// faces on a zone located on a processor cut belong to both processors
|
||||
// (hence the 0.5)
|
||||
|
||||
forAll(processorFaces_, f)
|
||||
{
|
||||
const label& faceI = processorFaces_[f];
|
||||
zoneSurfaceArea_ += 0.5*mag(mesh_.faceAreas()[faceI]);
|
||||
}
|
||||
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
for (int p = 0; p < Pstream::nProcs(); p++)
|
||||
{
|
||||
if (p != Pstream::myProcNo())
|
||||
{
|
||||
const int proc = p;
|
||||
{
|
||||
OPstream toNeighbour(Pstream::blocking, proc);
|
||||
toNeighbour << zoneSurfaceArea_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- receiving
|
||||
for (int p = 0; p < Pstream::nProcs(); p++)
|
||||
{
|
||||
if (p != Pstream::myProcNo())
|
||||
{
|
||||
scalar zoneSurfaceAreaProc;
|
||||
|
||||
const int proc = p;
|
||||
{
|
||||
IPstream fromNeighbour(Pstream::blocking, proc);
|
||||
fromNeighbour >> zoneSurfaceAreaProc;
|
||||
}
|
||||
|
||||
zoneSurfaceArea_ += zoneSurfaceAreaProc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll(faces, f)
|
||||
{
|
||||
const label& faceI = faces[f];
|
||||
|
||||
zoneSurfaceArea_ += mag(mesh_.faceAreas()[faceI]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void waterFluxController::updateTime()
|
||||
{
|
||||
time_++;
|
||||
|
||||
// const scalar& t = time_.time().timeOutputValue();
|
||||
//
|
||||
// if ((t - initialTime_) < timePeriod_)
|
||||
// {
|
||||
// time_.controlTimeInterval().endTime() = false;
|
||||
// // control_ = false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // control_ = true;
|
||||
// }
|
||||
}
|
||||
|
||||
void waterFluxController::updateFluxControllerProperties
|
||||
(
|
||||
const dictionary& newDict
|
||||
)
|
||||
{
|
||||
controllerDict_ = newDict.subDict("controllerProperties");
|
||||
|
||||
//- you can reset the controlling zone from here. This essentially
|
||||
// means that the coupling zone can infact move arbitrarily. To make
|
||||
// this happen we probably need to devise a technique for automatically
|
||||
// changing the cellZone else where, and then calling this function to
|
||||
// reset the controlling zone in which the controller operates in.
|
||||
|
||||
if (controllerDict_.found("controlSwitch"))
|
||||
{
|
||||
control_ = Switch(controllerDict_.lookup("controlSwitch"));
|
||||
}
|
||||
|
||||
if (controllerDict_.found("readStateFromFile"))
|
||||
{
|
||||
readStateFromFile_ = Switch
|
||||
(
|
||||
controllerDict_.lookup("readStateFromFile")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const labelList& waterFluxController::controlZone() const
|
||||
{
|
||||
return mesh_.faceZones()[regionId_];
|
||||
}
|
||||
|
||||
label waterFluxController::isFaceOnControlZone(const label& faceI)
|
||||
{
|
||||
const label f = findIndex(controlZone(), faceI);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
const word& waterFluxController::regionName() const
|
||||
{
|
||||
return regionName_;
|
||||
}
|
||||
|
||||
const scalar& waterFluxController::density() const
|
||||
{
|
||||
return density_;
|
||||
}
|
||||
|
||||
scalar& waterFluxController::density()
|
||||
{
|
||||
return density_;
|
||||
}
|
||||
|
||||
const vector& waterFluxController::velocity() const
|
||||
{
|
||||
return velocity_;
|
||||
}
|
||||
|
||||
vector& waterFluxController::velocity()
|
||||
{
|
||||
return velocity_;
|
||||
}
|
||||
|
||||
const scalar& waterFluxController::temperature() const
|
||||
{
|
||||
return temperature_;
|
||||
}
|
||||
|
||||
scalar& waterFluxController::temperature()
|
||||
{
|
||||
return temperature_;
|
||||
}
|
||||
|
||||
const scalar& waterFluxController::pressure() const
|
||||
{
|
||||
return pressure_;
|
||||
}
|
||||
|
||||
scalar& waterFluxController::pressure()
|
||||
{
|
||||
return pressure_;
|
||||
}
|
||||
|
||||
const tensor& waterFluxController::strainRate() const
|
||||
{
|
||||
return strainRate_;
|
||||
}
|
||||
|
||||
tensor& waterFluxController::strainRate()
|
||||
{
|
||||
return strainRate_;
|
||||
}
|
||||
|
||||
const vector& waterFluxController::tempGradient() const
|
||||
{
|
||||
return tempGradient_;
|
||||
}
|
||||
|
||||
vector& waterFluxController::tempGradient()
|
||||
{
|
||||
return tempGradient_;
|
||||
}
|
||||
|
||||
|
||||
const scalarField& waterFluxController::densityField() const
|
||||
{
|
||||
return densities_;
|
||||
}
|
||||
|
||||
scalarField& waterFluxController::densityField()
|
||||
{
|
||||
return densities_;
|
||||
}
|
||||
|
||||
const vectorField& waterFluxController::velocityField() const
|
||||
{
|
||||
return velocities_;
|
||||
}
|
||||
vectorField& waterFluxController::velocityField()
|
||||
{
|
||||
return velocities_;
|
||||
}
|
||||
|
||||
const scalarField& waterFluxController::temperatureField() const
|
||||
{
|
||||
return temperatures_;
|
||||
}
|
||||
|
||||
scalarField& waterFluxController::temperatureField()
|
||||
{
|
||||
return temperatures_;
|
||||
}
|
||||
|
||||
const scalarField& waterFluxController::pressureField() const
|
||||
{
|
||||
return pressures_;
|
||||
}
|
||||
|
||||
scalarField& waterFluxController::pressureField()
|
||||
{
|
||||
return pressures_;
|
||||
}
|
||||
|
||||
|
||||
const bool& waterFluxController::singleValueController() const
|
||||
{
|
||||
return singleValueController_;
|
||||
}
|
||||
|
||||
bool& waterFluxController::singleValueController()
|
||||
{
|
||||
return singleValueController_;
|
||||
}
|
||||
|
||||
const bool& waterFluxController::fieldController() const
|
||||
{
|
||||
return fieldController_;
|
||||
}
|
||||
|
||||
bool& waterFluxController::fieldController()
|
||||
{
|
||||
return fieldController_;
|
||||
}
|
||||
|
||||
|
||||
const bool& waterFluxController::writeInTimeDir() const
|
||||
{
|
||||
return writeInTimeDir_;
|
||||
}
|
||||
|
||||
const bool& waterFluxController::writeInCase() const
|
||||
{
|
||||
return writeInCase_;
|
||||
}
|
||||
|
||||
|
||||
// const scalar waterFluxController::avReqDensity() const
|
||||
// {
|
||||
// scalar totalDensity = 0.0;
|
||||
//
|
||||
// forAll(densities_, c)
|
||||
// {
|
||||
// totalDensity += densities_[c];
|
||||
// }
|
||||
//
|
||||
// if (cells_.size() > 0)
|
||||
// {
|
||||
// totalDensity /= scalar(cells_.size());
|
||||
// }
|
||||
//
|
||||
// return totalDensity;
|
||||
// }
|
||||
//
|
||||
// const vector waterFluxController::avReqVelocity() const
|
||||
// {
|
||||
// vector totalVel = vector::zero;
|
||||
//
|
||||
// forAll(velocities_, c)
|
||||
// {
|
||||
// totalVel += velocities_[c];
|
||||
// }
|
||||
//
|
||||
// if (cells_.size() > 0)
|
||||
// {
|
||||
// totalVel /= scalar(cells_.size());
|
||||
// }
|
||||
//
|
||||
// return totalVel;
|
||||
// }
|
||||
//
|
||||
// const scalar waterFluxController::avReqTemperature() const
|
||||
// {
|
||||
// scalar totalTemp = 0.0;
|
||||
//
|
||||
// forAll(densities_, c)
|
||||
// {
|
||||
// totalTemp += temperatures_[c];
|
||||
// }
|
||||
//
|
||||
// if (cells_.size() > 0)
|
||||
// {
|
||||
// totalTemp /= scalar(cells_.size());
|
||||
// }
|
||||
//
|
||||
// return totalTemp;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,272 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2011 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
|
||||
waterFluxController
|
||||
|
||||
Description
|
||||
|
||||
SourceFiles
|
||||
waterFluxControllerI.H
|
||||
waterFluxController.C
|
||||
waterFluxControllerIO.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef waterFluxController_H
|
||||
#define waterFluxController_H
|
||||
|
||||
#include "IOdictionary.H"
|
||||
#include "Time.H"
|
||||
#include "autoPtr.H"
|
||||
#include "runTimeSelectionTables.H"
|
||||
#include "vector.H"
|
||||
#include "volFields.H"
|
||||
#include "Random.H"
|
||||
#include "polyatomic.H"
|
||||
#include "timeData.H"
|
||||
#include "writeTimeData.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class waterFluxController Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class waterFluxController
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
// Time& time_;
|
||||
|
||||
const fvMesh& mesh_;
|
||||
|
||||
polyatomicCloud& cloud_;
|
||||
|
||||
Random rndGen_;
|
||||
|
||||
//- subDictionary containing the properties
|
||||
dictionary controllerDict_;
|
||||
|
||||
|
||||
dictionary timeDict_;
|
||||
|
||||
timeData time_;
|
||||
|
||||
//- name of face zone
|
||||
word regionName_;
|
||||
label regionId_;
|
||||
// labelList faces_;
|
||||
|
||||
scalar zoneSurfaceArea_;
|
||||
|
||||
labelList internalFaces_;
|
||||
labelList processorFaces_;
|
||||
|
||||
bool control_;
|
||||
bool readStateFromFile_;
|
||||
|
||||
//- set all the properties below from model if required
|
||||
|
||||
bool singleValueController_;
|
||||
|
||||
// target values
|
||||
scalar density_;
|
||||
vector velocity_;
|
||||
scalar temperature_;
|
||||
scalar pressure_;
|
||||
|
||||
tensor strainRate_;
|
||||
vector tempGradient_;
|
||||
|
||||
bool fieldController_;
|
||||
|
||||
//- targeted fields
|
||||
scalarField densities_;
|
||||
vectorField velocities_;
|
||||
scalarField temperatures_;
|
||||
scalarField pressures_;
|
||||
|
||||
bool writeInTimeDir_;
|
||||
bool writeInCase_;
|
||||
|
||||
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
void setFacesInfo();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("waterFluxController");
|
||||
|
||||
// Declare runtime constructor selection table
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
waterFluxController,
|
||||
dictionary,
|
||||
(
|
||||
Time& t,
|
||||
polyatomicCloud& cloud,
|
||||
const dictionary& dict
|
||||
),
|
||||
(t, cloud, dict)
|
||||
);
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
waterFluxController
|
||||
(
|
||||
Time& t,
|
||||
polyatomicCloud& cloud,
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
|
||||
// Selectors
|
||||
|
||||
static autoPtr<waterFluxController> New
|
||||
(
|
||||
Time& t,
|
||||
polyatomicCloud& cloud,
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
virtual ~waterFluxController();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
void updateTime();
|
||||
|
||||
//- create an initial configuration
|
||||
virtual void initialConfiguration() = 0;
|
||||
|
||||
|
||||
//- calculate any required properties
|
||||
virtual void calculateProperties() = 0;
|
||||
|
||||
|
||||
//- control the polyatomic from the tracking function
|
||||
virtual void controlMol
|
||||
(
|
||||
polyatomic& mol,
|
||||
polyatomic::trackData& td
|
||||
) = 0;
|
||||
|
||||
//- output data
|
||||
virtual void output
|
||||
(
|
||||
const fileName& fixedPathName,
|
||||
const fileName& timePath
|
||||
) = 0;
|
||||
|
||||
|
||||
//- E. update properties from a modified dictionary
|
||||
virtual void updateProperties(const dictionary&) = 0;
|
||||
|
||||
|
||||
void updateFluxControllerProperties(const dictionary&);
|
||||
|
||||
// Access
|
||||
|
||||
//- return the control zone cells
|
||||
const labelList& controlZone() const;
|
||||
|
||||
|
||||
label isFaceOnControlZone(const label& faceI);
|
||||
|
||||
//- return the control zone name
|
||||
const word& regionName() const;
|
||||
|
||||
//- return the targeted values
|
||||
const scalar& density() const;
|
||||
scalar& density();
|
||||
|
||||
const vector& velocity() const;
|
||||
vector& velocity();
|
||||
|
||||
const scalar& temperature() const;
|
||||
scalar& temperature();
|
||||
|
||||
const scalar& pressure() const;
|
||||
scalar& pressure();
|
||||
|
||||
const tensor& strainRate() const;
|
||||
tensor& strainRate();
|
||||
|
||||
const vector& tempGradient() const;
|
||||
vector& tempGradient();
|
||||
|
||||
//- return the targeted fields
|
||||
const scalarField& densityField() const;
|
||||
scalarField& densityField();
|
||||
|
||||
const vectorField& velocityField() const;
|
||||
vectorField& velocityField();
|
||||
|
||||
const scalarField& temperatureField() const;
|
||||
scalarField& temperatureField();
|
||||
|
||||
const scalarField& pressureField() const;
|
||||
scalarField& pressureField();
|
||||
|
||||
|
||||
const bool& singleValueController() const;
|
||||
bool& singleValueController();
|
||||
|
||||
const bool& fieldController() const;
|
||||
bool& fieldController();
|
||||
|
||||
const bool& writeInTimeDir() const;
|
||||
const bool& writeInCase() const;
|
||||
|
||||
// const scalar avReqDensity() const;
|
||||
// const vector avReqVelocity() const;
|
||||
// const scalar avReqTemperature() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,490 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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 "stateController.H"
|
||||
#include "IFstream.H"
|
||||
#include "polyatomicCloud.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
defineTypeNameAndDebug(stateController, 0);
|
||||
|
||||
defineRunTimeSelectionTable(stateController, dictionary);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::stateController::stateController
|
||||
(
|
||||
polyatomicCloud& cloud,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
mesh_(refCast<const fvMesh>(cloud.mesh())),
|
||||
cloud_(cloud),
|
||||
rndGen_(clock::getTime()),
|
||||
controllerDict_(dict.subDict("controllerProperties")),
|
||||
timeDict_(controllerDict_.subDict("timeProperties")),
|
||||
time_(mesh_.time(), timeDict_),
|
||||
timePeriod_(readScalar(timeDict_.lookup("initialTimePeriod"))), //temp
|
||||
initialTime_(time_.time().startTime().value()),
|
||||
regionName_(controllerDict_.lookup("zoneName")),
|
||||
regionId_(-1),
|
||||
control_(true),
|
||||
readStateFromFile_(true),
|
||||
singleValueController_(false),
|
||||
density_(0.0),
|
||||
velocity_(vector::zero),
|
||||
temperature_(0.0),
|
||||
pressure_(0.0),
|
||||
strainRate_(tensor::zero),
|
||||
tempGradient_(vector::zero),
|
||||
fieldController_(false),
|
||||
densities_(),
|
||||
velocities_(),
|
||||
temperatures_(),
|
||||
pressures_(),
|
||||
writeInTimeDir_(true),
|
||||
writeInCase_(true)
|
||||
{
|
||||
const cellZoneMesh& cellZones = mesh_.cellZones();
|
||||
|
||||
regionId_ = cellZones.findZoneID(regionName_);
|
||||
|
||||
if (regionId_ == -1)
|
||||
{
|
||||
FatalErrorIn("stateController::stateController()")
|
||||
<< "Cannot find region: " << regionName_ << nl << "in: "
|
||||
<< time_.time().system()/"controllersDict"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
control_ = Switch(controllerDict_.lookup("controlSwitch"));
|
||||
|
||||
readStateFromFile_ = Switch(controllerDict_.lookup("readStateFromFile"));
|
||||
|
||||
const scalar& avTimeInterval = time_.averageTimeInterval().deltaT();
|
||||
|
||||
if ((timePeriod_ < avTimeInterval) && (timePeriod_ > 0.0))
|
||||
{
|
||||
timePeriod_ = avTimeInterval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::autoPtr<Foam::stateController> Foam::stateController::New
|
||||
(
|
||||
polyatomicCloud& cloud,
|
||||
const dictionary& dict
|
||||
)
|
||||
{
|
||||
word stateControllerName
|
||||
(
|
||||
dict.lookup("stateControllerModel")
|
||||
);
|
||||
|
||||
Info<< "Selecting stateController "
|
||||
<< stateControllerName << endl;
|
||||
|
||||
dictionaryConstructorTable::iterator cstrIter =
|
||||
dictionaryConstructorTablePtr_->find(stateControllerName);
|
||||
|
||||
if (cstrIter == dictionaryConstructorTablePtr_->end())
|
||||
{
|
||||
FatalError
|
||||
<< "stateController::New(const dictionary&) : " << endl
|
||||
<< " unknown stateController type "
|
||||
<< stateControllerName
|
||||
<< ", constructor not in hash table" << endl << endl
|
||||
<< " Valid types are :" << endl;
|
||||
Info<< dictionaryConstructorTablePtr_->toc() << abort(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<stateController>
|
||||
(
|
||||
cstrIter()(cloud, dict)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::stateController::~stateController()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::stateController::updateTime()
|
||||
{
|
||||
time_++;
|
||||
|
||||
const scalar& t = time_.time().timeOutputValue();
|
||||
|
||||
if ((t - initialTime_) < timePeriod_)
|
||||
{
|
||||
time_.controlTimeInterval().endTime() = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::stateController::updateStateControllerProperties
|
||||
(
|
||||
const dictionary& newDict
|
||||
)
|
||||
{
|
||||
controllerDict_ = newDict.subDict("controllerProperties");
|
||||
|
||||
if (controllerDict_.found("controlSwitch"))
|
||||
{
|
||||
control_ = Switch(controllerDict_.lookup("controlSwitch"));
|
||||
}
|
||||
|
||||
if (controllerDict_.found("readStateFromFile"))
|
||||
{
|
||||
readStateFromFile_ = Switch
|
||||
(
|
||||
controllerDict_.lookup("readStateFromFile")
|
||||
);
|
||||
}
|
||||
|
||||
timeDict_ = controllerDict_.subDict("timeProperties");
|
||||
|
||||
if (timeDict_.found("resetAtOutput"))
|
||||
{
|
||||
time_.resetFieldsAtOutput() = Switch(timeDict_.lookup("resetAtOutput"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelList& Foam::stateController::controlZone() const
|
||||
{
|
||||
return mesh_.cellZones()[regionId_];
|
||||
}
|
||||
|
||||
const Foam::word& Foam::stateController::regionName() const
|
||||
{
|
||||
return regionName_;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::stateController::density() const
|
||||
{
|
||||
return density_;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar& Foam::stateController::density()
|
||||
{
|
||||
return density_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::vector& Foam::stateController::velocity() const
|
||||
{
|
||||
return velocity_;
|
||||
}
|
||||
|
||||
|
||||
Foam::vector& Foam::stateController::velocity()
|
||||
{
|
||||
return velocity_;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::stateController::temperature() const
|
||||
{
|
||||
return temperature_;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar& Foam::stateController::temperature()
|
||||
{
|
||||
return temperature_;
|
||||
}
|
||||
|
||||
const Foam::scalar& Foam::stateController::pressure() const
|
||||
{
|
||||
return pressure_;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar& Foam::stateController::pressure()
|
||||
{
|
||||
return pressure_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::tensor& Foam::stateController::strainRate() const
|
||||
{
|
||||
return strainRate_;
|
||||
}
|
||||
|
||||
|
||||
Foam::tensor& Foam::stateController::strainRate()
|
||||
{
|
||||
return strainRate_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::vector& Foam::stateController::tempGradient() const
|
||||
{
|
||||
return tempGradient_;
|
||||
}
|
||||
|
||||
|
||||
Foam::vector& Foam::stateController::tempGradient()
|
||||
{
|
||||
return tempGradient_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::scalarField& Foam::stateController::densityField() const
|
||||
{
|
||||
return densities_;
|
||||
}
|
||||
|
||||
Foam::scalarField& Foam::stateController::densityField()
|
||||
{
|
||||
return densities_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::vectorField& Foam::stateController::velocityField() const
|
||||
{
|
||||
return velocities_;
|
||||
}
|
||||
|
||||
|
||||
Foam::vectorField& Foam::stateController::velocityField()
|
||||
{
|
||||
return velocities_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::scalarField& Foam::stateController::temperatureField() const
|
||||
{
|
||||
return temperatures_;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalarField& Foam::stateController::temperatureField()
|
||||
{
|
||||
return temperatures_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::scalarField& Foam::stateController::pressureField() const
|
||||
{
|
||||
return pressures_;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalarField& Foam::stateController::pressureField()
|
||||
{
|
||||
return pressures_;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::stateController::singleValueController() const
|
||||
{
|
||||
return singleValueController_;
|
||||
}
|
||||
|
||||
|
||||
bool& Foam::stateController::singleValueController()
|
||||
{
|
||||
return singleValueController_;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::stateController::fieldController() const
|
||||
{
|
||||
return fieldController_;
|
||||
}
|
||||
|
||||
|
||||
bool& Foam::stateController::fieldController()
|
||||
{
|
||||
return fieldController_;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::stateController::writeInTimeDir() const
|
||||
{
|
||||
return writeInTimeDir_;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::stateController::writeInCase() const
|
||||
{
|
||||
return writeInCase_;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::stateController::avReqDensity()
|
||||
{
|
||||
scalar totalDensity = 0.0;
|
||||
|
||||
if (singleValueController_)
|
||||
{
|
||||
totalDensity = density_;
|
||||
}
|
||||
else if (fieldController_)
|
||||
{
|
||||
label controlCells = controlZone().size();
|
||||
|
||||
forAll(densities_, c)
|
||||
{
|
||||
totalDensity += densities_[c];
|
||||
}
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
reduce(totalDensity, sumOp<scalar>());
|
||||
|
||||
reduce(controlCells, sumOp<label>());
|
||||
}
|
||||
|
||||
if (controlCells > 0)
|
||||
{
|
||||
totalDensity /= scalar(controlCells);
|
||||
}
|
||||
}
|
||||
|
||||
return totalDensity;
|
||||
}
|
||||
|
||||
|
||||
Foam::vector Foam::stateController::avReqVelocity()
|
||||
{
|
||||
vector totalVel = vector::zero;
|
||||
|
||||
if (singleValueController_)
|
||||
{
|
||||
totalVel = velocity_;
|
||||
}
|
||||
else if (fieldController_)
|
||||
{
|
||||
label controlCells = controlZone().size();
|
||||
|
||||
forAll(velocities_, c)
|
||||
{
|
||||
totalVel += velocities_[c];
|
||||
}
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
reduce(totalVel, sumOp<vector>());
|
||||
|
||||
reduce(controlCells, sumOp<label>());
|
||||
}
|
||||
|
||||
if (controlCells > 0)
|
||||
{
|
||||
totalVel /= scalar(controlCells);
|
||||
}
|
||||
}
|
||||
|
||||
return totalVel;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::stateController::avReqTemperature()
|
||||
{
|
||||
scalar totalTemp = 0.0;
|
||||
|
||||
if (singleValueController_)
|
||||
{
|
||||
totalTemp = temperature_;
|
||||
}
|
||||
else if (fieldController_)
|
||||
{
|
||||
label controlCells = controlZone().size();
|
||||
|
||||
forAll(temperatures_, c)
|
||||
{
|
||||
totalTemp += temperatures_[c];
|
||||
}
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
reduce(totalTemp, sumOp<scalar>());
|
||||
|
||||
reduce(controlCells, sumOp<label>());
|
||||
}
|
||||
|
||||
if (controlCells > 0)
|
||||
{
|
||||
totalTemp /= scalar(controlCells);
|
||||
}
|
||||
}
|
||||
|
||||
return totalTemp;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::stateController::avReqPressure()
|
||||
{
|
||||
scalar totalPressure = 0.0;
|
||||
|
||||
if (singleValueController_)
|
||||
{
|
||||
totalPressure = pressure_;
|
||||
}
|
||||
else if (fieldController_)
|
||||
{
|
||||
label controlCells = controlZone().size();
|
||||
|
||||
forAll(pressures_, c)
|
||||
{
|
||||
totalPressure += pressures_[c];
|
||||
}
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
reduce(totalPressure, sumOp<scalar>());
|
||||
|
||||
reduce(controlCells, sumOp<label>());
|
||||
}
|
||||
|
||||
if (controlCells > 0)
|
||||
{
|
||||
totalPressure /= scalar(controlCells);
|
||||
}
|
||||
}
|
||||
|
||||
return totalPressure;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,270 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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
|
||||
stateController
|
||||
|
||||
Description
|
||||
|
||||
Basic/abstract class of a state controller
|
||||
|
||||
SourceFiles
|
||||
stateControllerI.H
|
||||
stateController.C
|
||||
stateControllerIO.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef stateController_H
|
||||
#define stateController_H
|
||||
|
||||
#include "IOdictionary.H"
|
||||
#include "autoPtr.H"
|
||||
#include "runTimeSelectionTables.H"
|
||||
#include "vector.H"
|
||||
#include "volFields.H"
|
||||
#include "Random.H"
|
||||
#include "polyatomic.H"
|
||||
#include "timeData.H"
|
||||
#include "writeTimeData.H"
|
||||
#include "selectIds.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class stateController Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class stateController
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//-
|
||||
const fvMesh& mesh_;
|
||||
|
||||
//-
|
||||
polyatomicCloud& cloud_;
|
||||
|
||||
//-
|
||||
Random rndGen_;
|
||||
|
||||
//- subDictionary containing the properties
|
||||
dictionary controllerDict_;
|
||||
|
||||
//-
|
||||
dictionary timeDict_;
|
||||
|
||||
//-
|
||||
timeData time_;
|
||||
|
||||
//-
|
||||
scalar timePeriod_;
|
||||
|
||||
//-
|
||||
scalar initialTime_;
|
||||
|
||||
//- name of control zone
|
||||
word regionName_;
|
||||
|
||||
//-
|
||||
label regionId_;
|
||||
|
||||
//-
|
||||
bool control_;
|
||||
|
||||
//-
|
||||
bool readStateFromFile_;
|
||||
|
||||
//- set all the properties below from model if required
|
||||
|
||||
//-
|
||||
bool singleValueController_;
|
||||
|
||||
//- target values
|
||||
scalar density_;
|
||||
vector velocity_;
|
||||
scalar temperature_;
|
||||
scalar pressure_;
|
||||
tensor strainRate_;
|
||||
vector tempGradient_;
|
||||
|
||||
//- set this in model
|
||||
bool fieldController_;
|
||||
|
||||
//- targeted fields
|
||||
scalarField densities_;
|
||||
vectorField velocities_;
|
||||
scalarField temperatures_;
|
||||
scalarField pressures_;
|
||||
|
||||
// set these in model
|
||||
bool writeInTimeDir_;
|
||||
bool writeInCase_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("stateController");
|
||||
|
||||
//- Declare runtime constructor selection table
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
stateController,
|
||||
dictionary,
|
||||
(
|
||||
polyatomicCloud& cloud,
|
||||
const dictionary& dict
|
||||
),
|
||||
(t, cloud, dict)
|
||||
);
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
stateController
|
||||
(
|
||||
polyatomicCloud& cloud,
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
|
||||
// Selectors
|
||||
|
||||
static autoPtr<stateController> New
|
||||
(
|
||||
polyatomicCloud& cloud,
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
virtual ~stateController();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
|
||||
void updateTime();
|
||||
|
||||
//- create an initial configuration
|
||||
virtual void initialConfiguration() = 0;
|
||||
|
||||
//- calculate any required properties
|
||||
virtual void calculateProperties() = 0;
|
||||
|
||||
//- control molecules at different stages of the integration time-step
|
||||
virtual void controlMolsBeg() = 0;
|
||||
|
||||
virtual void controlBeforeForces() = 0;
|
||||
|
||||
virtual void controlMols() = 0;
|
||||
|
||||
virtual void controlMolsEnd() = 0;
|
||||
|
||||
|
||||
//- output data
|
||||
virtual void output
|
||||
(
|
||||
const fileName& fixedPathName,
|
||||
const fileName& timePath
|
||||
) = 0;
|
||||
|
||||
//- update properties from a modified dictionary
|
||||
virtual void updateProperties(const dictionary&) = 0;
|
||||
|
||||
void updateStateControllerProperties(const dictionary&);
|
||||
|
||||
// Access
|
||||
|
||||
//- return the control zone cells
|
||||
const labelList& controlZone() const;
|
||||
|
||||
//- return the control zone name
|
||||
const word& regionName() const;
|
||||
|
||||
//- return the targeted fields
|
||||
scalar density() const;
|
||||
scalar& density();
|
||||
|
||||
const vector& velocity() const;
|
||||
vector& velocity();
|
||||
|
||||
scalar temperature() const;
|
||||
scalar& temperature();
|
||||
|
||||
scalar pressure() const;
|
||||
scalar& pressure();
|
||||
|
||||
const tensor& strainRate() const;
|
||||
tensor& strainRate();
|
||||
|
||||
const vector& tempGradient() const;
|
||||
vector& tempGradient();
|
||||
|
||||
//- return the targeted fields
|
||||
const scalarField& densityField() const;
|
||||
scalarField& densityField();
|
||||
|
||||
const vectorField& velocityField() const;
|
||||
vectorField& velocityField();
|
||||
|
||||
const scalarField& temperatureField() const;
|
||||
scalarField& temperatureField();
|
||||
|
||||
const scalarField& pressureField() const;
|
||||
scalarField& pressureField();
|
||||
|
||||
bool singleValueController() const;
|
||||
bool& singleValueController();
|
||||
|
||||
bool fieldController() const;
|
||||
bool& fieldController();
|
||||
|
||||
bool writeInTimeDir() const;
|
||||
bool writeInCase() const;
|
||||
|
||||
scalar avReqDensity();
|
||||
vector avReqVelocity();
|
||||
scalar avReqTemperature();
|
||||
scalar avReqPressure();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -220,4 +220,3 @@ if (runTime.outputTime())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -6,4 +6,3 @@
|
||||
#include "distribution.H"
|
||||
#include "reducedUnits.H"
|
||||
#endif
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
|
||||
@ -0,0 +1,114 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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 "constPropSite.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::constPropSite::constPropSite()
|
||||
:
|
||||
siteReferencePosition_(vector::zero),
|
||||
siteMass_(0.0),
|
||||
siteCharge_(0.0),
|
||||
siteId_(0),
|
||||
name_(),
|
||||
pairPotentialSite_(false),
|
||||
electrostaticSite_(false)
|
||||
{}
|
||||
|
||||
|
||||
Foam::constPropSite::constPropSite
|
||||
(
|
||||
const vector& siteReferencePosition,
|
||||
const scalar& siteMass,
|
||||
const scalar& siteCharge,
|
||||
const label& siteId,
|
||||
const word& name,
|
||||
const bool& pairPotentialSite,
|
||||
const bool& electrostaticSite
|
||||
)
|
||||
:
|
||||
siteReferencePosition_(siteReferencePosition),
|
||||
siteMass_(siteMass),
|
||||
siteCharge_(siteCharge),
|
||||
siteId_(siteId),
|
||||
name_(name),
|
||||
pairPotentialSite_(pairPotentialSite),
|
||||
electrostaticSite_(electrostaticSite)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::constPropSite::~constPropSite()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||
|
||||
Foam::Istream& Foam::operator>>(Istream& is, constPropSite& cPS)
|
||||
{
|
||||
is >> cPS.siteReferencePosition_
|
||||
>> cPS.siteMass_
|
||||
>> cPS.siteCharge_
|
||||
>> cPS.siteId_
|
||||
>> cPS.name_
|
||||
>> cPS.pairPotentialSite_
|
||||
>> cPS.electrostaticSite_;
|
||||
|
||||
// Check state of Istream
|
||||
is.check
|
||||
(
|
||||
"Foam::Istream& Foam::operator>>"
|
||||
"(Foam::Istream&, Foam::constPropSite&)"
|
||||
);
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const constPropSite& cPS)
|
||||
{
|
||||
|
||||
os << token::SPACE << cPS.siteReferencePosition()
|
||||
<< token::SPACE << cPS.siteMass()
|
||||
<< token::SPACE << cPS.siteCharge()
|
||||
<< token::SPACE << cPS.siteId()
|
||||
<< token::SPACE << cPS.name()
|
||||
<< token::SPACE << cPS.pairPotentialSite()
|
||||
<< token::SPACE << cPS.electrostaticSite();
|
||||
|
||||
// Check state of Ostream
|
||||
os.check
|
||||
(
|
||||
"Foam::Ostream& Foam::operator<<(Foam::Ostream&, "
|
||||
"const Foam::constPropSite&)"
|
||||
);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,185 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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
|
||||
|
||||
|
||||
Description
|
||||
|
||||
|
||||
SourceFiles
|
||||
constPropSiteI.H
|
||||
constPropSite.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef constPropSite_H
|
||||
#define constPropSite_H
|
||||
|
||||
#include "vector.H"
|
||||
#include "IOstreams.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
class Istream;
|
||||
class Ostream;
|
||||
|
||||
// Forward declaration of friend functions and operators
|
||||
class constPropSite;
|
||||
Istream& operator>>(Istream&, constPropSite&);
|
||||
Ostream& operator<<(Ostream&, const constPropSite&);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class constPropSite Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class constPropSite
|
||||
{
|
||||
// Private data
|
||||
|
||||
//-
|
||||
vector siteReferencePosition_;
|
||||
|
||||
//-
|
||||
scalar siteMass_;
|
||||
|
||||
//-
|
||||
scalar siteCharge_;
|
||||
|
||||
//-
|
||||
label siteId_;
|
||||
|
||||
//-
|
||||
word name_;
|
||||
|
||||
//-
|
||||
bool pairPotentialSite_;
|
||||
|
||||
//-
|
||||
bool electrostaticSite_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
constPropSite();
|
||||
|
||||
//- Construct from components
|
||||
constPropSite
|
||||
(
|
||||
const vector& siteReferencePosition,
|
||||
const scalar& siteMass,
|
||||
const scalar& siteCharge,
|
||||
const label& siteId,
|
||||
const word& name,
|
||||
const bool& pairPotentialSite,
|
||||
const bool& electrostaticSite
|
||||
);
|
||||
|
||||
|
||||
// Selectors
|
||||
|
||||
// Destructor
|
||||
|
||||
~constPropSite();
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//-
|
||||
inline const vector& siteReferencePosition() const;
|
||||
|
||||
//-
|
||||
inline vector& siteReferencePosition();
|
||||
|
||||
//-
|
||||
inline const scalar& siteMass() const;
|
||||
|
||||
//-
|
||||
inline scalar& siteMass();
|
||||
|
||||
//-
|
||||
inline const scalar& siteCharge() const;
|
||||
|
||||
//-
|
||||
inline scalar& siteCharge();
|
||||
|
||||
//-
|
||||
inline const label& siteId() const;
|
||||
|
||||
//-
|
||||
inline label& siteId();
|
||||
|
||||
//-
|
||||
inline const word& name() const;
|
||||
|
||||
//-
|
||||
inline word& name();
|
||||
|
||||
//-
|
||||
inline const bool& pairPotentialSite() const;
|
||||
|
||||
//-
|
||||
inline bool& pairPotentialSite();
|
||||
|
||||
//-
|
||||
inline const bool& electrostaticSite() const;
|
||||
|
||||
//-
|
||||
inline bool& electrostaticSite();
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
inline bool operator==(const constPropSite&) const;
|
||||
inline bool operator!=(const constPropSite&) const;
|
||||
|
||||
|
||||
// IOstream Operators
|
||||
|
||||
friend Istream& operator>>(Istream&, constPropSite&);
|
||||
friend Ostream& operator<<(Ostream&, const constPropSite&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "constPropSiteI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,139 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2011 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 * * * * * * * * * * * * * //
|
||||
|
||||
inline const Foam::vector& Foam::constPropSite::siteReferencePosition() const
|
||||
{
|
||||
return siteReferencePosition_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::vector& Foam::constPropSite::siteReferencePosition()
|
||||
{
|
||||
return siteReferencePosition_;
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::scalar& Foam::constPropSite::siteMass() const
|
||||
{
|
||||
return siteMass_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::scalar& Foam::constPropSite::siteMass()
|
||||
{
|
||||
return siteMass_;
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::scalar& Foam::constPropSite::siteCharge() const
|
||||
{
|
||||
return siteCharge_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::scalar& Foam::constPropSite::siteCharge()
|
||||
{
|
||||
return siteCharge_;
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::label& Foam::constPropSite::siteId() const
|
||||
{
|
||||
return siteId_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label& Foam::constPropSite::siteId()
|
||||
{
|
||||
return siteId_;
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::word& Foam::constPropSite::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::word& Foam::constPropSite::name()
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
|
||||
inline const bool& Foam::constPropSite::pairPotentialSite() const
|
||||
{
|
||||
return pairPotentialSite_;
|
||||
}
|
||||
|
||||
|
||||
inline bool& Foam::constPropSite::pairPotentialSite()
|
||||
{
|
||||
return pairPotentialSite_;
|
||||
}
|
||||
|
||||
|
||||
inline const bool& Foam::constPropSite::electrostaticSite() const
|
||||
{
|
||||
return electrostaticSite_;
|
||||
}
|
||||
|
||||
|
||||
inline bool& Foam::constPropSite::electrostaticSite()
|
||||
{
|
||||
return electrostaticSite_;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::constPropSite::operator==
|
||||
(
|
||||
const constPropSite& rhs
|
||||
) const
|
||||
{
|
||||
return
|
||||
siteReferencePosition_ == rhs.siteReferencePosition_
|
||||
&& siteMass_ == rhs.siteMass_
|
||||
&& siteCharge_ == rhs.siteCharge_
|
||||
&& siteId_ == rhs.siteId_
|
||||
&& name_ == rhs.name_
|
||||
&& pairPotentialSite_ == rhs.pairPotentialSite_
|
||||
&& electrostaticSite_ == rhs.electrostaticSite_;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::constPropSite::operator!=
|
||||
(
|
||||
const constPropSite& rhs
|
||||
) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,199 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2011 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 "monoatomic.H"
|
||||
#include "Random.H"
|
||||
#include "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(monoatomic, 0);
|
||||
defineTemplateTypeNameAndDebug(Cloud<monoatomic>, 0);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::monoatomic::move
|
||||
(
|
||||
monoatomic::trackingData& td,
|
||||
const scalar trackTime
|
||||
)
|
||||
{
|
||||
td.switchProcessor = false;
|
||||
td.keepParticle = true;
|
||||
|
||||
if (special_ != SPECIAL_FROZEN)
|
||||
{
|
||||
return td.keepParticle;
|
||||
}
|
||||
|
||||
const constantProperties& constProps(td.cloud().constProps(id_));
|
||||
|
||||
if (td.part() == trackingData::tpFirstVelocityHalfStep)
|
||||
{
|
||||
// First leapfrog velocity adjust part, required before tracking+force
|
||||
// part
|
||||
|
||||
v_ += 0.5*trackTime*a_;
|
||||
}
|
||||
else if (td.part() == trackingData::tpLinearTrack)
|
||||
{
|
||||
// Leapfrog tracking part
|
||||
|
||||
scalar tEnd = (1.0 - stepFraction())*trackTime;
|
||||
scalar dtMax = tEnd;
|
||||
|
||||
while (td.keepParticle && !td.switchProcessor && tEnd > ROOTVSMALL)
|
||||
{
|
||||
// set the lagrangian time-step
|
||||
scalar dt = min(dtMax, tEnd);
|
||||
|
||||
dt *= trackToFace(position() + dt*v_, td);
|
||||
|
||||
tEnd -= dt;
|
||||
stepFraction() = 1.0 - tEnd/trackTime;
|
||||
}
|
||||
|
||||
setSitePositions(constProps);
|
||||
}
|
||||
else if (td.part() == trackingData::tpSecondVelocityHalfStep)
|
||||
{
|
||||
// Second leapfrog velocity adjust part, required after tracking+force
|
||||
// part
|
||||
|
||||
a_ = siteForces_[0]/constProps.mass();
|
||||
|
||||
v_ += 0.5*trackTime*a_;
|
||||
}
|
||||
else if (td.part() != trackingData::tpRotationalTrack)
|
||||
{
|
||||
FatalErrorIn("monoatomic::move(trackingData&, const scalar)") << nl
|
||||
<< td.part() << " is an invalid part of the integration method."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return td.keepParticle;
|
||||
}
|
||||
|
||||
|
||||
void Foam::monoatomic::transformProperties(const tensor& T)
|
||||
{
|
||||
particle::transformProperties(T);
|
||||
|
||||
v_ = transform(T, v_);
|
||||
|
||||
a_ = transform(T, a_);
|
||||
|
||||
rf_ = transform(T, rf_);
|
||||
|
||||
sitePositions_[0] = position_ + (T & (sitePositions_[0] - position_));
|
||||
|
||||
siteForces_[0] = T & siteForces_[0];
|
||||
}
|
||||
|
||||
|
||||
void Foam::monoatomic::transformProperties(const vector& separation)
|
||||
{
|
||||
particle::transformProperties(separation);
|
||||
|
||||
if (special_ == SPECIAL_TETHERED)
|
||||
{
|
||||
specialPosition_ += separation;
|
||||
}
|
||||
|
||||
sitePositions_[0] += separation;
|
||||
}
|
||||
|
||||
|
||||
void Foam::monoatomic::setSitePositions(const constantProperties& constProps)
|
||||
{
|
||||
sitePositions_[0] = position_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::monoatomic::setSiteSizes(label size)
|
||||
{
|
||||
// Nothing required, size controlled internally
|
||||
}
|
||||
|
||||
|
||||
bool Foam::monoatomic::hitPatch
|
||||
(
|
||||
const polyPatch&,
|
||||
trackingData&,
|
||||
const label,
|
||||
const scalar,
|
||||
const tetIndices&
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Foam::monoatomic::hitProcessorPatch
|
||||
(
|
||||
const processorPolyPatch&,
|
||||
trackingData& td
|
||||
)
|
||||
{
|
||||
td.switchProcessor = true;
|
||||
}
|
||||
|
||||
|
||||
void Foam::monoatomic::hitWallPatch
|
||||
(
|
||||
const wallPolyPatch& wpp,
|
||||
trackingData& td,
|
||||
const tetIndices& tetIs
|
||||
)
|
||||
{
|
||||
// Use of the normal from tetIs is not required as
|
||||
// hasWallImpactDistance is false.
|
||||
vector nw = normal();
|
||||
nw /= mag(nw);
|
||||
|
||||
scalar vn = v_ & nw;
|
||||
|
||||
// Specular reflection
|
||||
if (vn > 0)
|
||||
{
|
||||
v_ -= 2*vn*nw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::monoatomic::hitPatch
|
||||
(
|
||||
const polyPatch&,
|
||||
trackingData& td
|
||||
)
|
||||
{
|
||||
td.keepParticle = false;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,418 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2011 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::monoatomic
|
||||
|
||||
Description
|
||||
Foam::monoatomic
|
||||
|
||||
SourceFiles
|
||||
monoatomicI.H
|
||||
monoatomic.C
|
||||
monoatomicIO.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef monoatomic_H
|
||||
#define monoatomic_H
|
||||
|
||||
#include "particle.H"
|
||||
#include "IOstream.H"
|
||||
#include "autoPtr.H"
|
||||
#include "diagTensor.H"
|
||||
#include "constPropSite.H"
|
||||
#include "MoleculeCloud.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class monoatomic Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class monoatomic
|
||||
:
|
||||
public particle
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// Values of special that are less than zero are for built-in functionality.
|
||||
// Values greater than zero are user specifiable/expandable (i.e. test
|
||||
// special_ >= SPECIAL_USER)
|
||||
|
||||
enum specialTypes
|
||||
{
|
||||
SPECIAL_TETHERED = -1,
|
||||
SPECIAL_FROZEN = -2,
|
||||
NOT_SPECIAL = 0,
|
||||
SPECIAL_USER = 1
|
||||
};
|
||||
|
||||
//- Class to hold monoatomic constant properties
|
||||
class constantProperties
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Sites of mass, charge or interaction
|
||||
FixedList<constPropSite, 1> sites_;
|
||||
|
||||
//- Which sites require electrostatic interactions
|
||||
FixedList<label, 1> electrostaticSites_;
|
||||
|
||||
//- Which sites require pair interactions
|
||||
FixedList<label, 1> pairPotSites_;
|
||||
|
||||
//-
|
||||
scalar mass_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//-
|
||||
inline constantProperties();
|
||||
|
||||
//- Construct from dictionary
|
||||
inline constantProperties
|
||||
(
|
||||
const dictionary& dict,
|
||||
const List<label>& siteIds
|
||||
);
|
||||
|
||||
// Member functions
|
||||
|
||||
//-
|
||||
inline const FixedList<constPropSite, 1>& sites() const;
|
||||
|
||||
//-
|
||||
inline const FixedList<label, 1>& pairPotSites() const;
|
||||
|
||||
//-
|
||||
inline const FixedList<label, 1>& electrostaticSites() const;
|
||||
|
||||
//-
|
||||
inline label degreesOfFreedom() const;
|
||||
|
||||
//-
|
||||
inline scalar mass() const;
|
||||
|
||||
//-
|
||||
inline label nSites() const;
|
||||
};
|
||||
|
||||
|
||||
//- Class used to pass tracking data to the trackToFace function
|
||||
class trackingData
|
||||
:
|
||||
public particle::TrackingData<MoleculeCloud<monoatomic> >
|
||||
{
|
||||
public:
|
||||
|
||||
enum trackPart
|
||||
{
|
||||
tpFirstVelocityHalfStep,
|
||||
tpLinearTrack,
|
||||
tpRotationalTrack,
|
||||
tpSecondVelocityHalfStep,
|
||||
tpAccess
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
// label specifying which part of the integration algorithm is taking
|
||||
label part_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
trackingData(MoleculeCloud<monoatomic>& cloud, trackPart part)
|
||||
:
|
||||
particle::TrackingData<MoleculeCloud<monoatomic> >(cloud),
|
||||
part_(part)
|
||||
{}
|
||||
|
||||
// Member functions
|
||||
|
||||
inline label part() const
|
||||
{
|
||||
return part_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private data
|
||||
|
||||
//- Linear velocity of monoatomic
|
||||
vector v_;
|
||||
|
||||
//- Total linear acceleration of monoatomic
|
||||
vector a_;
|
||||
|
||||
//-
|
||||
vector specialPosition_;
|
||||
|
||||
//-
|
||||
scalar potentialEnergy_;
|
||||
|
||||
// - r_ij f_ij, stress dyad
|
||||
tensor rf_;
|
||||
|
||||
// // - r_ij outer product f_ij: virial contribution
|
||||
// tensor rDotf_;
|
||||
|
||||
//-
|
||||
label special_;
|
||||
|
||||
//-
|
||||
label id_;
|
||||
|
||||
//-
|
||||
FixedList<vector, 1> siteForces_;
|
||||
|
||||
//-
|
||||
FixedList<vector, 1> sitePositions_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("monoatomic");
|
||||
|
||||
friend class Cloud<monoatomic>;
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct with macroscopic description
|
||||
inline monoatomic
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const vector& position,
|
||||
const label cellI,
|
||||
const label tetFaceI,
|
||||
const label tetPtI,
|
||||
const scalar temperature,
|
||||
const vector& bulkVelocity,
|
||||
const vector& specialPosition,
|
||||
const constantProperties& constProps,
|
||||
trackingData& td,
|
||||
const label special,
|
||||
const label id
|
||||
);
|
||||
|
||||
//- Construct from all components
|
||||
inline monoatomic
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const vector& position,
|
||||
const label cellI,
|
||||
const label tetFaceI,
|
||||
const label tetPtI,
|
||||
const vector& v,
|
||||
const vector& a,
|
||||
const vector& specialPosition,
|
||||
const constantProperties& constProps,
|
||||
const label special,
|
||||
const label id
|
||||
);
|
||||
|
||||
//- Construct from Istream
|
||||
monoatomic
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
Istream& is,
|
||||
bool readFields = true
|
||||
);
|
||||
|
||||
//- Construct and return a clone
|
||||
autoPtr<particle> clone() const
|
||||
{
|
||||
return autoPtr<particle>(new monoatomic(*this));
|
||||
}
|
||||
|
||||
//- Factory class to read-construct particles used for
|
||||
// parallel transfer
|
||||
class iNew
|
||||
{
|
||||
const polyMesh& mesh_;
|
||||
|
||||
public:
|
||||
|
||||
iNew(const polyMesh& mesh)
|
||||
:
|
||||
mesh_(mesh)
|
||||
{}
|
||||
|
||||
autoPtr<monoatomic> operator()(Istream& is) const
|
||||
{
|
||||
return autoPtr<monoatomic>(new monoatomic(mesh_, is, true));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Tracking
|
||||
|
||||
//-
|
||||
bool move(trackingData&, const scalar trackTime);
|
||||
|
||||
//-
|
||||
virtual void transformProperties(const tensor& T);
|
||||
|
||||
//-
|
||||
virtual void transformProperties(const vector& separation);
|
||||
|
||||
//-
|
||||
void setSitePositions(const constantProperties& constProps);
|
||||
|
||||
//-
|
||||
void setSiteSizes(label size);
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
//-
|
||||
inline const vector& v() const;
|
||||
|
||||
//-
|
||||
inline vector& v();
|
||||
|
||||
//-
|
||||
inline const vector& a() const;
|
||||
|
||||
//-
|
||||
inline vector& a();
|
||||
|
||||
//-
|
||||
inline const FixedList<vector, 1>& siteForces() const;
|
||||
|
||||
//-
|
||||
inline FixedList<vector, 1>& siteForces();
|
||||
|
||||
//-
|
||||
inline const FixedList<vector, 1>& sitePositions() const;
|
||||
|
||||
//-
|
||||
inline FixedList<vector, 1>& sitePositions();
|
||||
|
||||
//-
|
||||
inline const vector& specialPosition() const;
|
||||
|
||||
//-
|
||||
inline vector& specialPosition();
|
||||
|
||||
//-
|
||||
inline scalar potentialEnergy() const;
|
||||
|
||||
//-
|
||||
inline scalar& potentialEnergy();
|
||||
|
||||
//-
|
||||
inline const tensor& rf() const;
|
||||
|
||||
//-
|
||||
inline tensor& rf();
|
||||
|
||||
//-
|
||||
inline label special() const;
|
||||
|
||||
//-
|
||||
inline bool tethered() const;
|
||||
|
||||
//-
|
||||
inline label id() const;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- Overridable function to handle the particle hitting a patch
|
||||
// Executed before other patch-hitting functions
|
||||
bool hitPatch
|
||||
(
|
||||
const polyPatch&,
|
||||
trackingData& td,
|
||||
const label patchI,
|
||||
const scalar trackFraction,
|
||||
const tetIndices& tetIs
|
||||
);
|
||||
|
||||
//- Overridable function to handle the particle hitting a processorPatch
|
||||
void hitProcessorPatch
|
||||
(
|
||||
const processorPolyPatch&,
|
||||
trackingData& td
|
||||
);
|
||||
|
||||
//- Overridable function to handle the particle hitting a wallPatch
|
||||
void hitWallPatch
|
||||
(
|
||||
const wallPolyPatch&,
|
||||
trackingData& td,
|
||||
const tetIndices&
|
||||
);
|
||||
|
||||
//- Overridable function to handle the particle hitting a polyPatch
|
||||
void hitPatch
|
||||
(
|
||||
const polyPatch&,
|
||||
trackingData& td
|
||||
);
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Read
|
||||
static void readFields(Cloud<monoatomic>& mC);
|
||||
|
||||
//- Write
|
||||
static void writeFields(const Cloud<monoatomic>& mC);
|
||||
|
||||
//- Show info
|
||||
static void info(trackingData& td);
|
||||
|
||||
|
||||
// IOstream Operators
|
||||
|
||||
friend Ostream& operator<<(Ostream&, const monoatomic&);
|
||||
};
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "monoatomicI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user