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 =
|
const int nNonOrthCorr =
|
||||||
potentialFlow.lookupOrDefault<int>("nNonOrthogonalCorrectors", 0);
|
potentialFlow.lookupOrDefault<int>("nNonOrthogonalCorrectors", 0);
|
||||||
|
|
||||||
|
|||||||
@ -13,4 +13,3 @@ EXE_LIBS = \
|
|||||||
-lmolecule \
|
-lmolecule \
|
||||||
-lpotential \
|
-lpotential \
|
||||||
-lmolecularMeasurements
|
-lmolecularMeasurements
|
||||||
|
|
||||||
|
|||||||
@ -13,4 +13,3 @@ EXE_LIBS = \
|
|||||||
-lmolecule \
|
-lmolecule \
|
||||||
-lpotential \
|
-lpotential \
|
||||||
-lmolecularMeasurements
|
-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));
|
solve(UEqn == -fvc::grad(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -26,7 +26,7 @@ Application
|
|||||||
|
|
||||||
Description
|
Description
|
||||||
Calculates the inertia tensor and principal axes and moments of a
|
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
|
// Clear mesh before checking
|
||||||
mesh.clearOut();
|
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
|
// Reconstruct globalMeshData
|
||||||
mesh.globalData();
|
mesh.globalData();
|
||||||
|
|
||||||
|
|||||||
@ -208,7 +208,8 @@ int main(int argc, char *argv[])
|
|||||||
IOobject::MUST_READ
|
IOobject::MUST_READ
|
||||||
);
|
);
|
||||||
Info<< "Read set " << setName << " with size "
|
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())
|
if (currentSet.valid())
|
||||||
{
|
{
|
||||||
Info<< " Set " << currentSet().name()
|
Info<< " Set " << currentSet().name()
|
||||||
<< " now size " << currentSet().size()
|
<< " now size "
|
||||||
|
<< returnReduce(currentSet().size(), sumOp<label>())
|
||||||
<< endl;
|
<< 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
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
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
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -315,32 +315,12 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
triPointRef tri
|
triQ[faceI] = triPointRef
|
||||||
(
|
(
|
||||||
surf.points()[f[0]],
|
surf.points()[f[0]],
|
||||||
surf.points()[f[1]],
|
surf.points()[f[1]],
|
||||||
surf.points()[f[2]]
|
surf.points()[f[2]]
|
||||||
);
|
).quality();
|
||||||
|
|
||||||
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
|
|
||||||
(
|
|
||||||
surf.points()[f[0]],
|
|
||||||
surf.points()[f[1]],
|
|
||||||
surf.points()[f[2]]
|
|
||||||
).quality();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -66,8 +66,8 @@ static void writeRegionOBJ
|
|||||||
|
|
||||||
triSurface regionSurf(surf.subsetMesh(include, pointMap, faceMap));
|
triSurface regionSurf(surf.subsetMesh(include, pointMap, faceMap));
|
||||||
|
|
||||||
//Pout<< "Region " << regionI << " surface:" << nl;
|
Pout<< "Region " << regionI << " surface:" << nl;
|
||||||
//regionSurf.writeStats(Pout);
|
regionSurf.writeStats(Pout);
|
||||||
|
|
||||||
regionSurf.write(regionName);
|
regionSurf.write(regionName);
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ static void splitTri
|
|||||||
DynamicList<labelledTri>& tris
|
DynamicList<labelledTri>& tris
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
label oldNTris = tris.size();
|
//label oldNTris = tris.size();
|
||||||
|
|
||||||
label fp = findIndex(f, e[0]);
|
label fp = findIndex(f, e[0]);
|
||||||
label fp1 = f.fcIndex(fp);
|
label fp1 = f.fcIndex(fp);
|
||||||
@ -175,7 +175,7 @@ static void splitTri
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FatalErrorIn("splitTri")
|
FatalErrorIn("splitTri(..)")
|
||||||
<< "Edge " << e << " not part of triangle " << f
|
<< "Edge " << e << " not part of triangle " << f
|
||||||
<< " fp:" << fp
|
<< " fp:" << fp
|
||||||
<< " fp1:" << fp1
|
<< " fp1:" << fp1
|
||||||
@ -183,13 +183,13 @@ static void splitTri
|
|||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pout<< "Split face " << f << " along edge " << e
|
//Pout<< "Split face " << f << " along edge " << e
|
||||||
<< " into triangles:" << endl;
|
// << " into triangles:" << endl;
|
||||||
|
//
|
||||||
for (label i = oldNTris; i < tris.size(); i++)
|
//for (label i = oldNTris; i < tris.size(); i++)
|
||||||
{
|
//{
|
||||||
Pout<< " " << tris[i] << nl;
|
// Pout<< " " << tris[i] << nl;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -206,14 +206,14 @@ static bool insertSorted
|
|||||||
{
|
{
|
||||||
if (findIndex(sortedVerts, vertI) != -1)
|
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 "
|
<< " which is already in list of sorted vertices "
|
||||||
<< sortedVerts << abort(FatalError);
|
<< sortedVerts << abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weight <= 0 || weight >= 1)
|
if (weight <= 0 || weight >= 1)
|
||||||
{
|
{
|
||||||
FatalErrorIn("insertSorted") << "Trying to insert vertex " << vertI
|
FatalErrorIn("insertSorted(..)") << "Trying to insert vertex " << vertI
|
||||||
<< " with illegal weight " << weight
|
<< " with illegal weight " << weight
|
||||||
<< " into list of sorted vertices "
|
<< " into list of sorted vertices "
|
||||||
<< sortedVerts << abort(FatalError);
|
<< sortedVerts << abort(FatalError);
|
||||||
@ -228,7 +228,7 @@ static bool insertSorted
|
|||||||
|
|
||||||
if (mag(w - weight) < SMALL)
|
if (mag(w - weight) < SMALL)
|
||||||
{
|
{
|
||||||
WarningIn("insertSorted")
|
WarningIn("insertSorted(..)")
|
||||||
<< "Trying to insert weight " << weight << " which is close to"
|
<< "Trying to insert weight " << weight << " which is close to"
|
||||||
<< " existing weight " << w << " in " << sortedWeights
|
<< " existing weight " << w << " in " << sortedWeights
|
||||||
<< endl;
|
<< endl;
|
||||||
@ -263,64 +263,103 @@ static bool insertSorted
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Is triangle candidate for collapse? Small height or small quality
|
||||||
|
bool isSliver
|
||||||
|
(
|
||||||
|
const triSurface& surf,
|
||||||
|
const scalar minLen,
|
||||||
|
const scalar minQuality,
|
||||||
|
const label faceI,
|
||||||
|
const label edgeI
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const pointField& localPoints = surf.localPoints();
|
||||||
|
|
||||||
|
// Check
|
||||||
|
// - opposite vertex projects onto base edge
|
||||||
|
// - normal distance is small
|
||||||
|
// - or triangle quality is small
|
||||||
|
|
||||||
|
label opposite0 =
|
||||||
|
triSurfaceTools::oppositeVertex
|
||||||
|
(
|
||||||
|
surf,
|
||||||
|
faceI,
|
||||||
|
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
|
||||||
|
|| 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 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.
|
// Mark all faces that are going to be collapsed.
|
||||||
// faceToEdge: per face -1 or the base edge of the face.
|
// faceToEdge: per face -1 or the base edge of the face.
|
||||||
static void markCollapsedFaces
|
static void markCollapsedFaces
|
||||||
(
|
(
|
||||||
const triSurface& surf,
|
const triSurface& surf,
|
||||||
const scalar minLen,
|
const scalar minLen,
|
||||||
|
const scalar minQuality,
|
||||||
labelList& faceToEdge
|
labelList& faceToEdge
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
faceToEdge.setSize(surf.size());
|
faceToEdge.setSize(surf.size());
|
||||||
faceToEdge = -1;
|
faceToEdge = -1;
|
||||||
|
|
||||||
const pointField& localPoints = surf.localPoints();
|
|
||||||
const labelListList& edgeFaces = surf.edgeFaces();
|
const labelListList& edgeFaces = surf.edgeFaces();
|
||||||
|
|
||||||
forAll(edgeFaces, edgeI)
|
forAll(edgeFaces, edgeI)
|
||||||
{
|
{
|
||||||
const edge& e = surf.edges()[edgeI];
|
|
||||||
|
|
||||||
const labelList& eFaces = surf.edgeFaces()[edgeI];
|
const labelList& eFaces = surf.edgeFaces()[edgeI];
|
||||||
|
|
||||||
forAll(eFaces, i)
|
forAll(eFaces, i)
|
||||||
{
|
{
|
||||||
label faceI = eFaces[i];
|
label faceI = eFaces[i];
|
||||||
|
|
||||||
// Check distance of vertex to edge.
|
bool isCandidate = isSliver(surf, minLen, minQuality, faceI, edgeI);
|
||||||
label opposite0 =
|
|
||||||
triSurfaceTools::oppositeVertex
|
|
||||||
(
|
|
||||||
surf,
|
|
||||||
faceI,
|
|
||||||
edgeI
|
|
||||||
);
|
|
||||||
|
|
||||||
pointHit pHit =
|
if (isCandidate)
|
||||||
e.line(localPoints).nearestDist
|
|
||||||
(
|
|
||||||
localPoints[opposite0]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (pHit.hit() && pHit.distance() < minLen)
|
|
||||||
{
|
{
|
||||||
// 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;
|
|
||||||
|
|
||||||
// Mark face as being collapsed
|
// Mark face as being collapsed
|
||||||
if (faceToEdge[faceI] != -1)
|
if (faceToEdge[faceI] != -1)
|
||||||
{
|
{
|
||||||
FatalErrorIn("markCollapsedFaces")
|
FatalErrorIn("markCollapsedFaces(..)")
|
||||||
<< "Cannot collapse face " << faceI << " since "
|
<< "Cannot collapse face " << faceI << " since "
|
||||||
<< " is marked to be collapsed both to edge "
|
<< " is marked to be collapsed both to edge "
|
||||||
<< faceToEdge[faceI] << " and " << edgeI
|
<< faceToEdge[faceI] << " and " << edgeI
|
||||||
@ -347,7 +386,7 @@ static void markRegion
|
|||||||
{
|
{
|
||||||
if (faceToEdge[faceI] == -1 || collapseRegion[faceI] != -1)
|
if (faceToEdge[faceI] == -1 || collapseRegion[faceI] != -1)
|
||||||
{
|
{
|
||||||
FatalErrorIn("markRegion")
|
FatalErrorIn("markRegion(..)")
|
||||||
<< "Problem : crossed into uncollapsed/regionized face"
|
<< "Problem : crossed into uncollapsed/regionized face"
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
@ -383,7 +422,7 @@ static void markRegion
|
|||||||
}
|
}
|
||||||
else if (collapseRegion[nbrFaceI] != regionI)
|
else if (collapseRegion[nbrFaceI] != regionI)
|
||||||
{
|
{
|
||||||
FatalErrorIn("markRegion")
|
FatalErrorIn("markRegion(..)")
|
||||||
<< "Edge:" << edgeI << " between face " << faceI
|
<< "Edge:" << edgeI << " between face " << faceI
|
||||||
<< " with region " << regionI
|
<< " with region " << regionI
|
||||||
<< " and face " << nbrFaceI
|
<< " and face " << nbrFaceI
|
||||||
@ -411,8 +450,8 @@ static label markRegions
|
|||||||
{
|
{
|
||||||
if (collapseRegion[faceI] == -1 && faceToEdge[faceI] != -1)
|
if (collapseRegion[faceI] == -1 && faceToEdge[faceI] != -1)
|
||||||
{
|
{
|
||||||
Pout<< "markRegions : Marking region:" << regionI
|
//Pout<< "markRegions : Marking region:" << regionI
|
||||||
<< " starting from face " << faceI << endl;
|
// << " starting from face " << faceI << endl;
|
||||||
|
|
||||||
// Collapsed face. Mark connected region with current region number
|
// Collapsed face. Mark connected region with current region number
|
||||||
markRegion(surf, faceToEdge, regionI++, faceI, collapseRegion);
|
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;
|
label nTotalSplit = 0;
|
||||||
|
|
||||||
@ -743,7 +787,7 @@ label collapseBase(triSurface& surf, const scalar minLen)
|
|||||||
labelList faceToEdge(surf.size(), -1);
|
labelList faceToEdge(surf.size(), -1);
|
||||||
|
|
||||||
// Calculate faceToEdge (face collapses)
|
// Calculate faceToEdge (face collapses)
|
||||||
markCollapsedFaces(surf, minLen, faceToEdge);
|
markCollapsedFaces(surf, minLen, minQuality, faceToEdge);
|
||||||
|
|
||||||
|
|
||||||
// Find regions of connected collapsed faces
|
// Find regions of connected collapsed faces
|
||||||
@ -754,8 +798,8 @@ label collapseBase(triSurface& surf, const scalar minLen)
|
|||||||
|
|
||||||
label nRegions = markRegions(surf, faceToEdge, collapseRegion);
|
label nRegions = markRegions(surf, faceToEdge, collapseRegion);
|
||||||
|
|
||||||
Pout<< "Detected " << nRegions << " regions of faces to be collapsed"
|
//Pout<< "Detected " << nRegions << " regions of faces to be collapsed"
|
||||||
<< nl << endl;
|
// << nl << endl;
|
||||||
|
|
||||||
// Pick up all vertices on outside of region
|
// Pick up all vertices on outside of region
|
||||||
labelListList outsideVerts
|
labelListList outsideVerts
|
||||||
@ -772,10 +816,10 @@ label collapseBase(triSurface& surf, const scalar minLen)
|
|||||||
{
|
{
|
||||||
spanPoints[regionI] = getSpanPoints(surf, outsideVerts[regionI]);
|
spanPoints[regionI] = getSpanPoints(surf, outsideVerts[regionI]);
|
||||||
|
|
||||||
Pout<< "For region " << regionI << " found extrema at points "
|
//Pout<< "For region " << regionI << " found extrema at points "
|
||||||
<< surf.localPoints()[spanPoints[regionI][0]]
|
// << surf.localPoints()[spanPoints[regionI][0]]
|
||||||
<< surf.localPoints()[spanPoints[regionI][1]]
|
// << surf.localPoints()[spanPoints[regionI][1]]
|
||||||
<< endl;
|
// << endl;
|
||||||
|
|
||||||
// Project all non-span points onto the span edge.
|
// Project all non-span points onto the span edge.
|
||||||
projectNonSpanPoints
|
projectNonSpanPoints
|
||||||
@ -787,21 +831,21 @@ label collapseBase(triSurface& surf, const scalar minLen)
|
|||||||
orderedWeights[regionI]
|
orderedWeights[regionI]
|
||||||
);
|
);
|
||||||
|
|
||||||
Pout<< "For region:" << regionI
|
//Pout<< "For region:" << regionI
|
||||||
<< " span:" << spanPoints[regionI]
|
// << " span:" << spanPoints[regionI]
|
||||||
<< " orderedVerts:" << orderedVertices[regionI]
|
// << " orderedVerts:" << orderedVertices[regionI]
|
||||||
<< " orderedWeights:" << orderedWeights[regionI]
|
// << " orderedWeights:" << orderedWeights[regionI]
|
||||||
<< endl;
|
// << endl;
|
||||||
|
|
||||||
writeRegionOBJ
|
//writeRegionOBJ
|
||||||
(
|
//(
|
||||||
surf,
|
// surf,
|
||||||
regionI,
|
// regionI,
|
||||||
collapseRegion,
|
// collapseRegion,
|
||||||
outsideVerts[regionI]
|
// 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
|
// Split edge using splitVerts. All non-collapsed triangles
|
||||||
// using edge will get split.
|
// using edge will get split.
|
||||||
|
|
||||||
|
//{
|
||||||
{
|
// const pointField& localPoints = surf.localPoints();
|
||||||
const pointField& localPoints = surf.localPoints();
|
// Pout<< "edge " << edgeI << ' ' << e
|
||||||
Pout<< "edge " << edgeI << ' ' << e
|
// << " points "
|
||||||
<< " points "
|
// << localPoints[e[0]] << ' ' << localPoints[e[1]]
|
||||||
<< localPoints[e[0]] << ' ' << localPoints[e[1]]
|
// << " split into edges with extra points:"
|
||||||
<< " split into edges with extra points:"
|
// << endl;
|
||||||
<< endl;
|
// forAll(splitVerts, i)
|
||||||
forAll(splitVerts, i)
|
// {
|
||||||
{
|
// Pout<< " " << splitVerts[i] << " weight "
|
||||||
Pout<< " " << splitVerts[i] << " weight "
|
// << splitWeights[i] << nl;
|
||||||
<< splitWeights[i] << nl;
|
// }
|
||||||
}
|
//}
|
||||||
}
|
|
||||||
|
|
||||||
const labelList& eFaces = surf.edgeFaces()[edgeI];
|
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;
|
<< endl;
|
||||||
|
|
||||||
nTotalSplit += nSplit;
|
nTotalSplit += nSplit;
|
||||||
@ -927,15 +971,15 @@ label collapseBase(triSurface& surf, const scalar minLen)
|
|||||||
// Pack the triangles
|
// Pack the triangles
|
||||||
newTris.shrink();
|
newTris.shrink();
|
||||||
|
|
||||||
Pout<< "Resetting surface from " << surf.size() << " to "
|
//Pout<< "Resetting surface from " << surf.size() << " to "
|
||||||
<< newTris.size() << " triangles" << endl;
|
// << newTris.size() << " triangles" << endl;
|
||||||
surf = triSurface(newTris, surf.patches(), surf.localPoints());
|
surf = triSurface(newTris, surf.patches(), surf.localPoints());
|
||||||
|
|
||||||
{
|
//{
|
||||||
fileName fName("bla" + name(iter) + ".obj");
|
// fileName fName("bla" + name(iter) + ".obj");
|
||||||
Pout<< "Writing surf to " << fName << endl;
|
// Pout<< "Writing surf to " << fName << endl;
|
||||||
surf.write(fName);
|
// surf.write(fName);
|
||||||
}
|
//}
|
||||||
|
|
||||||
iter++;
|
iter++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
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.
|
// 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
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -121,8 +121,8 @@ label collapseEdge(triSurface& surf, const scalar minLen)
|
|||||||
pointMap[v1] = v;
|
pointMap[v1] = v;
|
||||||
newPoints[v] = 0.5*(localPoints[v1] + localPoints[v]);
|
newPoints[v] = 0.5*(localPoints[v1] + localPoints[v]);
|
||||||
|
|
||||||
Pout<< "Collapsing triange " << faceI << " to edge mid "
|
//Pout<< "Collapsing triange " << faceI
|
||||||
<< newPoints[v] << endl;
|
// << " to edge mid " << newPoints[v] << endl;
|
||||||
|
|
||||||
nCollapsed++;
|
nCollapsed++;
|
||||||
okToCollapse[faceI] = false;
|
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;
|
<< endl;
|
||||||
|
|
||||||
nTotalCollapsed += nCollapsed;
|
nTotalCollapsed += nCollapsed;
|
||||||
|
|||||||
@ -50,6 +50,7 @@ int main(int argc, char *argv[])
|
|||||||
argList::noParallel();
|
argList::noParallel();
|
||||||
argList::validArgs.append("surfaceFile");
|
argList::validArgs.append("surfaceFile");
|
||||||
argList::validArgs.append("min length");
|
argList::validArgs.append("min length");
|
||||||
|
argList::validArgs.append("min quality");
|
||||||
argList::validArgs.append("output surfaceFile");
|
argList::validArgs.append("output surfaceFile");
|
||||||
argList::addBoolOption
|
argList::addBoolOption
|
||||||
(
|
(
|
||||||
@ -60,10 +61,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
const fileName inFileName = args[1];
|
const fileName inFileName = args[1];
|
||||||
const scalar minLen = args.argRead<scalar>(2);
|
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
|
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;
|
<< "Writing result to " << outFileName << nl << endl;
|
||||||
|
|
||||||
|
|
||||||
@ -90,7 +94,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
label nSplitEdge = collapseBase(surf, minLen);
|
label nSplitEdge = collapseBase(surf, minLen, minQuality);
|
||||||
|
|
||||||
if (nSplitEdge == 0)
|
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
|
surfaceFeatureExtract.C
|
||||||
|
CGALPolyhedron/buildCGALPolyhedron.C
|
||||||
|
|
||||||
EXE = $(FOAM_APPBIN)/surfaceFeatureExtract
|
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_INC = \
|
||||||
|
${EXE_FROUNDING_MATH} \
|
||||||
|
${EXE_NDEBUG} \
|
||||||
|
${USE_F2C} \
|
||||||
|
${CGAL_INC} \
|
||||||
|
-ICGALPolyhedron \
|
||||||
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
-I$(LIB_SRC)/edgeMesh/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 = \
|
EXE_LIBS = \
|
||||||
|
$(CGAL_LIBS) \
|
||||||
|
-L$(CGAL_ARCH_PATH)/lib \
|
||||||
|
-llapack \
|
||||||
|
-lblas \
|
||||||
|
-lCGAL \
|
||||||
-lmeshTools \
|
-lmeshTools \
|
||||||
-ledgeMesh \
|
-ledgeMesh \
|
||||||
-ltriSurface
|
-ltriSurface \
|
||||||
|
-lsampling
|
||||||
|
|||||||
@ -40,7 +40,19 @@ Description
|
|||||||
#include "treeBoundBox.H"
|
#include "treeBoundBox.H"
|
||||||
#include "meshTools.H"
|
#include "meshTools.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
|
#include "triSurfaceMesh.H"
|
||||||
|
#include "vtkSurfaceWriter.H"
|
||||||
|
#include "triSurfaceFields.H"
|
||||||
#include "unitConversion.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;
|
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
|
// Unmark non-manifold edges if individual triangles are not features
|
||||||
void unmarkBaffles
|
void unmarkBaffles
|
||||||
(
|
(
|
||||||
@ -111,7 +318,7 @@ void unmarkBaffles
|
|||||||
{
|
{
|
||||||
label i0 = eFaces[0];
|
label i0 = eFaces[0];
|
||||||
//const labelledTri& f0 = surf[i0];
|
//const labelledTri& f0 = surf[i0];
|
||||||
const vector& n0 = surf.faceNormals()[i0];
|
const Foam::vector& n0 = surf.faceNormals()[i0];
|
||||||
|
|
||||||
//Pout<< "edge:" << edgeI << " n0:" << n0 << endl;
|
//Pout<< "edge:" << edgeI << " n0:" << n0 << endl;
|
||||||
|
|
||||||
@ -120,7 +327,7 @@ void unmarkBaffles
|
|||||||
for (label i = 1; i < eFaces.size(); i++)
|
for (label i = 1; i < eFaces.size(); i++)
|
||||||
{
|
{
|
||||||
//const labelledTri& f = surf[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;
|
//Pout<< " mag(n&n0): " << mag(n&n0) << endl;
|
||||||
|
|
||||||
@ -193,15 +400,63 @@ int main(int argc, char *argv[])
|
|||||||
"writeObj",
|
"writeObj",
|
||||||
"write extendedFeatureEdgeMesh obj files"
|
"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 "setRootCase.H"
|
||||||
# include "createTime.H"
|
# include "createTime.H"
|
||||||
|
|
||||||
Info<< "Feature line extraction is only valid on closed manifold surfaces."
|
bool writeVTK = args.optionFound("writeVTK");
|
||||||
<< endl;
|
|
||||||
|
|
||||||
bool writeObj = args.optionFound("writeObj");
|
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 surfFileName = args[1];
|
||||||
const fileName outFileName = args[2];
|
const fileName outFileName = args[2];
|
||||||
|
|
||||||
@ -221,6 +476,12 @@ int main(int argc, char *argv[])
|
|||||||
surf.writeStats(Info);
|
surf.writeStats(Info);
|
||||||
Info<< endl;
|
Info<< endl;
|
||||||
|
|
||||||
|
faceList faces(surf.size());
|
||||||
|
|
||||||
|
forAll(surf, fI)
|
||||||
|
{
|
||||||
|
faces[fI] = surf[fI].triFaceFace();
|
||||||
|
}
|
||||||
|
|
||||||
// Either construct features from surface&featureangle or read set.
|
// 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);
|
surfaceFeatures newSet(surf);
|
||||||
newSet.setFromStatus(edgeStat);
|
newSet.setFromStatus(edgeStat);
|
||||||
|
|
||||||
Info<< endl << "Writing trimmed features to " << outFileName << endl;
|
//Info<< endl << "Writing trimmed features to " << outFileName << endl;
|
||||||
newSet.write(outFileName);
|
//newSet.write(outFileName);
|
||||||
|
|
||||||
// Info<< endl << "Writing edge objs." << endl;
|
// Info<< endl << "Writing edge objs." << endl;
|
||||||
// newSet.writeObj("final");
|
// newSet.writeObj("final");
|
||||||
@ -397,6 +672,358 @@ int main(int argc, char *argv[])
|
|||||||
bfeMesh.regIOobject::write();
|
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;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
return 0;
|
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=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
|
# USER EDITABLE PART: Changes made here may be lost with the next upgrade
|
||||||
|
|||||||
@ -302,11 +302,13 @@ DebugSwitches
|
|||||||
ash 0;
|
ash 0;
|
||||||
atomizationModel 0;
|
atomizationModel 0;
|
||||||
attachDetach 0;
|
attachDetach 0;
|
||||||
|
autoDensity 0;
|
||||||
autoHexMeshDriver 0;
|
autoHexMeshDriver 0;
|
||||||
autoLayerDriver 0;
|
autoLayerDriver 0;
|
||||||
autoRefineDriver 0;
|
autoRefineDriver 0;
|
||||||
autoSnapDriver 0;
|
autoSnapDriver 0;
|
||||||
bC11H10 0;
|
bC11H10 0;
|
||||||
|
backgroundMeshDecomposition 0;
|
||||||
backward 0;
|
backward 0;
|
||||||
basePatch 0;
|
basePatch 0;
|
||||||
basicKinematicCloud 0;
|
basicKinematicCloud 0;
|
||||||
@ -345,6 +347,7 @@ DebugSwitches
|
|||||||
cellPointFace 0;
|
cellPointFace 0;
|
||||||
cellPointWeight 0;
|
cellPointWeight 0;
|
||||||
cellSet 0;
|
cellSet 0;
|
||||||
|
cellSizeControlSurfaces 0;
|
||||||
cellToCell 0;
|
cellToCell 0;
|
||||||
cellToFace 0;
|
cellToFace 0;
|
||||||
cellToPoint 0;
|
cellToPoint 0;
|
||||||
@ -406,7 +409,7 @@ DebugSwitches
|
|||||||
displacementLaplacian 0;
|
displacementLaplacian 0;
|
||||||
displacementSBRStress 0;
|
displacementSBRStress 0;
|
||||||
distanceSurface 0;
|
distanceSurface 0;
|
||||||
distribution 0;
|
Distribution 0;
|
||||||
downwind 0;
|
downwind 0;
|
||||||
dragModel 0;
|
dragModel 0;
|
||||||
duplicatePoints 0;
|
duplicatePoints 0;
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
setenv WM_PROJECT OpenFOAM
|
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
|
# 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 Type>
|
||||||
template <class CompareOp>
|
template <class CompareOp>
|
||||||
void Foam::indexedOctree<Type>::findNear
|
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
|
// Find node (as parent+octant) containing point
|
||||||
template <class Type>
|
template <class Type>
|
||||||
Foam::labelBits Foam::indexedOctree<Type>::findNode
|
Foam::labelBits Foam::indexedOctree<Type>::findNode
|
||||||
|
|||||||
@ -337,6 +337,16 @@ private:
|
|||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
//- Find all elements intersecting sphere.
|
||||||
|
void findSphere
|
||||||
|
(
|
||||||
|
const label nodeI,
|
||||||
|
const point& centre,
|
||||||
|
const scalar radiusSqr,
|
||||||
|
labelHashSet& elements
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
template <class CompareOp>
|
template <class CompareOp>
|
||||||
static void findNear
|
static void findNear
|
||||||
(
|
(
|
||||||
@ -565,6 +575,15 @@ public:
|
|||||||
// overlapping bounding box (i.e. all shapes not outside box)
|
// overlapping bounding box (i.e. all shapes not outside box)
|
||||||
labelList findBox(const treeBoundBox& bb) const;
|
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
|
//- Find deepest node (as parent+octant) containing point. Starts
|
||||||
// off from starting index in nodes_ (use 0 to start from top)
|
// off from starting index in nodes_ (use 0 to start from top)
|
||||||
// Use getNode and getOctant to extract info, or call findIndices.
|
// Use getNode and getOctant to extract info, or call findIndices.
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -295,6 +295,31 @@ Foam::polyMesh::polyMesh(const IOobject& io)
|
|||||||
neighbour_.write();
|
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.)
|
// Calculate topology for the patches (processor-processor comms etc.)
|
||||||
boundary_.updateMesh();
|
boundary_.updateMesh();
|
||||||
|
|
||||||
|
|||||||
@ -380,11 +380,11 @@ bool Foam::polyMeshTetDecomposition::checkFaceTets
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
const labelList& own = mesh.faceOwner();
|
const labelList& own = mesh.faceOwner();
|
||||||
const labelList& nei = mesh.faceNeighbour();
|
// const labelList& nei = mesh.faceNeighbour();
|
||||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||||
|
|
||||||
const vectorField& cc = mesh.cellCentres();
|
const vectorField& cc = mesh.cellCentres();
|
||||||
const vectorField& fc = mesh.faceCentres();
|
// const vectorField& fc = mesh.faceCentres();
|
||||||
|
|
||||||
// Calculate coupled cell centre
|
// Calculate coupled cell centre
|
||||||
pointField neiCc(mesh.nFaces() - mesh.nInternalFaces());
|
pointField neiCc(mesh.nFaces() - mesh.nInternalFaces());
|
||||||
@ -398,62 +398,62 @@ bool Foam::polyMeshTetDecomposition::checkFaceTets
|
|||||||
|
|
||||||
const faceList& fcs = mesh.faces();
|
const faceList& fcs = mesh.faces();
|
||||||
|
|
||||||
const pointField& p = mesh.points();
|
// const pointField& p = mesh.points();
|
||||||
|
|
||||||
label nErrorTets = 0;
|
label nErrorTets = 0;
|
||||||
|
|
||||||
forAll(fcs, faceI)
|
forAll(fcs, faceI)
|
||||||
{
|
{
|
||||||
const face& f = fcs[faceI];
|
// const face& f = fcs[faceI];
|
||||||
|
|
||||||
forAll(f, fPtI)
|
// forAll(f, fPtI)
|
||||||
{
|
// {
|
||||||
scalar tetQual = tetPointRef
|
// scalar tetQual = tetPointRef
|
||||||
(
|
// (
|
||||||
p[f[fPtI]],
|
// p[f[fPtI]],
|
||||||
p[f.nextLabel(fPtI)],
|
// p[f.nextLabel(fPtI)],
|
||||||
fc[faceI],
|
// fc[faceI],
|
||||||
cc[own[faceI]]
|
// cc[own[faceI]]
|
||||||
).quality();
|
// ).quality();
|
||||||
|
|
||||||
if (tetQual > -tol)
|
// if (tetQual > -tol)
|
||||||
{
|
// {
|
||||||
if (setPtr)
|
// if (setPtr)
|
||||||
{
|
// {
|
||||||
setPtr->insert(faceI);
|
// setPtr->insert(faceI);
|
||||||
}
|
// }
|
||||||
|
|
||||||
nErrorTets++;
|
// nErrorTets++;
|
||||||
break; // no need to check other tets
|
// break; // no need to check other tets
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (mesh.isInternalFace(faceI))
|
if (mesh.isInternalFace(faceI))
|
||||||
{
|
{
|
||||||
// Create the neighbour tet - it will have positive volume
|
// Create the neighbour tet - it will have positive volume
|
||||||
const face& f = fcs[faceI];
|
// const face& f = fcs[faceI];
|
||||||
|
|
||||||
forAll(f, fPtI)
|
// forAll(f, fPtI)
|
||||||
{
|
// {
|
||||||
scalar tetQual = tetPointRef
|
// scalar tetQual = tetPointRef
|
||||||
(
|
// (
|
||||||
p[f[fPtI]],
|
// p[f[fPtI]],
|
||||||
p[f.nextLabel(fPtI)],
|
// p[f.nextLabel(fPtI)],
|
||||||
fc[faceI],
|
// fc[faceI],
|
||||||
cc[nei[faceI]]
|
// cc[nei[faceI]]
|
||||||
).quality();
|
// ).quality();
|
||||||
|
|
||||||
if (tetQual < tol)
|
// if (tetQual < tol)
|
||||||
{
|
// {
|
||||||
if (setPtr)
|
// if (setPtr)
|
||||||
{
|
// {
|
||||||
setPtr->insert(faceI);
|
// setPtr->insert(faceI);
|
||||||
}
|
// }
|
||||||
|
|
||||||
nErrorTets++;
|
// nErrorTets++;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (findSharedBasePoint(mesh, faceI, tol, report) == -1)
|
if (findSharedBasePoint(mesh, faceI, tol, report) == -1)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -201,10 +201,34 @@ void Foam::processorPolyPatch::calcGeometry(PstreamBuffers& pBufs)
|
|||||||
boundaryMesh().mesh().time().path()
|
boundaryMesh().mesh().time().path()
|
||||||
/name()+"_faces.obj"
|
/name()+"_faces.obj"
|
||||||
);
|
);
|
||||||
Pout<< "processorPolyPatch::order : Writing my " << size()
|
|
||||||
|
Pout<< "processorPolyPatch::calcGeometry : Writing my "
|
||||||
|
<< size()
|
||||||
<< " faces to OBJ file " << nm << endl;
|
<< " faces to OBJ file " << nm << endl;
|
||||||
|
|
||||||
writeOBJ(nm, *this, points());
|
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
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"processorPolyPatch::calcGeometry()"
|
"processorPolyPatch::calcGeometry()"
|
||||||
|
|||||||
@ -496,6 +496,12 @@ public:
|
|||||||
const scalarField& cellVolumes() const;
|
const scalarField& cellVolumes() const;
|
||||||
const vectorField& faceAreas() const;
|
const vectorField& faceAreas() const;
|
||||||
|
|
||||||
|
// Override cell centres with supplied positions
|
||||||
|
void overrideCellCentres
|
||||||
|
(
|
||||||
|
const vectorField& cellCtrs
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
// Mesh motion
|
// Mesh motion
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,7 @@ Description
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "primitiveMesh.H"
|
#include "primitiveMesh.H"
|
||||||
|
#include "demandDrivenData.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * 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
|
// 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);
|
vector svHat = sv/(mag(sv) + VSMALL);
|
||||||
|
|
||||||
// Normalisation distance calculated as the approximate distance
|
// Normalisation distance calculated as the approximate distance
|
||||||
|
|||||||
@ -191,7 +191,7 @@ public:
|
|||||||
// - point : centre of sphere
|
// - point : centre of sphere
|
||||||
// - distance : radius of sphere
|
// - distance : radius of sphere
|
||||||
// - eligiblemiss: false
|
// - 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.
|
// whether point is inside: mag(pt - ctr) < (1+tol)*radius.
|
||||||
pointHit containmentSphere(const scalar tol) const;
|
pointHit containmentSphere(const scalar tol) const;
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -160,7 +160,15 @@ inline Foam::scalar Foam::triangle<Point, PointRef>::circumRadius() const
|
|||||||
template<class Point, class PointRef>
|
template<class Point, class PointRef>
|
||||||
inline Foam::scalar Foam::triangle<Point, PointRef>::quality() const
|
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)
|
forAll(points, octant)
|
||||||
{
|
{
|
||||||
points[octant] = corner(octant);
|
points[octant] = corner(octant);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tPts;
|
return tPts;
|
||||||
|
|||||||
@ -309,7 +309,6 @@ Foam::scalar Foam::polyMeshGeometry::calcSkewness
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Create the neighbour pyramid - it will have positive volume
|
|
||||||
bool Foam::polyMeshGeometry::checkFaceTet
|
bool Foam::polyMeshGeometry::checkFaceTet
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
@ -788,7 +787,7 @@ bool Foam::polyMeshGeometry::checkFaceTets
|
|||||||
// check whether decomposing each cell into tets results in
|
// check whether decomposing each cell into tets results in
|
||||||
// positive volume, non-flat tets
|
// positive volume, non-flat tets
|
||||||
const labelList& own = mesh.faceOwner();
|
const labelList& own = mesh.faceOwner();
|
||||||
const labelList& nei = mesh.faceNeighbour();
|
// const labelList& nei = mesh.faceNeighbour();
|
||||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||||
|
|
||||||
// Calculate coupled cell centre
|
// Calculate coupled cell centre
|
||||||
@ -803,48 +802,50 @@ bool Foam::polyMeshGeometry::checkFaceTets
|
|||||||
|
|
||||||
label nErrorTets = 0;
|
label nErrorTets = 0;
|
||||||
|
|
||||||
|
// bool tetError = false
|
||||||
|
|
||||||
forAll(checkFaces, i)
|
forAll(checkFaces, i)
|
||||||
{
|
{
|
||||||
label faceI = checkFaces[i];
|
label faceI = checkFaces[i];
|
||||||
|
|
||||||
// Create the owner pyramid - note: exchange cell and face centre
|
// Create the owner pyramid - note: exchange cell and face centre
|
||||||
// to get positive volume.
|
// to get positive volume.
|
||||||
bool tetError = checkFaceTet
|
// tetError = checkFaceTet
|
||||||
(
|
// (
|
||||||
mesh,
|
// mesh,
|
||||||
report,
|
// report,
|
||||||
minTetQuality,
|
// minTetQuality,
|
||||||
p,
|
// p,
|
||||||
faceI,
|
// faceI,
|
||||||
cellCentres[own[faceI]], // face centre
|
// cellCentres[own[faceI]], // face centre
|
||||||
faceCentres[faceI], // cell centre
|
// faceCentres[faceI], // cell centre
|
||||||
setPtr
|
// setPtr
|
||||||
);
|
// );
|
||||||
|
|
||||||
if (tetError)
|
// if (tetError)
|
||||||
{
|
// {
|
||||||
nErrorTets++;
|
// nErrorTets++;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (mesh.isInternalFace(faceI))
|
if (mesh.isInternalFace(faceI))
|
||||||
{
|
{
|
||||||
// Create the neighbour tets - they will have positive volume
|
// Create the neighbour tets - they will have positive volume
|
||||||
bool tetError = checkFaceTet
|
// tetError = checkFaceTet
|
||||||
(
|
// (
|
||||||
mesh,
|
// mesh,
|
||||||
report,
|
// report,
|
||||||
minTetQuality,
|
// minTetQuality,
|
||||||
p,
|
// p,
|
||||||
faceI,
|
// faceI,
|
||||||
faceCentres[faceI], // face centre
|
// faceCentres[faceI], // face centre
|
||||||
cellCentres[nei[faceI]], // cell centre
|
// cellCentres[nei[faceI]], // cell centre
|
||||||
setPtr
|
// setPtr
|
||||||
);
|
// );
|
||||||
|
|
||||||
if (tetError)
|
// if (tetError)
|
||||||
{
|
// {
|
||||||
nErrorTets++;
|
// nErrorTets++;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
@ -920,40 +921,40 @@ bool Foam::polyMeshGeometry::checkFaceTets
|
|||||||
label face0 = baffles[i].first();
|
label face0 = baffles[i].first();
|
||||||
label face1 = baffles[i].second();
|
label face1 = baffles[i].second();
|
||||||
|
|
||||||
bool tetError = checkFaceTet
|
// tetError = checkFaceTet
|
||||||
(
|
// (
|
||||||
mesh,
|
// mesh,
|
||||||
report,
|
// report,
|
||||||
minTetQuality,
|
// minTetQuality,
|
||||||
p,
|
// p,
|
||||||
face0,
|
// face0,
|
||||||
cellCentres[own[face0]], // face centre
|
// cellCentres[own[face0]], // face centre
|
||||||
faceCentres[face0], // cell centre
|
// faceCentres[face0], // cell centre
|
||||||
setPtr
|
// setPtr
|
||||||
);
|
// );
|
||||||
|
|
||||||
if (tetError)
|
// if (tetError)
|
||||||
{
|
// {
|
||||||
nErrorTets++;
|
// nErrorTets++;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Create the neighbour tets - they will have positive volume
|
// // Create the neighbour tets - they will have positive volume
|
||||||
tetError = checkFaceTet
|
// tetError = checkFaceTet
|
||||||
(
|
// (
|
||||||
mesh,
|
// mesh,
|
||||||
report,
|
// report,
|
||||||
minTetQuality,
|
// minTetQuality,
|
||||||
p,
|
// p,
|
||||||
face0,
|
// face0,
|
||||||
faceCentres[face0], // face centre
|
// faceCentres[face0], // face centre
|
||||||
cellCentres[own[face1]], // cell centre
|
// cellCentres[own[face1]], // cell centre
|
||||||
setPtr
|
// setPtr
|
||||||
);
|
// );
|
||||||
|
|
||||||
if (tetError)
|
// if (tetError)
|
||||||
{
|
// {
|
||||||
nErrorTets++;
|
// nErrorTets++;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -584,10 +584,7 @@ void Foam::InteractionLists<ParticleType>::buildInteractionLists()
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Find all cells intersecting extendedBb
|
// Find all cells intersecting extendedBb
|
||||||
labelList interactingElems
|
labelList interactingElems(allCellsTree.findBox(extendedBb));
|
||||||
(
|
|
||||||
allCellsTree.findBox(extendedBb)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Reserve space to avoid multiple resizing
|
// Reserve space to avoid multiple resizing
|
||||||
DynamicList<label> cellDIL(interactingElems.size());
|
DynamicList<label> cellDIL(interactingElems.size());
|
||||||
@ -660,10 +657,7 @@ void Foam::InteractionLists<ParticleType>::findExtendedProcBbsInRange
|
|||||||
|
|
||||||
if (procBb.overlaps(extendedReferredProcBb))
|
if (procBb.overlaps(extendedReferredProcBb))
|
||||||
{
|
{
|
||||||
tmpExtendedProcBbsInRange.append
|
tmpExtendedProcBbsInRange.append(extendedReferredProcBb);
|
||||||
(
|
|
||||||
extendedReferredProcBb
|
|
||||||
);
|
|
||||||
|
|
||||||
// Dummy index, there are no transforms, so there will
|
// Dummy index, there are no transforms, so there will
|
||||||
// be no resultant transform when this is decoded.
|
// be no resultant transform when this is decoded.
|
||||||
@ -903,7 +897,6 @@ void Foam::InteractionLists<ParticleType>::buildMap
|
|||||||
(
|
(
|
||||||
new mapDistribute
|
new mapDistribute
|
||||||
(
|
(
|
||||||
|
|
||||||
constructSize,
|
constructSize,
|
||||||
sendMap.xfer(),
|
sendMap.xfer(),
|
||||||
constructMap.xfer()
|
constructMap.xfer()
|
||||||
@ -921,7 +914,6 @@ void Foam::InteractionLists<ParticleType>::prepareParticlesToRefer
|
|||||||
const globalIndexAndTransform& globalTransforms =
|
const globalIndexAndTransform& globalTransforms =
|
||||||
mesh_.globalData().globalTransforms();
|
mesh_.globalData().globalTransforms();
|
||||||
|
|
||||||
|
|
||||||
referredParticles_.setSize(cellIndexAndTransformToDistribute_.size());
|
referredParticles_.setSize(cellIndexAndTransformToDistribute_.size());
|
||||||
|
|
||||||
// Clear all existing referred particles
|
// Clear all existing referred particles
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
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
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -6,4 +6,3 @@
|
|||||||
#include "distribution.H"
|
#include "distribution.H"
|
||||||
#include "reducedUnits.H"
|
#include "reducedUnits.H"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
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