Add the OpenFOAM source tree
This commit is contained in:
3
applications/utilities/mesh/advanced/PDRMesh/Make/files
Normal file
3
applications/utilities/mesh/advanced/PDRMesh/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
PDRMesh.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/PDRMesh
|
||||
10
applications/utilities/mesh/advanced/PDRMesh/Make/options
Normal file
10
applications/utilities/mesh/advanced/PDRMesh/Make/options
Normal file
@ -0,0 +1,10 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools \
|
||||
-ldynamicMesh \
|
||||
-lfiniteVolume \
|
||||
-lcompressibleRASModels
|
||||
1182
applications/utilities/mesh/advanced/PDRMesh/PDRMesh.C
Normal file
1182
applications/utilities/mesh/advanced/PDRMesh/PDRMesh.C
Normal file
File diff suppressed because it is too large
Load Diff
37
applications/utilities/mesh/advanced/PDRMesh/PDRMeshDict
Normal file
37
applications/utilities/mesh/advanced/PDRMesh/PDRMeshDict
Normal file
@ -0,0 +1,37 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: dev |
|
||||
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object PDRMeshDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Per faceSet the patch the faces should go into blocked baffles
|
||||
blockedFaces ((blockedFacesSet blockedFaces));
|
||||
|
||||
//- Per faceSet the patch the faces should go into coupled baffles
|
||||
coupledFaces
|
||||
{
|
||||
coupledFacesSet
|
||||
{
|
||||
wallPatchName baffleWall;
|
||||
cyclicMasterPatchName baffleCyclic_half0;
|
||||
}
|
||||
}
|
||||
|
||||
//- Name of cellSet that holds the cells to fully remove
|
||||
blockedCells blockedCellsSet;
|
||||
|
||||
//- All exposed faces that are not specified in blockedFaces go into
|
||||
// this patch
|
||||
defaultPatch outer;
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,4 @@
|
||||
autoRefineMesh.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/autoRefineMesh
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-ldynamicMesh \
|
||||
-lmeshTools \
|
||||
-ltriSurface \
|
||||
-llagrangian
|
||||
1006
applications/utilities/mesh/advanced/autoRefineMesh/autoRefineMesh.C
Normal file
1006
applications/utilities/mesh/advanced/autoRefineMesh/autoRefineMesh.C
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,112 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: dev |
|
||||
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object autoRefineMeshDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Surface to keep to
|
||||
surface "plexi.obj";
|
||||
|
||||
// What is outside. These points have to be inside a cell (so not on a face!)
|
||||
outsidePoints ((-0.99001 -0.99001 -0.99001));
|
||||
|
||||
//
|
||||
// Selection of cells to refine
|
||||
//
|
||||
|
||||
// If smallest edge of mesh > maxEdgeLen select all cut cells for refinement.
|
||||
// If < maxEdgeLen select only those cut cells which are closer than
|
||||
// curvatureDistance to surface
|
||||
// and with cos of angle between normals on surface < curvature.
|
||||
maxEdgeLen 0.1;
|
||||
curvatureDistance 1.0;
|
||||
curvature 0.9;
|
||||
|
||||
// if > 0: Remove inside cells at every step. Inside is given by number of
|
||||
// layers separating outside from inside.
|
||||
// (note that we cannot remove outside
|
||||
// cells since these contain the outsidePoints)
|
||||
// Do not use this option if you want mesh to spill through a hole which is
|
||||
// not visible on the coarsest level but only becomes visible after refinement
|
||||
nCutLayers 2;
|
||||
|
||||
// Refine until smallest edge of mesh < minEdgeLen
|
||||
minEdgeLen 0.1;
|
||||
|
||||
// Or until the number of cells would become more than (stops one level before
|
||||
// this)
|
||||
cellLimit 2500000;
|
||||
|
||||
//
|
||||
// Selection of final set
|
||||
//
|
||||
|
||||
// Select based on side of surface. Usually select inside cells and project
|
||||
// outwards or select outside cells and project inwards.
|
||||
selectCut false;
|
||||
selectInside false;
|
||||
selectOutside true;
|
||||
// Leave out cell closer than nearDistance to the surface. Usually
|
||||
// 0.5*minEdgeLen. Set to -1 to disable.
|
||||
nearDistance -1;
|
||||
|
||||
// Some cells on the surface of the selected cells might have all their
|
||||
// points on the 'outside'. These would get flattened when projecting so
|
||||
// are either kept and refined (selectHanging) or removed from the set
|
||||
selectHanging false;
|
||||
|
||||
//
|
||||
// Refinement parameters
|
||||
//
|
||||
|
||||
// Type of coordinate system
|
||||
coordinateSystem global;
|
||||
//coordinateSystem patchLocal;
|
||||
|
||||
// .. and its coefficients. x,y in this case. (normal = tan1^tan2)
|
||||
globalCoeffs
|
||||
{
|
||||
tan1 (1 0 0);
|
||||
tan2 (0 1 0);
|
||||
}
|
||||
|
||||
patchLocalCoeffs
|
||||
{
|
||||
patch outside; // Normal direction is facenormal of zero'th face of patch
|
||||
tan1 (1 0 0);
|
||||
|
||||
}
|
||||
|
||||
// List of directions to refine
|
||||
directions
|
||||
(
|
||||
tan1
|
||||
tan2
|
||||
normal
|
||||
);
|
||||
|
||||
// refinement level difference between neighbouring cells. Set to large if
|
||||
// there is no need for a limit.
|
||||
splitLevel 2;
|
||||
|
||||
// Cut purely geometric (will cut hexes through vertices) or take topology
|
||||
// into account.
|
||||
geometricCut false;
|
||||
|
||||
// Whether to use hex topology. This will never cut hex through vertices.
|
||||
useHexTopology yes;
|
||||
|
||||
// Write meshes from intermediate steps
|
||||
writeMesh true;
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
collapseEdges.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/collapseEdges
|
||||
@ -0,0 +1,9 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-ldynamicMesh \
|
||||
-lmeshTools \
|
||||
-lfiniteVolume
|
||||
@ -0,0 +1,97 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: dev |
|
||||
| \\ / A nd | Web: http://www.openfoam.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
|
||||
root "";
|
||||
case "";
|
||||
instance "";
|
||||
local "";
|
||||
|
||||
class dictionary;
|
||||
object collapseDict;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// If on, after collapsing check the quality of the mesh. If bad faces are
|
||||
// generated then redo the collapsing with stricter filtering.
|
||||
controlMeshQuality on;
|
||||
|
||||
|
||||
collapseEdgesCoeffs
|
||||
{
|
||||
// Edges shorter than this absolute value will be merged
|
||||
minimumEdgeLength 1e-6;
|
||||
|
||||
// The maximum angle between two edges that share a point attached to
|
||||
// no other edges
|
||||
maximumMergeAngle 30;
|
||||
}
|
||||
|
||||
|
||||
collapseFacesCoeffs
|
||||
{
|
||||
// The initial face length factor
|
||||
initialFaceLengthFactor 0.5;
|
||||
|
||||
// If the face can't be collapsed to an edge, and it has a span less than
|
||||
// the target face length multiplied by this coefficient, collapse it
|
||||
// to a point.
|
||||
maxCollapseFaceToPointSideLengthCoeff 0.3;
|
||||
|
||||
// Allow early collapse of edges to a point
|
||||
allowEarlyCollapseToPoint on;
|
||||
|
||||
// Fraction to premultiply maxCollapseFaceToPointSideLengthCoeff by if
|
||||
// allowEarlyCollapseToPoint is enabled
|
||||
allowEarlyCollapseCoeff 0.2;
|
||||
|
||||
// Defining how close to the midpoint (M) of the projected
|
||||
// vertices line a projected vertex (X) can be before making this
|
||||
// an invalid edge collapse
|
||||
//
|
||||
// X---X-g----------------M----X-----------g----X--X
|
||||
//
|
||||
// Only allow a collapse if all projected vertices are outwith
|
||||
// guardFraction (g) of the distance form the face centre to the
|
||||
// furthest vertex in the considered direction
|
||||
guardFraction 0.1;
|
||||
}
|
||||
|
||||
|
||||
controlMeshQualityCoeffs
|
||||
{
|
||||
// Name of the dictionary that has the mesh quality coefficients used
|
||||
// by motionSmoother::checkMesh
|
||||
#include "meshQualityDict";
|
||||
|
||||
// The amount that minimumEdgeLength will be reduced by for each
|
||||
// edge if that edge's collapse generates a poor quality face
|
||||
edgeReductionFactor 0.5;
|
||||
|
||||
// The amount that initialFaceLengthFactor will be reduced by for each
|
||||
// face if its collapse generates a poor quality face
|
||||
faceReductionFactor 0.5;
|
||||
|
||||
// Maximum number of smoothing iterations for the reductionFactors
|
||||
maximumSmoothingIterations 2;
|
||||
|
||||
// Maximum number of outer iterations is mesh quality checking is enabled
|
||||
maximumIterations 10;
|
||||
|
||||
// Maximum number of iterations deletion of a point can cause a bad face
|
||||
// to be constructed before it is forced to not be deleted
|
||||
maxPointErrorCount 5;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,247 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
collapseEdges
|
||||
|
||||
Description
|
||||
Collapses short edges and combines edges that are in line.
|
||||
|
||||
- collapse short edges. Length of edges to collapse provided as argument.
|
||||
- merge two edges if they are in line. Maximum angle provided as argument.
|
||||
- remove unused points.
|
||||
- collapse faces:
|
||||
- with small areas to a single point
|
||||
- that have a high aspect ratio (i.e. sliver face) to a single edge
|
||||
|
||||
Optionally checks the resulting mesh for bad faces and reduces the desired
|
||||
face length factor for those faces attached to the bad faces.
|
||||
|
||||
When collapsing an edge with one point on the boundary it will leave
|
||||
the boundary point intact. When both points inside it chooses random. When
|
||||
both points on boundary random again.
|
||||
|
||||
Usage
|
||||
- collapseEdges [OPTION]
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "timeSelector.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "fvMesh.H"
|
||||
#include "polyMeshFilter.H"
|
||||
#include "faceSet.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
timeSelector::addOptions(true, false);
|
||||
argList::addNote
|
||||
(
|
||||
"Collapses small edges to a point.\n"
|
||||
"Optionally collapse small faces to a point and thin faces to an edge."
|
||||
);
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
"collapseFaces",
|
||||
"Collapse small and sliver faces as well as small edges"
|
||||
);
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"collapseFaceSet",
|
||||
"faceSet",
|
||||
"Collapse faces that are in the supplied face set"
|
||||
);
|
||||
|
||||
# include "addOverwriteOption.H"
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
|
||||
runTime.functionObjects().off();
|
||||
instantList timeDirs = timeSelector::selectIfPresent(runTime, args);
|
||||
|
||||
# include "createMesh.H"
|
||||
|
||||
const word oldInstance = mesh.pointsInstance();
|
||||
|
||||
const bool overwrite = args.optionFound("overwrite");
|
||||
|
||||
const bool collapseFaces = args.optionFound("collapseFaces");
|
||||
const bool collapseFaceSet = args.optionFound("collapseFaceSet");
|
||||
|
||||
if (collapseFaces && collapseFaceSet)
|
||||
{
|
||||
FatalErrorIn("main(int, char*[])")
|
||||
<< "Both face zone collapsing and face collapsing have been"
|
||||
<< "selected. Choose only one of:" << nl
|
||||
<< " -collapseFaces" << nl
|
||||
<< " -collapseFaceSet <faceSet>"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
|
||||
// maintain indirectPatchFaces if it is there (default) or force
|
||||
// (if collapseFaceSet option provided)
|
||||
word faceSetName("indirectPatchFaces");
|
||||
IOobject::readOption readFlag = IOobject::READ_IF_PRESENT;
|
||||
|
||||
if (args.optionReadIfPresent("collapseFaceSet", faceSetName))
|
||||
{
|
||||
readFlag = IOobject::MUST_READ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
labelIOList pointPriority
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"pointPriority",
|
||||
runTime.timeName(),
|
||||
runTime,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
labelList(mesh.nPoints(), labelMin)
|
||||
);
|
||||
forAll(timeDirs, timeI)
|
||||
{
|
||||
runTime.setTime(timeDirs[timeI], timeI);
|
||||
|
||||
Info<< "Time = " << runTime.timeName() << endl;
|
||||
|
||||
autoPtr<polyMeshFilter> meshFilterPtr;
|
||||
|
||||
label nBadFaces = 0;
|
||||
|
||||
faceSet indirectPatchFaces
|
||||
(
|
||||
mesh,
|
||||
faceSetName,
|
||||
readFlag,
|
||||
IOobject::AUTO_WRITE
|
||||
);
|
||||
Info<< "Read faceSet " << indirectPatchFaces.name()
|
||||
<< " with "
|
||||
<< returnReduce(indirectPatchFaces.size(), sumOp<label>())
|
||||
<< " faces" << endl;
|
||||
|
||||
|
||||
{
|
||||
meshFilterPtr.set(new polyMeshFilter(mesh, pointPriority));
|
||||
polyMeshFilter& meshFilter = meshFilterPtr();
|
||||
|
||||
// newMesh will be empty until it is filtered
|
||||
const autoPtr<fvMesh>& newMesh = meshFilter.filteredMesh();
|
||||
|
||||
// Filter small edges only. This reduces the number of faces so that
|
||||
// the face filtering is sped up.
|
||||
nBadFaces = meshFilter.filterEdges(0);
|
||||
{
|
||||
polyTopoChange meshMod(newMesh());
|
||||
|
||||
meshMod.changeMesh(mesh, false);
|
||||
|
||||
polyMeshFilter::copySets(newMesh(), mesh);
|
||||
}
|
||||
|
||||
pointPriority = meshFilter.pointPriority();
|
||||
}
|
||||
|
||||
if (collapseFaceSet)
|
||||
{
|
||||
meshFilterPtr.reset(new polyMeshFilter(mesh, pointPriority));
|
||||
polyMeshFilter& meshFilter = meshFilterPtr();
|
||||
|
||||
const autoPtr<fvMesh>& newMesh = meshFilter.filteredMesh();
|
||||
|
||||
// Filter faces. Pass in the number of bad faces that are present
|
||||
// from the previous edge filtering to use as a stopping criterion.
|
||||
meshFilter.filter(indirectPatchFaces);
|
||||
{
|
||||
polyTopoChange meshMod(newMesh);
|
||||
|
||||
meshMod.changeMesh(mesh, false);
|
||||
|
||||
polyMeshFilter::copySets(newMesh(), mesh);
|
||||
}
|
||||
|
||||
pointPriority = meshFilter.pointPriority();
|
||||
}
|
||||
|
||||
if (collapseFaces)
|
||||
{
|
||||
meshFilterPtr.reset(new polyMeshFilter(mesh, pointPriority));
|
||||
polyMeshFilter& meshFilter = meshFilterPtr();
|
||||
|
||||
const autoPtr<fvMesh>& newMesh = meshFilter.filteredMesh();
|
||||
|
||||
// Filter faces. Pass in the number of bad faces that are present
|
||||
// from the previous edge filtering to use as a stopping criterion.
|
||||
meshFilter.filter(nBadFaces);
|
||||
{
|
||||
polyTopoChange meshMod(newMesh);
|
||||
|
||||
meshMod.changeMesh(mesh, false);
|
||||
|
||||
polyMeshFilter::copySets(newMesh(), mesh);
|
||||
}
|
||||
|
||||
pointPriority = meshFilter.pointPriority();
|
||||
}
|
||||
|
||||
// Write resulting mesh
|
||||
if (!overwrite)
|
||||
{
|
||||
runTime++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh.setInstance(oldInstance);
|
||||
}
|
||||
|
||||
Info<< nl << "Writing collapsed mesh to time "
|
||||
<< runTime.timeName() << nl << endl;
|
||||
|
||||
mesh.write();
|
||||
pointPriority.write();
|
||||
}
|
||||
|
||||
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,67 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: dev |
|
||||
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object meshQualityDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Maximum non-orthogonality allowed. Set to 180 to disable.
|
||||
maxNonOrtho 65;
|
||||
|
||||
//- Max skewness allowed. Set to <0 to disable.
|
||||
maxBoundarySkewness 50;
|
||||
|
||||
//- Max skewness allowed. Set to <0 to disable.
|
||||
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 1e-20;
|
||||
|
||||
//- Minimum quality of the tet formed by the face-centre
|
||||
// and variable base point minimum decomposition triangles and
|
||||
// the cell centre. 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 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.0;
|
||||
|
||||
//- 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;
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,4 @@
|
||||
combinePatchFaces.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/combinePatchFaces
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-ldynamicMesh
|
||||
@ -0,0 +1,462 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
combinePatchFaces
|
||||
|
||||
Description
|
||||
Checks for multiple patch faces on same cell and combines them.
|
||||
Multiple patch faces can result from e.g. removal of refined
|
||||
neighbouring cells, leaving 4 exposed faces with same owner.
|
||||
|
||||
Rules for merging:
|
||||
- only boundary faces (since multiple internal faces between two cells
|
||||
not allowed anyway)
|
||||
- faces have to have same owner
|
||||
- faces have to be connected via edge which are not features (so angle
|
||||
between them < feature angle)
|
||||
- outside of faces has to be single loop
|
||||
- outside of face should not be (or just slightly) concave (so angle
|
||||
between consecutive edges < concaveangle
|
||||
|
||||
E.g. to allow all faces on same patch to be merged:
|
||||
|
||||
combinePatchFaces 180 -concaveAngle 90
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "PstreamReduceOps.H"
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "polyModifyFace.H"
|
||||
#include "polyAddFace.H"
|
||||
#include "combineFaces.H"
|
||||
#include "removePoints.H"
|
||||
#include "polyMesh.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "unitConversion.H"
|
||||
#include "motionSmoother.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Merge faces on the same patch (usually from exposing refinement)
|
||||
// Can undo merges if these cause problems.
|
||||
label mergePatchFaces
|
||||
(
|
||||
const scalar minCos,
|
||||
const scalar concaveSin,
|
||||
const autoPtr<IOdictionary>& qualDictPtr,
|
||||
const Time& runTime,
|
||||
polyMesh& mesh
|
||||
)
|
||||
{
|
||||
// Patch face merging engine
|
||||
combineFaces faceCombiner(mesh);
|
||||
|
||||
// Get all sets of faces that can be merged
|
||||
labelListList allFaceSets(faceCombiner.getMergeSets(minCos, concaveSin));
|
||||
|
||||
label nFaceSets = returnReduce(allFaceSets.size(), sumOp<label>());
|
||||
|
||||
Info<< "Merging " << nFaceSets << " sets of faces." << endl;
|
||||
|
||||
if (nFaceSets > 0)
|
||||
{
|
||||
// Store the faces of the face sets
|
||||
List<faceList> allFaceSetsFaces(allFaceSets.size());
|
||||
forAll(allFaceSets, setI)
|
||||
{
|
||||
allFaceSetsFaces[setI] = UIndirectList<face>
|
||||
(
|
||||
mesh.faces(),
|
||||
allFaceSets[setI]
|
||||
);
|
||||
}
|
||||
|
||||
autoPtr<mapPolyMesh> map;
|
||||
{
|
||||
// Topology changes container
|
||||
polyTopoChange meshMod(mesh);
|
||||
|
||||
// Merge all faces of a set into the first face of the set.
|
||||
faceCombiner.setRefinement(allFaceSets, meshMod);
|
||||
|
||||
// Change the mesh (no inflation)
|
||||
map = meshMod.changeMesh(mesh, false, true);
|
||||
|
||||
// Update fields
|
||||
mesh.updateMesh(map);
|
||||
|
||||
// Move mesh (since morphing does not do this)
|
||||
if (map().hasMotionPoints())
|
||||
{
|
||||
mesh.movePoints(map().preMotionPoints());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delete mesh volumes. No other way to do this?
|
||||
mesh.clearOut();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check for errors and undo
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// Faces in error.
|
||||
labelHashSet errorFaces;
|
||||
|
||||
if (qualDictPtr.valid())
|
||||
{
|
||||
motionSmoother::checkMesh(false, mesh, qualDictPtr(), errorFaces);
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh.checkFacePyramids(false, -SMALL, &errorFaces);
|
||||
}
|
||||
|
||||
// Sets where the master is in error
|
||||
labelHashSet errorSets;
|
||||
|
||||
forAll(allFaceSets, setI)
|
||||
{
|
||||
label newMasterI = map().reverseFaceMap()[allFaceSets[setI][0]];
|
||||
|
||||
if (errorFaces.found(newMasterI))
|
||||
{
|
||||
errorSets.insert(setI);
|
||||
}
|
||||
}
|
||||
label nErrorSets = returnReduce(errorSets.size(), sumOp<label>());
|
||||
|
||||
Info<< "Detected " << nErrorSets
|
||||
<< " error faces on boundaries that have been merged."
|
||||
<< " These will be restored to their original faces."
|
||||
<< endl;
|
||||
|
||||
if (nErrorSets > 0)
|
||||
{
|
||||
// Renumber stored faces to new vertex numbering.
|
||||
forAllConstIter(labelHashSet, errorSets, iter)
|
||||
{
|
||||
label setI = iter.key();
|
||||
|
||||
faceList& setFaceVerts = allFaceSetsFaces[setI];
|
||||
|
||||
forAll(setFaceVerts, i)
|
||||
{
|
||||
inplaceRenumber(map().reversePointMap(), setFaceVerts[i]);
|
||||
|
||||
// Debug: check that all points are still there.
|
||||
forAll(setFaceVerts[i], j)
|
||||
{
|
||||
label newVertI = setFaceVerts[i][j];
|
||||
|
||||
if (newVertI < 0)
|
||||
{
|
||||
FatalErrorIn("mergePatchFaces")
|
||||
<< "In set:" << setI << " old face labels:"
|
||||
<< allFaceSets[setI] << " new face vertices:"
|
||||
<< setFaceVerts[i] << " are unmapped vertices!"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Topology changes container
|
||||
polyTopoChange meshMod(mesh);
|
||||
|
||||
|
||||
// Restore faces
|
||||
forAllConstIter(labelHashSet, errorSets, iter)
|
||||
{
|
||||
label setI = iter.key();
|
||||
|
||||
const labelList& setFaces = allFaceSets[setI];
|
||||
const faceList& setFaceVerts = allFaceSetsFaces[setI];
|
||||
|
||||
label newMasterI = map().reverseFaceMap()[setFaces[0]];
|
||||
|
||||
// Restore. Get face properties.
|
||||
|
||||
label own = mesh.faceOwner()[newMasterI];
|
||||
label zoneID = mesh.faceZones().whichZone(newMasterI);
|
||||
bool zoneFlip = false;
|
||||
if (zoneID >= 0)
|
||||
{
|
||||
const faceZone& fZone = mesh.faceZones()[zoneID];
|
||||
zoneFlip = fZone.flipMap()[fZone.whichFace(newMasterI)];
|
||||
}
|
||||
label patchID = mesh.boundaryMesh().whichPatch(newMasterI);
|
||||
|
||||
Pout<< "Restoring new master face " << newMasterI
|
||||
<< " to vertices " << setFaceVerts[0] << endl;
|
||||
|
||||
// Modify the master face.
|
||||
meshMod.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
setFaceVerts[0], // original face
|
||||
newMasterI, // label of face
|
||||
own, // owner
|
||||
-1, // neighbour
|
||||
false, // face flip
|
||||
patchID, // patch for face
|
||||
false, // remove from zone
|
||||
zoneID, // zone for face
|
||||
zoneFlip // face flip in zone
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// Add the previously removed faces
|
||||
for (label i = 1; i < setFaces.size(); i++)
|
||||
{
|
||||
Pout<< "Restoring removed face " << setFaces[i]
|
||||
<< " with vertices " << setFaceVerts[i] << endl;
|
||||
|
||||
meshMod.setAction
|
||||
(
|
||||
polyAddFace
|
||||
(
|
||||
setFaceVerts[i], // vertices
|
||||
own, // owner,
|
||||
-1, // neighbour,
|
||||
-1, // masterPointID,
|
||||
-1, // masterEdgeID,
|
||||
newMasterI, // masterFaceID,
|
||||
false, // flipFaceFlux,
|
||||
patchID, // patchID,
|
||||
zoneID, // zoneID,
|
||||
zoneFlip // zoneFlip
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Change the mesh (no inflation)
|
||||
map = meshMod.changeMesh(mesh, false, true);
|
||||
|
||||
// Update fields
|
||||
mesh.updateMesh(map);
|
||||
|
||||
// Move mesh (since morphing does not do this)
|
||||
if (map().hasMotionPoints())
|
||||
{
|
||||
mesh.movePoints(map().preMotionPoints());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delete mesh volumes. No other way to do this?
|
||||
mesh.clearOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "No faces merged ..." << endl;
|
||||
}
|
||||
|
||||
return nFaceSets;
|
||||
}
|
||||
|
||||
|
||||
// Remove points not used by any face or points used by only two faces where
|
||||
// the edges are in line
|
||||
label mergeEdges(const scalar minCos, polyMesh& mesh)
|
||||
{
|
||||
Info<< "Merging all points on surface that" << nl
|
||||
<< "- are used by only two boundary faces and" << nl
|
||||
<< "- make an angle with a cosine of more than " << minCos
|
||||
<< "." << nl << endl;
|
||||
|
||||
// Point removal analysis engine
|
||||
removePoints pointRemover(mesh);
|
||||
|
||||
// Count usage of points
|
||||
boolList pointCanBeDeleted;
|
||||
label nRemove = pointRemover.countPointUsage(minCos, pointCanBeDeleted);
|
||||
|
||||
if (nRemove > 0)
|
||||
{
|
||||
Info<< "Removing " << nRemove
|
||||
<< " straight edge points ..." << endl;
|
||||
|
||||
// Topology changes container
|
||||
polyTopoChange meshMod(mesh);
|
||||
|
||||
pointRemover.setRefinement(pointCanBeDeleted, meshMod);
|
||||
|
||||
// Change the mesh (no inflation)
|
||||
autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false, true);
|
||||
|
||||
// Update fields
|
||||
mesh.updateMesh(map);
|
||||
|
||||
// Move mesh (since morphing does not do this)
|
||||
if (map().hasMotionPoints())
|
||||
{
|
||||
mesh.movePoints(map().preMotionPoints());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delete mesh volumes. No other way to do this?
|
||||
mesh.clearOut();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "No straight edges simplified and no points removed ..." << endl;
|
||||
}
|
||||
|
||||
return nRemove;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
# include "addOverwriteOption.H"
|
||||
|
||||
argList::validArgs.append("featureAngle [0..180]");
|
||||
argList::addOption
|
||||
(
|
||||
"concaveAngle",
|
||||
"degrees",
|
||||
"specify concave angle [0..180] (default: 30 degrees)"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"meshQuality",
|
||||
"read user-defined mesh quality criterions from system/meshQualityDict"
|
||||
);
|
||||
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
runTime.functionObjects().off();
|
||||
# include "createPolyMesh.H"
|
||||
const word oldInstance = mesh.pointsInstance();
|
||||
|
||||
const scalar featureAngle = args.argRead<scalar>(1);
|
||||
const scalar minCos = Foam::cos(degToRad(featureAngle));
|
||||
|
||||
// Sin of angle between two consecutive edges on a face.
|
||||
// If sin(angle) larger than this the face will be considered concave.
|
||||
scalar concaveAngle = args.optionLookupOrDefault("concaveAngle", 30.0);
|
||||
scalar concaveSin = Foam::sin(degToRad(concaveAngle));
|
||||
|
||||
const bool overwrite = args.optionFound("overwrite");
|
||||
const bool meshQuality = args.optionFound("meshQuality");
|
||||
|
||||
Info<< "Merging all faces of a cell" << nl
|
||||
<< " - which are on the same patch" << nl
|
||||
<< " - which make an angle < " << featureAngle << " degrees"
|
||||
<< nl
|
||||
<< " (cos:" << minCos << ')' << nl
|
||||
<< " - even when resulting face becomes concave by more than "
|
||||
<< concaveAngle << " degrees" << nl
|
||||
<< " (sin:" << concaveSin << ')' << nl
|
||||
<< endl;
|
||||
|
||||
autoPtr<IOdictionary> qualDict;
|
||||
if (meshQuality)
|
||||
{
|
||||
Info<< "Enabling user-defined geometry checks." << nl << endl;
|
||||
|
||||
qualDict.reset
|
||||
(
|
||||
new IOdictionary
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"meshQualityDict",
|
||||
mesh.time().system(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (!overwrite)
|
||||
{
|
||||
runTime++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Merge faces on same patch
|
||||
label nChanged = mergePatchFaces
|
||||
(
|
||||
minCos,
|
||||
concaveSin,
|
||||
qualDict,
|
||||
runTime,
|
||||
mesh
|
||||
);
|
||||
|
||||
// Merge points on straight edges and remove unused points
|
||||
if (qualDict.valid())
|
||||
{
|
||||
Info<< "Merging all 'loose' points on surface edges, "
|
||||
<< "regardless of the angle they make." << endl;
|
||||
|
||||
// Surface bnound to be used to extrude. Merge all loose points.
|
||||
nChanged += mergeEdges(-1, mesh);
|
||||
}
|
||||
else
|
||||
{
|
||||
nChanged += mergeEdges(minCos, mesh);
|
||||
}
|
||||
|
||||
if (nChanged > 0)
|
||||
{
|
||||
if (overwrite)
|
||||
{
|
||||
mesh.setInstance(oldInstance);
|
||||
}
|
||||
|
||||
Info<< "Writing morphed mesh to time " << runTime.timeName() << endl;
|
||||
|
||||
mesh.write();
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Mesh unchanged." << endl;
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,4 @@
|
||||
cellSplitter.C
|
||||
modifyMesh.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/modifyMesh
|
||||
@ -0,0 +1,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools \
|
||||
-ldynamicMesh
|
||||
491
applications/utilities/mesh/advanced/modifyMesh/cellSplitter.C
Normal file
491
applications/utilities/mesh/advanced/modifyMesh/cellSplitter.C
Normal file
@ -0,0 +1,491 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ 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 "cellSplitter.H"
|
||||
#include "polyMesh.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "polyAddCell.H"
|
||||
#include "polyAddFace.H"
|
||||
#include "polyAddPoint.H"
|
||||
#include "polyModifyFace.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "meshTools.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(cellSplitter, 0);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::cellSplitter::getFaceInfo
|
||||
(
|
||||
const label faceI,
|
||||
label& patchID,
|
||||
label& zoneID,
|
||||
label& zoneFlip
|
||||
) const
|
||||
{
|
||||
patchID = -1;
|
||||
|
||||
if (!mesh_.isInternalFace(faceI))
|
||||
{
|
||||
patchID = mesh_.boundaryMesh().whichPatch(faceI);
|
||||
}
|
||||
|
||||
zoneID = mesh_.faceZones().whichZone(faceI);
|
||||
|
||||
zoneFlip = false;
|
||||
|
||||
if (zoneID >= 0)
|
||||
{
|
||||
const faceZone& fZone = mesh_.faceZones()[zoneID];
|
||||
|
||||
zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Find the new owner of faceI (since the original cell has been split into
|
||||
// newCells
|
||||
Foam::label Foam::cellSplitter::newOwner
|
||||
(
|
||||
const label faceI,
|
||||
const Map<labelList>& cellToCells
|
||||
) const
|
||||
{
|
||||
label oldOwn = mesh_.faceOwner()[faceI];
|
||||
|
||||
Map<labelList>::const_iterator fnd = cellToCells.find(oldOwn);
|
||||
|
||||
if (fnd == cellToCells.end())
|
||||
{
|
||||
// Unsplit cell
|
||||
return oldOwn;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Look up index of face in the cells' faces.
|
||||
|
||||
const labelList& newCells = fnd();
|
||||
|
||||
const cell& cFaces = mesh_.cells()[oldOwn];
|
||||
|
||||
return newCells[findIndex(cFaces, faceI)];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::cellSplitter::newNeighbour
|
||||
(
|
||||
const label faceI,
|
||||
const Map<labelList>& cellToCells
|
||||
) const
|
||||
{
|
||||
label oldNbr = mesh_.faceNeighbour()[faceI];
|
||||
|
||||
Map<labelList>::const_iterator fnd = cellToCells.find(oldNbr);
|
||||
|
||||
if (fnd == cellToCells.end())
|
||||
{
|
||||
// Unsplit cell
|
||||
return oldNbr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Look up index of face in the cells' faces.
|
||||
|
||||
const labelList& newCells = fnd();
|
||||
|
||||
const cell& cFaces = mesh_.cells()[oldNbr];
|
||||
|
||||
return newCells[findIndex(cFaces, faceI)];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
// Construct from components
|
||||
Foam::cellSplitter::cellSplitter(const polyMesh& mesh)
|
||||
:
|
||||
mesh_(mesh),
|
||||
addedPoints_()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::cellSplitter::~cellSplitter()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::cellSplitter::setRefinement
|
||||
(
|
||||
const Map<point>& cellToMidPoint,
|
||||
polyTopoChange& meshMod
|
||||
)
|
||||
{
|
||||
addedPoints_.clear();
|
||||
addedPoints_.resize(cellToMidPoint.size());
|
||||
|
||||
|
||||
//
|
||||
// Introduce cellToMidPoints.
|
||||
//
|
||||
|
||||
forAllConstIter(Map<point>, cellToMidPoint, iter)
|
||||
{
|
||||
label cellI = iter.key();
|
||||
|
||||
label anchorPoint = mesh_.cellPoints()[cellI][0];
|
||||
|
||||
label addedPointI =
|
||||
meshMod.setAction
|
||||
(
|
||||
polyAddPoint
|
||||
(
|
||||
iter(), // point
|
||||
anchorPoint, // master point
|
||||
-1, // zone for point
|
||||
true // supports a cell
|
||||
)
|
||||
);
|
||||
addedPoints_.insert(cellI, addedPointI);
|
||||
|
||||
//Pout<< "Added point " << addedPointI
|
||||
// << iter() << " in cell " << cellI << " with centre "
|
||||
// << mesh_.cellCentres()[cellI] << endl;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Add cells (first one is modified original cell)
|
||||
//
|
||||
|
||||
Map<labelList> cellToCells(cellToMidPoint.size());
|
||||
|
||||
forAllConstIter(Map<point>, cellToMidPoint, iter)
|
||||
{
|
||||
label cellI = iter.key();
|
||||
|
||||
const cell& cFaces = mesh_.cells()[cellI];
|
||||
|
||||
// Cells created for this cell.
|
||||
labelList newCells(cFaces.size());
|
||||
|
||||
// First pyramid is the original cell
|
||||
newCells[0] = cellI;
|
||||
|
||||
// Add other pyramids
|
||||
for (label i = 1; i < cFaces.size(); i++)
|
||||
{
|
||||
label addedCellI =
|
||||
meshMod.setAction
|
||||
(
|
||||
polyAddCell
|
||||
(
|
||||
-1, // master point
|
||||
-1, // master edge
|
||||
-1, // master face
|
||||
cellI, // master cell
|
||||
-1 // zone
|
||||
)
|
||||
);
|
||||
|
||||
newCells[i] = addedCellI;
|
||||
}
|
||||
|
||||
cellToCells.insert(cellI, newCells);
|
||||
|
||||
//Pout<< "Split cell " << cellI
|
||||
// << " with centre " << mesh_.cellCentres()[cellI] << nl
|
||||
// << " faces:" << cFaces << nl
|
||||
// << " into :" << newCells << endl;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Introduce internal faces. These go from edges of the cell to the mid
|
||||
// point.
|
||||
//
|
||||
|
||||
forAllConstIter(Map<point>, cellToMidPoint, iter)
|
||||
{
|
||||
label cellI = iter.key();
|
||||
|
||||
label midPointI = addedPoints_[cellI];
|
||||
|
||||
const cell& cFaces = mesh_.cells()[cellI];
|
||||
|
||||
const labelList& cEdges = mesh_.cellEdges()[cellI];
|
||||
|
||||
forAll(cEdges, i)
|
||||
{
|
||||
label edgeI = cEdges[i];
|
||||
const edge& e = mesh_.edges()[edgeI];
|
||||
|
||||
// Get the faces on the cell using the edge
|
||||
label face0, face1;
|
||||
meshTools::getEdgeFaces(mesh_, cellI, edgeI, face0, face1);
|
||||
|
||||
// Get the cells on both sides of the face by indexing into cFaces.
|
||||
// (since newly created cells are stored in cFaces order)
|
||||
const labelList& newCells = cellToCells[cellI];
|
||||
|
||||
label cell0 = newCells[findIndex(cFaces, face0)];
|
||||
label cell1 = newCells[findIndex(cFaces, face1)];
|
||||
|
||||
if (cell0 < cell1)
|
||||
{
|
||||
// Construct face to midpoint that is pointing away from
|
||||
// (pyramid split off from) cellI
|
||||
|
||||
const face& f0 = mesh_.faces()[face0];
|
||||
|
||||
label index = findIndex(f0, e[0]);
|
||||
|
||||
bool edgeInFaceOrder = (f0[f0.fcIndex(index)] == e[1]);
|
||||
|
||||
// Check if cellI is the face owner
|
||||
|
||||
face newF(3);
|
||||
if (edgeInFaceOrder == (mesh_.faceOwner()[face0] == cellI))
|
||||
{
|
||||
// edge used in face order.
|
||||
newF[0] = e[1];
|
||||
newF[1] = e[0];
|
||||
newF[2] = midPointI;
|
||||
}
|
||||
else
|
||||
{
|
||||
newF[0] = e[0];
|
||||
newF[1] = e[1];
|
||||
newF[2] = midPointI;
|
||||
}
|
||||
|
||||
// Now newF points away from cell0
|
||||
meshMod.setAction
|
||||
(
|
||||
polyAddFace
|
||||
(
|
||||
newF, // face
|
||||
cell0, // owner
|
||||
cell1, // neighbour
|
||||
-1, // master point
|
||||
-1, // master edge
|
||||
face0, // master face for addition
|
||||
false, // flux flip
|
||||
-1, // patch for face
|
||||
-1, // zone for face
|
||||
false // face zone flip
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Construct face to midpoint that is pointing away from
|
||||
// (pyramid split off from) cellI
|
||||
|
||||
const face& f1 = mesh_.faces()[face1];
|
||||
|
||||
label index = findIndex(f1, e[0]);
|
||||
|
||||
bool edgeInFaceOrder = (f1[f1.fcIndex(index)] == e[1]);
|
||||
|
||||
// Check if cellI is the face owner
|
||||
|
||||
face newF(3);
|
||||
if (edgeInFaceOrder == (mesh_.faceOwner()[face1] == cellI))
|
||||
{
|
||||
// edge used in face order.
|
||||
newF[0] = e[1];
|
||||
newF[1] = e[0];
|
||||
newF[2] = midPointI;
|
||||
}
|
||||
else
|
||||
{
|
||||
newF[0] = e[0];
|
||||
newF[1] = e[1];
|
||||
newF[2] = midPointI;
|
||||
}
|
||||
|
||||
// Now newF points away from cell1
|
||||
meshMod.setAction
|
||||
(
|
||||
polyAddFace
|
||||
(
|
||||
newF, // face
|
||||
cell1, // owner
|
||||
cell0, // neighbour
|
||||
-1, // master point
|
||||
-1, // master edge
|
||||
face0, // master face for addition
|
||||
false, // flux flip
|
||||
-1, // patch for face
|
||||
-1, // zone for face
|
||||
false // face zone flip
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Update all existing faces for split owner or neighbour.
|
||||
//
|
||||
|
||||
|
||||
// Mark off affected face.
|
||||
boolList faceUpToDate(mesh_.nFaces(), true);
|
||||
|
||||
forAllConstIter(Map<point>, cellToMidPoint, iter)
|
||||
{
|
||||
label cellI = iter.key();
|
||||
|
||||
const cell& cFaces = mesh_.cells()[cellI];
|
||||
|
||||
forAll(cFaces, i)
|
||||
{
|
||||
label faceI = cFaces[i];
|
||||
|
||||
faceUpToDate[faceI] = false;
|
||||
}
|
||||
}
|
||||
|
||||
forAll(faceUpToDate, faceI)
|
||||
{
|
||||
if (!faceUpToDate[faceI])
|
||||
{
|
||||
const face& f = mesh_.faces()[faceI];
|
||||
|
||||
if (mesh_.isInternalFace(faceI))
|
||||
{
|
||||
label newOwn = newOwner(faceI, cellToCells);
|
||||
label newNbr = newNeighbour(faceI, cellToCells);
|
||||
|
||||
if (newOwn < newNbr)
|
||||
{
|
||||
meshMod.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
f,
|
||||
faceI,
|
||||
newOwn, // owner
|
||||
newNbr, // neighbour
|
||||
false, // flux flip
|
||||
-1, // patch for face
|
||||
false, // remove from zone
|
||||
-1, // zone for face
|
||||
false // face zone flip
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
meshMod.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
f.reverseFace(),
|
||||
faceI,
|
||||
newNbr, // owner
|
||||
newOwn, // neighbour
|
||||
false, // flux flip
|
||||
-1, // patch for face
|
||||
false, // remove from zone
|
||||
-1, // zone for face
|
||||
false // face zone flip
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
label newOwn = newOwner(faceI, cellToCells);
|
||||
|
||||
label patchID, zoneID, zoneFlip;
|
||||
getFaceInfo(faceI, patchID, zoneID, zoneFlip);
|
||||
|
||||
meshMod.setAction
|
||||
(
|
||||
polyModifyFace
|
||||
(
|
||||
mesh_.faces()[faceI],
|
||||
faceI,
|
||||
newOwn, // owner
|
||||
-1, // neighbour
|
||||
false, // flux flip
|
||||
patchID, // patch for face
|
||||
false, // remove from zone
|
||||
zoneID, // zone for face
|
||||
zoneFlip // face zone flip
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
faceUpToDate[faceI] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::cellSplitter::updateMesh(const mapPolyMesh& morphMap)
|
||||
{
|
||||
// Create copy since we're deleting entries. Only if both cell and added
|
||||
// point get mapped do they get inserted.
|
||||
Map<label> newAddedPoints(addedPoints_.size());
|
||||
|
||||
forAllConstIter(Map<label>, addedPoints_, iter)
|
||||
{
|
||||
label oldCellI = iter.key();
|
||||
|
||||
label newCellI = morphMap.reverseCellMap()[oldCellI];
|
||||
|
||||
label oldPointI = iter();
|
||||
|
||||
label newPointI = morphMap.reversePointMap()[oldPointI];
|
||||
|
||||
if (newCellI >= 0 && newPointI >= 0)
|
||||
{
|
||||
newAddedPoints.insert(newCellI, newPointI);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy
|
||||
addedPoints_.transfer(newAddedPoints);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
149
applications/utilities/mesh/advanced/modifyMesh/cellSplitter.H
Normal file
149
applications/utilities/mesh/advanced/modifyMesh/cellSplitter.H
Normal file
@ -0,0 +1,149 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ 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::cellSplitter
|
||||
|
||||
Description
|
||||
Does pyramidal decomposition of selected cells. So all faces will become
|
||||
base of pyramid with as top a user-supplied point (usually the cell centre)
|
||||
|
||||
SourceFiles
|
||||
cellSplitter.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef cellSplitter_H
|
||||
#define cellSplitter_H
|
||||
|
||||
#include "Map.H"
|
||||
#include "edge.H"
|
||||
#include "typeInfo.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
class polyTopoChange;
|
||||
class mapPolyMesh;
|
||||
class polyMesh;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class cellSplitter Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class cellSplitter
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Reference to mesh
|
||||
const polyMesh& mesh_;
|
||||
|
||||
//- Per cell the mid point added.
|
||||
Map<label> addedPoints_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Get patch and zone info for face
|
||||
void getFaceInfo
|
||||
(
|
||||
const label faceI,
|
||||
label& patchID,
|
||||
label& zoneID,
|
||||
label& zoneFlip
|
||||
) const;
|
||||
|
||||
//- Find the new owner (if any) of the face.
|
||||
label newOwner
|
||||
(
|
||||
const label faceI,
|
||||
const Map<labelList>& cellToCells
|
||||
) const;
|
||||
|
||||
//- Find the new neighbour (if any) of the face.
|
||||
label newNeighbour
|
||||
(
|
||||
const label faceI,
|
||||
const Map<labelList>& cellToCells
|
||||
) const;
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
cellSplitter(const cellSplitter&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const cellSplitter&);
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
ClassName("cellSplitter");
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from mesh
|
||||
cellSplitter(const polyMesh& mesh);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~cellSplitter();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Edit
|
||||
|
||||
//- Insert mesh changes into meshMod.
|
||||
// cellToMidPoint : cell to cut and position of its new midpoint
|
||||
void setRefinement
|
||||
(
|
||||
const Map<point>& cellToMidPoint,
|
||||
polyTopoChange& meshMod
|
||||
);
|
||||
|
||||
//- Force recalculation of locally stored data on topological change
|
||||
void updateMesh(const mapPolyMesh&);
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
//- Per cell the mid point added.
|
||||
const Map<label>& addedPoints() const
|
||||
{
|
||||
return addedPoints_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
692
applications/utilities/mesh/advanced/modifyMesh/modifyMesh.C
Normal file
692
applications/utilities/mesh/advanced/modifyMesh/modifyMesh.C
Normal file
@ -0,0 +1,692 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
modifyMesh
|
||||
|
||||
Description
|
||||
Manipulates mesh elements.
|
||||
|
||||
Actions are:
|
||||
(boundary)points:
|
||||
- move
|
||||
|
||||
(boundary)edges:
|
||||
- split and move introduced point
|
||||
|
||||
(boundary)faces:
|
||||
- split(triangulate) and move introduced point
|
||||
|
||||
edges:
|
||||
- collapse
|
||||
|
||||
cells:
|
||||
- split into polygonal base pyramids around newly introduced mid
|
||||
point
|
||||
|
||||
Is a bit of a loose collection of mesh change drivers.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "boundaryCutter.H"
|
||||
#include "cellSplitter.H"
|
||||
#include "edgeCollapser.H"
|
||||
#include "meshTools.H"
|
||||
#include "Pair.H"
|
||||
#include "globalIndex.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Locate point on patch. Returns (mesh) point label.
|
||||
label findPoint(const primitivePatch& pp, const point& nearPoint)
|
||||
{
|
||||
const pointField& points = pp.points();
|
||||
const labelList& meshPoints = pp.meshPoints();
|
||||
|
||||
// Find nearest and next nearest
|
||||
scalar minDistSqr = GREAT;
|
||||
label minI = -1;
|
||||
|
||||
scalar almostMinDistSqr = GREAT;
|
||||
label almostMinI = -1;
|
||||
|
||||
forAll(meshPoints, i)
|
||||
{
|
||||
label pointI = meshPoints[i];
|
||||
|
||||
scalar distSqr = magSqr(nearPoint - points[pointI]);
|
||||
|
||||
if (distSqr < minDistSqr)
|
||||
{
|
||||
almostMinDistSqr = minDistSqr;
|
||||
almostMinI = minI;
|
||||
|
||||
minDistSqr = distSqr;
|
||||
minI = pointI;
|
||||
}
|
||||
else if (distSqr < almostMinDistSqr)
|
||||
{
|
||||
almostMinDistSqr = distSqr;
|
||||
almostMinI = pointI;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Decide if nearPoint unique enough.
|
||||
Info<< "Found to point " << nearPoint << nl
|
||||
<< " nearest point : " << minI
|
||||
<< " distance " << Foam::sqrt(minDistSqr)
|
||||
<< " at " << points[minI] << nl
|
||||
<< " next nearest point : " << almostMinI
|
||||
<< " distance " << Foam::sqrt(almostMinDistSqr)
|
||||
<< " at " << points[almostMinI] << endl;
|
||||
|
||||
if (almostMinDistSqr < 4*minDistSqr)
|
||||
{
|
||||
Info<< "Next nearest too close to nearest. Aborting" << endl;
|
||||
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return minI;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Locate edge on patch. Return mesh edge label.
|
||||
label findEdge
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const primitivePatch& pp,
|
||||
const point& nearPoint
|
||||
)
|
||||
{
|
||||
const pointField& localPoints = pp.localPoints();
|
||||
const pointField& points = pp.points();
|
||||
const labelList& meshPoints = pp.meshPoints();
|
||||
const edgeList& edges = pp.edges();
|
||||
|
||||
// Find nearest and next nearest
|
||||
scalar minDist = GREAT;
|
||||
label minI = -1;
|
||||
|
||||
scalar almostMinDist = GREAT;
|
||||
label almostMinI = -1;
|
||||
|
||||
forAll(edges, edgeI)
|
||||
{
|
||||
const edge& e = edges[edgeI];
|
||||
|
||||
pointHit pHit(e.line(localPoints).nearestDist(nearPoint));
|
||||
|
||||
if (pHit.hit())
|
||||
{
|
||||
if (pHit.distance() < minDist)
|
||||
{
|
||||
almostMinDist = minDist;
|
||||
almostMinI = minI;
|
||||
|
||||
minDist = pHit.distance();
|
||||
minI = meshTools::findEdge
|
||||
(
|
||||
mesh,
|
||||
meshPoints[e[0]],
|
||||
meshPoints[e[1]]
|
||||
);
|
||||
}
|
||||
else if (pHit.distance() < almostMinDist)
|
||||
{
|
||||
almostMinDist = pHit.distance();
|
||||
almostMinI = meshTools::findEdge
|
||||
(
|
||||
mesh,
|
||||
meshPoints[e[0]],
|
||||
meshPoints[e[1]]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (minI == -1)
|
||||
{
|
||||
Info<< "Did not find edge close to point " << nearPoint << endl;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Decide if nearPoint unique enough.
|
||||
Info<< "Found to point " << nearPoint << nl
|
||||
<< " nearest edge : " << minI
|
||||
<< " distance " << minDist << " endpoints "
|
||||
<< mesh.edges()[minI].line(points) << nl
|
||||
<< " next nearest edge : " << almostMinI
|
||||
<< " distance " << almostMinDist << " endpoints "
|
||||
<< mesh.edges()[almostMinI].line(points) << nl
|
||||
<< endl;
|
||||
|
||||
if (almostMinDist < 2*minDist)
|
||||
{
|
||||
Info<< "Next nearest too close to nearest. Aborting" << endl;
|
||||
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return minI;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Find face on patch. Return mesh face label.
|
||||
label findFace
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const primitivePatch& pp,
|
||||
const point& nearPoint
|
||||
)
|
||||
{
|
||||
const pointField& points = pp.points();
|
||||
|
||||
// Find nearest and next nearest
|
||||
scalar minDist = GREAT;
|
||||
label minI = -1;
|
||||
|
||||
scalar almostMinDist = GREAT;
|
||||
label almostMinI = -1;
|
||||
|
||||
forAll(pp, patchFaceI)
|
||||
{
|
||||
pointHit pHit(pp[patchFaceI].nearestPoint(nearPoint, points));
|
||||
|
||||
if (pHit.hit())
|
||||
{
|
||||
if (pHit.distance() < minDist)
|
||||
{
|
||||
almostMinDist = minDist;
|
||||
almostMinI = minI;
|
||||
|
||||
minDist = pHit.distance();
|
||||
minI = patchFaceI + mesh.nInternalFaces();
|
||||
}
|
||||
else if (pHit.distance() < almostMinDist)
|
||||
{
|
||||
almostMinDist = pHit.distance();
|
||||
almostMinI = patchFaceI + mesh.nInternalFaces();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (minI == -1)
|
||||
{
|
||||
Info<< "Did not find face close to point " << nearPoint << endl;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Decide if nearPoint unique enough.
|
||||
Info<< "Found to point " << nearPoint << nl
|
||||
<< " nearest face : " << minI
|
||||
<< " distance " << minDist
|
||||
<< " to face centre " << mesh.faceCentres()[minI] << nl
|
||||
<< " next nearest face : " << almostMinI
|
||||
<< " distance " << almostMinDist
|
||||
<< " to face centre " << mesh.faceCentres()[almostMinI] << nl
|
||||
<< endl;
|
||||
|
||||
if (almostMinDist < 2*minDist)
|
||||
{
|
||||
Info<< "Next nearest too close to nearest. Aborting" << endl;
|
||||
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return minI;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Find cell with cell centre close to given point.
|
||||
label findCell(const primitiveMesh& mesh, const point& nearPoint)
|
||||
{
|
||||
label cellI = mesh.findCell(nearPoint);
|
||||
|
||||
if (cellI != -1)
|
||||
{
|
||||
scalar distToCcSqr = magSqr(nearPoint - mesh.cellCentres()[cellI]);
|
||||
|
||||
const labelList& cPoints = mesh.cellPoints()[cellI];
|
||||
|
||||
label minI = -1;
|
||||
scalar minDistSqr = GREAT;
|
||||
|
||||
forAll(cPoints, i)
|
||||
{
|
||||
label pointI = cPoints[i];
|
||||
|
||||
scalar distSqr = magSqr(nearPoint - mesh.points()[pointI]);
|
||||
|
||||
if (distSqr < minDistSqr)
|
||||
{
|
||||
minDistSqr = distSqr;
|
||||
minI = pointI;
|
||||
}
|
||||
}
|
||||
|
||||
// Decide if nearPoint unique enough.
|
||||
Info<< "Found to point " << nearPoint << nl
|
||||
<< " nearest cell : " << cellI
|
||||
<< " distance " << Foam::sqrt(distToCcSqr)
|
||||
<< " to cell centre " << mesh.cellCentres()[cellI] << nl
|
||||
<< " nearest mesh point : " << minI
|
||||
<< " distance " << Foam::sqrt(minDistSqr)
|
||||
<< " to " << mesh.points()[minI] << nl
|
||||
<< endl;
|
||||
|
||||
if (minDistSqr < 4*distToCcSqr)
|
||||
{
|
||||
Info<< "Mesh point too close to nearest cell centre. Aborting"
|
||||
<< endl;
|
||||
|
||||
cellI = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return cellI;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
# include "addOverwriteOption.H"
|
||||
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
runTime.functionObjects().off();
|
||||
# include "createPolyMesh.H"
|
||||
const word oldInstance = mesh.pointsInstance();
|
||||
|
||||
const bool overwrite = args.optionFound("overwrite");
|
||||
|
||||
Info<< "Reading modifyMeshDict\n" << endl;
|
||||
|
||||
IOdictionary dict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"modifyMeshDict",
|
||||
runTime.system(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
// Read all from the dictionary.
|
||||
List<Pair<point> > pointsToMove(dict.lookup("pointsToMove"));
|
||||
List<Pair<point> > edgesToSplit(dict.lookup("edgesToSplit"));
|
||||
List<Pair<point> > facesToTriangulate
|
||||
(
|
||||
dict.lookup("facesToTriangulate")
|
||||
);
|
||||
|
||||
bool cutBoundary =
|
||||
(
|
||||
pointsToMove.size()
|
||||
|| edgesToSplit.size()
|
||||
|| facesToTriangulate.size()
|
||||
);
|
||||
|
||||
List<Pair<point> > edgesToCollapse(dict.lookup("edgesToCollapse"));
|
||||
|
||||
bool collapseEdge = edgesToCollapse.size();
|
||||
|
||||
List<Pair<point> > cellsToPyramidise(dict.lookup("cellsToSplit"));
|
||||
|
||||
bool cellsToSplit = cellsToPyramidise.size();
|
||||
|
||||
// List<Tuple2<pointField,point> >
|
||||
// cellsToCreate(dict.lookup("cellsToCreate"));
|
||||
|
||||
Info<< "Read from " << dict.name() << nl
|
||||
<< " Boundary cutting module:" << nl
|
||||
<< " points to move :" << pointsToMove.size() << nl
|
||||
<< " edges to split :" << edgesToSplit.size() << nl
|
||||
<< " faces to triangulate:" << facesToTriangulate.size() << nl
|
||||
<< " Cell splitting module:" << nl
|
||||
<< " cells to split :" << cellsToPyramidise.size() << nl
|
||||
<< " Edge collapsing module:" << nl
|
||||
<< " edges to collapse :" << edgesToCollapse.size() << nl
|
||||
//<< " cells to create :" << cellsToCreate.size() << nl
|
||||
<< endl;
|
||||
|
||||
if
|
||||
(
|
||||
(cutBoundary && collapseEdge)
|
||||
|| (cutBoundary && cellsToSplit)
|
||||
|| (collapseEdge && cellsToSplit)
|
||||
)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Used more than one mesh modifying module "
|
||||
<< "(boundary cutting, cell splitting, edge collapsing)" << nl
|
||||
<< "Please do them in separate passes." << exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Get calculating engine for all of outside
|
||||
const SubList<face> outsideFaces
|
||||
(
|
||||
mesh.faces(),
|
||||
mesh.nFaces() - mesh.nInternalFaces(),
|
||||
mesh.nInternalFaces()
|
||||
);
|
||||
|
||||
primitivePatch allBoundary(outsideFaces, mesh.points());
|
||||
|
||||
|
||||
// Look up mesh labels and convert to input for boundaryCutter.
|
||||
|
||||
bool validInputs = true;
|
||||
|
||||
|
||||
Info<< nl << "Looking up points to move ..." << nl << endl;
|
||||
Map<point> pointToPos(pointsToMove.size());
|
||||
forAll(pointsToMove, i)
|
||||
{
|
||||
const Pair<point>& pts = pointsToMove[i];
|
||||
|
||||
label pointI = findPoint(allBoundary, pts.first());
|
||||
|
||||
if (pointI == -1 || !pointToPos.insert(pointI, pts.second()))
|
||||
{
|
||||
Info<< "Could not insert mesh point " << pointI
|
||||
<< " for input point " << pts.first() << nl
|
||||
<< "Perhaps the point is already marked for moving?" << endl;
|
||||
validInputs = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Info<< nl << "Looking up edges to split ..." << nl << endl;
|
||||
Map<List<point> > edgeToCuts(edgesToSplit.size());
|
||||
forAll(edgesToSplit, i)
|
||||
{
|
||||
const Pair<point>& pts = edgesToSplit[i];
|
||||
|
||||
label edgeI = findEdge(mesh, allBoundary, pts.first());
|
||||
|
||||
if
|
||||
(
|
||||
edgeI == -1
|
||||
|| !edgeToCuts.insert(edgeI, List<point>(1, pts.second()))
|
||||
)
|
||||
{
|
||||
Info<< "Could not insert mesh edge " << edgeI
|
||||
<< " for input point " << pts.first() << nl
|
||||
<< "Perhaps the edge is already marked for cutting?" << endl;
|
||||
|
||||
validInputs = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Info<< nl << "Looking up faces to triangulate ..." << nl << endl;
|
||||
Map<point> faceToDecompose(facesToTriangulate.size());
|
||||
forAll(facesToTriangulate, i)
|
||||
{
|
||||
const Pair<point>& pts = facesToTriangulate[i];
|
||||
|
||||
label faceI = findFace(mesh, allBoundary, pts.first());
|
||||
|
||||
if (faceI == -1 || !faceToDecompose.insert(faceI, pts.second()))
|
||||
{
|
||||
Info<< "Could not insert mesh face " << faceI
|
||||
<< " for input point " << pts.first() << nl
|
||||
<< "Perhaps the face is already marked for splitting?" << endl;
|
||||
|
||||
validInputs = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Info<< nl << "Looking up cells to convert to pyramids around"
|
||||
<< " cell centre ..." << nl << endl;
|
||||
Map<point> cellToPyrCentre(cellsToPyramidise.size());
|
||||
forAll(cellsToPyramidise, i)
|
||||
{
|
||||
const Pair<point>& pts = cellsToPyramidise[i];
|
||||
|
||||
label cellI = findCell(mesh, pts.first());
|
||||
|
||||
if (cellI == -1 || !cellToPyrCentre.insert(cellI, pts.second()))
|
||||
{
|
||||
Info<< "Could not insert mesh cell " << cellI
|
||||
<< " for input point " << pts.first() << nl
|
||||
<< "Perhaps the cell is already marked for splitting?" << endl;
|
||||
|
||||
validInputs = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Info<< nl << "Looking up edges to collapse ..." << nl << endl;
|
||||
Map<point> edgeToPos(edgesToCollapse.size());
|
||||
forAll(edgesToCollapse, i)
|
||||
{
|
||||
const Pair<point>& pts = edgesToCollapse[i];
|
||||
|
||||
label edgeI = findEdge(mesh, allBoundary, pts.first());
|
||||
|
||||
if (edgeI == -1 || !edgeToPos.insert(edgeI, pts.second()))
|
||||
{
|
||||
Info<< "Could not insert mesh edge " << edgeI
|
||||
<< " for input point " << pts.first() << nl
|
||||
<< "Perhaps the edge is already marked for collaping?" << endl;
|
||||
|
||||
validInputs = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!validInputs)
|
||||
{
|
||||
Info<< nl << "There was a problem in one of the inputs in the"
|
||||
<< " dictionary. Not modifying mesh." << endl;
|
||||
}
|
||||
else if (cellToPyrCentre.size())
|
||||
{
|
||||
Info<< nl << "All input cells located. Modifying mesh." << endl;
|
||||
|
||||
// Mesh change engine
|
||||
cellSplitter cutter(mesh);
|
||||
|
||||
// Topo change container
|
||||
polyTopoChange meshMod(mesh);
|
||||
|
||||
// Insert commands into meshMod
|
||||
cutter.setRefinement(cellToPyrCentre, meshMod);
|
||||
|
||||
// Do changes
|
||||
autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh(mesh, false);
|
||||
|
||||
if (morphMap().hasMotionPoints())
|
||||
{
|
||||
mesh.movePoints(morphMap().preMotionPoints());
|
||||
}
|
||||
|
||||
cutter.updateMesh(morphMap());
|
||||
|
||||
if (!overwrite)
|
||||
{
|
||||
runTime++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh.setInstance(oldInstance);
|
||||
}
|
||||
|
||||
// Write resulting mesh
|
||||
Info<< "Writing modified mesh to time " << runTime.timeName() << endl;
|
||||
mesh.write();
|
||||
}
|
||||
else if (edgeToPos.size())
|
||||
{
|
||||
Info<< nl << "All input edges located. Modifying mesh." << endl;
|
||||
|
||||
// Mesh change engine
|
||||
edgeCollapser cutter(mesh);
|
||||
|
||||
const edgeList& edges = mesh.edges();
|
||||
const pointField& points = mesh.points();
|
||||
|
||||
pointField newPoints(points);
|
||||
|
||||
PackedBoolList collapseEdge(mesh.nEdges());
|
||||
Map<point> collapsePointToLocation(mesh.nPoints());
|
||||
|
||||
// Get new positions and construct collapse network
|
||||
forAllConstIter(Map<point>, edgeToPos, iter)
|
||||
{
|
||||
label edgeI = iter.key();
|
||||
const edge& e = edges[edgeI];
|
||||
|
||||
collapseEdge[edgeI] = true;
|
||||
collapsePointToLocation.set(e[1], points[e[0]]);
|
||||
|
||||
newPoints[e[0]] = iter();
|
||||
}
|
||||
|
||||
// Move master point to destination.
|
||||
mesh.movePoints(newPoints);
|
||||
|
||||
List<pointEdgeCollapse> allPointInfo;
|
||||
const globalIndex globalPoints(mesh.nPoints());
|
||||
labelList pointPriority(mesh.nPoints(), 0);
|
||||
|
||||
cutter.consistentCollapse
|
||||
(
|
||||
globalPoints,
|
||||
pointPriority,
|
||||
collapsePointToLocation,
|
||||
collapseEdge,
|
||||
allPointInfo
|
||||
);
|
||||
|
||||
// Topo change container
|
||||
polyTopoChange meshMod(mesh);
|
||||
|
||||
// Insert
|
||||
cutter.setRefinement(allPointInfo, meshMod);
|
||||
|
||||
// Do changes
|
||||
autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh(mesh, false);
|
||||
|
||||
if (morphMap().hasMotionPoints())
|
||||
{
|
||||
mesh.movePoints(morphMap().preMotionPoints());
|
||||
}
|
||||
|
||||
// Not implemented yet:
|
||||
//cutter.updateMesh(morphMap());
|
||||
|
||||
|
||||
if (!overwrite)
|
||||
{
|
||||
runTime++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh.setInstance(oldInstance);
|
||||
}
|
||||
|
||||
// Write resulting mesh
|
||||
Info<< "Writing modified mesh to time " << runTime.timeName() << endl;
|
||||
mesh.write();
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< nl << "All input points located. Modifying mesh." << endl;
|
||||
|
||||
// Mesh change engine
|
||||
boundaryCutter cutter(mesh);
|
||||
|
||||
// Topo change container
|
||||
polyTopoChange meshMod(mesh);
|
||||
|
||||
// Insert commands into meshMod
|
||||
cutter.setRefinement
|
||||
(
|
||||
pointToPos,
|
||||
edgeToCuts,
|
||||
Map<labelPair>(0), // Faces to split diagonally
|
||||
faceToDecompose, // Faces to triangulate
|
||||
meshMod
|
||||
);
|
||||
|
||||
// Do changes
|
||||
autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh(mesh, false);
|
||||
|
||||
if (morphMap().hasMotionPoints())
|
||||
{
|
||||
mesh.movePoints(morphMap().preMotionPoints());
|
||||
}
|
||||
|
||||
cutter.updateMesh(morphMap());
|
||||
|
||||
if (!overwrite)
|
||||
{
|
||||
runTime++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh.setInstance(oldInstance);
|
||||
}
|
||||
|
||||
// Write resulting mesh
|
||||
Info<< "Writing modified mesh to time " << runTime.timeName() << endl;
|
||||
mesh.write();
|
||||
}
|
||||
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,79 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: dev |
|
||||
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object modifyMeshDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Move boundary points:
|
||||
// Every entry is two coordinates. First one is location of the point to move,
|
||||
// the second is the position to move to.
|
||||
pointsToMove
|
||||
(
|
||||
(( -0.17861 -0.45073 0.75276)( -0.18 -0.45073 0.75276))
|
||||
);
|
||||
|
||||
// Split boundary edge in two:
|
||||
// First coord is a point on the (boundary) edge to cut, second is the
|
||||
// position of the newly introduced point
|
||||
edgesToSplit
|
||||
(
|
||||
(( -0.17692 -0.45312 0.74516)( -0.18 -0.45 0.742))
|
||||
);
|
||||
|
||||
// Triangulate a boundary face:
|
||||
// First coord is a point on the face to triangulate. It will introduce a
|
||||
// point on the face, triangulate and move the point to the second coordinate.
|
||||
facesToTriangulate
|
||||
(
|
||||
(( -0.039123 -0.45045 0.74083) (-0.03844 -0.45049 0.73572))
|
||||
);
|
||||
|
||||
// Boundary edges to collapse. First coord is point on the edge, second
|
||||
// is coordinate to collapse to.
|
||||
edgesToCollapse
|
||||
(
|
||||
((0.054975 0.099987 0.0044074)(0.054975 0.099987 0.0044074))
|
||||
);
|
||||
|
||||
// Split cells:
|
||||
// First coord is a point inside the cell to split. A point inside the cell will
|
||||
// be introduced and the cell will get decomposed into polygonal base pyramids
|
||||
// with this new point as top. (so the original faces will not get split)
|
||||
cellsToSplit
|
||||
(
|
||||
(( -0.039123 -0.45045 0.74083) (-0.03844 -0.45049 0.73572))
|
||||
);
|
||||
|
||||
// Change patch:
|
||||
// Changes patchID of boundary faces. Coord selects the face, label is the
|
||||
// patch index.
|
||||
facesToRepatch
|
||||
(
|
||||
(( -0.039123 -0.45045 0.74083) 1)
|
||||
);
|
||||
|
||||
//// Create cell:
|
||||
//// Creates a cell on the boundary given a face covering a cavity. Gets
|
||||
//// the vertices of the face (outwards pointing normal) and a point internal
|
||||
//// to the new cell. (used to check the orientation of the face). Walks all
|
||||
//// boundary faces reachable from any edge on the face and constructs cell
|
||||
//// from it.
|
||||
//cellsToCreate
|
||||
//(
|
||||
// (
|
||||
// ((0 0 0) (1 0 0) (1 1 0) (0 1 0)) // vertices of face
|
||||
// (0.5 0.5 0.1) // cell centre
|
||||
// )
|
||||
//);
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
refineHexMesh.C
|
||||
EXE = $(FOAM_APPBIN)/refineHexMesh
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
|
||||
EXE_LIBS = \
|
||||
-ldynamicMesh \
|
||||
-lmeshTools \
|
||||
-lfiniteVolume \
|
||||
-lgenericPatchFields
|
||||
@ -0,0 +1,204 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
refineHexMesh
|
||||
|
||||
Description
|
||||
Refines a hex mesh by 2x2x2 cell splitting.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvMesh.H"
|
||||
#include "pointMesh.H"
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "hexRef8.H"
|
||||
#include "cellSet.H"
|
||||
#include "OFstream.H"
|
||||
#include "meshTools.H"
|
||||
#include "IFstream.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "volMesh.H"
|
||||
#include "surfaceMesh.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "pointFields.H"
|
||||
#include "ReadFields.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "addOverwriteOption.H"
|
||||
#include "addRegionOption.H"
|
||||
argList::validArgs.append("cellSet");
|
||||
argList::addBoolOption
|
||||
(
|
||||
"minSet",
|
||||
"remove cells from input cellSet to keep to 2:1 ratio"
|
||||
" (default is to extend set)"
|
||||
);
|
||||
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
runTime.functionObjects().off();
|
||||
#include "createNamedMesh.H"
|
||||
const word oldInstance = mesh.pointsInstance();
|
||||
|
||||
word cellSetName(args.args()[1]);
|
||||
const bool overwrite = args.optionFound("overwrite");
|
||||
|
||||
const bool minSet = args.optionFound("minSet");
|
||||
|
||||
Info<< "Reading cells to refine from cellSet " << cellSetName
|
||||
<< nl << endl;
|
||||
|
||||
cellSet cellsToRefine(mesh, cellSetName);
|
||||
|
||||
Info<< "Read " << returnReduce(cellsToRefine.size(), sumOp<label>())
|
||||
<< " cells to refine from cellSet " << cellSetName << nl
|
||||
<< endl;
|
||||
|
||||
|
||||
// Read objects in time directory
|
||||
IOobjectList objects(mesh, runTime.timeName());
|
||||
|
||||
// Read vol fields.
|
||||
|
||||
PtrList<volScalarField> vsFlds;
|
||||
ReadFields(mesh, objects, vsFlds);
|
||||
|
||||
PtrList<volVectorField> vvFlds;
|
||||
ReadFields(mesh, objects, vvFlds);
|
||||
|
||||
PtrList<volSphericalTensorField> vstFlds;
|
||||
ReadFields(mesh, objects, vstFlds);
|
||||
|
||||
PtrList<volSymmTensorField> vsymtFlds;
|
||||
ReadFields(mesh, objects, vsymtFlds);
|
||||
|
||||
PtrList<volTensorField> vtFlds;
|
||||
ReadFields(mesh, objects, vtFlds);
|
||||
|
||||
// Read surface fields.
|
||||
|
||||
PtrList<surfaceScalarField> ssFlds;
|
||||
ReadFields(mesh, objects, ssFlds);
|
||||
|
||||
PtrList<surfaceVectorField> svFlds;
|
||||
ReadFields(mesh, objects, svFlds);
|
||||
|
||||
PtrList<surfaceSphericalTensorField> sstFlds;
|
||||
ReadFields(mesh, objects, sstFlds);
|
||||
|
||||
PtrList<surfaceSymmTensorField> ssymtFlds;
|
||||
ReadFields(mesh, objects, ssymtFlds);
|
||||
|
||||
PtrList<surfaceTensorField> stFlds;
|
||||
ReadFields(mesh, objects, stFlds);
|
||||
|
||||
// Read point fields
|
||||
PtrList<pointScalarField> psFlds;
|
||||
ReadFields(pointMesh::New(mesh), objects, psFlds);
|
||||
|
||||
PtrList<pointVectorField> pvFlds;
|
||||
ReadFields(pointMesh::New(mesh), objects, pvFlds);
|
||||
|
||||
|
||||
// Construct refiner without unrefinement. Read existing point/cell level.
|
||||
hexRef8 meshCutter(mesh);
|
||||
|
||||
// Some stats
|
||||
Info<< "Read mesh:" << nl
|
||||
<< " cells:" << mesh.globalData().nTotalCells() << nl
|
||||
<< " faces:" << mesh.globalData().nTotalFaces() << nl
|
||||
<< " points:" << mesh.globalData().nTotalPoints() << nl
|
||||
<< " cellLevel :"
|
||||
<< " min:" << gMin(meshCutter.cellLevel())
|
||||
<< " max:" << gMax(meshCutter.cellLevel()) << nl
|
||||
<< " pointLevel :"
|
||||
<< " min:" << gMin(meshCutter.pointLevel())
|
||||
<< " max:" << gMax(meshCutter.pointLevel()) << nl
|
||||
<< endl;
|
||||
|
||||
|
||||
// Maintain 2:1 ratio
|
||||
labelList newCellsToRefine
|
||||
(
|
||||
meshCutter.consistentRefinement
|
||||
(
|
||||
cellsToRefine.toc(),
|
||||
!minSet // extend set
|
||||
)
|
||||
);
|
||||
|
||||
// Mesh changing engine.
|
||||
polyTopoChange meshMod(mesh);
|
||||
|
||||
// Play refinement commands into mesh changer.
|
||||
meshCutter.setRefinement(newCellsToRefine, meshMod);
|
||||
|
||||
if (!overwrite)
|
||||
{
|
||||
runTime++;
|
||||
}
|
||||
|
||||
// Create mesh, return map from old to new mesh.
|
||||
autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
|
||||
|
||||
// Update fields
|
||||
mesh.updateMesh(map);
|
||||
|
||||
// Update numbering of cells/vertices.
|
||||
meshCutter.updateMesh(map);
|
||||
|
||||
// Optionally inflate mesh
|
||||
if (map().hasMotionPoints())
|
||||
{
|
||||
mesh.movePoints(map().preMotionPoints());
|
||||
}
|
||||
|
||||
Info<< "Refined from " << returnReduce(map().nOldCells(), sumOp<label>())
|
||||
<< " to " << mesh.globalData().nTotalCells() << " cells." << nl << endl;
|
||||
|
||||
if (overwrite)
|
||||
{
|
||||
mesh.setInstance(oldInstance);
|
||||
meshCutter.setInstance(oldInstance);
|
||||
}
|
||||
Info<< "Writing mesh to " << runTime.timeName() << endl;
|
||||
|
||||
mesh.write();
|
||||
meshCutter.write();
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,4 @@
|
||||
refineWallLayer.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/refineWallLayer
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-ldynamicMesh \
|
||||
-lmeshTools
|
||||
@ -0,0 +1,244 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
refineWallLayer
|
||||
|
||||
Description
|
||||
Utility to refine cells next to patches.
|
||||
|
||||
Takes a patchName and number of layers to refine. Works out cells within
|
||||
these layers and refines those in the wall-normal direction.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "polyTopoChanger.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "polyMesh.H"
|
||||
#include "cellCuts.H"
|
||||
#include "cellSet.H"
|
||||
#include "meshCutter.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "addOverwriteOption.H"
|
||||
argList::noParallel();
|
||||
argList::validArgs.append("patchName");
|
||||
argList::validArgs.append("edgeWeight");
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"useSet",
|
||||
"name",
|
||||
"restrict cells to refine based on specified cellSet name"
|
||||
);
|
||||
|
||||
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
runTime.functionObjects().off();
|
||||
# include "createPolyMesh.H"
|
||||
const word oldInstance = mesh.pointsInstance();
|
||||
|
||||
const word patchName = args[1];
|
||||
const scalar weight = args.argRead<scalar>(2);
|
||||
const bool overwrite = args.optionFound("overwrite");
|
||||
|
||||
label patchID = mesh.boundaryMesh().findPatchID(patchName);
|
||||
|
||||
if (patchID == -1)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Cannot find patch " << patchName << endl
|
||||
<< "Valid patches are " << mesh.boundaryMesh().names()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
const polyPatch& pp = mesh.boundaryMesh()[patchID];
|
||||
|
||||
|
||||
// Cells cut
|
||||
|
||||
labelHashSet cutCells(4*pp.size());
|
||||
|
||||
const labelList& meshPoints = pp.meshPoints();
|
||||
|
||||
forAll(meshPoints, pointI)
|
||||
{
|
||||
label meshPointI = meshPoints[pointI];
|
||||
|
||||
const labelList& pCells = mesh.pointCells()[meshPointI];
|
||||
|
||||
forAll(pCells, pCellI)
|
||||
{
|
||||
cutCells.insert(pCells[pCellI]);
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Selected " << cutCells.size()
|
||||
<< " cells connected to patch " << pp.name() << endl << endl;
|
||||
|
||||
//
|
||||
// List of cells to refine
|
||||
//
|
||||
|
||||
word setName;
|
||||
if (args.optionReadIfPresent("useSet", setName))
|
||||
{
|
||||
Info<< "Subsetting cells to cut based on cellSet"
|
||||
<< setName << nl << endl;
|
||||
|
||||
cellSet cells(mesh, setName);
|
||||
|
||||
Info<< "Read " << cells.size() << " cells from cellSet "
|
||||
<< cells.instance()/cells.local()/cells.name()
|
||||
<< nl << endl;
|
||||
|
||||
forAllConstIter(cellSet, cells, iter)
|
||||
{
|
||||
cutCells.erase(iter.key());
|
||||
}
|
||||
Info<< "Removed from cells to cut all the ones not in set "
|
||||
<< setName << nl << endl;
|
||||
}
|
||||
|
||||
// Mark all meshpoints on patch
|
||||
|
||||
boolList vertOnPatch(mesh.nPoints(), false);
|
||||
|
||||
forAll(meshPoints, pointI)
|
||||
{
|
||||
const label meshPointI = meshPoints[pointI];
|
||||
|
||||
vertOnPatch[meshPointI] = true;
|
||||
}
|
||||
|
||||
|
||||
// Mark cut edges.
|
||||
|
||||
DynamicList<label> allCutEdges(pp.nEdges());
|
||||
|
||||
DynamicList<scalar> allCutEdgeWeights(pp.nEdges());
|
||||
|
||||
forAll(meshPoints, pointI)
|
||||
{
|
||||
label meshPointI = meshPoints[pointI];
|
||||
|
||||
const labelList& pEdges = mesh.pointEdges()[meshPointI];
|
||||
|
||||
forAll(pEdges, pEdgeI)
|
||||
{
|
||||
const label edgeI = pEdges[pEdgeI];
|
||||
const edge& e = mesh.edges()[edgeI];
|
||||
|
||||
label otherPointI = e.otherVertex(meshPointI);
|
||||
|
||||
if (!vertOnPatch[otherPointI])
|
||||
{
|
||||
allCutEdges.append(edgeI);
|
||||
|
||||
if (e.start() == meshPointI)
|
||||
{
|
||||
allCutEdgeWeights.append(weight);
|
||||
}
|
||||
else
|
||||
{
|
||||
allCutEdgeWeights.append(1 - weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allCutEdges.shrink();
|
||||
allCutEdgeWeights.shrink();
|
||||
|
||||
Info<< "Cutting:" << nl
|
||||
<< " cells:" << cutCells.size() << nl
|
||||
<< " edges:" << allCutEdges.size() << nl
|
||||
<< endl;
|
||||
|
||||
// Transfer DynamicLists to straight ones.
|
||||
scalarField cutEdgeWeights;
|
||||
cutEdgeWeights.transfer(allCutEdgeWeights);
|
||||
allCutEdgeWeights.clear();
|
||||
|
||||
|
||||
// Gets cuts across cells from cuts through edges.
|
||||
cellCuts cuts
|
||||
(
|
||||
mesh,
|
||||
cutCells.toc(), // cells candidate for cutting
|
||||
labelList(0), // cut vertices
|
||||
allCutEdges, // cut edges
|
||||
cutEdgeWeights // weight on cut edges
|
||||
);
|
||||
|
||||
polyTopoChange meshMod(mesh);
|
||||
|
||||
// Cutting engine
|
||||
meshCutter cutter(mesh);
|
||||
|
||||
// Insert mesh refinement into polyTopoChange.
|
||||
cutter.setRefinement(cuts, meshMod);
|
||||
|
||||
// Do all changes
|
||||
Info<< "Morphing ..." << endl;
|
||||
|
||||
if (!overwrite)
|
||||
{
|
||||
runTime++;
|
||||
}
|
||||
|
||||
autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh(mesh, false);
|
||||
|
||||
if (morphMap().hasMotionPoints())
|
||||
{
|
||||
mesh.movePoints(morphMap().preMotionPoints());
|
||||
}
|
||||
|
||||
// Update stored labels on meshCutter.
|
||||
cutter.updateMesh(morphMap());
|
||||
|
||||
if (overwrite)
|
||||
{
|
||||
mesh.setInstance(oldInstance);
|
||||
}
|
||||
|
||||
// Write resulting mesh
|
||||
Info<< "Writing refined morphMesh to time " << runTime.timeName() << endl;
|
||||
|
||||
mesh.write();
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,4 @@
|
||||
refinementLevel.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/refinementLevel
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lmeshTools
|
||||
@ -0,0 +1,368 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
refinementLevel
|
||||
|
||||
Description
|
||||
Tries to figure out what the refinement level is on refined cartesian
|
||||
meshes. Run BEFORE snapping.
|
||||
|
||||
Writes
|
||||
- volScalarField 'refinementLevel' with current refinement level.
|
||||
- cellSet 'refCells' which are the cells that need to be refined to satisfy
|
||||
2:1 refinement.
|
||||
|
||||
Works by dividing cells into volume bins.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
#include "cellSet.H"
|
||||
#include "SortableList.H"
|
||||
#include "labelIOList.H"
|
||||
#include "fvMesh.H"
|
||||
#include "volFields.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Return true if any cells had to be split to keep a difference between
|
||||
// neighbouring refinement levels < limitDiff. Puts cells into refCells and
|
||||
// update refLevel to account for refinement.
|
||||
bool limitRefinementLevel
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
labelList& refLevel,
|
||||
cellSet& refCells
|
||||
)
|
||||
{
|
||||
const labelListList& cellCells = mesh.cellCells();
|
||||
|
||||
label oldNCells = refCells.size();
|
||||
|
||||
forAll(cellCells, cellI)
|
||||
{
|
||||
const labelList& cCells = cellCells[cellI];
|
||||
|
||||
forAll(cCells, i)
|
||||
{
|
||||
if (refLevel[cCells[i]] > (refLevel[cellI]+1))
|
||||
{
|
||||
// Found neighbour with >=2 difference in refLevel.
|
||||
refCells.insert(cellI);
|
||||
refLevel[cellI]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (refCells.size() > oldNCells)
|
||||
{
|
||||
Info<< "Added an additional " << refCells.size() - oldNCells
|
||||
<< " cells to satisfy 1:2 refinement level"
|
||||
<< endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::addBoolOption
|
||||
(
|
||||
"readLevel",
|
||||
"read level from refinementLevel file"
|
||||
);
|
||||
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createPolyMesh.H"
|
||||
|
||||
Info<< "Dividing cells into bins depending on cell volume.\nThis will"
|
||||
<< " correspond to refinement levels for a mesh with only 2x2x2"
|
||||
<< " refinement\n"
|
||||
<< "The upper range for every bin is always 1.1 times the lower range"
|
||||
<< " to allow for some truncation error."
|
||||
<< nl << endl;
|
||||
|
||||
const bool readLevel = args.optionFound("readLevel");
|
||||
|
||||
const scalarField& vols = mesh.cellVolumes();
|
||||
|
||||
SortableList<scalar> sortedVols(vols);
|
||||
|
||||
// All cell labels, sorted per bin.
|
||||
DynamicList<DynamicList<label> > bins;
|
||||
|
||||
// Lower/upper limits
|
||||
DynamicList<scalar> lowerLimits;
|
||||
DynamicList<scalar> upperLimits;
|
||||
|
||||
// Create bin0. Have upperlimit as factor times lowerlimit.
|
||||
bins.append(DynamicList<label>());
|
||||
lowerLimits.append(sortedVols[0]);
|
||||
upperLimits.append(1.1 * lowerLimits.last());
|
||||
|
||||
forAll(sortedVols, i)
|
||||
{
|
||||
if (sortedVols[i] > upperLimits.last())
|
||||
{
|
||||
// New value outside of current bin
|
||||
|
||||
// Shrink old bin.
|
||||
DynamicList<label>& bin = bins.last();
|
||||
|
||||
bin.shrink();
|
||||
|
||||
Info<< "Collected " << bin.size() << " elements in bin "
|
||||
<< lowerLimits.last() << " .. "
|
||||
<< upperLimits.last() << endl;
|
||||
|
||||
// Create new bin.
|
||||
bins.append(DynamicList<label>());
|
||||
lowerLimits.append(sortedVols[i]);
|
||||
upperLimits.append(1.1 * lowerLimits.last());
|
||||
|
||||
Info<< "Creating new bin " << lowerLimits.last()
|
||||
<< " .. " << upperLimits.last()
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Append to current bin.
|
||||
DynamicList<label>& bin = bins.last();
|
||||
|
||||
bin.append(sortedVols.indices()[i]);
|
||||
}
|
||||
Info<< endl;
|
||||
|
||||
bins.last().shrink();
|
||||
bins.shrink();
|
||||
lowerLimits.shrink();
|
||||
upperLimits.shrink();
|
||||
|
||||
|
||||
//
|
||||
// Write to cellSets.
|
||||
//
|
||||
|
||||
Info<< "Volume bins:" << nl;
|
||||
forAll(bins, binI)
|
||||
{
|
||||
const DynamicList<label>& bin = bins[binI];
|
||||
|
||||
cellSet cells(mesh, "vol" + name(binI), bin.size());
|
||||
|
||||
forAll(bin, i)
|
||||
{
|
||||
cells.insert(bin[i]);
|
||||
}
|
||||
|
||||
Info<< " " << lowerLimits[binI] << " .. " << upperLimits[binI]
|
||||
<< " : writing " << bin.size() << " cells to cellSet "
|
||||
<< cells.name() << endl;
|
||||
|
||||
cells.write();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Convert bins into refinement level.
|
||||
//
|
||||
|
||||
|
||||
// Construct fvMesh to be able to construct volScalarField
|
||||
|
||||
fvMesh fMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fvMesh::defaultRegion,
|
||||
runTime.timeName(),
|
||||
runTime
|
||||
),
|
||||
xferCopy(mesh.points()), // could we safely re-use the data?
|
||||
xferCopy(mesh.faces()),
|
||||
xferCopy(mesh.cells())
|
||||
);
|
||||
|
||||
// Add the boundary patches
|
||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||
|
||||
List<polyPatch*> p(patches.size());
|
||||
|
||||
forAll(p, patchI)
|
||||
{
|
||||
p[patchI] = patches[patchI].clone(fMesh.boundaryMesh()).ptr();
|
||||
}
|
||||
|
||||
fMesh.addFvPatches(p);
|
||||
|
||||
|
||||
// Refinement level
|
||||
IOobject refHeader
|
||||
(
|
||||
"refinementLevel",
|
||||
runTime.timeName(),
|
||||
polyMesh::defaultRegion,
|
||||
runTime
|
||||
);
|
||||
|
||||
if (!readLevel && refHeader.headerOk())
|
||||
{
|
||||
WarningIn(args.executable())
|
||||
<< "Detected " << refHeader.name() << " file in "
|
||||
<< polyMesh::defaultRegion << " directory. Please remove to"
|
||||
<< " recreate it or use the -readLevel option to use it"
|
||||
<< endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
labelIOList refLevel
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"refinementLevel",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
labelList(mesh.nCells(), 0)
|
||||
);
|
||||
|
||||
if (readLevel)
|
||||
{
|
||||
refLevel = labelIOList(refHeader);
|
||||
}
|
||||
|
||||
// Construct volScalarField with same info for post processing
|
||||
volScalarField postRefLevel
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"refinementLevel",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
fMesh,
|
||||
dimensionedScalar("zero", dimless/dimTime, 0)
|
||||
);
|
||||
|
||||
// Set cell values
|
||||
forAll(bins, binI)
|
||||
{
|
||||
const DynamicList<label>& bin = bins[binI];
|
||||
|
||||
forAll(bin, i)
|
||||
{
|
||||
refLevel[bin[i]] = bins.size() - binI - 1;
|
||||
postRefLevel[bin[i]] = refLevel[bin[i]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// For volScalarField: set boundary values to same as cell.
|
||||
// Note: could also put
|
||||
// zeroGradient b.c. on postRefLevel and do evaluate.
|
||||
forAll(postRefLevel.boundaryField(), patchI)
|
||||
{
|
||||
const polyPatch& pp = patches[patchI];
|
||||
|
||||
fvPatchScalarField& bField = postRefLevel.boundaryField()[patchI];
|
||||
|
||||
Info<< "Setting field for patch "<< endl;
|
||||
|
||||
forAll(bField, faceI)
|
||||
{
|
||||
label own = mesh.faceOwner()[pp.start() + faceI];
|
||||
|
||||
bField[faceI] = postRefLevel[own];
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Determined current refinement level and writing to "
|
||||
<< postRefLevel.name() << " (as volScalarField; for post processing)"
|
||||
<< nl
|
||||
<< polyMesh::defaultRegion/refLevel.name()
|
||||
<< " (as labelIOList; for meshing)" << nl
|
||||
<< endl;
|
||||
|
||||
refLevel.write();
|
||||
postRefLevel.write();
|
||||
|
||||
|
||||
// Find out cells to refine to keep to 2:1 refinement level restriction
|
||||
|
||||
// Cells to refine
|
||||
cellSet refCells(mesh, "refCells", 100);
|
||||
|
||||
while
|
||||
(
|
||||
limitRefinementLevel
|
||||
(
|
||||
mesh,
|
||||
refLevel, // current refinement level
|
||||
refCells // cells to refine
|
||||
)
|
||||
)
|
||||
{}
|
||||
|
||||
if (refCells.size())
|
||||
{
|
||||
Info<< "Collected " << refCells.size() << " cells that need to be"
|
||||
<< " refined to get closer to overall 2:1 refinement level limit"
|
||||
<< nl
|
||||
<< "Written cells to be refined to cellSet " << refCells.name()
|
||||
<< nl << endl;
|
||||
|
||||
refCells.write();
|
||||
|
||||
Info<< "After refinement this tool can be run again to see if the 2:1"
|
||||
<< " limit is observed all over the mesh" << nl << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "All cells in the mesh observe the 2:1 refinement level limit"
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,4 @@
|
||||
removeFaces.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/removeFaces
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools \
|
||||
-ldynamicMesh \
|
||||
-lfiniteVolume \
|
||||
-lgenericPatchFields
|
||||
186
applications/utilities/mesh/advanced/removeFaces/removeFaces.C
Normal file
186
applications/utilities/mesh/advanced/removeFaces/removeFaces.C
Normal file
@ -0,0 +1,186 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
removeFaces
|
||||
|
||||
Description
|
||||
Utility to remove faces (combines cells on both sides).
|
||||
|
||||
Takes faceSet of candidates for removal and writes faceSet with faces that
|
||||
will actually be removed. (because e.g. would cause two faces between the
|
||||
same cells). See removeFaces in dynamicMesh library for constraints.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "faceSet.H"
|
||||
#include "removeFaces.H"
|
||||
#include "ReadFields.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
# include "addOverwriteOption.H"
|
||||
argList::validArgs.append("faceSet");
|
||||
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
runTime.functionObjects().off();
|
||||
# include "createMesh.H"
|
||||
const word oldInstance = mesh.pointsInstance();
|
||||
|
||||
const word setName = args[1];
|
||||
const bool overwrite = args.optionFound("overwrite");
|
||||
|
||||
// Read faces
|
||||
faceSet candidateSet(mesh, setName);
|
||||
|
||||
Pout<< "Read " << candidateSet.size() << " faces to remove" << nl
|
||||
<< endl;
|
||||
|
||||
|
||||
labelList candidates(candidateSet.toc());
|
||||
|
||||
// Face removal engine. No checking for not merging boundary faces.
|
||||
removeFaces faceRemover(mesh, 2);
|
||||
|
||||
// Get compatible set of faces and connected sets of cells.
|
||||
labelList cellRegion;
|
||||
labelList cellRegionMaster;
|
||||
labelList facesToRemove;
|
||||
|
||||
faceRemover.compatibleRemoves
|
||||
(
|
||||
candidates,
|
||||
cellRegion,
|
||||
cellRegionMaster,
|
||||
facesToRemove
|
||||
);
|
||||
|
||||
{
|
||||
faceSet compatibleRemoves(mesh, "compatibleRemoves", facesToRemove);
|
||||
|
||||
Pout<< "Original faces to be removed:" << candidateSet.size() << nl
|
||||
<< "New faces to be removed:" << compatibleRemoves.size() << nl
|
||||
<< endl;
|
||||
|
||||
Pout<< "Writing new faces to be removed to faceSet "
|
||||
<< compatibleRemoves.instance()
|
||||
/compatibleRemoves.local()
|
||||
/compatibleRemoves.name()
|
||||
<< endl;
|
||||
|
||||
compatibleRemoves.write();
|
||||
}
|
||||
|
||||
|
||||
// Read objects in time directory
|
||||
IOobjectList objects(mesh, runTime.timeName());
|
||||
|
||||
// Read vol fields.
|
||||
PtrList<volScalarField> vsFlds;
|
||||
ReadFields(mesh, objects, vsFlds);
|
||||
|
||||
PtrList<volVectorField> vvFlds;
|
||||
ReadFields(mesh, objects, vvFlds);
|
||||
|
||||
PtrList<volSphericalTensorField> vstFlds;
|
||||
ReadFields(mesh, objects, vstFlds);
|
||||
|
||||
PtrList<volSymmTensorField> vsymtFlds;
|
||||
ReadFields(mesh, objects, vsymtFlds);
|
||||
|
||||
PtrList<volTensorField> vtFlds;
|
||||
ReadFields(mesh, objects, vtFlds);
|
||||
|
||||
// Read surface fields.
|
||||
PtrList<surfaceScalarField> ssFlds;
|
||||
ReadFields(mesh, objects, ssFlds);
|
||||
|
||||
PtrList<surfaceVectorField> svFlds;
|
||||
ReadFields(mesh, objects, svFlds);
|
||||
|
||||
PtrList<surfaceSphericalTensorField> sstFlds;
|
||||
ReadFields(mesh, objects, sstFlds);
|
||||
|
||||
PtrList<surfaceSymmTensorField> ssymtFlds;
|
||||
ReadFields(mesh, objects, ssymtFlds);
|
||||
|
||||
PtrList<surfaceTensorField> stFlds;
|
||||
ReadFields(mesh, objects, stFlds);
|
||||
|
||||
|
||||
// Topo changes container
|
||||
polyTopoChange meshMod(mesh);
|
||||
|
||||
// Insert mesh refinement into polyTopoChange.
|
||||
faceRemover.setRefinement
|
||||
(
|
||||
facesToRemove,
|
||||
cellRegion,
|
||||
cellRegionMaster,
|
||||
meshMod
|
||||
);
|
||||
|
||||
autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh(mesh, false);
|
||||
|
||||
mesh.updateMesh(morphMap);
|
||||
|
||||
// Move mesh (since morphing does not do this)
|
||||
if (morphMap().hasMotionPoints())
|
||||
{
|
||||
mesh.movePoints(morphMap().preMotionPoints());
|
||||
}
|
||||
|
||||
// Update numbering of cells/vertices.
|
||||
faceRemover.updateMesh(morphMap);
|
||||
|
||||
if (!overwrite)
|
||||
{
|
||||
runTime++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh.setInstance(oldInstance);
|
||||
}
|
||||
|
||||
// Take over refinement levels and write to new time directory.
|
||||
Pout<< "Writing mesh to time " << runTime.timeName() << endl;
|
||||
mesh.write();
|
||||
|
||||
Pout<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,5 @@
|
||||
edgeStats.C
|
||||
selectCells.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/selectCells
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude
|
||||
|
||||
|
||||
EXE_LIBS = \
|
||||
-ldynamicMesh \
|
||||
-lmeshTools \
|
||||
-ltriSurface \
|
||||
-llagrangian
|
||||
221
applications/utilities/mesh/advanced/selectCells/edgeStats.C
Normal file
221
applications/utilities/mesh/advanced/selectCells/edgeStats.C
Normal file
@ -0,0 +1,221 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ 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 "edgeStats.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
#include "Ostream.H"
|
||||
#include "twoDPointCorrector.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::scalar Foam::edgeStats::edgeTol_ = 1e-3;
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::direction Foam::edgeStats::getNormalDir
|
||||
(
|
||||
const twoDPointCorrector* correct2DPtr
|
||||
) const
|
||||
{
|
||||
direction dir = 3;
|
||||
|
||||
if (correct2DPtr)
|
||||
{
|
||||
const vector& normal = correct2DPtr->planeNormal();
|
||||
|
||||
if (mag(normal & vector(1, 0, 0)) > 1-edgeTol_)
|
||||
{
|
||||
dir = 0;
|
||||
}
|
||||
else if (mag(normal & vector(0, 1, 0)) > 1-edgeTol_)
|
||||
{
|
||||
dir = 1;
|
||||
}
|
||||
else if (mag(normal & vector(0, 0, 1)) > 1-edgeTol_)
|
||||
{
|
||||
dir = 2;
|
||||
}
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
// Construct from mesh
|
||||
Foam::edgeStats::edgeStats(const polyMesh& mesh)
|
||||
:
|
||||
mesh_(mesh),
|
||||
normalDir_(3)
|
||||
{
|
||||
IOobject motionObj
|
||||
(
|
||||
"motionProperties",
|
||||
mesh.time().constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
if (motionObj.headerOk())
|
||||
{
|
||||
Info<< "Reading " << mesh.time().constant() / "motionProperties"
|
||||
<< endl << endl;
|
||||
|
||||
IOdictionary motionProperties(motionObj);
|
||||
|
||||
Switch twoDMotion(motionProperties.lookup("twoDMotion"));
|
||||
|
||||
if (twoDMotion)
|
||||
{
|
||||
Info<< "Correcting for 2D motion" << endl << endl;
|
||||
|
||||
autoPtr<twoDPointCorrector> correct2DPtr
|
||||
(
|
||||
new twoDPointCorrector(mesh)
|
||||
);
|
||||
|
||||
normalDir_ = getNormalDir(&correct2DPtr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Construct from components
|
||||
Foam::edgeStats::edgeStats
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const twoDPointCorrector* correct2DPtr
|
||||
)
|
||||
:
|
||||
mesh_(mesh),
|
||||
normalDir_(getNormalDir(correct2DPtr))
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::scalar Foam::edgeStats::minLen(Ostream& os) const
|
||||
{
|
||||
label nX = 0;
|
||||
label nY = 0;
|
||||
label nZ = 0;
|
||||
|
||||
scalar minX = GREAT;
|
||||
scalar maxX = -GREAT;
|
||||
vector x(1, 0, 0);
|
||||
|
||||
scalar minY = GREAT;
|
||||
scalar maxY = -GREAT;
|
||||
vector y(0, 1, 0);
|
||||
|
||||
scalar minZ = GREAT;
|
||||
scalar maxZ = -GREAT;
|
||||
vector z(0, 0, 1);
|
||||
|
||||
scalar minOther = GREAT;
|
||||
scalar maxOther = -GREAT;
|
||||
|
||||
const edgeList& edges = mesh_.edges();
|
||||
|
||||
forAll(edges, edgeI)
|
||||
{
|
||||
const edge& e = edges[edgeI];
|
||||
|
||||
vector eVec(e.vec(mesh_.points()));
|
||||
|
||||
scalar eMag = mag(eVec);
|
||||
|
||||
eVec /= eMag;
|
||||
|
||||
if (mag(eVec & x) > 1-edgeTol_)
|
||||
{
|
||||
minX = min(minX, eMag);
|
||||
maxX = max(maxX, eMag);
|
||||
nX++;
|
||||
}
|
||||
else if (mag(eVec & y) > 1-edgeTol_)
|
||||
{
|
||||
minY = min(minY, eMag);
|
||||
maxY = max(maxY, eMag);
|
||||
nY++;
|
||||
}
|
||||
else if (mag(eVec & z) > 1-edgeTol_)
|
||||
{
|
||||
minZ = min(minZ, eMag);
|
||||
maxZ = max(maxZ, eMag);
|
||||
nZ++;
|
||||
}
|
||||
else
|
||||
{
|
||||
minOther = min(minOther, eMag);
|
||||
maxOther = max(maxOther, eMag);
|
||||
}
|
||||
}
|
||||
|
||||
os << "Mesh bounding box:" << boundBox(mesh_.points()) << nl << nl
|
||||
<< "Mesh edge statistics:" << nl
|
||||
<< " x aligned : number:" << nX << "\tminLen:" << minX
|
||||
<< "\tmaxLen:" << maxX << nl
|
||||
<< " y aligned : number:" << nY << "\tminLen:" << minY
|
||||
<< "\tmaxLen:" << maxY << nl
|
||||
<< " z aligned : number:" << nZ << "\tminLen:" << minZ
|
||||
<< "\tmaxLen:" << maxZ << nl
|
||||
<< " other : number:" << mesh_.nEdges() - nX - nY - nZ
|
||||
<< "\tminLen:" << minOther
|
||||
<< "\tmaxLen:" << maxOther << nl << endl;
|
||||
|
||||
if (normalDir_ == 0)
|
||||
{
|
||||
return min(minY, min(minZ, minOther));
|
||||
}
|
||||
else if (normalDir_ == 1)
|
||||
{
|
||||
return min(minX, min(minZ, minOther));
|
||||
}
|
||||
else if (normalDir_ == 2)
|
||||
{
|
||||
return min(minX, min(minY, minOther));
|
||||
}
|
||||
else
|
||||
{
|
||||
return min(minX, min(minY, min(minZ, minOther)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
110
applications/utilities/mesh/advanced/selectCells/edgeStats.H
Normal file
110
applications/utilities/mesh/advanced/selectCells/edgeStats.H
Normal file
@ -0,0 +1,110 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ 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::edgeStats
|
||||
|
||||
Description
|
||||
Helper class to calculate minimum edge length on mesh.
|
||||
|
||||
SourceFiles
|
||||
edgeStats.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef edgeStats_H
|
||||
#define edgeStats_H
|
||||
|
||||
#include "direction.H"
|
||||
#include "scalar.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
class polyMesh;
|
||||
class Ostream;
|
||||
class twoDPointCorrector;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class edgeStats Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class edgeStats
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Reference to mesh.
|
||||
const polyMesh& mesh_;
|
||||
|
||||
//- Component (0,1,2) of normal direction or 3 if 3D case.
|
||||
direction normalDir_;
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- If 2d get component of normal dir.
|
||||
direction getNormalDir(const twoDPointCorrector*) const;
|
||||
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
edgeStats(const edgeStats&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const edgeStats&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Static data members
|
||||
|
||||
// Max (cos of) angle for edges to be considered aligned with axis.
|
||||
static const scalar edgeTol_;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from mesh
|
||||
edgeStats(const polyMesh& mesh);
|
||||
|
||||
//- Construct from mesh and corrector
|
||||
edgeStats(const polyMesh& mesh, const twoDPointCorrector* );
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Calculate minimum edge length and print
|
||||
scalar minLen(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
522
applications/utilities/mesh/advanced/selectCells/selectCells.C
Normal file
522
applications/utilities/mesh/advanced/selectCells/selectCells.C
Normal file
@ -0,0 +1,522 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
selectCells
|
||||
|
||||
Description
|
||||
Select cells in relation to surface.
|
||||
|
||||
Divides cells into three sets:
|
||||
- cutCells : cells cut by surface or close to surface.
|
||||
- outside : cells not in cutCells and reachable from set of
|
||||
user-defined points (outsidePoints)
|
||||
- inside : same but not reachable.
|
||||
|
||||
Finally the wanted sets are combined into a cellSet 'selected'. Apart
|
||||
from straightforward adding the contents there are a few extra rules to
|
||||
make sure that the surface of the 'outside' of the mesh is singly
|
||||
connected.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
#include "IOdictionary.H"
|
||||
#include "twoDPointCorrector.H"
|
||||
#include "OFstream.H"
|
||||
#include "meshTools.H"
|
||||
|
||||
#include "triSurface.H"
|
||||
#include "triSurfaceSearch.H"
|
||||
#include "meshSearch.H"
|
||||
#include "cellClassification.H"
|
||||
#include "cellSet.H"
|
||||
#include "cellInfo.H"
|
||||
#include "MeshWave.H"
|
||||
#include "edgeStats.H"
|
||||
#include "treeDataTriSurface.H"
|
||||
#include "indexedOctree.H"
|
||||
#include "globalMeshData.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// cellType for cells included/not included in mesh.
|
||||
static const label MESH = cellClassification::INSIDE;
|
||||
static const label NONMESH = cellClassification::OUTSIDE;
|
||||
|
||||
|
||||
void writeSet(const cellSet& cells, const string& msg)
|
||||
{
|
||||
Info<< "Writing " << msg << " (" << cells.size() << ") to cellSet "
|
||||
<< cells.instance()/cells.local()/cells.name()
|
||||
<< endl << endl;
|
||||
cells.write();
|
||||
}
|
||||
|
||||
|
||||
void getType(const labelList& elems, const label type, labelHashSet& set)
|
||||
{
|
||||
forAll(elems, i)
|
||||
{
|
||||
if (elems[i] == type)
|
||||
{
|
||||
set.insert(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void cutBySurface
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const meshSearch& queryMesh,
|
||||
const triSurfaceSearch& querySurf,
|
||||
|
||||
const pointField& outsidePts,
|
||||
const bool selectCut,
|
||||
const bool selectInside,
|
||||
const bool selectOutside,
|
||||
const scalar nearDist,
|
||||
|
||||
cellClassification& cellType
|
||||
)
|
||||
{
|
||||
// Cut with surface and classify as inside/outside/cut
|
||||
cellType =
|
||||
cellClassification
|
||||
(
|
||||
mesh,
|
||||
queryMesh,
|
||||
querySurf,
|
||||
outsidePts
|
||||
);
|
||||
|
||||
// Get inside/outside/cutCells cellSets.
|
||||
cellSet inside(mesh, "inside", mesh.nCells()/10);
|
||||
getType(cellType, cellClassification::INSIDE, inside);
|
||||
writeSet(inside, "inside cells");
|
||||
|
||||
cellSet outside(mesh, "outside", mesh.nCells()/10);
|
||||
getType(cellType, cellClassification::OUTSIDE, outside);
|
||||
writeSet(outside, "outside cells");
|
||||
|
||||
cellSet cutCells(mesh, "cutCells", mesh.nCells()/10);
|
||||
getType(cellType, cellClassification::CUT, cutCells);
|
||||
writeSet(cutCells, "cells cut by surface");
|
||||
|
||||
|
||||
// Change cellType to reflect selected part of mesh. Use
|
||||
// MESH to denote selected part, NONMESH for all
|
||||
// other cells.
|
||||
// Is a bit of a hack but allows us to reuse all the functionality
|
||||
// in cellClassification.
|
||||
|
||||
forAll(cellType, cellI)
|
||||
{
|
||||
label cType = cellType[cellI];
|
||||
|
||||
if (cType == cellClassification::CUT)
|
||||
{
|
||||
if (selectCut)
|
||||
{
|
||||
cellType[cellI] = MESH;
|
||||
}
|
||||
else
|
||||
{
|
||||
cellType[cellI] = NONMESH;
|
||||
}
|
||||
}
|
||||
else if (cType == cellClassification::INSIDE)
|
||||
{
|
||||
if (selectInside)
|
||||
{
|
||||
cellType[cellI] = MESH;
|
||||
}
|
||||
else
|
||||
{
|
||||
cellType[cellI] = NONMESH;
|
||||
}
|
||||
}
|
||||
else if (cType == cellClassification::OUTSIDE)
|
||||
{
|
||||
if (selectOutside)
|
||||
{
|
||||
cellType[cellI] = MESH;
|
||||
}
|
||||
else
|
||||
{
|
||||
cellType[cellI] = NONMESH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn("cutBySurface")
|
||||
<< "Multiple mesh regions in original mesh" << endl
|
||||
<< "Please use splitMeshRegions to separate these"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (nearDist > 0)
|
||||
{
|
||||
Info<< "Removing cells with points closer than " << nearDist
|
||||
<< " to the surface ..." << nl << endl;
|
||||
|
||||
const pointField& pts = mesh.points();
|
||||
const indexedOctree<treeDataTriSurface>& tree = querySurf.tree();
|
||||
|
||||
label nRemoved = 0;
|
||||
|
||||
forAll(pts, pointI)
|
||||
{
|
||||
const point& pt = pts[pointI];
|
||||
|
||||
pointIndexHit hitInfo = tree.findNearest(pt, sqr(nearDist));
|
||||
|
||||
if (hitInfo.hit())
|
||||
{
|
||||
const labelList& pCells = mesh.pointCells()[pointI];
|
||||
|
||||
forAll(pCells, i)
|
||||
{
|
||||
if (cellType[pCells[i]] != NONMESH)
|
||||
{
|
||||
cellType[pCells[i]] = NONMESH;
|
||||
nRemoved++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tmp<pointField> tnearest = querySurf.calcNearest(pts);
|
||||
// const pointField& nearest = tnearest();
|
||||
//
|
||||
// label nRemoved = 0;
|
||||
//
|
||||
// forAll(nearest, pointI)
|
||||
// {
|
||||
// if (mag(nearest[pointI] - pts[pointI]) < nearDist)
|
||||
// {
|
||||
// const labelList& pCells = mesh.pointCells()[pointI];
|
||||
//
|
||||
// forAll(pCells, i)
|
||||
// {
|
||||
// if (cellType[pCells[i]] != NONMESH)
|
||||
// {
|
||||
// cellType[pCells[i]] = NONMESH;
|
||||
// nRemoved++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
Info<< "Removed " << nRemoved << " cells since too close to surface"
|
||||
<< nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// We're meshing the outside. Subset the currently selected mesh cells with the
|
||||
// ones reachable from the outsidepoints.
|
||||
label selectOutsideCells
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const meshSearch& queryMesh,
|
||||
const pointField& outsidePts,
|
||||
cellClassification& cellType
|
||||
)
|
||||
{
|
||||
//
|
||||
// Check all outsidePts and for all of them inside a mesh cell
|
||||
// collect the faces to start walking from
|
||||
//
|
||||
|
||||
// Outside faces
|
||||
labelHashSet outsideFacesMap(outsidePts.size() * 6 * 2);
|
||||
DynamicList<label> outsideFaces(outsideFacesMap.size());
|
||||
// CellInfo on outside faces
|
||||
DynamicList<cellInfo> outsideFacesInfo(outsideFacesMap.size());
|
||||
|
||||
// cellInfo for mesh cell
|
||||
const cellInfo meshInfo(MESH);
|
||||
|
||||
forAll(outsidePts, outsidePtI)
|
||||
{
|
||||
// Find cell containing point. Linear search.
|
||||
label cellI = queryMesh.findCell(outsidePts[outsidePtI], -1, false);
|
||||
|
||||
if (cellI != -1 && cellType[cellI] == MESH)
|
||||
{
|
||||
Info<< "Marking cell " << cellI << " containing outside point "
|
||||
<< outsidePts[outsidePtI] << " with type " << cellType[cellI]
|
||||
<< " ..." << endl;
|
||||
|
||||
//
|
||||
// Mark this cell and its faces to start walking from
|
||||
//
|
||||
|
||||
// Mark faces of cellI
|
||||
const labelList& cFaces = mesh.cells()[cellI];
|
||||
forAll(cFaces, i)
|
||||
{
|
||||
label faceI = cFaces[i];
|
||||
|
||||
if (outsideFacesMap.insert(faceI))
|
||||
{
|
||||
outsideFaces.append(faceI);
|
||||
outsideFacesInfo.append(meshInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Floodfill starting from outsideFaces (of type meshInfo)
|
||||
MeshWave<cellInfo> regionCalc
|
||||
(
|
||||
mesh,
|
||||
outsideFaces.shrink(),
|
||||
outsideFacesInfo.shrink(),
|
||||
mesh.globalData().nTotalCells()+1 // max iterations
|
||||
);
|
||||
|
||||
// Now regionCalc should hold info on cells that are reachable from
|
||||
// changedFaces. Use these to subset cellType
|
||||
const List<cellInfo>& allCellInfo = regionCalc.allCellInfo();
|
||||
|
||||
label nChanged = 0;
|
||||
|
||||
forAll(allCellInfo, cellI)
|
||||
{
|
||||
if (cellType[cellI] == MESH)
|
||||
{
|
||||
// Original cell was selected for meshing. Check if cell was
|
||||
// reached from outsidePoints
|
||||
if (allCellInfo[cellI].type() != MESH)
|
||||
{
|
||||
cellType[cellI] = NONMESH;
|
||||
nChanged++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nChanged;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
# include "createPolyMesh.H"
|
||||
|
||||
// Mesh edge statistics calculator
|
||||
edgeStats edgeCalc(mesh);
|
||||
|
||||
|
||||
IOdictionary refineDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"selectCellsDict",
|
||||
runTime.system(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
fileName surfName(refineDict.lookup("surface"));
|
||||
pointField outsidePts(refineDict.lookup("outsidePoints"));
|
||||
bool useSurface(readBool(refineDict.lookup("useSurface")));
|
||||
bool selectCut(readBool(refineDict.lookup("selectCut")));
|
||||
bool selectInside(readBool(refineDict.lookup("selectInside")));
|
||||
bool selectOutside(readBool(refineDict.lookup("selectOutside")));
|
||||
scalar nearDist(readScalar(refineDict.lookup("nearDistance")));
|
||||
|
||||
|
||||
if (useSurface)
|
||||
{
|
||||
Info<< "Cells to be used for meshing (0=false, 1=true):" << nl
|
||||
<< " cells cut by surface : " << selectCut << nl
|
||||
<< " cells inside of surface : " << selectInside << nl
|
||||
<< " cells outside of surface : " << selectOutside << nl
|
||||
<< " cells with points further than : " << nearDist << nl
|
||||
<< endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Cells to be used for meshing (0=false, 1=true):" << nl
|
||||
<< " cells reachable from outsidePoints:" << selectOutside << nl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Print edge stats on original mesh.
|
||||
(void)edgeCalc.minLen(Info);
|
||||
|
||||
// Search engine on mesh. Face decomposition since faces might be warped.
|
||||
meshSearch queryMesh(mesh);
|
||||
|
||||
// Check all 'outside' points
|
||||
forAll(outsidePts, outsideI)
|
||||
{
|
||||
const point& outsidePoint = outsidePts[outsideI];
|
||||
|
||||
label cellI = queryMesh.findCell(outsidePoint, -1, false);
|
||||
if (returnReduce(cellI, maxOp<label>()) == -1)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "outsidePoint " << outsidePoint
|
||||
<< " is not inside any cell"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Cell status (compared to surface if provided): inside/outside/cut.
|
||||
// Start off from everything selected and cut later.
|
||||
cellClassification cellType
|
||||
(
|
||||
mesh,
|
||||
labelList
|
||||
(
|
||||
mesh.nCells(),
|
||||
cellClassification::MESH
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// Surface
|
||||
autoPtr<triSurface> surf(NULL);
|
||||
// Search engine on surface.
|
||||
autoPtr<triSurfaceSearch> querySurf(NULL);
|
||||
|
||||
if (useSurface)
|
||||
{
|
||||
surf.reset(new triSurface(surfName));
|
||||
|
||||
// Dump some stats
|
||||
surf().writeStats(Info);
|
||||
|
||||
// Search engine on surface.
|
||||
querySurf.reset(new triSurfaceSearch(surf));
|
||||
|
||||
// Set cellType[cellI] according to relation to surface
|
||||
cutBySurface
|
||||
(
|
||||
mesh,
|
||||
queryMesh,
|
||||
querySurf,
|
||||
|
||||
outsidePts,
|
||||
selectCut,
|
||||
selectInside,
|
||||
selectOutside,
|
||||
nearDist,
|
||||
|
||||
cellType
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Now 'trim' all the corners from the mesh so meshing/surface extraction
|
||||
// becomes easier.
|
||||
|
||||
label nHanging, nRegionEdges, nRegionPoints, nOutside;
|
||||
|
||||
do
|
||||
{
|
||||
Info<< "Removing cells which after subsetting would have all points"
|
||||
<< " on outside ..." << nl << endl;
|
||||
|
||||
nHanging = cellType.fillHangingCells
|
||||
(
|
||||
MESH, // meshType
|
||||
NONMESH, // fill type
|
||||
mesh.nCells()
|
||||
);
|
||||
|
||||
|
||||
Info<< "Removing edges connecting cells unconnected by faces ..."
|
||||
<< nl << endl;
|
||||
|
||||
nRegionEdges = cellType.fillRegionEdges
|
||||
(
|
||||
MESH, // meshType
|
||||
NONMESH, // fill type
|
||||
mesh.nCells()
|
||||
);
|
||||
|
||||
|
||||
Info<< "Removing points connecting cells unconnected by faces ..."
|
||||
<< nl << endl;
|
||||
|
||||
nRegionPoints = cellType.fillRegionPoints
|
||||
(
|
||||
MESH, // meshType
|
||||
NONMESH, // fill type
|
||||
mesh.nCells()
|
||||
);
|
||||
|
||||
nOutside = 0;
|
||||
if (selectOutside)
|
||||
{
|
||||
// Since we're selecting the cells reachable from outsidePoints
|
||||
// and the set might have changed, redo the outsideCells
|
||||
// calculation
|
||||
nOutside = selectOutsideCells
|
||||
(
|
||||
mesh,
|
||||
queryMesh,
|
||||
outsidePts,
|
||||
cellType
|
||||
);
|
||||
}
|
||||
} while
|
||||
(
|
||||
nHanging != 0
|
||||
|| nRegionEdges != 0
|
||||
|| nRegionPoints != 0
|
||||
|| nOutside != 0
|
||||
);
|
||||
|
||||
cellSet selectedCells(mesh, "selected", mesh.nCells()/10);
|
||||
getType(cellType, MESH, selectedCells);
|
||||
|
||||
writeSet(selectedCells, "cells selected for meshing");
|
||||
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,40 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: dev |
|
||||
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object selectCellsDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Whether to use surface. If false no surface will be read and only
|
||||
// outsidePoints/selectOutside will be used to determine cells to keep.
|
||||
useSurface false;
|
||||
|
||||
// Surface to keep to
|
||||
surface "plexi.obj";
|
||||
|
||||
// What is outside
|
||||
outsidePoints ((-1 -1 -1));
|
||||
|
||||
//
|
||||
// Selection of final set
|
||||
//
|
||||
|
||||
// Select based on side of surface. Usually select inside cells and project
|
||||
// outwards or select outside cells and project inwards.
|
||||
selectCut false;
|
||||
selectInside false;
|
||||
selectOutside true;
|
||||
// Leave out cell closer than nearDistance to the surface. Usually
|
||||
// 0.5*of the cell size. Set to <0 to disable.
|
||||
nearDistance -1;
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,4 @@
|
||||
splitCells.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/splitCells
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-ldynamicMesh \
|
||||
-lmeshTools
|
||||
721
applications/utilities/mesh/advanced/splitCells/splitCells.C
Normal file
721
applications/utilities/mesh/advanced/splitCells/splitCells.C
Normal file
@ -0,0 +1,721 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
splitCells
|
||||
|
||||
Description
|
||||
Utility to split cells with flat faces.
|
||||
|
||||
Uses a geometric cut with a plane dividing the edge angle into two so
|
||||
might produce funny cells. For hexes it will use by default a cut from
|
||||
edge onto opposite edge (i.e. purely topological).
|
||||
|
||||
Options:
|
||||
- split cells from cellSet only
|
||||
- use geometric cut for hexes as well
|
||||
|
||||
The angle is the angle between two faces sharing an edge as seen from
|
||||
inside each cell. So a cube will have all angles 90. If you want
|
||||
to split cells with cell centre outside use e.g. angle 200
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "polyTopoChanger.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "polyMesh.H"
|
||||
#include "cellCuts.H"
|
||||
#include "cellSet.H"
|
||||
#include "cellModeller.H"
|
||||
#include "meshCutter.H"
|
||||
#include "unitConversion.H"
|
||||
#include "geomCellLooper.H"
|
||||
#include "plane.H"
|
||||
#include "edgeVertex.H"
|
||||
#include "meshTools.H"
|
||||
#include "ListOps.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
labelList pack(const boolList& lst)
|
||||
{
|
||||
labelList packedLst(lst.size());
|
||||
label packedI = 0;
|
||||
|
||||
forAll(lst, i)
|
||||
{
|
||||
if (lst[i])
|
||||
{
|
||||
packedLst[packedI++] = i;
|
||||
}
|
||||
}
|
||||
packedLst.setSize(packedI);
|
||||
|
||||
return packedLst;
|
||||
}
|
||||
|
||||
|
||||
scalarField pack(const boolList& lst, const scalarField& elems)
|
||||
{
|
||||
scalarField packedElems(lst.size());
|
||||
label packedI = 0;
|
||||
|
||||
forAll(lst, i)
|
||||
{
|
||||
if (lst[i])
|
||||
{
|
||||
packedElems[packedI++] = elems[i];
|
||||
}
|
||||
}
|
||||
packedElems.setSize(packedI);
|
||||
|
||||
return packedElems;
|
||||
}
|
||||
|
||||
|
||||
// Given sin and cos of max angle between normals calculate whether f0 and f1
|
||||
// on cellI make larger angle. Uses sinAngle only for quadrant detection.
|
||||
bool largerAngle
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const scalar cosAngle,
|
||||
const scalar sinAngle,
|
||||
|
||||
const label cellI,
|
||||
const label f0, // face label
|
||||
const label f1,
|
||||
|
||||
const vector& n0, // normal at f0
|
||||
const vector& n1
|
||||
)
|
||||
{
|
||||
const labelList& own = mesh.faceOwner();
|
||||
|
||||
bool sameFaceOrder = !((own[f0] == cellI) ^ (own[f1] == cellI));
|
||||
|
||||
// Get cos between faceArea vectors. Correct so flat angle (180 degrees)
|
||||
// gives -1.
|
||||
scalar normalCosAngle = n0 & n1;
|
||||
|
||||
if (sameFaceOrder)
|
||||
{
|
||||
normalCosAngle = -normalCosAngle;
|
||||
}
|
||||
|
||||
|
||||
// Get cos between faceCentre and normal vector to determine in
|
||||
// which quadrant angle is. (Is correct for unwarped faces only!)
|
||||
// Correct for non-outwards pointing normal.
|
||||
vector c1c0(mesh.faceCentres()[f1] - mesh.faceCentres()[f0]);
|
||||
c1c0 /= mag(c1c0) + VSMALL;
|
||||
|
||||
scalar fcCosAngle = n0 & c1c0;
|
||||
|
||||
if (own[f0] != cellI)
|
||||
{
|
||||
fcCosAngle = -fcCosAngle;
|
||||
}
|
||||
|
||||
if (sinAngle < 0.0)
|
||||
{
|
||||
// Looking for concave angles (quadrant 3 or 4)
|
||||
if (fcCosAngle <= 0)
|
||||
{
|
||||
// Angle is convex so smaller.
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (normalCosAngle < cosAngle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Looking for convex angles (quadrant 1 or 2)
|
||||
if (fcCosAngle > 0)
|
||||
{
|
||||
// Concave angle
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convex. Check cos of normal vectors.
|
||||
if (normalCosAngle > cosAngle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Split hex (and hex only) along edgeI creating two prisms
|
||||
bool splitHex
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const label cellI,
|
||||
const label edgeI,
|
||||
|
||||
DynamicList<label>& cutCells,
|
||||
DynamicList<labelList>& cellLoops,
|
||||
DynamicList<scalarField>& cellEdgeWeights
|
||||
)
|
||||
{
|
||||
// cut handling functions
|
||||
edgeVertex ev(mesh);
|
||||
|
||||
const edgeList& edges = mesh.edges();
|
||||
const faceList& faces = mesh.faces();
|
||||
|
||||
const edge& e = edges[edgeI];
|
||||
|
||||
// Get faces on the side, i.e. faces not using edge but still using one of
|
||||
// the edge endpoints.
|
||||
|
||||
label leftI = -1;
|
||||
label rightI = -1;
|
||||
label leftFp = -1;
|
||||
label rightFp = -1;
|
||||
|
||||
const cell& cFaces = mesh.cells()[cellI];
|
||||
|
||||
forAll(cFaces, i)
|
||||
{
|
||||
label faceI = cFaces[i];
|
||||
|
||||
const face& f = faces[faceI];
|
||||
|
||||
label fp0 = findIndex(f, e[0]);
|
||||
label fp1 = findIndex(f, e[1]);
|
||||
|
||||
if (fp0 == -1)
|
||||
{
|
||||
if (fp1 != -1)
|
||||
{
|
||||
// Face uses e[1] but not e[0]
|
||||
rightI = faceI;
|
||||
rightFp = fp1;
|
||||
|
||||
if (leftI != -1)
|
||||
{
|
||||
// Have both faces so exit
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fp1 != -1)
|
||||
{
|
||||
// Face uses both e[1] and e[0]
|
||||
}
|
||||
else
|
||||
{
|
||||
leftI = faceI;
|
||||
leftFp = fp0;
|
||||
|
||||
if (rightI != -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (leftI == -1 || rightI == -1)
|
||||
{
|
||||
FatalErrorIn("splitHex") << "Problem : leftI:" << leftI
|
||||
<< " rightI:" << rightI << abort(FatalError);
|
||||
}
|
||||
|
||||
// Walk two vertices further on faces.
|
||||
|
||||
const face& leftF = faces[leftI];
|
||||
|
||||
label leftV = leftF[(leftFp + 2) % leftF.size()];
|
||||
|
||||
const face& rightF = faces[rightI];
|
||||
|
||||
label rightV = rightF[(rightFp + 2) % rightF.size()];
|
||||
|
||||
labelList loop(4);
|
||||
loop[0] = ev.vertToEVert(e[0]);
|
||||
loop[1] = ev.vertToEVert(leftV);
|
||||
loop[2] = ev.vertToEVert(rightV);
|
||||
loop[3] = ev.vertToEVert(e[1]);
|
||||
|
||||
scalarField loopWeights(4);
|
||||
loopWeights[0] = -GREAT;
|
||||
loopWeights[1] = -GREAT;
|
||||
loopWeights[2] = -GREAT;
|
||||
loopWeights[3] = -GREAT;
|
||||
|
||||
cutCells.append(cellI);
|
||||
cellLoops.append(loop);
|
||||
cellEdgeWeights.append(loopWeights);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Split cellI along edgeI with a plane along halfNorm direction.
|
||||
bool splitCell
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const geomCellLooper& cellCutter,
|
||||
|
||||
const label cellI,
|
||||
const label edgeI,
|
||||
const vector& halfNorm,
|
||||
|
||||
const boolList& vertIsCut,
|
||||
const boolList& edgeIsCut,
|
||||
const scalarField& edgeWeight,
|
||||
|
||||
DynamicList<label>& cutCells,
|
||||
DynamicList<labelList>& cellLoops,
|
||||
DynamicList<scalarField>& cellEdgeWeights
|
||||
)
|
||||
{
|
||||
const edge& e = mesh.edges()[edgeI];
|
||||
|
||||
vector eVec = e.vec(mesh.points());
|
||||
eVec /= mag(eVec);
|
||||
|
||||
vector planeN = eVec ^ halfNorm;
|
||||
|
||||
// Slightly tilt plane to make it not cut edges exactly
|
||||
// halfway on fully regular meshes (since we want cuts
|
||||
// to be snapped to vertices)
|
||||
planeN += 0.01*halfNorm;
|
||||
|
||||
planeN /= mag(planeN);
|
||||
|
||||
// Define plane through edge
|
||||
plane cutPlane(mesh.points()[e.start()], planeN);
|
||||
|
||||
labelList loop;
|
||||
scalarField loopWeights;
|
||||
|
||||
if
|
||||
(
|
||||
cellCutter.cut
|
||||
(
|
||||
cutPlane,
|
||||
cellI,
|
||||
vertIsCut,
|
||||
edgeIsCut,
|
||||
edgeWeight,
|
||||
loop,
|
||||
loopWeights
|
||||
)
|
||||
)
|
||||
{
|
||||
// Did manage to cut cell. Copy into overall list.
|
||||
cutCells.append(cellI);
|
||||
cellLoops.append(loop);
|
||||
cellEdgeWeights.append(loopWeights);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Collects cuts for all cells in cellSet
|
||||
void collectCuts
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const geomCellLooper& cellCutter,
|
||||
const bool geometry,
|
||||
const scalar minCos,
|
||||
const scalar minSin,
|
||||
const cellSet& cellsToCut,
|
||||
|
||||
DynamicList<label>& cutCells,
|
||||
DynamicList<labelList>& cellLoops,
|
||||
DynamicList<scalarField>& cellEdgeWeights
|
||||
)
|
||||
{
|
||||
// Get data from mesh
|
||||
const cellShapeList& cellShapes = mesh.cellShapes();
|
||||
const labelList& own = mesh.faceOwner();
|
||||
const labelListList& cellEdges = mesh.cellEdges();
|
||||
const vectorField& faceAreas = mesh.faceAreas();
|
||||
|
||||
// Hex shape
|
||||
const cellModel& hex = *(cellModeller::lookup("hex"));
|
||||
|
||||
// cut handling functions
|
||||
edgeVertex ev(mesh);
|
||||
|
||||
|
||||
// Cut information per mesh entity
|
||||
boolList vertIsCut(mesh.nPoints(), false);
|
||||
boolList edgeIsCut(mesh.nEdges(), false);
|
||||
scalarField edgeWeight(mesh.nEdges(), -GREAT);
|
||||
|
||||
forAllConstIter(cellSet, cellsToCut, iter)
|
||||
{
|
||||
const label cellI = iter.key();
|
||||
const labelList& cEdges = cellEdges[cellI];
|
||||
|
||||
forAll(cEdges, i)
|
||||
{
|
||||
label edgeI = cEdges[i];
|
||||
|
||||
label f0, f1;
|
||||
meshTools::getEdgeFaces(mesh, cellI, edgeI, f0, f1);
|
||||
|
||||
vector n0 = faceAreas[f0];
|
||||
n0 /= mag(n0);
|
||||
|
||||
vector n1 = faceAreas[f1];
|
||||
n1 /= mag(n1);
|
||||
|
||||
if
|
||||
(
|
||||
largerAngle
|
||||
(
|
||||
mesh,
|
||||
minCos,
|
||||
minSin,
|
||||
|
||||
cellI,
|
||||
f0,
|
||||
f1,
|
||||
n0,
|
||||
n1
|
||||
)
|
||||
)
|
||||
{
|
||||
bool splitOk = false;
|
||||
|
||||
if (!geometry && cellShapes[cellI].model() == hex)
|
||||
{
|
||||
splitOk =
|
||||
splitHex
|
||||
(
|
||||
mesh,
|
||||
cellI,
|
||||
edgeI,
|
||||
|
||||
cutCells,
|
||||
cellLoops,
|
||||
cellEdgeWeights
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
vector halfNorm;
|
||||
|
||||
if ((own[f0] == cellI) ^ (own[f1] == cellI))
|
||||
{
|
||||
// Opposite owner orientation
|
||||
halfNorm = 0.5*(n0 - n1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Faces have same owner or same neighbour so
|
||||
// normals point in same direction
|
||||
halfNorm = 0.5*(n0 + n1);
|
||||
}
|
||||
|
||||
splitOk =
|
||||
splitCell
|
||||
(
|
||||
mesh,
|
||||
cellCutter,
|
||||
cellI,
|
||||
edgeI,
|
||||
halfNorm,
|
||||
|
||||
vertIsCut,
|
||||
edgeIsCut,
|
||||
edgeWeight,
|
||||
|
||||
cutCells,
|
||||
cellLoops,
|
||||
cellEdgeWeights
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (splitOk)
|
||||
{
|
||||
// Update cell/edge/vertex wise info.
|
||||
label index = cellLoops.size() - 1;
|
||||
const labelList& loop = cellLoops[index];
|
||||
const scalarField& loopWeights = cellEdgeWeights[index];
|
||||
|
||||
forAll(loop, i)
|
||||
{
|
||||
label cut = loop[i];
|
||||
|
||||
if (ev.isEdge(cut))
|
||||
{
|
||||
edgeIsCut[ev.getEdge(cut)] = true;
|
||||
edgeWeight[ev.getEdge(cut)] = loopWeights[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
vertIsCut[ev.getVertex(cut)] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Stop checking edges for this cell.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cutCells.shrink();
|
||||
cellLoops.shrink();
|
||||
cellEdgeWeights.shrink();
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::addNote
|
||||
(
|
||||
"split cells with flat faces"
|
||||
);
|
||||
#include "addOverwriteOption.H"
|
||||
argList::noParallel();
|
||||
argList::validArgs.append("edgeAngle [0..360]");
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"set",
|
||||
"name",
|
||||
"split cells from specified cellSet only"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"geometry",
|
||||
"use geometric cut for hexes as well"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"tol",
|
||||
"scalar", "edge snap tolerance (default 0.2)"
|
||||
);
|
||||
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
runTime.functionObjects().off();
|
||||
#include "createPolyMesh.H"
|
||||
const word oldInstance = mesh.pointsInstance();
|
||||
|
||||
const scalar featureAngle = args.argRead<scalar>(1);
|
||||
const scalar minCos = Foam::cos(degToRad(featureAngle));
|
||||
const scalar minSin = Foam::sin(degToRad(featureAngle));
|
||||
|
||||
const bool readSet = args.optionFound("set");
|
||||
const bool geometry = args.optionFound("geometry");
|
||||
const bool overwrite = args.optionFound("overwrite");
|
||||
|
||||
const scalar edgeTol = args.optionLookupOrDefault("tol", 0.2);
|
||||
|
||||
Info<< "Trying to split cells with internal angles > feature angle\n" << nl
|
||||
<< "featureAngle : " << featureAngle << nl
|
||||
<< "edge snapping tol : " << edgeTol << nl;
|
||||
if (readSet)
|
||||
{
|
||||
Info<< "candidate cells : cellSet " << args["set"] << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "candidate cells : all cells" << nl;
|
||||
}
|
||||
if (geometry)
|
||||
{
|
||||
Info<< "hex cuts : geometric; using edge tolerance" << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "hex cuts : topological; cut to opposite edge" << nl;
|
||||
}
|
||||
Info<< endl;
|
||||
|
||||
|
||||
// Cell circumference cutter
|
||||
geomCellLooper cellCutter(mesh);
|
||||
// Snap all edge cuts close to endpoints to vertices.
|
||||
geomCellLooper::setSnapTol(edgeTol);
|
||||
|
||||
// Candidate cells to cut
|
||||
cellSet cellsToCut(mesh, "cellsToCut", mesh.nCells()/100);
|
||||
|
||||
if (readSet)
|
||||
{
|
||||
// Read cells to cut from cellSet
|
||||
cellSet cells(mesh, args["set"]);
|
||||
|
||||
cellsToCut = cells;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!readSet)
|
||||
{
|
||||
// Try all cells for cutting
|
||||
for (label cellI = 0; cellI < mesh.nCells(); cellI++)
|
||||
{
|
||||
cellsToCut.insert(cellI);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Cut information per cut cell
|
||||
DynamicList<label> cutCells(mesh.nCells()/10 + 10);
|
||||
DynamicList<labelList> cellLoops(mesh.nCells()/10 + 10);
|
||||
DynamicList<scalarField> cellEdgeWeights(mesh.nCells()/10 + 10);
|
||||
|
||||
collectCuts
|
||||
(
|
||||
mesh,
|
||||
cellCutter,
|
||||
geometry,
|
||||
minCos,
|
||||
minSin,
|
||||
cellsToCut,
|
||||
|
||||
cutCells,
|
||||
cellLoops,
|
||||
cellEdgeWeights
|
||||
);
|
||||
|
||||
cellSet cutSet(mesh, "cutSet", cutCells.size());
|
||||
forAll(cutCells, i)
|
||||
{
|
||||
cutSet.insert(cutCells[i]);
|
||||
}
|
||||
|
||||
// Gets cuts across cells from cuts through edges.
|
||||
Info<< "Writing " << cutSet.size() << " cells to cut to cellSet "
|
||||
<< cutSet.instance()/cutSet.local()/cutSet.name()
|
||||
<< endl << endl;
|
||||
cutSet.write();
|
||||
|
||||
// Analyze cuts for clashes.
|
||||
cellCuts cuts
|
||||
(
|
||||
mesh,
|
||||
cutCells, // cells candidate for cutting
|
||||
cellLoops,
|
||||
cellEdgeWeights
|
||||
);
|
||||
|
||||
Info<< "Actually cut cells:" << cuts.nLoops() << nl << endl;
|
||||
|
||||
if (cuts.nLoops() == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Remove cut cells from cellsToCut (Note:only relevant if -readSet)
|
||||
forAll(cuts.cellLoops(), cellI)
|
||||
{
|
||||
if (cuts.cellLoops()[cellI].size())
|
||||
{
|
||||
//Info<< "Removing cut cell " << cellI << " from wishlist"
|
||||
// << endl;
|
||||
cellsToCut.erase(cellI);
|
||||
}
|
||||
}
|
||||
|
||||
// At least some cells are cut.
|
||||
polyTopoChange meshMod(mesh);
|
||||
|
||||
// Cutting engine
|
||||
meshCutter cutter(mesh);
|
||||
|
||||
// Insert mesh refinement into polyTopoChange.
|
||||
cutter.setRefinement(cuts, meshMod);
|
||||
|
||||
// Do all changes
|
||||
Info<< "Morphing ..." << endl;
|
||||
|
||||
if (!overwrite)
|
||||
{
|
||||
runTime++;
|
||||
}
|
||||
|
||||
autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh(mesh, false);
|
||||
|
||||
if (morphMap().hasMotionPoints())
|
||||
{
|
||||
mesh.movePoints(morphMap().preMotionPoints());
|
||||
}
|
||||
|
||||
// Update stored labels on meshCutter
|
||||
cutter.updateMesh(morphMap());
|
||||
|
||||
// Update cellSet
|
||||
cellsToCut.updateMesh(morphMap());
|
||||
|
||||
Info<< "Remaining:" << cellsToCut.size() << endl;
|
||||
|
||||
// Write resulting mesh
|
||||
if (overwrite)
|
||||
{
|
||||
mesh.setInstance(oldInstance);
|
||||
}
|
||||
|
||||
Info<< "Writing refined morphMesh to time " << runTime.timeName()
|
||||
<< endl;
|
||||
|
||||
mesh.write();
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
17
applications/utilities/mesh/conversion/Optional/Allwmake
Executable file
17
applications/utilities/mesh/conversion/Optional/Allwmake
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Build optional components (eg, may depend on third-party libraries)
|
||||
# -----------------------------------------------------------------------------
|
||||
cd ${0%/*} || exit 1 # run from this directory
|
||||
set -x
|
||||
|
||||
# build libccmio and create lnInclude directory
|
||||
$WM_THIRD_PARTY_DIR/AllwmakeLibccmio
|
||||
|
||||
# if the library built properly, the headers should exist too
|
||||
if [ -e $FOAM_EXT_LIBBIN/libccmio.so ]
|
||||
then
|
||||
wmake ccm26ToFoam
|
||||
fi
|
||||
|
||||
# ----------------------------------------------------------------- end-of-file
|
||||
@ -0,0 +1,3 @@
|
||||
ccm26ToFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/ccm26ToFoam
|
||||
@ -0,0 +1,12 @@
|
||||
LIBCCMIO_DIR = $(WM_THIRD_PARTY_DIR)/libccmio-2.6.1
|
||||
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIBCCMIO_DIR) \
|
||||
-I$(LIBCCMIO_DIR)/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lmeshTools \
|
||||
-L$(FOAM_EXT_LIBBIN) -lccmio
|
||||
@ -0,0 +1,36 @@
|
||||
1. how to write mesh from prostar
|
||||
|
||||
Type ngeom,[name].ngeom,star in the command line. This will create a
|
||||
.ngeom file of your Prostar model.
|
||||
|
||||
If you have boundaries defined, these will be kept in the .ngeom file so
|
||||
you won't have to rename and redefine the boundaries in ccm+. However,
|
||||
the values (properties) are not exported.
|
||||
|
||||
If you don't have boundaries you'll get a single wall patch in ccm+ that
|
||||
you'll have to split accordingly.
|
||||
|
||||
2. how to load it into star-ccm+
|
||||
|
||||
In ccm+ create a new simulation and do File>Import...
|
||||
|
||||
Browse to the location where you have your .ngeom file, select it, press
|
||||
OK and that's it.
|
||||
|
||||
3. how to do merging (or is automatic?)
|
||||
|
||||
If you had couples in your Prostar model, your meshes will all be
|
||||
"fused" together automatically in ccm+ when you import the .ngeom file.
|
||||
Keep a look on the output window in Prostar when you run the ngeom
|
||||
command to make sure the couples are exported OK.
|
||||
|
||||
Alternatively, you can "fuse" the different fluid regions in ccm+. To do
|
||||
this select all the fluid regions you want to merge together from the
|
||||
command tree on the left of your screen, under Regions. Press control
|
||||
and click on top of each one, once you've selected all, click the
|
||||
right-hand buttom of your mouse and select Fuse...
|
||||
|
||||
4. how to save it from star-ccm+
|
||||
|
||||
Once your model is ready in ccm+ (i.e. all regions and boundary patches
|
||||
defined), go to File>Export... and select .ccm format.
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,3 @@
|
||||
ansysToFoam.L
|
||||
|
||||
EXE = $(FOAM_APPBIN)/ansysToFoam
|
||||
711
applications/utilities/mesh/conversion/ansysToFoam/ansysToFoam.L
Normal file
711
applications/utilities/mesh/conversion/ansysToFoam/ansysToFoam.L
Normal file
@ -0,0 +1,711 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
ansysToFoam
|
||||
|
||||
Description
|
||||
Converts an ANSYS input mesh file, exported from I-DEAS,
|
||||
to OpenFOAM format.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
%{
|
||||
|
||||
#undef yyFlexLexer
|
||||
|
||||
/* ------------------------------------------------------------------------- *\
|
||||
------ local definitions
|
||||
\* ------------------------------------------------------------------------- */
|
||||
|
||||
#include <sstream>
|
||||
// For EOF only
|
||||
#include <cstdio>
|
||||
|
||||
#include "scalar.H"
|
||||
#include "IStringStream.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
#include "emptyPolyPatch.H"
|
||||
#include "preservePatchTypes.H"
|
||||
#include "cellShape.H"
|
||||
#include "cellModeller.H"
|
||||
#include "SLList.H"
|
||||
#include "SLPtrList.H"
|
||||
|
||||
SLList<point> slPoints;
|
||||
SLList<label> slPointMap;
|
||||
label maxNodei = 0;
|
||||
|
||||
SLPtrList<labelList> slCellLabels;
|
||||
SLList<label> slCellMap;
|
||||
SLList<label> slCellType;
|
||||
label maxCelli = 0;
|
||||
|
||||
PtrList<SLList<label> > slPatchCells;
|
||||
PtrList<SLList<label> > slPatchCellFaces;
|
||||
|
||||
// Cell types
|
||||
Map<word> cellTypes;
|
||||
label currentTypei = -1;
|
||||
|
||||
|
||||
// Dummy yywrap to keep yylex happy at compile time.
|
||||
// It is called by yylex but is not used as the mechanism to change file.
|
||||
// See <<EOF>>
|
||||
#if YY_FLEX_SUBMINOR_VERSION < 34
|
||||
extern "C" int yywrap()
|
||||
#else
|
||||
int yyFlexLexer::yywrap()
|
||||
#endif
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
one_space [ \t\f\r]
|
||||
space {one_space}*
|
||||
some_space {one_space}+
|
||||
cspace ","{space}
|
||||
|
||||
alpha [_A-Za-z]
|
||||
digit [0-9]
|
||||
|
||||
identifier {alpha}({alpha}|{digit})*
|
||||
integer {digit}+
|
||||
label [1-9]{digit}*
|
||||
|
||||
exponent_part [eE][-+]?{digit}+
|
||||
fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
|
||||
|
||||
floatNum (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
|
||||
|
||||
x {floatNum}
|
||||
y {floatNum}
|
||||
z {floatNum}
|
||||
value {floatNum}
|
||||
|
||||
node ^{space}"N"{cspace}
|
||||
element ^{space}"EN"{cspace}
|
||||
bface ^{space}"SFE"{cspace}
|
||||
elementTypeName ^{space}"ET"{cspace}
|
||||
elementType ^{space}"TYPE"{cspace}
|
||||
|
||||
|
||||
%%
|
||||
|
||||
%{
|
||||
labelList labels(8);
|
||||
%}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *\
|
||||
------ Start Lexing ------
|
||||
\* ------------------------------------------------------------------------- */
|
||||
|
||||
{node}{label}{cspace}{x}{cspace}{y}{cspace}{z}{space}\n {
|
||||
IStringStream nodeStream(YYText());
|
||||
char tag, c;
|
||||
label nodei;
|
||||
point node;
|
||||
nodeStream
|
||||
>> tag
|
||||
>> c >> nodei
|
||||
>> c >> node.x()
|
||||
>> c >> node.y()
|
||||
>> c >> node.z();
|
||||
|
||||
if (nodei > maxNodei) maxNodei = nodei;
|
||||
|
||||
slPointMap.append(nodei);
|
||||
slPoints.append(node);
|
||||
}
|
||||
|
||||
|
||||
{element}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{space}\n {
|
||||
IStringStream elementStream(YYText());
|
||||
char tag, c;
|
||||
label celli;
|
||||
elementStream
|
||||
>> tag >> tag
|
||||
>> c >> celli
|
||||
>> c >> labels[0]
|
||||
>> c >> labels[1]
|
||||
>> c >> labels[2]
|
||||
>> c >> labels[3]
|
||||
>> c >> labels[4]
|
||||
>> c >> labels[5]
|
||||
>> c >> labels[6]
|
||||
>> c >> labels[7];
|
||||
|
||||
if (celli > maxCelli) maxCelli = celli;
|
||||
|
||||
slCellMap.append(celli);
|
||||
slCellLabels.append(new labelList(labels));
|
||||
slCellType.append(currentTypei);
|
||||
}
|
||||
|
||||
|
||||
{bface}{label}{cspace}{label}{cspace}{identifier}{cspace}{integer}{cspace}{value}{space}\n {
|
||||
IStringStream bfaceStream(YYText());
|
||||
char tag, c;
|
||||
label elementi;
|
||||
label facei;
|
||||
scalar indexValue, unknown;
|
||||
bfaceStream
|
||||
>> tag >> tag >> tag
|
||||
>> c >> elementi
|
||||
>> c >> facei
|
||||
>> c >> tag >> tag >> tag >> tag
|
||||
>> c >> unknown
|
||||
>> c >> indexValue;
|
||||
|
||||
label patchi = label(indexValue);
|
||||
|
||||
if (patchi > slPatchCells.size())
|
||||
{
|
||||
slPatchCells.setSize(patchi);
|
||||
|
||||
forAll(slPatchCells, i)
|
||||
{
|
||||
if (!slPatchCells(i))
|
||||
{
|
||||
slPatchCells.set(i, new SLList<label>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (patchi > slPatchCellFaces.size())
|
||||
{
|
||||
slPatchCellFaces.setSize(patchi);
|
||||
|
||||
forAll(slPatchCells, i)
|
||||
{
|
||||
if (!slPatchCellFaces(i))
|
||||
{
|
||||
slPatchCellFaces.set(i, new SLList<label>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
slPatchCells[patchi-1].append(elementi);
|
||||
slPatchCellFaces[patchi-1].append(facei);
|
||||
}
|
||||
|
||||
|
||||
{elementTypeName}{label}{cspace}{identifier}{space}\n {
|
||||
|
||||
IStringStream elementStream(YYText());
|
||||
char tag,c;
|
||||
label cellTypei;
|
||||
word cellTypeName;
|
||||
elementStream
|
||||
>> tag >> tag // skip 'ET'
|
||||
>> c >> cellTypei
|
||||
>> c >> cellTypeName;
|
||||
|
||||
Info<< "Read typeName " << cellTypeName
|
||||
<< " for type " << cellTypei << endl;
|
||||
|
||||
cellTypes.insert(cellTypei, cellTypeName);
|
||||
}
|
||||
|
||||
|
||||
{elementType}{label}{space}\n {
|
||||
IStringStream elementStream(YYText());
|
||||
char tag,c;
|
||||
label cellTypei;
|
||||
elementStream
|
||||
>> tag >> tag >> tag >> tag // skip 'TYPE'
|
||||
>> c >> cellTypei;
|
||||
|
||||
currentTypei = cellTypei;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *\
|
||||
------ Ignore remaining space and \n s. Any other characters are errors.
|
||||
\* ------------------------------------------------------------------------- */
|
||||
|
||||
.|\n {}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *\
|
||||
------ On EOF return to previous file, if none exists terminate.
|
||||
\* ------------------------------------------------------------------------- */
|
||||
|
||||
<<EOF>> {
|
||||
yyterminate();
|
||||
}
|
||||
%%
|
||||
|
||||
|
||||
#include "fileName.H"
|
||||
#include <fstream>
|
||||
using std::ifstream;
|
||||
|
||||
|
||||
label findFace(const polyMesh& mesh, const face& f)
|
||||
{
|
||||
const labelList& pFaces = mesh.pointFaces()[f[0]];
|
||||
|
||||
forAll(pFaces, i)
|
||||
{
|
||||
label faceI = pFaces[i];
|
||||
|
||||
if (mesh.faces()[faceI] == f)
|
||||
{
|
||||
return faceI;
|
||||
}
|
||||
}
|
||||
|
||||
FatalErrorIn("findFace(const polyMesh&, const face&)")
|
||||
<< "Cannot find a face matching " << f
|
||||
<< exit(FatalError);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
argList::validArgs.append("ANSYS input file");
|
||||
argList::addOption
|
||||
(
|
||||
"scale",
|
||||
"factor",
|
||||
"geometry scaling factor - default is 1"
|
||||
);
|
||||
|
||||
argList args(argc, argv);
|
||||
|
||||
if (!args.check())
|
||||
{
|
||||
FatalError.exit();
|
||||
}
|
||||
|
||||
const scalar scaleFactor = args.optionLookupOrDefault("scale", 1.0);
|
||||
|
||||
# include "createTime.H"
|
||||
|
||||
fileName ansysFile(args.additionalArgs()[0]);
|
||||
ifstream ansysStream(ansysFile.c_str());
|
||||
|
||||
if (!ansysStream)
|
||||
{
|
||||
FatalErrorIn("ansysToFoam::main(int argc, char *argv[])")
|
||||
<< args.executable()
|
||||
<< ": file " << ansysFile << " not found"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
yyFlexLexer lexer(&ansysStream);
|
||||
while (lexer.yylex() != 0)
|
||||
{}
|
||||
|
||||
Info<< "Creating points" << endl;
|
||||
|
||||
pointField points(slPoints.size());
|
||||
|
||||
label i = 0;
|
||||
forAllConstIter(SLList<point>, slPoints, pointIter)
|
||||
{
|
||||
// Scale points for the given scale factor
|
||||
points[i++] = scaleFactor * pointIter();
|
||||
}
|
||||
|
||||
|
||||
labelList pointMap(maxNodei+1);
|
||||
|
||||
i = 0;
|
||||
forAllConstIter(SLList<label>, slPointMap, pointMapIter)
|
||||
{
|
||||
pointMap[pointMapIter()] = i++;
|
||||
}
|
||||
|
||||
Info<< "Creating cells" << endl;
|
||||
|
||||
labelList cellMap(maxCelli+1);
|
||||
|
||||
i = 0;
|
||||
forAllConstIter(SLList<label>, slCellMap, cellMapIter)
|
||||
{
|
||||
cellMap[cellMapIter()] = i++;
|
||||
}
|
||||
|
||||
|
||||
const cellModel& hex = *(cellModeller::lookup("hex"));
|
||||
const cellModel& prism = *(cellModeller::lookup("prism"));
|
||||
const cellModel& pyr = *(cellModeller::lookup("pyr"));
|
||||
const cellModel& tet = *(cellModeller::lookup("tet"));
|
||||
|
||||
labelList labelsHex(8);
|
||||
labelList labelsPrism(6);
|
||||
labelList labelsPyramid(5);
|
||||
labelList labelsTet(4);
|
||||
|
||||
cellShapeList cellShapes(slCellLabels.size());
|
||||
label nCells = 0;
|
||||
|
||||
forAllConstIter(SLPtrList<labelList>, slCellLabels, cellIter)
|
||||
{
|
||||
if // Tetrahedron
|
||||
(
|
||||
cellIter()[2] == cellIter()[3]
|
||||
&& cellIter()[4] == cellIter()[5]
|
||||
&& cellIter()[5] == cellIter()[6]
|
||||
&& cellIter()[6] == cellIter()[7]
|
||||
)
|
||||
{
|
||||
labelsTet[0] = pointMap[cellIter()[0] ];
|
||||
labelsTet[1] = pointMap[cellIter()[1] ];
|
||||
labelsTet[2] = pointMap[cellIter()[2] ];
|
||||
labelsTet[3] = pointMap[cellIter()[4] ];
|
||||
|
||||
cellShapes[nCells++] = cellShape(tet, labelsTet);
|
||||
}
|
||||
|
||||
else if // Square-based pyramid
|
||||
(
|
||||
cellIter()[4] == cellIter()[5]
|
||||
&& cellIter()[5] == cellIter()[6]
|
||||
&& cellIter()[6] == cellIter()[7]
|
||||
)
|
||||
{
|
||||
labelsPyramid[0] = pointMap[cellIter()[0] ];
|
||||
labelsPyramid[1] = pointMap[cellIter()[1] ];
|
||||
labelsPyramid[2] = pointMap[cellIter()[2] ];
|
||||
labelsPyramid[3] = pointMap[cellIter()[3] ];
|
||||
labelsPyramid[4] = pointMap[cellIter()[4] ];
|
||||
|
||||
cellShapes[nCells++] = cellShape(pyr, labelsPyramid);
|
||||
}
|
||||
|
||||
else if // Triangular prism
|
||||
(
|
||||
cellIter()[2] == cellIter()[3]
|
||||
&& cellIter()[6] == cellIter()[7]
|
||||
)
|
||||
{
|
||||
labelsPrism[0] = pointMap[cellIter()[0] ];
|
||||
labelsPrism[1] = pointMap[cellIter()[1] ];
|
||||
labelsPrism[2] = pointMap[cellIter()[2] ];
|
||||
labelsPrism[3] = pointMap[cellIter()[4] ];
|
||||
labelsPrism[4] = pointMap[cellIter()[5] ];
|
||||
labelsPrism[5] = pointMap[cellIter()[6] ];
|
||||
|
||||
cellShapes[nCells++] = cellShape(prism, labelsPrism);
|
||||
}
|
||||
|
||||
else // Hex
|
||||
{
|
||||
labelsHex[0] = pointMap[cellIter()[0] ];
|
||||
labelsHex[1] = pointMap[cellIter()[1] ];
|
||||
labelsHex[2] = pointMap[cellIter()[2] ];
|
||||
labelsHex[3] = pointMap[cellIter()[3] ];
|
||||
labelsHex[4] = pointMap[cellIter()[4] ];
|
||||
labelsHex[5] = pointMap[cellIter()[5] ];
|
||||
labelsHex[6] = pointMap[cellIter()[6] ];
|
||||
labelsHex[7] = pointMap[cellIter()[7] ];
|
||||
|
||||
cellShapes[nCells++] = cellShape(hex, labelsHex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const word defaultFacesName = "defaultFaces";
|
||||
word defaultFacesType = emptyPolyPatch::typeName;
|
||||
|
||||
// Create dummy mesh just to find out what are internal/external
|
||||
// faces
|
||||
autoPtr<polyMesh> dummyMesh
|
||||
(
|
||||
new polyMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dummyMesh",
|
||||
runTime.constant(),
|
||||
runTime
|
||||
),
|
||||
xferCopy(points),
|
||||
cellShapes,
|
||||
faceListList(0),
|
||||
wordList(0),
|
||||
wordList(0),
|
||||
defaultFacesName,
|
||||
defaultFacesType,
|
||||
wordList(0)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// Warning: tet face order has changed between version 1.9.6 and 2.0
|
||||
//
|
||||
label faceIndex[7][6] =
|
||||
{
|
||||
{-1, -1, -1, -1, -1, -1}, // 0
|
||||
{-1, -1, -1, -1, -1, -1}, // 1
|
||||
{-1, -1, -1, -1, -1, -1}, // 2
|
||||
{-1, -1, -1, -1, -1, -1}, // 3
|
||||
{ 3, 2, 0, -1, 1, -1}, // tet (version 2.0)
|
||||
{ 0, 4, 3, -1, 2, 1}, // prism
|
||||
{ 4, 2, 1, 3, 0, 5}, // hex
|
||||
};
|
||||
|
||||
Info<< "Creating boundary patches" << endl;
|
||||
|
||||
faceListList boundary(slPatchCells.size());
|
||||
wordList patchNames(slPatchCells.size());
|
||||
|
||||
forAll(slPatchCells, patchI)
|
||||
{
|
||||
SLList<face> patchFaces;
|
||||
|
||||
SLList<label>::iterator cellIter(slPatchCells[patchI].begin());
|
||||
SLList<label>::iterator faceIter(slPatchCellFaces[patchI].begin());
|
||||
|
||||
for
|
||||
(
|
||||
;
|
||||
cellIter != slPatchCells[patchI].end()
|
||||
&& faceIter != slPatchCellFaces[patchI].end();
|
||||
++cellIter, ++faceIter
|
||||
)
|
||||
{
|
||||
const cellShape& shape = cellShapes[cellMap[cellIter()]];
|
||||
|
||||
patchFaces.append
|
||||
(
|
||||
shape.faces()
|
||||
[
|
||||
faceIndex
|
||||
[shape.nFaces()]
|
||||
[faceIter()-1]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
boundary[patchI] = patchFaces;
|
||||
patchNames[patchI] = word("patch") + name(patchI + 1);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Lookup the face labels for all the boundary faces
|
||||
//
|
||||
labelListList boundaryFaceLabels(boundary.size());
|
||||
forAll(boundary, patchI)
|
||||
{
|
||||
const faceList& bFaces = boundary[patchI];
|
||||
labelList& bFaceLabels = boundaryFaceLabels[patchI];
|
||||
bFaceLabels.setSize(bFaces.size());
|
||||
forAll(bFaces, i)
|
||||
{
|
||||
bFaceLabels[i] = findFace(dummyMesh(), bFaces[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now split the boundary faces into external and internal faces. All
|
||||
// faces go into faceZones and external faces go into patches.
|
||||
List<faceList> patchFaces(slPatchCells.size());
|
||||
labelList patchNFaces(slPatchCells.size(), 0);
|
||||
forAll(boundary, patchI)
|
||||
{
|
||||
const faceList& bFaces = boundary[patchI];
|
||||
const labelList& bFaceLabels = boundaryFaceLabels[patchI];
|
||||
|
||||
patchFaces[patchI].setSize(bFaces.size());
|
||||
|
||||
forAll(bFaces, i)
|
||||
{
|
||||
if (!dummyMesh().isInternalFace(bFaceLabels[i]))
|
||||
{
|
||||
patchFaces[patchI][patchNFaces[patchI]++] = bFaces[i];
|
||||
}
|
||||
}
|
||||
patchFaces[patchI].setSize(patchNFaces[patchI]);
|
||||
|
||||
Info<< "Patch " << patchI << " named " << patchNames[patchI]
|
||||
<< ": " << boundary[patchI].size() << " faces" << endl;
|
||||
}
|
||||
|
||||
// We no longer need the dummyMesh
|
||||
dummyMesh.clear();
|
||||
|
||||
|
||||
Info<< "ansysToFoam: " << endl
|
||||
<< "Ansys file format does not provide information about the type of "
|
||||
<< "the patch (eg. wall, symmetry plane, cyclic etc)." << endl
|
||||
<< "All the patches have been created "
|
||||
<< "as type patch. Please reset after mesh conversion as necessary."
|
||||
<< endl;
|
||||
|
||||
PtrList<dictionary> patchDicts;
|
||||
|
||||
preservePatchTypes
|
||||
(
|
||||
runTime,
|
||||
runTime.constant(),
|
||||
polyMesh::meshSubDir,
|
||||
patchNames,
|
||||
patchDicts,
|
||||
defaultFacesName,
|
||||
defaultFacesType
|
||||
);
|
||||
|
||||
// Add information to dictionary
|
||||
forAll(patchNames, patchI)
|
||||
{
|
||||
if (!patchDicts.set(patchI))
|
||||
{
|
||||
patchDicts.set(patchI, new dictionary());
|
||||
}
|
||||
// Add but not overwrite
|
||||
patchDicts[patchI].add("type", polyPatch::typeName, false);
|
||||
}
|
||||
|
||||
|
||||
polyMesh pShapeMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
polyMesh::defaultRegion,
|
||||
runTime.constant(),
|
||||
runTime
|
||||
),
|
||||
xferMove(points),
|
||||
cellShapes,
|
||||
patchFaces,
|
||||
patchNames,
|
||||
patchDicts,
|
||||
defaultFacesName,
|
||||
defaultFacesType
|
||||
);
|
||||
|
||||
|
||||
if (cellTypes.size() > 0 || patchNames.size() > 0)
|
||||
{
|
||||
DynamicList<pointZone*> pz;
|
||||
DynamicList<faceZone*> fz;
|
||||
DynamicList<cellZone*> cz;
|
||||
|
||||
// FaceZones
|
||||
forAll(boundaryFaceLabels, patchI)
|
||||
{
|
||||
if (boundaryFaceLabels[patchI].size())
|
||||
{
|
||||
// Re-do the boundaryFaceLabels since the boundary face
|
||||
// labels will be different on the pShapeMesh.
|
||||
const faceList& bFaces = boundary[patchI];
|
||||
labelList& bFaceLabels = boundaryFaceLabels[patchI];
|
||||
forAll(bFaceLabels, i)
|
||||
{
|
||||
bFaceLabels[i] = findFace(pShapeMesh, bFaces[i]);
|
||||
}
|
||||
|
||||
Info<< "Creating faceZone " << patchNames[patchI]
|
||||
<< " with " << bFaceLabels.size() << " faces" << endl;
|
||||
|
||||
fz.append
|
||||
(
|
||||
new faceZone
|
||||
(
|
||||
patchNames[patchI],
|
||||
bFaceLabels,
|
||||
boolList(bFaceLabels.size(), false),
|
||||
fz.size(),
|
||||
pShapeMesh.faceZones()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// CellZones
|
||||
labelList types = cellTypes.sortedToc();
|
||||
|
||||
forAll(types, j)
|
||||
{
|
||||
label cellType = types[j];
|
||||
|
||||
// Pick up cells in zone
|
||||
DynamicList<label> addr;
|
||||
|
||||
SLList<label>::iterator cellMapIter = slCellMap.begin();
|
||||
SLList<label>::iterator typeIter = slCellType.begin();
|
||||
|
||||
for
|
||||
(
|
||||
;
|
||||
typeIter != slCellType.end();
|
||||
++typeIter, ++cellMapIter
|
||||
)
|
||||
{
|
||||
if (typeIter() == cellType)
|
||||
{
|
||||
addr.append(cellMap[cellMapIter()]);
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Creating cellZone " << cellTypes[cellType]
|
||||
<< " with " << addr.size() << " cells" << endl;
|
||||
|
||||
cz.append
|
||||
(
|
||||
new cellZone
|
||||
(
|
||||
cellTypes[cellType],
|
||||
addr,
|
||||
j,
|
||||
pShapeMesh.cellZones()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
pShapeMesh.addZones(pz, fz, cz);
|
||||
}
|
||||
|
||||
|
||||
// Set the precision of the points data to 10
|
||||
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
|
||||
|
||||
Info<< "Writing polyMesh" << endl;
|
||||
pShapeMesh.write();
|
||||
|
||||
Info<< nl << "end" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *\
|
||||
------ End of ansysToFoam.L
|
||||
\* ------------------------------------------------------------------------- */
|
||||
@ -0,0 +1,4 @@
|
||||
hexBlock.C
|
||||
cfx4ToFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/cfx4ToFoam
|
||||
761
applications/utilities/mesh/conversion/cfx4ToFoam/cfx4ToFoam.C
Normal file
761
applications/utilities/mesh/conversion/cfx4ToFoam/cfx4ToFoam.C
Normal file
@ -0,0 +1,761 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
cfx4ToFoam
|
||||
|
||||
Description
|
||||
Converts a CFX 4 mesh to OpenFOAM format.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "IFstream.H"
|
||||
#include "hexBlock.H"
|
||||
#include "polyMesh.H"
|
||||
#include "wallPolyPatch.H"
|
||||
#include "symmetryPolyPatch.H"
|
||||
#include "preservePatchTypes.H"
|
||||
#include "cellShape.H"
|
||||
#include "cellModeller.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
argList::validArgs.append("CFX geom file");
|
||||
argList::addOption
|
||||
(
|
||||
"scale",
|
||||
"factor",
|
||||
"geometry scaling factor - default is 1"
|
||||
);
|
||||
|
||||
argList args(argc, argv);
|
||||
|
||||
if (!args.check())
|
||||
{
|
||||
FatalError.exit();
|
||||
}
|
||||
|
||||
const scalar scaleFactor = args.optionLookupOrDefault("scale", 1.0);
|
||||
|
||||
# include "createTime.H"
|
||||
|
||||
IFstream cfxFile(args[1]);
|
||||
|
||||
// Read the cfx information using a fixed format reader.
|
||||
// Comments in the file are in C++ style, so the stream parser will remove
|
||||
// them with no intervention
|
||||
label nblock, npatch, nglue, nelem, npoint;
|
||||
|
||||
cfxFile >> nblock >> npatch >> nglue >> nelem >> npoint;
|
||||
|
||||
Info<< "Reading blocks" << endl;
|
||||
|
||||
PtrList<hexBlock> blocks(nblock);
|
||||
|
||||
{
|
||||
word blockName;
|
||||
label nx, ny, nz;
|
||||
|
||||
forAll(blocks, blockI)
|
||||
{
|
||||
cfxFile >> blockName;
|
||||
cfxFile >> nx >> ny >> nz;
|
||||
|
||||
blocks.set(blockI, new hexBlock(nx, ny, nz));
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Reading patch definitions" << endl;
|
||||
|
||||
wordList cfxPatchTypes(npatch);
|
||||
wordList cfxPatchNames(npatch);
|
||||
labelList patchMasterBlocks(npatch);
|
||||
labelList patchDirections(npatch);
|
||||
labelListList patchRanges(npatch);
|
||||
|
||||
{
|
||||
label no, blkNo, patchLabel;
|
||||
|
||||
forAll(cfxPatchTypes, patchI)
|
||||
{
|
||||
// Grab patch type and name
|
||||
cfxFile >> cfxPatchTypes[patchI] >> cfxPatchNames[patchI] >> no;
|
||||
|
||||
// Grab patch range
|
||||
patchRanges[patchI].setSize(6);
|
||||
labelList& curRange = patchRanges[patchI];
|
||||
|
||||
forAll(curRange, rI)
|
||||
{
|
||||
cfxFile >> curRange[rI];
|
||||
}
|
||||
|
||||
// Grab patch direction and master block ID
|
||||
// Note: direc is the direction, from the cfx manual
|
||||
// 0 = solid (3-D patch),
|
||||
// 1 = high i, 2 = high j, 3 = high k
|
||||
// 4 = low i, 5 = low j, 6 = low k
|
||||
cfxFile >> patchDirections[patchI] >> blkNo >> patchLabel;
|
||||
|
||||
patchMasterBlocks[patchI] = blkNo - 1;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Reading block glueing information" << endl;
|
||||
|
||||
labelList glueMasterPatches(nglue, -1);
|
||||
labelList glueSlavePatches(nglue, -1);
|
||||
|
||||
{
|
||||
label masterPatch, slavePatch;
|
||||
label dirIndex1, dirIndex2, dirIndex3, joinNumber;
|
||||
|
||||
for (label glueI = 0; glueI < nglue; glueI++)
|
||||
{
|
||||
cfxFile >> masterPatch >> slavePatch;
|
||||
cfxFile >> dirIndex1 >> dirIndex2 >> dirIndex3 >> joinNumber;
|
||||
|
||||
glueMasterPatches[glueI] = masterPatch - 1;
|
||||
glueSlavePatches[glueI] = slavePatch - 1;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Reading block points" << endl;
|
||||
|
||||
forAll(blocks, blockI)
|
||||
{
|
||||
Info<< "block " << blockI << " is a ";
|
||||
blocks[blockI].readPoints(cfxFile);
|
||||
}
|
||||
|
||||
Info<< "Calculating block offsets" << endl;
|
||||
|
||||
labelList blockOffsets(nblock, -1);
|
||||
|
||||
blockOffsets[0] = 0;
|
||||
|
||||
label nMeshPoints = blocks[0].nBlockPoints();
|
||||
label nMeshCells = blocks[0].nBlockCells();
|
||||
|
||||
for (label blockI = 1; blockI < nblock; blockI++)
|
||||
{
|
||||
nMeshPoints += blocks[blockI].nBlockPoints();
|
||||
nMeshCells += blocks[blockI].nBlockCells();
|
||||
|
||||
blockOffsets[blockI] =
|
||||
blockOffsets[blockI - 1]
|
||||
+ blocks[blockI - 1].nBlockPoints();
|
||||
}
|
||||
|
||||
Info<< "Assembling patches" << endl;
|
||||
|
||||
faceListList rawPatches(npatch);
|
||||
|
||||
forAll(rawPatches, patchI)
|
||||
{
|
||||
const word& patchType = cfxPatchTypes[patchI];
|
||||
|
||||
// reject volume patches
|
||||
if
|
||||
(
|
||||
patchType == "POROUS" || patchType == "SOLID"
|
||||
|| patchType == "SOLCON" || patchType == "USER3D"
|
||||
)
|
||||
{
|
||||
patchMasterBlocks[patchI] = -1;
|
||||
rawPatches[patchI].setSize(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// read and create a 2-D patch
|
||||
rawPatches[patchI] =
|
||||
blocks[patchMasterBlocks[patchI]].patchFaces
|
||||
(
|
||||
patchDirections[patchI],
|
||||
patchRanges[patchI]
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Merging points ";
|
||||
|
||||
labelList pointMergeList(nMeshPoints, -1);
|
||||
|
||||
// In order to ensure robust merging, it is necessary to traverse
|
||||
// the patch glueing list until the pointMergeList stops changing.
|
||||
//
|
||||
|
||||
// For efficiency, create merge pairs in the first pass
|
||||
labelListListList glueMergePairs(glueMasterPatches.size());
|
||||
|
||||
forAll(glueMasterPatches, glueI)
|
||||
{
|
||||
const label masterPatch = glueMasterPatches[glueI];
|
||||
const label slavePatch = glueSlavePatches[glueI];
|
||||
|
||||
const label blockPlabel = patchMasterBlocks[masterPatch];
|
||||
const label blockNlabel = patchMasterBlocks[slavePatch];
|
||||
|
||||
const pointField& blockPpoints = blocks[blockPlabel].points();
|
||||
const pointField& blockNpoints = blocks[blockNlabel].points();
|
||||
|
||||
const faceList& blockPFaces = rawPatches[masterPatch];
|
||||
const faceList& blockNFaces = rawPatches[slavePatch];
|
||||
|
||||
labelListList& curPairs = glueMergePairs[glueI];
|
||||
curPairs.setSize(blockPFaces.size());
|
||||
|
||||
if (blockPFaces.size() != blockNFaces.size())
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Inconsistent number of faces for glue pair "
|
||||
<< glueI << " between blocks " << blockPlabel + 1
|
||||
<< " and " << blockNlabel + 1
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Calculate sqr of the merge tolerance as 1/10th of the min
|
||||
// sqr point to point distance on the block face. This is an
|
||||
// N^2 algorithm, sorry but I cannot quickly come up with
|
||||
// something better.
|
||||
|
||||
scalar sqrMergeTol = GREAT;
|
||||
|
||||
forAll(blockPFaces, blockPFaceLabel)
|
||||
{
|
||||
const labelList& blockPFacePoints =
|
||||
blockPFaces[blockPFaceLabel];
|
||||
|
||||
forAll(blockPFacePoints, blockPFacePointI)
|
||||
{
|
||||
forAll(blockPFacePoints, blockPFacePointI2)
|
||||
{
|
||||
if (blockPFacePointI != blockPFacePointI2)
|
||||
{
|
||||
sqrMergeTol =
|
||||
min
|
||||
(
|
||||
sqrMergeTol,
|
||||
magSqr
|
||||
(
|
||||
blockPpoints
|
||||
[blockPFacePoints[blockPFacePointI]]
|
||||
- blockPpoints
|
||||
[blockPFacePoints[blockPFacePointI2]]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sqrMergeTol /= 10.0;
|
||||
|
||||
register bool found = false;
|
||||
|
||||
// N-squared point search over all points of all faces of
|
||||
// master block over all point of all faces of slave block
|
||||
forAll(blockPFaces, blockPFaceLabel)
|
||||
{
|
||||
const labelList& blockPFacePoints =
|
||||
blockPFaces[blockPFaceLabel];
|
||||
|
||||
labelList& cp = curPairs[blockPFaceLabel];
|
||||
cp.setSize(blockPFacePoints.size());
|
||||
|
||||
forAll(blockPFacePoints, blockPFacePointI)
|
||||
{
|
||||
found = false;
|
||||
|
||||
forAll(blockNFaces, blockNFaceLabel)
|
||||
{
|
||||
const labelList& blockNFacePoints =
|
||||
blockNFaces[blockNFaceLabel];
|
||||
|
||||
forAll(blockNFacePoints, blockNFacePointI)
|
||||
{
|
||||
if
|
||||
(
|
||||
magSqr
|
||||
(
|
||||
blockPpoints
|
||||
[blockPFacePoints[blockPFacePointI]]
|
||||
- blockNpoints
|
||||
[blockNFacePoints[blockNFacePointI]]
|
||||
)
|
||||
< sqrMergeTol
|
||||
)
|
||||
{
|
||||
// Found a new pair
|
||||
found = true;
|
||||
|
||||
cp[blockPFacePointI] =
|
||||
blockNFacePoints[blockNFacePointI];
|
||||
|
||||
label PpointLabel =
|
||||
blockPFacePoints[blockPFacePointI]
|
||||
+ blockOffsets[blockPlabel];
|
||||
|
||||
label NpointLabel =
|
||||
blockNFacePoints[blockNFacePointI]
|
||||
+ blockOffsets[blockNlabel];
|
||||
|
||||
label minPN = min(PpointLabel, NpointLabel);
|
||||
|
||||
if (pointMergeList[PpointLabel] != -1)
|
||||
{
|
||||
minPN = min(minPN, pointMergeList[PpointLabel]);
|
||||
}
|
||||
|
||||
if (pointMergeList[NpointLabel] != -1)
|
||||
{
|
||||
minPN = min(minPN, pointMergeList[NpointLabel]);
|
||||
}
|
||||
|
||||
pointMergeList[PpointLabel]
|
||||
= pointMergeList[NpointLabel]
|
||||
= minPN;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
register bool changedPointMerge = false;
|
||||
label nPasses = 0;
|
||||
|
||||
do
|
||||
{
|
||||
changedPointMerge = false;
|
||||
nPasses++;
|
||||
|
||||
forAll(glueMasterPatches, glueI)
|
||||
{
|
||||
const label masterPatch = glueMasterPatches[glueI];
|
||||
const label slavePatch = glueSlavePatches[glueI];
|
||||
|
||||
const label blockPlabel = patchMasterBlocks[masterPatch];
|
||||
const label blockNlabel = patchMasterBlocks[slavePatch];
|
||||
|
||||
const faceList& blockPFaces = rawPatches[masterPatch];
|
||||
|
||||
const labelListList& curPairs = glueMergePairs[glueI];
|
||||
|
||||
forAll(blockPFaces, blockPFaceLabel)
|
||||
{
|
||||
const labelList& blockPFacePoints =
|
||||
blockPFaces[blockPFaceLabel];
|
||||
|
||||
const labelList& cp = curPairs[blockPFaceLabel];
|
||||
|
||||
forAll(cp, blockPFacePointI)
|
||||
{
|
||||
label PpointLabel =
|
||||
blockPFacePoints[blockPFacePointI]
|
||||
+ blockOffsets[blockPlabel];
|
||||
|
||||
label NpointLabel =
|
||||
cp[blockPFacePointI]
|
||||
+ blockOffsets[blockNlabel];
|
||||
|
||||
if
|
||||
(
|
||||
pointMergeList[PpointLabel]
|
||||
!= pointMergeList[NpointLabel]
|
||||
)
|
||||
{
|
||||
changedPointMerge = true;
|
||||
|
||||
pointMergeList[PpointLabel]
|
||||
= pointMergeList[NpointLabel]
|
||||
= min
|
||||
(
|
||||
pointMergeList[PpointLabel],
|
||||
pointMergeList[NpointLabel]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Info<< "." << flush;
|
||||
}
|
||||
while (changedPointMerge && nPasses < 8);
|
||||
Info<< endl;
|
||||
|
||||
if (changedPointMerge == true)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Point merging failed after max number of passes."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
|
||||
forAll(glueMasterPatches, glueI)
|
||||
{
|
||||
const label masterPatch = glueMasterPatches[glueI];
|
||||
const label slavePatch = glueSlavePatches[glueI];
|
||||
|
||||
const label blockPlabel = patchMasterBlocks[masterPatch];
|
||||
const label blockNlabel = patchMasterBlocks[slavePatch];
|
||||
|
||||
const faceList& blockPFaces = rawPatches[masterPatch];
|
||||
const faceList& blockNFaces = rawPatches[slavePatch];
|
||||
|
||||
|
||||
forAll(blockPFaces, blockPFaceLabel)
|
||||
{
|
||||
const labelList& blockPFacePoints
|
||||
= blockPFaces[blockPFaceLabel];
|
||||
|
||||
forAll(blockPFacePoints, blockPFacePointI)
|
||||
{
|
||||
label PpointLabel =
|
||||
blockPFacePoints[blockPFacePointI]
|
||||
+ blockOffsets[blockPlabel];
|
||||
|
||||
if (pointMergeList[PpointLabel] == -1)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Unable to merge point " << blockPFacePointI
|
||||
<< " of face " << blockPFaceLabel
|
||||
<< " of block " << blockPlabel
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forAll(blockNFaces, blockNFaceLabel)
|
||||
{
|
||||
const labelList& blockNFacePoints
|
||||
= blockNFaces[blockNFaceLabel];
|
||||
|
||||
forAll(blockNFacePoints, blockNFacePointI)
|
||||
{
|
||||
label NpointLabel =
|
||||
blockNFacePoints[blockNFacePointI]
|
||||
+ blockOffsets[blockNlabel];
|
||||
|
||||
if (pointMergeList[NpointLabel] == -1)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Unable to merge point " << blockNFacePointI
|
||||
<< " of face " << blockNFaceLabel
|
||||
<< " of block " << blockNlabel
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sort merge list to return new point label (in new shorter list)
|
||||
// given old point label
|
||||
label nNewPoints = 0;
|
||||
|
||||
forAll(pointMergeList, pointLabel)
|
||||
{
|
||||
if (pointMergeList[pointLabel] > pointLabel)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "ouch" << abort(FatalError);
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
(pointMergeList[pointLabel] == -1)
|
||||
|| pointMergeList[pointLabel] == pointLabel
|
||||
)
|
||||
{
|
||||
pointMergeList[pointLabel] = nNewPoints;
|
||||
nNewPoints++;
|
||||
}
|
||||
else
|
||||
{
|
||||
pointMergeList[pointLabel] =
|
||||
pointMergeList[pointMergeList[pointLabel]];
|
||||
}
|
||||
}
|
||||
|
||||
nMeshPoints = nNewPoints;
|
||||
|
||||
Info<< "Creating points" << endl;
|
||||
|
||||
pointField points(nMeshPoints);
|
||||
|
||||
forAll(blocks, blockI)
|
||||
{
|
||||
const pointField& blockPoints = blocks[blockI].points();
|
||||
|
||||
forAll(blockPoints, blockPointLabel)
|
||||
{
|
||||
points
|
||||
[
|
||||
pointMergeList
|
||||
[
|
||||
blockPointLabel
|
||||
+ blockOffsets[blockI]
|
||||
]
|
||||
] = blockPoints[blockPointLabel];
|
||||
}
|
||||
}
|
||||
|
||||
// Scale the points
|
||||
if (scaleFactor > 1.0 + SMALL || scaleFactor < 1.0 - SMALL)
|
||||
{
|
||||
points *= scaleFactor;
|
||||
}
|
||||
|
||||
Info<< "Creating cells" << endl;
|
||||
|
||||
cellShapeList cellShapes(nMeshCells);
|
||||
|
||||
const cellModel& hex = *(cellModeller::lookup("hex"));
|
||||
|
||||
label nCreatedCells = 0;
|
||||
|
||||
forAll(blocks, blockI)
|
||||
{
|
||||
labelListList curBlockCells = blocks[blockI].blockCells();
|
||||
|
||||
forAll(curBlockCells, blockCellI)
|
||||
{
|
||||
labelList cellPoints(curBlockCells[blockCellI].size());
|
||||
|
||||
forAll(cellPoints, pointI)
|
||||
{
|
||||
cellPoints[pointI] =
|
||||
pointMergeList
|
||||
[
|
||||
curBlockCells[blockCellI][pointI]
|
||||
+ blockOffsets[blockI]
|
||||
];
|
||||
}
|
||||
|
||||
cellShapes[nCreatedCells] = cellShape(hex, cellPoints);
|
||||
|
||||
nCreatedCells++;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Creating boundary patches" << endl;
|
||||
|
||||
faceListList boundary(npatch);
|
||||
wordList patchNames(npatch);
|
||||
wordList patchTypes(npatch);
|
||||
word defaultFacesName = "defaultFaces";
|
||||
word defaultFacesType = wallPolyPatch::typeName;
|
||||
|
||||
label nCreatedPatches = 0;
|
||||
|
||||
forAll(rawPatches, patchI)
|
||||
{
|
||||
if (rawPatches[patchI].size() && cfxPatchTypes[patchI] != "BLKBDY")
|
||||
{
|
||||
// Check if this name has been already created
|
||||
label existingPatch = -1;
|
||||
|
||||
for (label oldPatchI = 0; oldPatchI < nCreatedPatches; oldPatchI++)
|
||||
{
|
||||
if (patchNames[oldPatchI] == cfxPatchNames[patchI])
|
||||
{
|
||||
existingPatch = oldPatchI;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const faceList& curRawPatch = rawPatches[patchI];
|
||||
label curBlock = patchMasterBlocks[patchI];
|
||||
|
||||
if (existingPatch >= 0)
|
||||
{
|
||||
Info<< "CFX patch " << patchI
|
||||
<< ", of type " << cfxPatchTypes[patchI]
|
||||
<< ", name " << cfxPatchNames[patchI]
|
||||
<< " already exists as OpenFOAM patch " << existingPatch
|
||||
<< ". Adding faces." << endl;
|
||||
|
||||
faceList& renumberedPatch = boundary[existingPatch];
|
||||
label oldSize = renumberedPatch.size();
|
||||
renumberedPatch.setSize(oldSize + curRawPatch.size());
|
||||
|
||||
forAll(curRawPatch, faceI)
|
||||
{
|
||||
const face& oldFace = curRawPatch[faceI];
|
||||
|
||||
face& newFace = renumberedPatch[oldSize + faceI];
|
||||
newFace.setSize(oldFace.size());
|
||||
|
||||
forAll(oldFace, pointI)
|
||||
{
|
||||
newFace[pointI] =
|
||||
pointMergeList
|
||||
[
|
||||
oldFace[pointI]
|
||||
+ blockOffsets[curBlock]
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Real patch to be created
|
||||
faceList& renumberedPatch = boundary[nCreatedPatches];
|
||||
renumberedPatch.setSize(curRawPatch.size());
|
||||
|
||||
forAll(curRawPatch, faceI)
|
||||
{
|
||||
const face& oldFace = curRawPatch[faceI];
|
||||
|
||||
face& newFace = renumberedPatch[faceI];
|
||||
newFace.setSize(oldFace.size());
|
||||
|
||||
forAll(oldFace, pointI)
|
||||
{
|
||||
newFace[pointI] =
|
||||
pointMergeList
|
||||
[
|
||||
oldFace[pointI]
|
||||
+ blockOffsets[curBlock]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "CFX patch " << patchI
|
||||
<< ", of type " << cfxPatchTypes[patchI]
|
||||
<< ", name " << cfxPatchNames[patchI]
|
||||
<< " converted into OpenFOAM patch " << nCreatedPatches
|
||||
<< " type ";
|
||||
|
||||
if (cfxPatchTypes[patchI] == "WALL")
|
||||
{
|
||||
Info<< "wall." << endl;
|
||||
|
||||
patchTypes[nCreatedPatches] = wallPolyPatch::typeName;
|
||||
patchNames[nCreatedPatches] = cfxPatchNames[patchI];
|
||||
nCreatedPatches++;
|
||||
}
|
||||
else if (cfxPatchTypes[patchI] == "SYMMET")
|
||||
{
|
||||
Info<< "symmetryPlane." << endl;
|
||||
|
||||
patchTypes[nCreatedPatches] = symmetryPolyPatch::typeName;
|
||||
patchNames[nCreatedPatches] = cfxPatchNames[patchI];
|
||||
nCreatedPatches++;
|
||||
}
|
||||
else if
|
||||
(
|
||||
cfxPatchTypes[patchI] == "INLET"
|
||||
|| cfxPatchTypes[patchI] == "OUTLET"
|
||||
|| cfxPatchTypes[patchI] == "PRESS"
|
||||
|| cfxPatchTypes[patchI] == "CNDBDY"
|
||||
|| cfxPatchTypes[patchI] == "USER2D"
|
||||
)
|
||||
{
|
||||
Info<< "generic." << endl;
|
||||
|
||||
patchTypes[nCreatedPatches] = polyPatch::typeName;
|
||||
patchNames[nCreatedPatches] = cfxPatchNames[patchI];
|
||||
nCreatedPatches++;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Unrecognised CFX patch type "
|
||||
<< cfxPatchTypes[patchI]
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boundary.setSize(nCreatedPatches);
|
||||
patchTypes.setSize(nCreatedPatches);
|
||||
patchNames.setSize(nCreatedPatches);
|
||||
|
||||
PtrList<dictionary> patchDicts;
|
||||
|
||||
preservePatchTypes
|
||||
(
|
||||
runTime,
|
||||
runTime.constant(),
|
||||
polyMesh::meshSubDir,
|
||||
patchNames,
|
||||
patchDicts,
|
||||
defaultFacesName,
|
||||
defaultFacesType
|
||||
);
|
||||
|
||||
// Add information to dictionary
|
||||
forAll(patchNames, patchI)
|
||||
{
|
||||
if (!patchDicts.set(patchI))
|
||||
{
|
||||
patchDicts.set(patchI, new dictionary());
|
||||
}
|
||||
// Add but not overwrite
|
||||
patchDicts[patchI].add("type", patchTypes[patchI], false);
|
||||
}
|
||||
|
||||
polyMesh pShapeMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
polyMesh::defaultRegion,
|
||||
runTime.constant(),
|
||||
runTime
|
||||
),
|
||||
xferMove(points),
|
||||
cellShapes,
|
||||
boundary,
|
||||
patchNames,
|
||||
patchDicts,
|
||||
defaultFacesName,
|
||||
defaultFacesType
|
||||
);
|
||||
|
||||
// Set the precision of the points data to 10
|
||||
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
|
||||
|
||||
Info<< "Writing polyMesh" << endl;
|
||||
pShapeMesh.write();
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
390
applications/utilities/mesh/conversion/cfx4ToFoam/hexBlock.C
Normal file
390
applications/utilities/mesh/conversion/cfx4ToFoam/hexBlock.C
Normal file
@ -0,0 +1,390 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ 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 "hexBlock.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
label hexBlock::vtxLabel(label a, label b, label c) const
|
||||
{
|
||||
return (a + b*(xDim_ + 1) + c*(xDim_ + 1)*(yDim_ + 1));
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
// Construct from components
|
||||
hexBlock::hexBlock(const label nx, const label ny, const label nz)
|
||||
:
|
||||
xDim_(nx),
|
||||
yDim_(ny),
|
||||
zDim_(nz),
|
||||
blockHandedness_(noPoints),
|
||||
points_((xDim_ + 1)*(yDim_ + 1)*(zDim_ + 1))
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void hexBlock::readPoints(Istream& is)
|
||||
{
|
||||
forAll(points_, i)
|
||||
{
|
||||
is >> points_[i].x() >> points_[i].y() >> points_[i].z();
|
||||
}
|
||||
|
||||
// Calculate the handedness of the block
|
||||
vector i = points_[xDim_] - points_[0];
|
||||
vector j = points_[(xDim_ + 1)*yDim_] - points_[0];
|
||||
vector k = points_[(xDim_ + 1)*(yDim_ + 1)*zDim_] - points_[0];
|
||||
|
||||
if (((i ^ j) & k) > 0)
|
||||
{
|
||||
Info<< "right-handed block" << endl;
|
||||
blockHandedness_ = right;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "left-handed block" << endl;
|
||||
blockHandedness_ = left;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
labelListList hexBlock::blockCells() const
|
||||
{
|
||||
labelListList result(xDim_*yDim_*zDim_);
|
||||
|
||||
label cellNo = 0;
|
||||
|
||||
if (blockHandedness_ == right)
|
||||
{
|
||||
for (label k = 0; k <= zDim_ - 1; k++)
|
||||
{
|
||||
for (label j = 0; j <= yDim_ - 1; j++)
|
||||
{
|
||||
for (label i = 0; i <= xDim_ - 1; i++)
|
||||
{
|
||||
labelList& hexLabels = result[cellNo];
|
||||
hexLabels.setSize(8);
|
||||
|
||||
hexLabels[0] = vtxLabel(i, j, k);
|
||||
hexLabels[1] = vtxLabel(i+1, j, k);
|
||||
hexLabels[2] = vtxLabel(i+1, j+1, k);
|
||||
hexLabels[3] = vtxLabel(i, j+1, k);
|
||||
hexLabels[4] = vtxLabel(i, j, k+1);
|
||||
hexLabels[5] = vtxLabel(i+1, j, k+1);
|
||||
hexLabels[6] = vtxLabel(i+1, j+1, k+1);
|
||||
hexLabels[7] = vtxLabel(i, j+1, k+1);
|
||||
|
||||
cellNo++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (blockHandedness_ == left)
|
||||
{
|
||||
for (label k = 0; k <= zDim_ - 1; k++)
|
||||
{
|
||||
for (label j = 0; j <= yDim_ - 1; j++)
|
||||
{
|
||||
for (label i = 0; i <= xDim_ - 1; i++)
|
||||
{
|
||||
labelList& hexLabels = result[cellNo];
|
||||
hexLabels.setSize(8);
|
||||
|
||||
hexLabels[0] = vtxLabel(i, j, k+1);
|
||||
hexLabels[1] = vtxLabel(i+1, j, k+1);
|
||||
hexLabels[2] = vtxLabel(i+1, j+1, k+1);
|
||||
hexLabels[3] = vtxLabel(i, j+1, k+1);
|
||||
hexLabels[4] = vtxLabel(i, j, k);
|
||||
hexLabels[5] = vtxLabel(i+1, j, k);
|
||||
hexLabels[6] = vtxLabel(i+1, j+1, k);
|
||||
hexLabels[7] = vtxLabel(i, j+1, k);
|
||||
|
||||
cellNo++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn("hexBlock::cellShapes()")
|
||||
<< "Unable to determine block handedness as points "
|
||||
<< "have not been read in yet"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Return block patch faces given direction and range limits
|
||||
// From the cfx manual: direction
|
||||
// 0 = solid (3-D patch),
|
||||
// 1 = high i, 2 = high j, 3 = high k
|
||||
// 4 = low i, 5 = low j, 6 = low k
|
||||
faceList hexBlock::patchFaces(const label direc, const labelList& range) const
|
||||
{
|
||||
if (range.size() != 6)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"patchFaces(const label direc, const labelList& range) const"
|
||||
) << "Invalid size of the range array: " << range.size()
|
||||
<< ". Should be 6 (xMin, xMax, yMin, yMax, zMin, zMax"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
label xMinRange = range[0];
|
||||
label xMaxRange = range[1];
|
||||
label yMinRange = range[2];
|
||||
label yMaxRange = range[3];
|
||||
label zMinRange = range[4];
|
||||
label zMaxRange = range[5];
|
||||
|
||||
faceList result(0);
|
||||
|
||||
switch (direc)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
// high i = xmax
|
||||
|
||||
result.setSize
|
||||
(
|
||||
(yMaxRange - yMinRange + 1)*(zMaxRange - zMinRange + 1)
|
||||
);
|
||||
|
||||
label p = 0;
|
||||
for (label k = zMinRange - 1; k <= zMaxRange - 1; k++)
|
||||
{
|
||||
for (label j = yMinRange - 1; j <= yMaxRange - 1; j++)
|
||||
{
|
||||
result[p].setSize(4);
|
||||
|
||||
// set the points
|
||||
result[p][0] = vtxLabel(xDim_, j, k);
|
||||
result[p][1] = vtxLabel(xDim_, j+1, k);
|
||||
result[p][2] = vtxLabel(xDim_, j+1, k+1);
|
||||
result[p][3] = vtxLabel(xDim_, j, k+1);
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
result.setSize(p);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
// high j = ymax
|
||||
result.setSize
|
||||
(
|
||||
(xMaxRange - xMinRange + 1)*(zMaxRange - zMinRange + 1)
|
||||
);
|
||||
|
||||
label p = 0;
|
||||
for (label i = xMinRange - 1; i <= xMaxRange - 1; i++)
|
||||
{
|
||||
for (label k = zMinRange - 1; k <= zMaxRange - 1; k++)
|
||||
{
|
||||
result[p].setSize(4);
|
||||
|
||||
// set the points
|
||||
result[p][0] = vtxLabel(i, yDim_, k);
|
||||
result[p][1] = vtxLabel(i, yDim_, k + 1);
|
||||
result[p][2] = vtxLabel(i + 1, yDim_, k + 1);
|
||||
result[p][3] = vtxLabel(i + 1, yDim_, k);
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
result.setSize(p);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
// high k = zmax
|
||||
result.setSize
|
||||
(
|
||||
(xMaxRange - xMinRange + 1)*(yMaxRange - yMinRange + 1)
|
||||
);
|
||||
|
||||
label p = 0;
|
||||
for (label i = xMinRange - 1; i <= xMaxRange - 1; i++)
|
||||
{
|
||||
for (label j = yMinRange - 1; j <= yMaxRange - 1; j++)
|
||||
{
|
||||
result[p].setSize(4);
|
||||
|
||||
// set the points
|
||||
result[p][0] = vtxLabel(i, j, zDim_);
|
||||
result[p][1] = vtxLabel(i + 1, j, zDim_);
|
||||
result[p][2] = vtxLabel(i + 1, j + 1, zDim_);
|
||||
result[p][3] = vtxLabel(i, j + 1, zDim_);
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
result.setSize(p);
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
// low i = xmin
|
||||
result.setSize
|
||||
(
|
||||
(yMaxRange - yMinRange + 1)*(zMaxRange - zMinRange + 1)
|
||||
);
|
||||
|
||||
label p = 0;
|
||||
for (label k = zMinRange - 1; k <= zMaxRange - 1; k++)
|
||||
{
|
||||
for (label j = yMinRange - 1; j <= yMaxRange - 1; j++)
|
||||
{
|
||||
result[p].setSize(4);
|
||||
|
||||
// set the points
|
||||
result[p][0] = vtxLabel(0, j, k);
|
||||
result[p][1] = vtxLabel(0, j, k + 1);
|
||||
result[p][2] = vtxLabel(0, j + 1, k + 1);
|
||||
result[p][3] = vtxLabel(0, j + 1, k);
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
result.setSize(p);
|
||||
break;
|
||||
}
|
||||
|
||||
case 5:
|
||||
{
|
||||
// low j = ymin
|
||||
result.setSize
|
||||
(
|
||||
(xMaxRange - xMinRange + 1)*(zMaxRange - zMinRange + 1)
|
||||
);
|
||||
|
||||
label p = 0;
|
||||
for (label i = xMinRange - 1; i <= xMaxRange - 1; i++)
|
||||
{
|
||||
for (label k = zMinRange - 1; k <= zMaxRange - 1; k++)
|
||||
{
|
||||
result[p].setSize(4);
|
||||
|
||||
// set the points
|
||||
result[p][0] = vtxLabel(i, 0, k);
|
||||
result[p][1] = vtxLabel(i + 1, 0, k);
|
||||
result[p][2] = vtxLabel(i + 1, 0, k + 1);
|
||||
result[p][3] = vtxLabel(i, 0, k + 1);
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
result.setSize(p);
|
||||
break;
|
||||
}
|
||||
|
||||
case 6:
|
||||
{
|
||||
// low k = zmin
|
||||
result.setSize
|
||||
(
|
||||
(xMaxRange - xMinRange + 1)*(yMaxRange - yMinRange + 1)
|
||||
);
|
||||
|
||||
label p = 0;
|
||||
for (label i = xMinRange - 1; i <= xMaxRange - 1; i++)
|
||||
{
|
||||
for (label j = yMinRange - 1; j <= yMaxRange - 1; j++)
|
||||
{
|
||||
result[p].setSize(4);
|
||||
|
||||
// set the points
|
||||
result[p][0] = vtxLabel(i, j, 0);
|
||||
result[p][1] = vtxLabel(i, j + 1, 0);
|
||||
result[p][2] = vtxLabel(i + 1, j + 1, 0);
|
||||
result[p][3] = vtxLabel(i + 1, j, 0);
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
result.setSize(p);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"patchFaces(const label direc, const labelList& range) const"
|
||||
) << "direction out of range (1 to 6): " << direc
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Correct the face orientation based on the handedness of the block.
|
||||
// Do nothing for the right-handed block
|
||||
if (blockHandedness_ == noPoints)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"patchFaces(const label direc, const labelList& range) const"
|
||||
) << "Unable to determine block handedness as points "
|
||||
<< "have not been read in yet"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
else if (blockHandedness_ == left)
|
||||
{
|
||||
// turn all faces inside out
|
||||
forAll(result, faceI)
|
||||
{
|
||||
result[faceI].flip();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
159
applications/utilities/mesh/conversion/cfx4ToFoam/hexBlock.H
Normal file
159
applications/utilities/mesh/conversion/cfx4ToFoam/hexBlock.H
Normal file
@ -0,0 +1,159 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ 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::hexBlock
|
||||
|
||||
Description
|
||||
Hex block definition used in the cfx converter.
|
||||
|
||||
SourceFiles
|
||||
hexBlock.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef hexBlock_H
|
||||
#define hexBlock_H
|
||||
|
||||
#include "labelList.H"
|
||||
#include "pointField.H"
|
||||
#include "faceList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class hexBlock Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class hexBlock
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Handedness of the block
|
||||
enum handed
|
||||
{
|
||||
noPoints,
|
||||
right,
|
||||
left
|
||||
};
|
||||
|
||||
//- Number of point in each direction
|
||||
label xDim_;
|
||||
label yDim_;
|
||||
label zDim_;
|
||||
|
||||
//- Handedness of the block
|
||||
handed blockHandedness_;
|
||||
|
||||
//- List of points
|
||||
pointField points_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
hexBlock(const hexBlock&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const hexBlock&);
|
||||
|
||||
//- Vertex addressing inside the block
|
||||
inline label vtxLabel(label i, label j, label k) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
hexBlock(const label nx, const label ny, const label nz);
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Number of points
|
||||
label xDim() const
|
||||
{
|
||||
return xDim_;
|
||||
}
|
||||
|
||||
label yDim() const
|
||||
{
|
||||
return yDim_;
|
||||
}
|
||||
|
||||
label zDim() const
|
||||
{
|
||||
return zDim_;
|
||||
}
|
||||
|
||||
label nBlockPoints() const
|
||||
{
|
||||
return (xDim_ + 1)*(yDim_ + 1)*(zDim_ + 1);
|
||||
}
|
||||
|
||||
label nBlockCells() const
|
||||
{
|
||||
return xDim_*yDim_*zDim_;
|
||||
}
|
||||
|
||||
//- Return block points
|
||||
const pointField& points() const
|
||||
{
|
||||
if (blockHandedness_ == noPoints)
|
||||
{
|
||||
FatalErrorIn("hexBlock::points() const")
|
||||
<< "points not read in yet"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return points_;
|
||||
}
|
||||
|
||||
//- Return block cells
|
||||
labelListList blockCells() const;
|
||||
|
||||
//- Return block patch faces given direction and range limits
|
||||
// From the cfx manual: direction
|
||||
// 0 = solid (3-D patch),
|
||||
// 1 = high i, 2 = high j, 3 = high k
|
||||
// 4 = low i, 5 = low j, 6 = low k
|
||||
faceList patchFaces(label direc, const labelList& range) const;
|
||||
|
||||
|
||||
//- Read block points
|
||||
void readPoints(Istream&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
datToFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/datToFoam
|
||||
@ -0,0 +1,5 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools
|
||||
151
applications/utilities/mesh/conversion/datToFoam/datToFoam.C
Normal file
151
applications/utilities/mesh/conversion/datToFoam/datToFoam.C
Normal file
@ -0,0 +1,151 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
datToFoam
|
||||
|
||||
Description
|
||||
Reads in a datToFoam mesh file and outputs a points file. Used in
|
||||
conjunction with blockMesh.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "IFstream.H"
|
||||
#include "OFstream.H"
|
||||
#include "pointField.H"
|
||||
#include "unitConversion.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
argList::validArgs.append("dat file");
|
||||
|
||||
argList args(argc, argv);
|
||||
|
||||
if (!args.check())
|
||||
{
|
||||
FatalError.exit();
|
||||
}
|
||||
|
||||
#include "createTime.H"
|
||||
|
||||
std::ifstream plot3dFile(args.args()[1].c_str());
|
||||
|
||||
string line;
|
||||
std::getline(plot3dFile, line);
|
||||
std::getline(plot3dFile, line);
|
||||
|
||||
IStringStream Istring(line);
|
||||
word block;
|
||||
string zoneName;
|
||||
token punctuation;
|
||||
label iPoints;
|
||||
label jPoints;
|
||||
|
||||
Istring >> block;
|
||||
Istring >> block;
|
||||
Istring >> zoneName;
|
||||
Istring >> punctuation;
|
||||
Istring >> block;
|
||||
Istring >> iPoints;
|
||||
Istring >> block;
|
||||
Istring >> jPoints;
|
||||
|
||||
Info<< "Number of vertices in i direction = " << iPoints << endl
|
||||
<< "Number of vertices in j direction = " << jPoints << endl;
|
||||
|
||||
// We ignore the first layer of points in i and j the biconic meshes
|
||||
label nPointsij = (iPoints - 1)*(jPoints - 1);
|
||||
|
||||
pointField points(nPointsij, vector::zero);
|
||||
|
||||
for (direction comp = 0; comp < 2; comp++)
|
||||
{
|
||||
label p(0);
|
||||
|
||||
for (label j = 0; j < jPoints; j++)
|
||||
{
|
||||
for (label i = 0; i < iPoints; i++)
|
||||
{
|
||||
double coord;
|
||||
plot3dFile >> coord;
|
||||
|
||||
// if statement ignores the first layer in i and j
|
||||
if (i>0 && j>0)
|
||||
{
|
||||
points[p++][comp] = coord;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// correct error in biconic meshes
|
||||
forAll(points, i)
|
||||
{
|
||||
if (points[i][1] < 1e-07)
|
||||
{
|
||||
points[i][1] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
pointField pointsWedge(nPointsij*2, vector::zero);
|
||||
|
||||
fileName pointsFile(runTime.constantPath()/"points.tmp");
|
||||
OFstream pFile(pointsFile);
|
||||
|
||||
scalar a(degToRad(0.1));
|
||||
tensor rotateZ =
|
||||
tensor
|
||||
(
|
||||
1.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0,
|
||||
0.0, -::sin(a), ::cos(a)
|
||||
);
|
||||
|
||||
forAll(points, i)
|
||||
{
|
||||
pointsWedge[i] = (rotateZ & points[i]);
|
||||
pointsWedge[i+nPointsij] = cmptMultiply
|
||||
(
|
||||
vector(1.0, 1.0, -1.0),
|
||||
pointsWedge[i]
|
||||
);
|
||||
}
|
||||
|
||||
Info<< "Writing points to: " << nl
|
||||
<< " " << pointsFile << endl;
|
||||
pFile << pointsWedge;
|
||||
|
||||
Info<< "End" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
fluent3DMeshToFoam.L
|
||||
|
||||
EXE = $(FOAM_APPBIN)/fluent3DMeshToFoam
|
||||
@ -0,0 +1,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools \
|
||||
-ldynamicMesh
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,6 @@
|
||||
extrudedTriangleCellShape.C
|
||||
extrudedQuadCellShape.C
|
||||
create3DCellShape.C
|
||||
fluentMeshToFoam.L
|
||||
|
||||
EXE = $(FOAM_APPBIN)/fluentMeshToFoam
|
||||
@ -0,0 +1,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools \
|
||||
-ldynamicMesh
|
||||
@ -0,0 +1,35 @@
|
||||
Notes for fluentMeshToFoam with zone preservation
|
||||
#################################################
|
||||
|
||||
1. New option added:
|
||||
- writeSets:
|
||||
Writes all Fluent boundaries faceSets preserving Fluent names
|
||||
Writes all Fluent regions to cellSets preserving Fluent names
|
||||
lines: 1375 - 1393 & 1673 - 1741
|
||||
sets are useful for post-processing using foamToVTK with the "-faceSet
|
||||
<name>" and "-cellSet <name>" options.
|
||||
|
||||
- writeZones:
|
||||
Writes all regions to cellZones preserving Fluent names
|
||||
Writes all region internal face to faceZones preserving Fluent names
|
||||
lines: 1545 - 1667
|
||||
Zones are usefull for porous media and MRF calculations
|
||||
|
||||
2. Zone Access
|
||||
- Zones are simple lists of label lists that can be accessed from polyMesh
|
||||
with the cellZones(), faceZones() and pointZones() member functions
|
||||
|
||||
- Example (Members from polyMesh.H and ZoneMesh.H):
|
||||
const labelList& thisCellZone = mesh.cellZones()["thisZoneName"];
|
||||
|
||||
- Zone integrity is preserved during mesh modification and decompomposition.
|
||||
|
||||
- Once created via addZones, zones allow modification through non-const
|
||||
access
|
||||
|
||||
3. Fluent boundary types.
|
||||
- All internal and baffle elements are ignored during conversion
|
||||
|
||||
- Boundary faces labelled as internal (i.e. interior, interface, internal,
|
||||
solid, fan, radiator, porous-jump) but that are in fact external boundaries
|
||||
will be added to a default wall boundary.
|
||||
@ -0,0 +1,87 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ 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/>.
|
||||
|
||||
InClass
|
||||
Foam::cellShapeRecognition
|
||||
|
||||
Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef cellShapeRecognition_H
|
||||
#define cellShapeRecognition_H
|
||||
|
||||
#include "cellShape.H"
|
||||
#include "cellModeller.H"
|
||||
#include "faceList.H"
|
||||
#include "PtrList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
cellShape extrudedTriangleCellShape
|
||||
(
|
||||
const label cellIndex,
|
||||
const labelList& faceLabels,
|
||||
const faceList& faces,
|
||||
const labelList& owner,
|
||||
const labelList& neighbour,
|
||||
const label pointOffset,
|
||||
faceList& frontAndBackFaces
|
||||
);
|
||||
|
||||
|
||||
cellShape extrudedQuadCellShape
|
||||
(
|
||||
const label cellIndex,
|
||||
const labelList& faceLabels,
|
||||
const faceList& faces,
|
||||
const labelList& owner,
|
||||
const labelList& neighbour,
|
||||
const label pointOffset,
|
||||
faceList& frontAndBackFaces
|
||||
);
|
||||
|
||||
|
||||
cellShape create3DCellShape
|
||||
(
|
||||
const label cellIndex,
|
||||
const labelList& faceLabels,
|
||||
const faceList& faces,
|
||||
const labelList& owner,
|
||||
const labelList& neighbour,
|
||||
const label fluentCellModelID
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,297 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
Construct a cell shape from face information
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "cellShapeRecognition.H"
|
||||
#include "labelList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
cellShape create3DCellShape
|
||||
(
|
||||
const label cellIndex,
|
||||
const labelList& faceLabels,
|
||||
const faceList& faces,
|
||||
const labelList& owner,
|
||||
const labelList& neighbour,
|
||||
const label fluentCellModelID
|
||||
)
|
||||
{
|
||||
// List of pointers to shape models for 3-D shape recognition
|
||||
static List<const cellModel*> fluentCellModelLookup
|
||||
(
|
||||
7,
|
||||
reinterpret_cast<const cellModel*>(0)
|
||||
);
|
||||
|
||||
fluentCellModelLookup[2] = cellModeller::lookup("tet");
|
||||
fluentCellModelLookup[4] = cellModeller::lookup("hex");
|
||||
fluentCellModelLookup[5] = cellModeller::lookup("pyr");
|
||||
fluentCellModelLookup[6] = cellModeller::lookup("prism");
|
||||
|
||||
static label faceMatchingOrder[7][6] =
|
||||
{
|
||||
{-1, -1, -1, -1, -1, -1},
|
||||
{-1, -1, -1, -1, -1, -1},
|
||||
{ 0, 1, 2, 3, -1, -1}, // tet
|
||||
{-1, -1, -1, -1, -1, -1},
|
||||
{ 0, 2, 4, 3, 5, 1}, // hex
|
||||
{ 0, 1, 2, 3, 4, -1}, // pyr
|
||||
{ 0, 2, 3, 4, 1, -1}, // prism
|
||||
};
|
||||
|
||||
const cellModel& curModel = *fluentCellModelLookup[fluentCellModelID];
|
||||
|
||||
// Checking
|
||||
if (faceLabels.size() != curModel.nFaces())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"create3DCellShape(const label cellIndex, "
|
||||
"const labelList& faceLabels, const labelListList& faces, "
|
||||
"const labelList& owner, const labelList& neighbour, "
|
||||
"const label fluentCellModelID)"
|
||||
) << "Number of face labels not equal to"
|
||||
<< "number of face in the model. "
|
||||
<< "Number of face labels: " << faceLabels.size()
|
||||
<< " number of faces in model: " << curModel.nFaces()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// make a list of outward-pointing faces
|
||||
labelListList localFaces(faceLabels.size());
|
||||
|
||||
forAll(faceLabels, faceI)
|
||||
{
|
||||
const label curFaceLabel = faceLabels[faceI];
|
||||
|
||||
const labelList& curFace = faces[curFaceLabel];
|
||||
|
||||
if (owner[curFaceLabel] == cellIndex)
|
||||
{
|
||||
localFaces[faceI] = curFace;
|
||||
}
|
||||
else if (neighbour[curFaceLabel] == cellIndex)
|
||||
{
|
||||
// Reverse the face
|
||||
localFaces[faceI].setSize(curFace.size());
|
||||
|
||||
forAllReverse(curFace, i)
|
||||
{
|
||||
localFaces[faceI][curFace.size() - i - 1] =
|
||||
curFace[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"create3DCellShape(const label cellIndex, "
|
||||
"const labelList& faceLabels, const labelListList& faces, "
|
||||
"const labelList& owner, const labelList& neighbour, "
|
||||
"const label fluentCellModelID)"
|
||||
) << "face " << curFaceLabel
|
||||
<< " does not belong to cell " << cellIndex
|
||||
<< ". Face owner: " << owner[curFaceLabel] << " neighbour: "
|
||||
<< neighbour[curFaceLabel]
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Algorithm:
|
||||
// Make an empty list of pointLabels and initialise it with -1. Pick the
|
||||
// first face from modelFaces and look through the faces to find one with
|
||||
// the same number of labels. Insert face by copying its labels into
|
||||
// pointLabels. Mark the face as used. Loop through all model faces.
|
||||
// For each model face loop through faces. If the face is unused and the
|
||||
// numbers of labels fit, try to match the face onto the point labels. If
|
||||
// at least one edge is matched, insert the face into pointLabels. If at
|
||||
// any stage the matching algorithm reaches the end of faces, the matching
|
||||
// algorithm has failed. Once all the faces are matched, the list of
|
||||
// pointLabels defines the model.
|
||||
|
||||
// Make a list of empty pointLabels
|
||||
labelList pointLabels(curModel.nPoints(), -1);
|
||||
|
||||
// Follow the used mesh faces
|
||||
List<bool> meshFaceUsed(localFaces.size(), false);
|
||||
|
||||
// Get the raw model faces
|
||||
const faceList& modelFaces = curModel.modelFaces();
|
||||
|
||||
// Insert the first face into the list
|
||||
const labelList& firstModelFace =
|
||||
modelFaces[faceMatchingOrder[fluentCellModelID][0]];
|
||||
|
||||
bool found = false;
|
||||
|
||||
forAll(localFaces, meshFaceI)
|
||||
{
|
||||
if (localFaces[meshFaceI].size() == firstModelFace.size())
|
||||
{
|
||||
// Match. Insert points into the pointLabels
|
||||
found = true;
|
||||
|
||||
const labelList& curMeshFace = localFaces[meshFaceI];
|
||||
|
||||
meshFaceUsed[meshFaceI] = true;
|
||||
|
||||
forAll(curMeshFace, pointI)
|
||||
{
|
||||
pointLabels[firstModelFace[pointI]] = curMeshFace[pointI];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"create3DCellShape(const label cellIndex, "
|
||||
"const labelList& faceLabels, const labelListList& faces, "
|
||||
"const labelList& owner, const labelList& neighbour, "
|
||||
"const label fluentCellModelID)"
|
||||
) << "Cannot find match for first face. "
|
||||
<< "cell model: " << curModel.name() << " first model face: "
|
||||
<< firstModelFace << " Mesh faces: " << localFaces
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
for (label modelFaceI = 1; modelFaceI < modelFaces.size(); modelFaceI++)
|
||||
{
|
||||
// get the next model face
|
||||
const labelList& curModelFace =
|
||||
modelFaces
|
||||
[faceMatchingOrder[fluentCellModelID][modelFaceI]];
|
||||
|
||||
found = false;
|
||||
|
||||
// Loop through mesh faces until a match is found
|
||||
forAll(localFaces, meshFaceI)
|
||||
{
|
||||
if
|
||||
(
|
||||
!meshFaceUsed[meshFaceI]
|
||||
&& localFaces[meshFaceI].size() == curModelFace.size()
|
||||
)
|
||||
{
|
||||
// A possible match. A mesh face will be rotated, so make a copy
|
||||
labelList meshFaceLabels = localFaces[meshFaceI];
|
||||
|
||||
for
|
||||
(
|
||||
label rotation = 0;
|
||||
rotation < meshFaceLabels.size();
|
||||
rotation++
|
||||
)
|
||||
{
|
||||
// try matching the face
|
||||
label nMatchedLabels = 0;
|
||||
|
||||
forAll(meshFaceLabels, pointI)
|
||||
{
|
||||
if
|
||||
(
|
||||
pointLabels[curModelFace[pointI]]
|
||||
== meshFaceLabels[pointI]
|
||||
)
|
||||
{
|
||||
nMatchedLabels++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nMatchedLabels >= 2)
|
||||
{
|
||||
// match!
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
// match found. Insert mesh face
|
||||
forAll(meshFaceLabels, pointI)
|
||||
{
|
||||
pointLabels[curModelFace[pointI]] =
|
||||
meshFaceLabels[pointI];
|
||||
}
|
||||
|
||||
meshFaceUsed[meshFaceI] = true;
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No match found. Rotate face
|
||||
label firstLabel = meshFaceLabels[0];
|
||||
|
||||
for (label i = 1; i < meshFaceLabels.size(); i++)
|
||||
{
|
||||
meshFaceLabels[i - 1] = meshFaceLabels[i];
|
||||
}
|
||||
|
||||
meshFaceLabels.last() = firstLabel;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
// A model face is not matched. Shape detection failed
|
||||
FatalErrorIn
|
||||
(
|
||||
"create3DCellShape(const label cellIndex, "
|
||||
"const labelList& faceLabels, const labelListList& faces, "
|
||||
"const labelList& owner, const labelList& neighbour, "
|
||||
"const label fluentCellModelID)"
|
||||
) << "Cannot find match for face "
|
||||
<< modelFaceI
|
||||
<< ".\nModel: " << curModel.name() << " model face: "
|
||||
<< curModelFace << " Mesh faces: " << localFaces
|
||||
<< "Matched points: " << pointLabels
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
return cellShape(curModel, pointLabels);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,275 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
Construct an extruded hex cell shape from four straight edges
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "cellShapeRecognition.H"
|
||||
#include "labelList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
cellShape extrudedQuadCellShape
|
||||
(
|
||||
const label cellIndex,
|
||||
const labelList& faceLabels,
|
||||
const faceList& faces,
|
||||
const labelList& owner,
|
||||
const labelList& neighbour,
|
||||
const label pointOffset,
|
||||
faceList& frontAndBackFaces
|
||||
)
|
||||
{
|
||||
static const cellModel* hexModelPtr_ = NULL;
|
||||
|
||||
if (!hexModelPtr_)
|
||||
{
|
||||
hexModelPtr_ = cellModeller::lookup("hex");
|
||||
}
|
||||
|
||||
const cellModel& hex = *hexModelPtr_;
|
||||
|
||||
// Checking
|
||||
if (faceLabels.size() != 4)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"extrudedQuadCellShape(const label cellIndex, "
|
||||
"const labelList& faceLabels, const faceList& faces, "
|
||||
"const labelList& owner, const labelList& neighbour, "
|
||||
"const label pointOffset, faceList& frontAndBackFaces)"
|
||||
) << "Trying to create a quad with " << faceLabels.size() << " faces"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// make a list of outward-pointing faces
|
||||
labelListList localFaces(4);
|
||||
|
||||
forAll(faceLabels, faceI)
|
||||
{
|
||||
const label curFaceLabel = faceLabels[faceI];
|
||||
|
||||
const face& curFace = faces[curFaceLabel];
|
||||
|
||||
if (curFace.size() != 2)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"extrudedQuadCellShape(const label cellIndex, "
|
||||
"const labelList& faceLabels, const faceList& faces, "
|
||||
"const labelList& owner, const labelList& neighbour, "
|
||||
"const label pointOffset, faceList& frontAndBackFaces)"
|
||||
) << "face " << curFaceLabel
|
||||
<< "does not have 2 vertices. Number of vertices: " << curFace
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
if (owner[curFaceLabel] == cellIndex)
|
||||
{
|
||||
localFaces[faceI] = curFace;
|
||||
}
|
||||
else if (neighbour[curFaceLabel] == cellIndex)
|
||||
{
|
||||
// Reverse the face. Note: it is necessary to reverse by
|
||||
// hand to preserve connectivity of a 2-D mesh.
|
||||
//
|
||||
localFaces[faceI].setSize(curFace.size());
|
||||
|
||||
forAllReverse(curFace, i)
|
||||
{
|
||||
localFaces[faceI][curFace.size() - i - 1] =
|
||||
curFace[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"extrudedQuadCellShape(const label cellIndex, "
|
||||
"const labelList& faceLabels, const faceList& faces, "
|
||||
"const labelList& owner, const labelList& neighbour, "
|
||||
"const label pointOffset, faceList& frontAndBackFaces)"
|
||||
) << "face " << curFaceLabel
|
||||
<< " does not belong to cell " << cellIndex
|
||||
<< ". Face owner: " << owner[curFaceLabel] << " neighbour: "
|
||||
<< neighbour[curFaceLabel]
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a label list for the model
|
||||
// This is done by finding two edges that do not share any vertices.
|
||||
// Knowing the opposite pair of edges (with normals poining outward
|
||||
// is enough to make a cell
|
||||
if
|
||||
(
|
||||
localFaces[0][0] != localFaces[1][1]
|
||||
&& localFaces[0][1] != localFaces[1][0]
|
||||
)
|
||||
{
|
||||
// Set front and back plane faces
|
||||
labelList missingPlaneFace(4);
|
||||
|
||||
// front plane
|
||||
missingPlaneFace[0] = localFaces[0][0];
|
||||
missingPlaneFace[1] = localFaces[1][1];
|
||||
missingPlaneFace[2] = localFaces[1][0];
|
||||
missingPlaneFace[3] = localFaces[0][1];
|
||||
|
||||
frontAndBackFaces[2*cellIndex] = face(missingPlaneFace);
|
||||
|
||||
// back plane
|
||||
missingPlaneFace[0] = localFaces[0][0] + pointOffset;
|
||||
missingPlaneFace[1] = localFaces[0][1] + pointOffset;
|
||||
missingPlaneFace[2] = localFaces[1][0] + pointOffset;
|
||||
missingPlaneFace[3] = localFaces[1][1] + pointOffset;
|
||||
|
||||
frontAndBackFaces[2*cellIndex + 1] = face(missingPlaneFace);
|
||||
|
||||
// make a cell
|
||||
labelList cellShapeLabels(8);
|
||||
|
||||
cellShapeLabels[0] = localFaces[0][0];
|
||||
cellShapeLabels[1] = localFaces[0][1];
|
||||
cellShapeLabels[2] = localFaces[1][0];
|
||||
cellShapeLabels[3] = localFaces[1][1];
|
||||
|
||||
cellShapeLabels[4] = localFaces[0][0] + pointOffset;
|
||||
cellShapeLabels[5] = localFaces[0][1] + pointOffset;
|
||||
cellShapeLabels[6] = localFaces[1][0] + pointOffset;
|
||||
cellShapeLabels[7] = localFaces[1][1] + pointOffset;
|
||||
|
||||
|
||||
return cellShape(hex, cellShapeLabels);
|
||||
}
|
||||
else if
|
||||
(
|
||||
localFaces[0][0] != localFaces[2][1]
|
||||
&& localFaces[0][1] != localFaces[2][0]
|
||||
)
|
||||
{
|
||||
// Set front and back plane faces
|
||||
labelList missingPlaneFace(4);
|
||||
|
||||
// front plane
|
||||
missingPlaneFace[0] = localFaces[0][0];
|
||||
missingPlaneFace[1] = localFaces[2][1];
|
||||
missingPlaneFace[2] = localFaces[2][0];
|
||||
missingPlaneFace[3] = localFaces[0][1];
|
||||
|
||||
frontAndBackFaces[2*cellIndex] = face(missingPlaneFace);
|
||||
|
||||
// back plane
|
||||
missingPlaneFace[0] = localFaces[0][0] + pointOffset;
|
||||
missingPlaneFace[1] = localFaces[0][1] + pointOffset;
|
||||
missingPlaneFace[2] = localFaces[2][0] + pointOffset;
|
||||
missingPlaneFace[3] = localFaces[2][1] + pointOffset;
|
||||
|
||||
frontAndBackFaces[2*cellIndex + 1] = face(missingPlaneFace);
|
||||
|
||||
// make a cell
|
||||
labelList cellShapeLabels(8);
|
||||
|
||||
cellShapeLabels[0] = localFaces[0][0];
|
||||
cellShapeLabels[1] = localFaces[0][1];
|
||||
cellShapeLabels[2] = localFaces[2][0];
|
||||
cellShapeLabels[3] = localFaces[2][1];
|
||||
|
||||
cellShapeLabels[4] = localFaces[0][0] + pointOffset;
|
||||
cellShapeLabels[5] = localFaces[0][1] + pointOffset;
|
||||
cellShapeLabels[6] = localFaces[2][0] + pointOffset;
|
||||
cellShapeLabels[7] = localFaces[2][1] + pointOffset;
|
||||
|
||||
|
||||
return cellShape(hex, cellShapeLabels);
|
||||
}
|
||||
else if
|
||||
(
|
||||
localFaces[0][0] != localFaces[3][1]
|
||||
&& localFaces[0][1] != localFaces[3][0]
|
||||
)
|
||||
{
|
||||
// Set front and back plane faces
|
||||
labelList missingPlaneFace(4);
|
||||
|
||||
// front plane
|
||||
missingPlaneFace[0] = localFaces[0][0];
|
||||
missingPlaneFace[1] = localFaces[3][1];
|
||||
missingPlaneFace[2] = localFaces[3][0];
|
||||
missingPlaneFace[3] = localFaces[0][1];
|
||||
|
||||
frontAndBackFaces[2*cellIndex] = face(missingPlaneFace);
|
||||
|
||||
// back plane
|
||||
missingPlaneFace[0] = localFaces[0][0] + pointOffset;
|
||||
missingPlaneFace[1] = localFaces[0][1] + pointOffset;
|
||||
missingPlaneFace[2] = localFaces[3][0] + pointOffset;
|
||||
missingPlaneFace[3] = localFaces[3][1] + pointOffset;
|
||||
|
||||
frontAndBackFaces[2*cellIndex + 1] = face(missingPlaneFace);
|
||||
|
||||
// make a cell
|
||||
labelList cellShapeLabels(8);
|
||||
|
||||
cellShapeLabels[0] = localFaces[0][0];
|
||||
cellShapeLabels[1] = localFaces[0][1];
|
||||
cellShapeLabels[2] = localFaces[3][0];
|
||||
cellShapeLabels[3] = localFaces[3][1];
|
||||
|
||||
cellShapeLabels[4] = localFaces[0][0] + pointOffset;
|
||||
cellShapeLabels[5] = localFaces[0][1] + pointOffset;
|
||||
cellShapeLabels[6] = localFaces[3][0] + pointOffset;
|
||||
cellShapeLabels[7] = localFaces[3][1] + pointOffset;
|
||||
|
||||
|
||||
return cellShape(hex, cellShapeLabels);
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"extrudedQuadCellShape(const label cellIndex, "
|
||||
"const labelList& faceLabels, const faceList& faces, "
|
||||
"const labelList& owner, const labelList& neighbour, "
|
||||
"const label pointOffset, faceList& frontAndBackFaces)"
|
||||
) << "Problem with edge matching. Edges: " << localFaces
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Return added to keep compiler happy
|
||||
return cellShape(hex, labelList(0));
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,215 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
Construct an extruded triangular prism cell shape from three straight edges
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "cellShapeRecognition.H"
|
||||
#include "labelList.H"
|
||||
#include "cellModeller.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
cellShape extrudedTriangleCellShape
|
||||
(
|
||||
const label cellIndex,
|
||||
const labelList& faceLabels,
|
||||
const faceList& faces,
|
||||
const labelList& owner,
|
||||
const labelList& neighbour,
|
||||
const label pointOffset,
|
||||
faceList& frontAndBackFaces
|
||||
)
|
||||
{
|
||||
static const cellModel* prismModelPtr_ = NULL;
|
||||
|
||||
if (!prismModelPtr_)
|
||||
{
|
||||
prismModelPtr_ = cellModeller::lookup("prism");
|
||||
}
|
||||
|
||||
const cellModel& prism = *prismModelPtr_;
|
||||
|
||||
// Checking
|
||||
if (faceLabels.size() != 3)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"extrudedTriangleCellShape(const label cellIndex, "
|
||||
"const labelList& faceLabels, const faceList& faces, "
|
||||
"const labelList& owner, const labelList& neighbour, "
|
||||
"const label pointOffset, faceList& frontAndBackFaces)"
|
||||
) << "Trying to create a triangle with " << faceLabels.size()
|
||||
<< " faces"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// make a list of outward-pointing faces
|
||||
labelListList localFaces(3);
|
||||
|
||||
forAll(faceLabels, faceI)
|
||||
{
|
||||
const label curFaceLabel = faceLabels[faceI];
|
||||
|
||||
const face& curFace = faces[curFaceLabel];
|
||||
|
||||
if (curFace.size() != 2)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"extrudedTriangleCellShape(const label cellIndex, "
|
||||
"const labelList& faceLabels, const faceList& faces, "
|
||||
"const labelList& owner, const labelList& neighbour, "
|
||||
"const label pointOffset, faceList& frontAndBackFaces)"
|
||||
) << "face " << curFaceLabel
|
||||
<< "does not have 2 vertices. Number of vertices: " << curFace
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
if (owner[curFaceLabel] == cellIndex)
|
||||
{
|
||||
localFaces[faceI] = curFace;
|
||||
}
|
||||
else if (neighbour[curFaceLabel] == cellIndex)
|
||||
{
|
||||
// Reverse the face. Note: it is necessary to reverse by
|
||||
// hand to preserve connectivity of a 2-D mesh.
|
||||
//
|
||||
localFaces[faceI].setSize(curFace.size());
|
||||
|
||||
forAllReverse(curFace, i)
|
||||
{
|
||||
localFaces[faceI][curFace.size() - i - 1] =
|
||||
curFace[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"extrudedTriangleCellShape(const label cellIndex, "
|
||||
"const labelList& faceLabels, const faceList& faces, "
|
||||
"const labelList& owner, const labelList& neighbour, "
|
||||
"const label pointOffset, faceList& frontAndBackFaces)"
|
||||
) << "face " << curFaceLabel
|
||||
<< " does not belong to cell " << cellIndex
|
||||
<< ". Face owner: " << owner[curFaceLabel] << " neighbour: "
|
||||
<< neighbour[curFaceLabel]
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a label list for the model
|
||||
if (localFaces[0][1] == localFaces[1][0])
|
||||
{
|
||||
// Set front and back plane faces
|
||||
labelList missingPlaneFace(3);
|
||||
|
||||
// front plane
|
||||
missingPlaneFace[0] = localFaces[0][0];
|
||||
missingPlaneFace[1] = localFaces[1][1];
|
||||
missingPlaneFace[2] = localFaces[0][1];
|
||||
|
||||
frontAndBackFaces[2*cellIndex] = face(missingPlaneFace);
|
||||
|
||||
// back plane
|
||||
missingPlaneFace[0] = localFaces[0][0] + pointOffset;
|
||||
missingPlaneFace[1] = localFaces[0][1] + pointOffset;
|
||||
missingPlaneFace[2] = localFaces[1][1] + pointOffset;
|
||||
|
||||
frontAndBackFaces[2*cellIndex + 1] = face(missingPlaneFace);
|
||||
|
||||
// make a cell
|
||||
labelList cellShapeLabels(6);
|
||||
|
||||
cellShapeLabels[0] = localFaces[0][0];
|
||||
cellShapeLabels[1] = localFaces[0][1];
|
||||
cellShapeLabels[2] = localFaces[1][1];
|
||||
|
||||
cellShapeLabels[3] = localFaces[0][0] + pointOffset;
|
||||
cellShapeLabels[4] = localFaces[0][1] + pointOffset;
|
||||
cellShapeLabels[5] = localFaces[1][1] + pointOffset;
|
||||
|
||||
return cellShape(prism, cellShapeLabels);
|
||||
}
|
||||
else if (localFaces[0][1] == localFaces[2][0])
|
||||
{
|
||||
// Set front and back plane faces
|
||||
labelList missingPlaneFace(3);
|
||||
|
||||
// front plane
|
||||
missingPlaneFace[0] = localFaces[0][0];
|
||||
missingPlaneFace[1] = localFaces[2][1];
|
||||
missingPlaneFace[2] = localFaces[0][1];
|
||||
|
||||
frontAndBackFaces[2*cellIndex] = face(missingPlaneFace);
|
||||
|
||||
// back plane
|
||||
missingPlaneFace[0] = localFaces[0][0] + pointOffset;
|
||||
missingPlaneFace[1] = localFaces[0][1] + pointOffset;
|
||||
missingPlaneFace[2] = localFaces[2][1] + pointOffset;
|
||||
|
||||
frontAndBackFaces[2*cellIndex + 1] = face(missingPlaneFace);
|
||||
|
||||
// make a cell
|
||||
labelList cellShapeLabels(6);
|
||||
|
||||
cellShapeLabels[0] = localFaces[0][0];
|
||||
cellShapeLabels[1] = localFaces[0][1];
|
||||
cellShapeLabels[2] = localFaces[2][1];
|
||||
|
||||
cellShapeLabels[3] = localFaces[0][0] + pointOffset;
|
||||
cellShapeLabels[4] = localFaces[0][1] + pointOffset;
|
||||
cellShapeLabels[5] = localFaces[2][1] + pointOffset;
|
||||
|
||||
return cellShape(prism, cellShapeLabels);
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"extrudedTriangleCellShape(const label cellIndex, "
|
||||
"const labelList& faceLabels, const faceList& faces, "
|
||||
"const labelList& owner, const labelList& neighbour, "
|
||||
"const label pointOffset, faceList& frontAndBackFaces)"
|
||||
) << "Problem with edge matching. Edges: " << localFaces
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Return added to keep compiler happy
|
||||
return cellShape(prism, labelList(0));
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,4 @@
|
||||
fluentFvMesh.C
|
||||
foamMeshToFluent.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/foamMeshToFluent
|
||||
@ -0,0 +1,5 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume
|
||||
@ -0,0 +1,307 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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 <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using std::ofstream;
|
||||
using std::ios;
|
||||
|
||||
#include "Time.H"
|
||||
#include "fluentFvMesh.H"
|
||||
#include "primitiveMesh.H"
|
||||
#include "wallFvPatch.H"
|
||||
#include "symmetryPlaneFvPatch.H"
|
||||
#include "symmetryFvPatch.H"
|
||||
#include "cellModeller.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::fluentFvMesh::fluentFvMesh(const IOobject& io)
|
||||
:
|
||||
fvMesh(io)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::fluentFvMesh::writeFluentMesh() const
|
||||
{
|
||||
// make a directory called proInterface in the case
|
||||
mkDir(time().rootPath()/time().caseName()/"fluentInterface");
|
||||
|
||||
// open a file for the mesh
|
||||
ofstream fluentMeshFile
|
||||
(
|
||||
(
|
||||
time().rootPath()/
|
||||
time().caseName()/
|
||||
"fluentInterface"/
|
||||
time().caseName() + ".msh"
|
||||
).c_str()
|
||||
);
|
||||
|
||||
Info<< "Writing Header" << endl;
|
||||
|
||||
fluentMeshFile
|
||||
<< "(0 \"FOAM to Fluent Mesh File\")" << std::endl << std::endl
|
||||
<< "(0 \"Dimension:\")" << std::endl
|
||||
<< "(2 3)" << std::endl << std::endl
|
||||
<< "(0 \"Grid dimensions:\")" << std::endl;
|
||||
|
||||
// Writing number of points
|
||||
fluentMeshFile
|
||||
<< "(10 (0 1 ";
|
||||
|
||||
// Writing hex
|
||||
fluentMeshFile.setf(ios::hex, ios::basefield);
|
||||
|
||||
fluentMeshFile
|
||||
<< nPoints() << " 0 3))" << std::endl;
|
||||
|
||||
// Writing number of cells
|
||||
fluentMeshFile
|
||||
<< "(12 (0 1 "
|
||||
<< nCells() << " 0 0))" << std::endl;
|
||||
|
||||
// Writing number of faces
|
||||
label nFcs = nFaces();
|
||||
|
||||
fluentMeshFile
|
||||
<< "(13 (0 1 ";
|
||||
|
||||
// Still writing hex
|
||||
fluentMeshFile
|
||||
<< nFcs << " 0 0))" << std::endl << std::endl;
|
||||
|
||||
// Return to dec
|
||||
fluentMeshFile.setf(ios::dec, ios::basefield);
|
||||
|
||||
// Writing points
|
||||
fluentMeshFile
|
||||
<< "(10 (1 1 ";
|
||||
|
||||
fluentMeshFile.setf(ios::hex, ios::basefield);
|
||||
fluentMeshFile
|
||||
<< nPoints() << " 1 3)"
|
||||
<< std::endl << "(" << std::endl;
|
||||
|
||||
fluentMeshFile.precision(10);
|
||||
fluentMeshFile.setf(ios::scientific);
|
||||
|
||||
const pointField& p = points();
|
||||
|
||||
forAll(p, pointI)
|
||||
{
|
||||
fluentMeshFile
|
||||
<< " "
|
||||
<< p[pointI].x() << " "
|
||||
<< p[pointI].y()
|
||||
<< " " << p[pointI].z() << std::endl;
|
||||
}
|
||||
|
||||
fluentMeshFile
|
||||
<< "))" << std::endl << std::endl;
|
||||
|
||||
const labelUList& own = owner();
|
||||
const labelUList& nei = neighbour();
|
||||
|
||||
const faceList& fcs = faces();
|
||||
|
||||
// Writing (mixed) internal faces
|
||||
fluentMeshFile
|
||||
<< "(13 (2 1 "
|
||||
<< own.size() << " 2 0)" << std::endl << "(" << std::endl;
|
||||
|
||||
forAll(own, faceI)
|
||||
{
|
||||
const labelList& l = fcs[faceI];
|
||||
|
||||
fluentMeshFile << " ";
|
||||
|
||||
fluentMeshFile << l.size() << " ";
|
||||
|
||||
forAll(l, lI)
|
||||
{
|
||||
fluentMeshFile << l[lI] + 1 << " ";
|
||||
}
|
||||
|
||||
fluentMeshFile << nei[faceI] + 1 << " ";
|
||||
fluentMeshFile << own[faceI] + 1 << std::endl;
|
||||
}
|
||||
|
||||
fluentMeshFile << "))" << std::endl;
|
||||
|
||||
label nWrittenFaces = own.size();
|
||||
|
||||
// Writing boundary faces
|
||||
forAll(boundary(), patchI)
|
||||
{
|
||||
const faceUList& patchFaces = boundaryMesh()[patchI];
|
||||
|
||||
const labelList& patchFaceCells =
|
||||
boundaryMesh()[patchI].faceCells();
|
||||
|
||||
// The face group will be offset by 10 from the patch label
|
||||
|
||||
// Write header
|
||||
fluentMeshFile
|
||||
<< "(13 (" << patchI + 10 << " " << nWrittenFaces + 1
|
||||
<< " " << nWrittenFaces + patchFaces.size() << " ";
|
||||
|
||||
nWrittenFaces += patchFaces.size();
|
||||
|
||||
// Write patch type
|
||||
if (isA<wallFvPatch>(boundary()[patchI]))
|
||||
{
|
||||
fluentMeshFile << 3;
|
||||
}
|
||||
else if
|
||||
(
|
||||
isA<symmetryPlaneFvPatch>(boundary()[patchI])
|
||||
|| isA<symmetryFvPatch>(boundary()[patchI])
|
||||
)
|
||||
{
|
||||
fluentMeshFile << 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
fluentMeshFile << 4;
|
||||
}
|
||||
|
||||
fluentMeshFile
|
||||
<<" 0)" << std::endl << "(" << std::endl;
|
||||
|
||||
forAll(patchFaces, faceI)
|
||||
{
|
||||
const labelList& l = patchFaces[faceI];
|
||||
|
||||
fluentMeshFile << " ";
|
||||
|
||||
fluentMeshFile << l.size() << " ";
|
||||
|
||||
// Note: In Fluent, all boundary faces point inwards, which is
|
||||
// opposite from the OpenFOAM convention.
|
||||
// Turn them around on printout
|
||||
forAllReverse (l, lI)
|
||||
{
|
||||
fluentMeshFile << l[lI] + 1 << " ";
|
||||
}
|
||||
|
||||
fluentMeshFile << patchFaceCells[faceI] + 1 << " 0" << std::endl;
|
||||
}
|
||||
|
||||
fluentMeshFile << "))" << std::endl;
|
||||
}
|
||||
|
||||
// Writing cells
|
||||
fluentMeshFile
|
||||
<< "(12 (1 1 "
|
||||
<< nCells() << " 1 0)(" << std::endl;
|
||||
|
||||
const cellModel& hex = *(cellModeller::lookup("hex"));
|
||||
const cellModel& prism = *(cellModeller::lookup("prism"));
|
||||
const cellModel& pyr = *(cellModeller::lookup("pyr"));
|
||||
const cellModel& tet = *(cellModeller::lookup("tet"));
|
||||
|
||||
const cellShapeList& cells = cellShapes();
|
||||
|
||||
bool hasWarned = false;
|
||||
|
||||
forAll(cells, cellI)
|
||||
{
|
||||
if (cells[cellI].model() == tet)
|
||||
{
|
||||
fluentMeshFile << " " << 2;
|
||||
}
|
||||
else if (cells[cellI].model() == hex)
|
||||
{
|
||||
fluentMeshFile << " " << 4;
|
||||
}
|
||||
else if (cells[cellI].model() == pyr)
|
||||
{
|
||||
fluentMeshFile << " " << 5;
|
||||
}
|
||||
else if (cells[cellI].model() == prism)
|
||||
{
|
||||
fluentMeshFile << " " << 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!hasWarned)
|
||||
{
|
||||
hasWarned = true;
|
||||
|
||||
WarningIn("void fluentFvMesh::writeFluentMesh() const")
|
||||
<< "foamMeshToFluent: cell shape for cell "
|
||||
<< cellI << " only supported by Fluent polyhedral meshes."
|
||||
<< nl
|
||||
<< " Suppressing any further messages for polyhedral"
|
||||
<< " cells." << endl;
|
||||
}
|
||||
fluentMeshFile << " " << 7;
|
||||
}
|
||||
}
|
||||
|
||||
fluentMeshFile << ")())" << std::endl;
|
||||
|
||||
// Return to dec
|
||||
fluentMeshFile.setf(ios::dec, ios::basefield);
|
||||
|
||||
// Writing patch types
|
||||
fluentMeshFile << "(39 (1 fluid fluid-1)())" << std::endl;
|
||||
fluentMeshFile << "(39 (2 interior interior-1)())" << std::endl;
|
||||
|
||||
// Writing boundary patch types
|
||||
forAll(boundary(), patchI)
|
||||
{
|
||||
fluentMeshFile
|
||||
<< "(39 (" << patchI + 10 << " ";
|
||||
|
||||
// Write patch type
|
||||
if (isA<wallFvPatch>(boundary()[patchI]))
|
||||
{
|
||||
fluentMeshFile << "wall ";
|
||||
}
|
||||
else if
|
||||
(
|
||||
isA<symmetryPlaneFvPatch>(boundary()[patchI])
|
||||
|| isA<symmetryFvPatch>(boundary()[patchI])
|
||||
)
|
||||
{
|
||||
fluentMeshFile << "symmetry ";
|
||||
}
|
||||
else
|
||||
{
|
||||
fluentMeshFile << "pressure-outlet ";
|
||||
}
|
||||
|
||||
fluentMeshFile
|
||||
<< boundary()[patchI].name() << ")())" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,75 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ 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::fluentFvMesh
|
||||
|
||||
Description
|
||||
|
||||
SourceFiles
|
||||
fluentFvMesh.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef fluentFvMesh_H
|
||||
#define fluentFvMesh_H
|
||||
|
||||
#include "fvMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class fluentFvMesh Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class fluentFvMesh
|
||||
:
|
||||
public fvMesh
|
||||
{
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from IOobject
|
||||
fluentFvMesh(const IOobject& io);
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
//- Write Fluent mesh
|
||||
void writeFluentMesh() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,67 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
foamMeshToFluent
|
||||
|
||||
Description
|
||||
Writes out the OpenFOAM mesh in Fluent mesh format.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "fluentFvMesh.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
|
||||
Info<< "Create mesh for time = "
|
||||
<< runTime.timeName() << nl << endl;
|
||||
|
||||
fluentFvMesh mesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fluentFvMesh::defaultRegion,
|
||||
runTime.constant(),
|
||||
runTime
|
||||
)
|
||||
);
|
||||
|
||||
mesh.writeFluentMesh();
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
foamToStarMesh.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/foamToStarMesh
|
||||
@ -0,0 +1,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/conversion/lnInclude \
|
||||
-I$(LIB_SRC)/fileFormats/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lconversion
|
||||
@ -0,0 +1,140 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
foamToStarMesh
|
||||
|
||||
Description
|
||||
Reads an OpenFOAM mesh and writes a pro-STAR (v4) bnd/cel/vrt format.
|
||||
|
||||
Usage
|
||||
- foamToStarMesh [OPTION] \n
|
||||
Reads an OpenFOAM mesh and writes a pro-STAR (v4) bnd/cel/vrt format.
|
||||
|
||||
\param -noBnd \n
|
||||
Suppress writing the \c .bnd file
|
||||
|
||||
\param -scale \<factor\>\n
|
||||
Specify an alternative geometry scaling factor.
|
||||
The default is \b 1000 (scale \em [m] to \em [mm]).
|
||||
|
||||
Note
|
||||
The cellTable information available in the files
|
||||
\c constant/cellTable and \c constant/polyMesh/cellTableId
|
||||
will be used if available. Otherwise the cellZones are used when
|
||||
creating the cellTable information.
|
||||
|
||||
See Also
|
||||
Foam::cellTable, Foam::meshWriter and Foam::meshWriters::STARCD
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "timeSelector.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
#include "STARCDMeshWriter.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::addNote
|
||||
(
|
||||
"read OpenFOAM mesh and write a pro-STAR (v4) bnd/cel/vrt format"
|
||||
);
|
||||
argList::noParallel();
|
||||
timeSelector::addOptions();
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"scale",
|
||||
"factor",
|
||||
"geometry scaling factor - default is 1000 ([m] to [mm])"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"noBnd",
|
||||
"suppress writing a boundary (.bnd) file"
|
||||
);
|
||||
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
|
||||
instantList timeDirs = timeSelector::select0(runTime, args);
|
||||
|
||||
fileName exportName = meshWriter::defaultMeshName;
|
||||
if (args.optionFound("case"))
|
||||
{
|
||||
exportName += '-' + args.globalCaseName();
|
||||
}
|
||||
|
||||
// default: rescale from [m] to [mm]
|
||||
scalar scaleFactor = 1000;
|
||||
if (args.optionReadIfPresent("scale", scaleFactor))
|
||||
{
|
||||
if (scaleFactor <= 0)
|
||||
{
|
||||
scaleFactor = 1;
|
||||
}
|
||||
}
|
||||
|
||||
# include "createPolyMesh.H"
|
||||
|
||||
forAll(timeDirs, timeI)
|
||||
{
|
||||
runTime.setTime(timeDirs[timeI], timeI);
|
||||
|
||||
# include "getTimeIndex.H"
|
||||
|
||||
polyMesh::readUpdateState state = mesh.readUpdate();
|
||||
|
||||
if (!timeI || state != polyMesh::UNCHANGED)
|
||||
{
|
||||
meshWriters::STARCD writer(mesh, scaleFactor);
|
||||
|
||||
if (args.optionFound("noBnd"))
|
||||
{
|
||||
writer.noBoundary();
|
||||
}
|
||||
|
||||
fileName meshName(exportName);
|
||||
if (state != polyMesh::UNCHANGED)
|
||||
{
|
||||
meshName += '_' + runTime.timeName();
|
||||
}
|
||||
|
||||
writer.write(meshName);
|
||||
}
|
||||
|
||||
Info<< nl << endl;
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,51 @@
|
||||
// Read time index from */uniform/time, but treat 0 and constant specially
|
||||
|
||||
word timeName = "0";
|
||||
|
||||
if
|
||||
(
|
||||
runTime.timeName() != runTime.constant()
|
||||
&& runTime.timeName() != "0"
|
||||
)
|
||||
{
|
||||
IOobject io
|
||||
(
|
||||
"time",
|
||||
runTime.timeName(),
|
||||
"uniform",
|
||||
runTime,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
);
|
||||
|
||||
if (io.headerOk())
|
||||
{
|
||||
IOdictionary timeObject
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"time",
|
||||
runTime.timeName(),
|
||||
"uniform",
|
||||
runTime,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
label index;
|
||||
timeObject.lookup("index") >> index;
|
||||
timeName = Foam::name(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeName = runTime.timeName();
|
||||
// Info<< "skip ... missing entry " << io.objectPath() << endl;
|
||||
// continue;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "\nTime [" << timeName << "] = " << runTime.timeName() << nl;
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
foamToSurface.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/foamToSurface
|
||||
@ -0,0 +1,5 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/surfMesh/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lsurfMesh
|
||||
@ -0,0 +1,140 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
foamToSurface
|
||||
|
||||
Description
|
||||
Reads an OpenFOAM mesh and writes the boundaries in a surface format.
|
||||
|
||||
Usage
|
||||
- foamToSurface [OPTION] \n
|
||||
Reads an OpenFOAM mesh and writes the boundaries in a surface format.
|
||||
|
||||
\param -scale \<factor\>\n
|
||||
Specify an alternative geometry scaling factor.
|
||||
Eg, use \b 1000 to scale \em [m] to \em [mm].
|
||||
|
||||
\param -tri \n
|
||||
Triangulate surface.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "timeSelector.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
|
||||
#include "MeshedSurfaces.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
argList::validArgs.append("outputFile.ext");
|
||||
timeSelector::addOptions();
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"scale",
|
||||
"factor",
|
||||
"geometry scaling factor - default is 1"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"tri",
|
||||
"triangulate surface"
|
||||
);
|
||||
|
||||
# include "setRootCase.H"
|
||||
|
||||
fileName exportName = args[1];
|
||||
|
||||
scalar scaleFactor = 0;
|
||||
args.optionReadIfPresent<scalar>("scale", scaleFactor);
|
||||
const bool doTriangulate = args.optionFound("tri");
|
||||
|
||||
fileName exportBase = exportName.lessExt();
|
||||
word exportExt = exportName.ext();
|
||||
|
||||
if (!meshedSurface::canWriteType(exportExt, true))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
# include "createTime.H"
|
||||
instantList timeDirs = timeSelector::select0(runTime, args);
|
||||
# include "createPolyMesh.H"
|
||||
|
||||
forAll(timeDirs, timeI)
|
||||
{
|
||||
runTime.setTime(timeDirs[timeI], timeI);
|
||||
# include "getTimeIndex.H"
|
||||
|
||||
polyMesh::readUpdateState state = mesh.readUpdate();
|
||||
|
||||
if (timeI == 0 || state != polyMesh::UNCHANGED)
|
||||
{
|
||||
if (state == polyMesh::UNCHANGED)
|
||||
{
|
||||
exportName = exportBase + "." + exportExt;
|
||||
}
|
||||
else
|
||||
{
|
||||
exportName =
|
||||
exportBase + '_' + runTime.timeName() + "." + exportExt;
|
||||
}
|
||||
|
||||
meshedSurface surf(mesh.boundaryMesh());
|
||||
surf.scalePoints(scaleFactor);
|
||||
|
||||
Info<< "writing " << exportName;
|
||||
if (doTriangulate)
|
||||
{
|
||||
Info<< " triangulated";
|
||||
surf.triangulate();
|
||||
}
|
||||
|
||||
if (scaleFactor <= 0)
|
||||
{
|
||||
Info<< " without scaling" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< " with scaling " << scaleFactor << endl;
|
||||
}
|
||||
surf.write(exportName);
|
||||
}
|
||||
|
||||
Info<< nl << endl;
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,51 @@
|
||||
// Read time index from */uniform/time, but treat 0 and constant specially
|
||||
|
||||
word timeName = "0";
|
||||
|
||||
if
|
||||
(
|
||||
runTime.timeName() != runTime.constant()
|
||||
&& runTime.timeName() != "0"
|
||||
)
|
||||
{
|
||||
IOobject io
|
||||
(
|
||||
"time",
|
||||
runTime.timeName(),
|
||||
"uniform",
|
||||
runTime,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
);
|
||||
|
||||
if (io.headerOk())
|
||||
{
|
||||
IOdictionary timeObject
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"time",
|
||||
runTime.timeName(),
|
||||
"uniform",
|
||||
runTime,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
label index;
|
||||
timeObject.lookup("index") >> index;
|
||||
timeName = Foam::name(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeName = runTime.timeName();
|
||||
// Info<< "skip ... missing entry " << io.objectPath() << endl;
|
||||
// continue;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "\nTime [" << timeName << "] = " << runTime.timeName() << nl;
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
gambitToFoam.L
|
||||
|
||||
EXE = $(FOAM_APPBIN)/gambitToFoam
|
||||
@ -0,0 +1,877 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
gambitToFoam
|
||||
|
||||
Description
|
||||
Converts a GAMBIT mesh to OpenFOAM format.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
%{
|
||||
|
||||
#undef yyFlexLexer
|
||||
|
||||
/* ------------------------------------------------------------------------- *\
|
||||
------ local definitions
|
||||
\* ------------------------------------------------------------------------- */
|
||||
|
||||
#include "scalarList.H"
|
||||
#include "IStringStream.H"
|
||||
|
||||
// For EOF only
|
||||
#include <cstdio>
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
#include "emptyPolyPatch.H"
|
||||
#include "preservePatchTypes.H"
|
||||
#include "cellModeller.H"
|
||||
#include "cellShape.H"
|
||||
#include "SLList.H"
|
||||
#include "SLPtrList.H"
|
||||
|
||||
label nPoints = 0;
|
||||
label nCells = 0;
|
||||
label nCellStreams = 0;
|
||||
label nPatches = 0;
|
||||
|
||||
label nCoordDirections = 0;
|
||||
label nVectorComponents = 0;
|
||||
|
||||
|
||||
pointField points(0);
|
||||
labelList pointMap(0);
|
||||
|
||||
PtrList<labelList> cellLabels(0);
|
||||
labelList cellMap(0);
|
||||
labelList cellTypes(0);
|
||||
labelList cellStreamIDs(0);
|
||||
|
||||
wordList patchNames(0);
|
||||
labelListList patchCells(0);
|
||||
labelListList patchCellFaces(0);
|
||||
label nValuesForPatchFaces = 0;
|
||||
|
||||
// Dummy yywrap to keep yylex happy at compile time.
|
||||
// It is called by yylex but is not used as the mechanism to change file.
|
||||
// See <<EOF>>
|
||||
#if YY_FLEX_SUBMINOR_VERSION < 34
|
||||
extern "C" int yywrap()
|
||||
#else
|
||||
int yyFlexLexer::yywrap()
|
||||
#endif
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
one_space [ \t\f\r]
|
||||
space {one_space}*
|
||||
some_space {one_space}+
|
||||
spaceNl ({space}|\n)*
|
||||
|
||||
alpha [_[:alpha:]]
|
||||
digit [[:digit:]]
|
||||
|
||||
dotColonDash [.:-]
|
||||
|
||||
label [0-9]{digit}*
|
||||
zeroLabel {digit}*
|
||||
|
||||
word ({alpha}|{digit}|{dotColonDash})*
|
||||
|
||||
exponent_part [eE][-+]?{digit}+
|
||||
fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
|
||||
|
||||
floatNum ((({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))|0)
|
||||
|
||||
x {floatNum}
|
||||
y {floatNum}
|
||||
z {floatNum}
|
||||
|
||||
labelListElement {space}{zeroLabel}
|
||||
scalarListElement {space}{floatNum}
|
||||
labelList ({labelListElement}+{space})
|
||||
scalarList ({scalarListElement}+{space})
|
||||
|
||||
starStar ("**")
|
||||
text ({space}({word}*{space})*\n)
|
||||
|
||||
dateDDMMYYYY ({digit}{digit}"/"{digit}{digit}"/"{digit}{digit}{digit}{digit})
|
||||
dateDDMonYYYY ((({digit}{digit}{space})|({digit}{space})){alpha}*{space}{digit}{digit}{digit}{digit})
|
||||
time ({digit}{digit}":"{digit}{digit}":"{digit}{digit})
|
||||
|
||||
versionNumber ({digit}|".")*
|
||||
|
||||
controlInfo ^{space}"CONTROL INFO"{space}{versionNumber}
|
||||
applicationData ^{space}"APPLICATION DATA"{space}{versionNumber}
|
||||
nodalCoords ^{space}"NODAL COORDINATES"{space}{versionNumber}
|
||||
cellsAndElements ^{space}"ELEMENTS/CELLS"{space}{versionNumber}
|
||||
cellStreams ^{space}"ELEMENT GROUP"{space}{versionNumber}
|
||||
boundaryPatch ^{space}"BOUNDARY CONDITIONS"{space}{versionNumber}
|
||||
faceConnectivity ^{space}"FACE CONNECTIVITY"{space}{versionNumber}
|
||||
|
||||
endOfSection ^{space}"ENDOFSECTION"{space}
|
||||
|
||||
program {space}"PROGRAM:"{space}
|
||||
version {space}"VERSION:"{space}
|
||||
|
||||
group {space}"GROUP:"{space}
|
||||
elements {space}"ELEMENTS:"{space}
|
||||
material {space}"MATERIAL:"{space}
|
||||
nFlags {space}"NFLAGS:"{space}
|
||||
mtype {space}"MTYPE:"{space}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *\
|
||||
----- Exclusive start states -----
|
||||
\* ------------------------------------------------------------------------- */
|
||||
|
||||
%option stack
|
||||
|
||||
%x controlInfo
|
||||
%x readControlHeader
|
||||
%x readTitle
|
||||
%x readProgramID
|
||||
%x readVersionID
|
||||
%x applicationData
|
||||
%x nodalCoords
|
||||
%x cellsAndElements
|
||||
%x cellStreams
|
||||
%x cellStreamTitle
|
||||
%x cellStreamFlags
|
||||
%x cellStreamLabels
|
||||
%x readCellStreamGroupID
|
||||
%x readCellStreamNElements
|
||||
%x readCellStreamMaterial
|
||||
%x readCellStreamNFlags
|
||||
%x boundaryPatch
|
||||
%x boundaryPatchParams
|
||||
%x boundaryPatchFaces
|
||||
%x faceConnectivity
|
||||
|
||||
%x globalMeshData
|
||||
%x cellContLine
|
||||
|
||||
%%
|
||||
|
||||
%{
|
||||
label nCellContinuationLines = 0;
|
||||
label curNumberOfNodes = 0;
|
||||
label curNumberOfCells = 0;
|
||||
label curGroupID = 0;
|
||||
label nFlagsForStream = 0;
|
||||
label curBoundaryPatch = 0;
|
||||
label curPatchFace = 0;
|
||||
%}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *\
|
||||
------ Start Lexing ------
|
||||
\* ------------------------------------------------------------------------- */
|
||||
|
||||
/* ------ Reading control header ------ */
|
||||
|
||||
{controlInfo} {
|
||||
BEGIN(readControlHeader);
|
||||
}
|
||||
|
||||
|
||||
<readControlHeader>{starStar}{space}{text} {
|
||||
BEGIN(readTitle);
|
||||
}
|
||||
|
||||
|
||||
<readTitle>{text} {
|
||||
|
||||
Info << "Title: " << YYText();
|
||||
BEGIN(controlInfo);
|
||||
}
|
||||
|
||||
|
||||
<controlInfo>{spaceNl}{program} {
|
||||
BEGIN(readProgramID);
|
||||
}
|
||||
|
||||
|
||||
<readProgramID>{space}{word} {
|
||||
|
||||
Info<< "Written by " << YYText() << " ";
|
||||
BEGIN(controlInfo);
|
||||
}
|
||||
|
||||
|
||||
<controlInfo>{spaceNl}{version} {
|
||||
BEGIN(readVersionID);
|
||||
}
|
||||
|
||||
|
||||
<readVersionID>{space}{versionNumber} {
|
||||
|
||||
Info<< " version " << YYText() << endl;
|
||||
BEGIN(controlInfo);
|
||||
}
|
||||
|
||||
|
||||
<controlInfo>{space}{dateDDMonYYYY}{space}{time} {
|
||||
|
||||
Info<< "File written on " << YYText() << endl;
|
||||
}
|
||||
|
||||
|
||||
<controlInfo>{space}{dateDDMMYYYY}{space}{time} {
|
||||
|
||||
Info<< "File written on " << YYText() << endl;
|
||||
}
|
||||
|
||||
|
||||
<controlInfo>{spaceNl}"NUMNP"{space}"NELEM"{space}"NGRPS"{space}"NBSETS"{space}("NDFCD"|"NDCFD"){space}"NDFVL"{space}\n {
|
||||
BEGIN(globalMeshData);
|
||||
}
|
||||
|
||||
|
||||
<globalMeshData>{spaceNl}{label}{space}{label}{space}{label}{space}{label}{space}{label}{space}{label}{space}\n {
|
||||
|
||||
IStringStream nodeStream(YYText());
|
||||
|
||||
nPoints = readLabel(nodeStream);
|
||||
nCells = readLabel(nodeStream);
|
||||
nCellStreams = readLabel(nodeStream);
|
||||
nPatches = readLabel(nodeStream);
|
||||
nCoordDirections = readLabel(nodeStream);
|
||||
nVectorComponents = readLabel(nodeStream);
|
||||
|
||||
// reset list sizes - now known!
|
||||
points.setSize(nPoints);
|
||||
pointMap.setSize(nPoints);
|
||||
|
||||
cellLabels.setSize(nCells);
|
||||
cellMap.setSize(nCells);
|
||||
cellTypes.setSize(nCells);
|
||||
cellStreamIDs.setSize(nCells);
|
||||
|
||||
patchNames.setSize(nPatches);
|
||||
patchCells.setSize(nPatches);
|
||||
patchCellFaces.setSize(nPatches);
|
||||
|
||||
Info<< " number of points: " << nPoints << endl
|
||||
<< " number of cells: " << nCells << endl
|
||||
<< " number of patches: " << nPatches << endl;
|
||||
|
||||
BEGIN(controlInfo);
|
||||
}
|
||||
|
||||
|
||||
/* ------ Reading nodal coordinates ------ */
|
||||
|
||||
{nodalCoords}{spaceNl} {
|
||||
|
||||
curNumberOfNodes = 0;
|
||||
Info<< "Reading nodal coordinates" << endl;
|
||||
BEGIN(nodalCoords);
|
||||
}
|
||||
|
||||
|
||||
<nodalCoords>{spaceNl}{label}{space}{x}{space}{y}{space}{z}{space}\n {
|
||||
|
||||
IStringStream nodeStream(YYText());
|
||||
|
||||
label nodeI(readLabel(nodeStream));
|
||||
|
||||
// Note: coordinates must be read one at the time.
|
||||
scalar x = readScalar(nodeStream);
|
||||
scalar y = readScalar(nodeStream);
|
||||
scalar z = readScalar(nodeStream);
|
||||
|
||||
// add mapping and scalced node to the list
|
||||
pointMap[curNumberOfNodes] = nodeI;
|
||||
points[curNumberOfNodes] = point(x, y, z);
|
||||
curNumberOfNodes++;
|
||||
}
|
||||
|
||||
|
||||
/* ------ Reading cells and elements ------ */
|
||||
|
||||
{cellsAndElements}{spaceNl} {
|
||||
|
||||
curNumberOfCells = 0;
|
||||
Info<< "Reading cells" << endl;
|
||||
BEGIN(cellsAndElements);
|
||||
}
|
||||
|
||||
<cellsAndElements>{spaceNl}{label}{space}{label}{space}{label}{labelList} {
|
||||
|
||||
IStringStream elementStream(YYText());
|
||||
|
||||
label cellI(readLabel(elementStream));
|
||||
label cellType(readLabel(elementStream));
|
||||
label nVertices(readLabel(elementStream));
|
||||
|
||||
// reset number of continuation lines
|
||||
nCellContinuationLines = 0;
|
||||
|
||||
cellMap[curNumberOfCells] = cellI;
|
||||
cellTypes[curNumberOfCells] = cellType;
|
||||
cellLabels.set(curNumberOfCells, new labelList(nVertices));
|
||||
|
||||
labelList& curLabels = cellLabels[curNumberOfCells];
|
||||
|
||||
// Find out how many labels are expected. If less or equal to
|
||||
// seven, read them all and finish with it. If there is more,
|
||||
// set read of the next line
|
||||
label labelsToRead = min(8, nVertices);
|
||||
label labelI = 0;
|
||||
for (; labelI < labelsToRead; labelI++)
|
||||
{
|
||||
if (elementStream.eof()) break;
|
||||
|
||||
// Check token to avoid trailing space.
|
||||
token curLabelTok(elementStream);
|
||||
if (curLabelTok.isLabel())
|
||||
{
|
||||
curLabels[labelI] = curLabelTok.labelToken();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (labelI < nVertices)
|
||||
{
|
||||
BEGIN(cellContLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
curNumberOfCells++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<cellContLine>{spaceNl}{labelList} {
|
||||
|
||||
IStringStream elementStream(YYText());
|
||||
|
||||
nCellContinuationLines++;
|
||||
|
||||
labelList& curLabels = cellLabels[curNumberOfCells];
|
||||
|
||||
label labelsToRead = min
|
||||
(
|
||||
(nCellContinuationLines + 1)*7,
|
||||
curLabels.size()
|
||||
);
|
||||
|
||||
for
|
||||
(
|
||||
label labelI = nCellContinuationLines*7;
|
||||
labelI < labelsToRead;
|
||||
labelI++
|
||||
)
|
||||
{
|
||||
curLabels[labelI] = readLabel(elementStream);
|
||||
}
|
||||
|
||||
// if read is finished, go back to reading cells
|
||||
if (curLabels.size() < (nCellContinuationLines + 1)*7)
|
||||
{
|
||||
curNumberOfCells++;
|
||||
|
||||
BEGIN(cellsAndElements);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------ Reading element group information ------ */
|
||||
|
||||
{cellStreams}{spaceNl} {
|
||||
Info<< "Reading cell streams" << endl;
|
||||
BEGIN(cellStreams);
|
||||
}
|
||||
|
||||
|
||||
<cellStreams>{spaceNl}{group} {
|
||||
BEGIN(readCellStreamGroupID);
|
||||
}
|
||||
|
||||
|
||||
<readCellStreamGroupID>{space}{label} {
|
||||
IStringStream groupStream(YYText());
|
||||
|
||||
if (curGroupID > 0)
|
||||
{
|
||||
FatalErrorIn("gambitToFoam::main")
|
||||
<< "<readCellStreamGroupID>{space}{label} : "
|
||||
<< "trying to reset group ID while active"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
else
|
||||
{
|
||||
curGroupID = readLabel(groupStream);
|
||||
}
|
||||
|
||||
BEGIN(cellStreams);
|
||||
}
|
||||
|
||||
|
||||
<cellStreams>{spaceNl}{elements} {
|
||||
BEGIN(readCellStreamNElements);
|
||||
}
|
||||
|
||||
|
||||
<readCellStreamNElements>{space}{label} {
|
||||
|
||||
IStringStream nElementsStream(YYText());
|
||||
|
||||
readLabel(nElementsStream);
|
||||
|
||||
BEGIN(cellStreams);
|
||||
}
|
||||
|
||||
<cellStreams>{spaceNl}{material} {
|
||||
BEGIN(readCellStreamMaterial);
|
||||
}
|
||||
|
||||
|
||||
<readCellStreamMaterial>{space}{label} {
|
||||
|
||||
IStringStream materialIDstream(YYText());
|
||||
|
||||
readLabel(materialIDstream);
|
||||
|
||||
BEGIN(cellStreams);
|
||||
}
|
||||
|
||||
|
||||
<cellStreams>{spaceNl}{nFlags} {
|
||||
BEGIN(readCellStreamNFlags);
|
||||
}
|
||||
|
||||
|
||||
<readCellStreamNFlags>{space}{label} {
|
||||
|
||||
IStringStream nFlagsStream(YYText());
|
||||
|
||||
nFlagsForStream = readLabel(nFlagsStream);
|
||||
|
||||
BEGIN(cellStreamTitle);
|
||||
}
|
||||
|
||||
|
||||
<cellStreamTitle>{spaceNl}{word}{spaceNl} {
|
||||
|
||||
word streamName(Foam::string::validate<word>(YYText()));
|
||||
|
||||
BEGIN(cellStreamFlags);
|
||||
}
|
||||
|
||||
|
||||
<cellStreamFlags>{labelList} {
|
||||
Info<< "Reading cell stream labels" << endl;
|
||||
BEGIN(cellStreamLabels);
|
||||
}
|
||||
|
||||
|
||||
<cellStreamLabels>{spaceNl}{labelList} {
|
||||
|
||||
IStringStream nFlagsStream(YYText());
|
||||
|
||||
label cellLabel;
|
||||
while (nFlagsStream.read(cellLabel))
|
||||
{
|
||||
cellStreamIDs[cellLabel - 1] = curGroupID;
|
||||
}
|
||||
|
||||
// reset current group ID and a number of flags
|
||||
curGroupID = 0;
|
||||
nFlagsForStream = 0;
|
||||
}
|
||||
|
||||
|
||||
/* ------ Reading end of section and others ------ */
|
||||
|
||||
<cellStreamLabels>{endOfSection}\n {
|
||||
|
||||
Info<< "Finished reading cell stream labels" << endl;
|
||||
|
||||
// reset current group ID and a number of flags
|
||||
curGroupID = 0;
|
||||
nFlagsForStream = 0;
|
||||
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
|
||||
|
||||
{boundaryPatch}{spaceNl} {
|
||||
curPatchFace = 0;
|
||||
Info<< "Reading patches" << endl;
|
||||
BEGIN(boundaryPatchParams);
|
||||
}
|
||||
|
||||
|
||||
<boundaryPatchParams>{spaceNl}{word}{labelList} {
|
||||
|
||||
IStringStream patchParamsStream(YYText());
|
||||
|
||||
patchParamsStream.read(patchNames[curBoundaryPatch]);
|
||||
|
||||
readLabel(patchParamsStream);
|
||||
label nEntry(readLabel(patchParamsStream));
|
||||
nValuesForPatchFaces = readLabel(patchParamsStream);
|
||||
|
||||
patchCells[curBoundaryPatch].setSize(nEntry);
|
||||
patchCellFaces[curBoundaryPatch].setSize(nEntry);
|
||||
|
||||
Info<< "patch " << curBoundaryPatch
|
||||
<< ": name: " << patchNames[curBoundaryPatch]
|
||||
<< endl;
|
||||
|
||||
BEGIN(boundaryPatchFaces);
|
||||
}
|
||||
|
||||
|
||||
<boundaryPatchFaces>{spaceNl}{label}{space}{label}{space}{label}({scalarList}|{space}\n) {
|
||||
|
||||
// Face-based boundary condition
|
||||
IStringStream patchFacesStream(YYText());
|
||||
|
||||
patchCells[curBoundaryPatch][curPatchFace] =
|
||||
readLabel(patchFacesStream);
|
||||
readLabel(patchFacesStream);
|
||||
patchCellFaces[curBoundaryPatch][curPatchFace] =
|
||||
readLabel(patchFacesStream);
|
||||
|
||||
// patch face values currently discarded
|
||||
if (nValuesForPatchFaces > 0)
|
||||
{
|
||||
scalarList patchFaceValues(nValuesForPatchFaces);
|
||||
|
||||
forAll(patchFaceValues, fI)
|
||||
{
|
||||
patchFaceValues[fI] = readScalar(patchFacesStream);
|
||||
}
|
||||
}
|
||||
|
||||
curPatchFace++;
|
||||
}
|
||||
|
||||
|
||||
<boundaryPatchFaces>{spaceNl}{label}({scalarList}|\n) {
|
||||
|
||||
// Vertex-based boundary condition
|
||||
FatalErrorIn("gambitToFoam::main")
|
||||
<< "<boundaryPatchFaces>{spaceNl}{label}{scalarList} : "
|
||||
<< "boundary condition specified on vertices not supported"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
|
||||
<boundaryPatchFaces>{endOfSection}\n {
|
||||
|
||||
curBoundaryPatch++;
|
||||
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
|
||||
|
||||
/* ------ Reading end of section and others ------ */
|
||||
|
||||
<controlInfo,nodalCoords,cellsAndElements>{endOfSection}\n {
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
|
||||
|
||||
/* ------ Ignore remaining space and \n s. Any other characters are errors. */
|
||||
|
||||
.|\n {}
|
||||
|
||||
|
||||
/* ------ On EOF return to previous file, if none exists terminate. ------ */
|
||||
|
||||
<<EOF>> {
|
||||
yyterminate();
|
||||
}
|
||||
%%
|
||||
|
||||
|
||||
#include "fileName.H"
|
||||
#include <fstream>
|
||||
using std::ifstream;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
argList::validArgs.append("GAMBIT file");
|
||||
argList::addOption
|
||||
(
|
||||
"scale",
|
||||
"factor",
|
||||
"geometry scaling factor - default is 1"
|
||||
);
|
||||
|
||||
argList args(argc, argv);
|
||||
|
||||
if (!args.check())
|
||||
{
|
||||
FatalError.exit();
|
||||
}
|
||||
|
||||
const scalar scaleFactor = args.optionLookupOrDefault("scale", 1.0);
|
||||
|
||||
# include "createTime.H"
|
||||
|
||||
const fileName gambitFile = args[1];
|
||||
ifstream gambitStream(gambitFile.c_str());
|
||||
|
||||
if (!gambitStream)
|
||||
{
|
||||
FatalErrorIn("gambitToFoam::main")
|
||||
<< args.executable()
|
||||
<< ": file " << gambitFile << " not found"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
yyFlexLexer lexer(&gambitStream);
|
||||
while (lexer.yylex() != 0)
|
||||
{}
|
||||
|
||||
Info<< "Finished lexing" << endl;
|
||||
|
||||
// make a point mapping array
|
||||
label maxPointIndex = 0;
|
||||
|
||||
forAll(pointMap, pointI)
|
||||
{
|
||||
if (pointMap[pointI] > maxPointIndex)
|
||||
{
|
||||
maxPointIndex = pointMap[pointI];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
labelList pointLookup(maxPointIndex + 1, -1);
|
||||
|
||||
forAll(pointMap, pointI)
|
||||
{
|
||||
pointLookup[pointMap[pointI] ] = pointI;
|
||||
}
|
||||
|
||||
// make a cell mapping array
|
||||
label maxCellIndex = 0;
|
||||
|
||||
forAll(cellMap, cellI)
|
||||
{
|
||||
if (cellMap[cellI] > maxCellIndex)
|
||||
{
|
||||
maxCellIndex = cellMap[cellI];
|
||||
}
|
||||
}
|
||||
|
||||
labelList cellLookup(maxCellIndex + 1);
|
||||
|
||||
forAll(cellMap, cellI)
|
||||
{
|
||||
cellLookup[cellMap[cellI] ] = cellI;
|
||||
}
|
||||
|
||||
const cellModel& hex = *(cellModeller::lookup("hex"));
|
||||
const cellModel& prism = *(cellModeller::lookup("prism"));
|
||||
const cellModel& pyr = *(cellModeller::lookup("pyr"));
|
||||
const cellModel& tet = *(cellModeller::lookup("tet"));
|
||||
|
||||
labelList labelsHex(8);
|
||||
labelList labelsPrism(6);
|
||||
labelList labelsPyramid(5);
|
||||
labelList labelsTet(4);
|
||||
|
||||
cellShapeList cells(cellLabels.size());
|
||||
|
||||
forAll(cellTypes, cellI)
|
||||
{
|
||||
const labelList& curCellLabels = cellLabels[cellI];
|
||||
|
||||
// Tetrahedron
|
||||
if (cellTypes[cellI] == 6)
|
||||
{
|
||||
labelsTet[0] = pointLookup[curCellLabels[0] ];
|
||||
labelsTet[1] = pointLookup[curCellLabels[2] ];
|
||||
labelsTet[2] = pointLookup[curCellLabels[3] ];
|
||||
labelsTet[3] = pointLookup[curCellLabels[1] ];
|
||||
|
||||
cells[cellI] = cellShape(tet, labelsTet);
|
||||
}
|
||||
|
||||
// Square-based pyramid
|
||||
else if (cellTypes[cellI] == 7)
|
||||
{
|
||||
labelsPyramid[0] = pointLookup[curCellLabels[0] ];
|
||||
labelsPyramid[1] = pointLookup[curCellLabels[1] ];
|
||||
labelsPyramid[2] = pointLookup[curCellLabels[3] ];
|
||||
labelsPyramid[3] = pointLookup[curCellLabels[2] ];
|
||||
labelsPyramid[4] = pointLookup[curCellLabels[4] ];
|
||||
|
||||
cells[cellI] = cellShape(pyr, labelsPyramid);
|
||||
}
|
||||
|
||||
// Triangular prism
|
||||
else if (cellTypes[cellI] == 5)
|
||||
{
|
||||
labelsPrism[0] = pointLookup[curCellLabels[0] ];
|
||||
labelsPrism[1] = pointLookup[curCellLabels[1] ];
|
||||
labelsPrism[2] = pointLookup[curCellLabels[2] ];
|
||||
labelsPrism[3] = pointLookup[curCellLabels[3] ];
|
||||
labelsPrism[4] = pointLookup[curCellLabels[4] ];
|
||||
labelsPrism[5] = pointLookup[curCellLabels[5] ];
|
||||
|
||||
cells[cellI] = cellShape(prism, labelsPrism);
|
||||
}
|
||||
|
||||
// Hex
|
||||
else if (cellTypes[cellI] == 4)
|
||||
{
|
||||
labelsHex[0] = pointLookup[curCellLabels[0] ];
|
||||
labelsHex[1] = pointLookup[curCellLabels[1] ];
|
||||
labelsHex[2] = pointLookup[curCellLabels[3] ];
|
||||
labelsHex[3] = pointLookup[curCellLabels[2] ];
|
||||
labelsHex[4] = pointLookup[curCellLabels[4] ];
|
||||
labelsHex[5] = pointLookup[curCellLabels[5] ];
|
||||
labelsHex[6] = pointLookup[curCellLabels[7] ];
|
||||
labelsHex[7] = pointLookup[curCellLabels[6] ];
|
||||
|
||||
cells[cellI] = cellShape(hex, labelsHex);
|
||||
}
|
||||
}
|
||||
|
||||
// give foam model face number given a fluent model face number
|
||||
label faceIndex[8][6] =
|
||||
{
|
||||
{-1, -1, -1, -1, -1, -1}, // 0
|
||||
{-1, -1, -1, -1, -1, -1}, // 1
|
||||
{-1, -1, -1, -1, -1, -1}, // 2
|
||||
{ 2, 1, 3, 0, 4, 5}, // Hex (3)
|
||||
{-1, -1, -1, -1, -1, -1}, // 4
|
||||
{ 4, 3, 2, 0, 1, -1}, // Triangular prism (5)
|
||||
{ 0, 4, 3, 2, 1, -1}, // Pyramid (6)
|
||||
{ 2, 1, 0, 3, -1, -1} // Tet (7)
|
||||
};
|
||||
|
||||
faceListList boundary(patchCells.size());
|
||||
|
||||
forAll(patchCells, patchI)
|
||||
{
|
||||
labelList& curCells = patchCells[patchI];
|
||||
labelList& curFaces = patchCellFaces[patchI];
|
||||
|
||||
faceList& patchFaces = boundary[patchI];
|
||||
patchFaces.setSize(curCells.size());
|
||||
|
||||
forAll(curCells, faceI)
|
||||
{
|
||||
patchFaces[faceI] =
|
||||
cells[cellLookup[curCells[faceI] ] ].faces()
|
||||
[
|
||||
faceIndex
|
||||
[
|
||||
// this picks a cell type
|
||||
cells[cellLookup[curCells[faceI] ] ]
|
||||
.model().index()
|
||||
]
|
||||
[curFaces[faceI] - 1] // this gives a fluent face - 1
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "gambitToFoam: " << endl
|
||||
<< "Gambit file format does not provide information about the type of "
|
||||
<< "the patch (eg. wall, symmetry plane, cyclic etc)." << endl
|
||||
<< "All the patches have been created "
|
||||
<< "as type patch. Please reset after mesh conversion as necessary."
|
||||
<< endl;
|
||||
|
||||
// Scale points
|
||||
points *= scaleFactor;
|
||||
|
||||
PtrList<dictionary> patchDicts(boundary.size());
|
||||
word defaultFacesName = "defaultFaces";
|
||||
word defaultFacesType = emptyPolyPatch::typeName;
|
||||
|
||||
preservePatchTypes
|
||||
(
|
||||
runTime,
|
||||
runTime.constant(),
|
||||
polyMesh::meshSubDir,
|
||||
patchNames,
|
||||
patchDicts,
|
||||
defaultFacesName,
|
||||
defaultFacesType
|
||||
);
|
||||
|
||||
// Add information to dictionary
|
||||
forAll(patchNames, patchI)
|
||||
{
|
||||
if (!patchDicts.set(patchI))
|
||||
{
|
||||
patchDicts.set(patchI, new dictionary());
|
||||
}
|
||||
// Add but not overwrite
|
||||
patchDicts[patchI].add("type", polyPatch::typeName, false);
|
||||
}
|
||||
|
||||
polyMesh pShapeMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
polyMesh::defaultRegion,
|
||||
runTime.constant(),
|
||||
runTime
|
||||
),
|
||||
xferMove(points),
|
||||
cells,
|
||||
boundary,
|
||||
patchNames,
|
||||
patchDicts,
|
||||
defaultFacesName,
|
||||
defaultFacesType
|
||||
);
|
||||
|
||||
// Set the precision of the points data to 10
|
||||
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
|
||||
|
||||
Info<< "Writing polyMesh" << endl;
|
||||
pShapeMesh.write();
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *\
|
||||
------ End of gambitToFoam.L
|
||||
\* ------------------------------------------------------------------------- */
|
||||
@ -0,0 +1,4 @@
|
||||
|
||||
gmshToFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/gmshToFoam
|
||||
@ -0,0 +1,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-ldynamicMesh \
|
||||
-lmeshTools
|
||||
1011
applications/utilities/mesh/conversion/gmshToFoam/gmsh/CubeVer1.msh
Normal file
1011
applications/utilities/mesh/conversion/gmshToFoam/gmsh/CubeVer1.msh
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,79 @@
|
||||
// Parametres geometriques
|
||||
r1 = 200*Cos(Pi/4)/1000;
|
||||
r2 = 200*Cos(Pi/4)/1000;
|
||||
|
||||
h1 = 250/1000;
|
||||
h2 = 360/1000;
|
||||
h3 = 900/1000;
|
||||
h4 = 1900/1000;
|
||||
|
||||
// Parametres de maillage
|
||||
// selon le rayon
|
||||
rCells = 10/2; rRatio = 0.85;
|
||||
// selon S1
|
||||
S1Cells = 30/2; S1ratio = 1;
|
||||
// selon S2
|
||||
S2Cells = 35/2; S2ratio = 0.95;
|
||||
// selon S3
|
||||
S3Cells = 20/2; S3ratio = 1;
|
||||
|
||||
Point(1) = {r1, r1, h4};
|
||||
Point(2) = {r1, r1, h3};
|
||||
Point(3) = {r2, r2, h2};
|
||||
Point(4) = {r2, r2, h1};
|
||||
Point(5) = {0, 0, h1};
|
||||
Point(6) = {0, 0, h2};
|
||||
Point(7) = {0, 0, h3};
|
||||
Point(8) = {0, 0, h4};
|
||||
|
||||
Line(1) = {8, 1};
|
||||
Line(2) = {1, 2};
|
||||
Line(3) = {7, 2};
|
||||
Line(4) = {8, 7};
|
||||
Line(5) = {2, 3};
|
||||
Line(6) = {6, 3};
|
||||
Line(7) = {7, 6};
|
||||
Line(8) = {3, 4};
|
||||
Line(9) = {5, 4};
|
||||
Line(10) = {6, 5};
|
||||
|
||||
Line Loop(11) = {1, 2, -3, -4};
|
||||
Ruled Surface(12) = {11};
|
||||
Line Loop(13) = {5, -6, -7, 3};
|
||||
Ruled Surface(14) = {13};
|
||||
Line Loop(15) = {8, -9, -10, 6};
|
||||
Ruled Surface(16) = {15};
|
||||
Transfinite Line {1, 3, 6, 9} = rCells Using Progression rRatio;
|
||||
Transfinite Line {4, 2} = S1Cells Using Progression S1ratio;
|
||||
Transfinite Line {7, 5} = S2Cells Using Progression S2ratio;
|
||||
Transfinite Line {10, 8} = S3Cells Using Progression S3ratio;
|
||||
Transfinite Surface {12} = {8, 1, 2, 7};
|
||||
Transfinite Surface {14} = {7, 2, 3, 6};
|
||||
Transfinite Surface {16} = {6, 3, 4, 5};
|
||||
Recombine Surface {12, 14, 16};
|
||||
Extrude {{0, 0, 1}, {0, 0, 0}, Pi/2} {
|
||||
Surface{12, 14, 16};
|
||||
Layers{25};
|
||||
Recombine;
|
||||
}
|
||||
Extrude {{0, 0, 1}, {0, 0, 0}, Pi/2} {
|
||||
Surface{33, 50, 67};
|
||||
Layers{25};
|
||||
Recombine;
|
||||
}
|
||||
Extrude {{0, 0, 1}, {0, 0, 0}, Pi/2} {
|
||||
Surface{84, 101, 118};
|
||||
Layers{25};
|
||||
Recombine;
|
||||
}
|
||||
Extrude {{0, 0, 1}, {0, 0, 0}, Pi/2} {
|
||||
Surface{135, 152, 169};
|
||||
Layers{25};
|
||||
Recombine;
|
||||
}
|
||||
Physical Surface("entree") = {126, 75, 24, 177};
|
||||
Physical Surface("S1") = {28, 181, 130, 79};
|
||||
Physical Surface("S2") = {93, 42, 193, 144};
|
||||
Physical Surface("S3") = {110, 59, 205, 161};
|
||||
Physical Surface("fond") = {113, 62, 208, 164};
|
||||
Physical Volume("fluide") = {4, 7, 10, 1, 5, 8, 11, 2, 9, 12, 3, 6};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1135
applications/utilities/mesh/conversion/gmshToFoam/gmshToFoam.C
Normal file
1135
applications/utilities/mesh/conversion/gmshToFoam/gmshToFoam.C
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,3 @@
|
||||
ideasUnvToFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/ideasUnvToFoam
|
||||
@ -0,0 +1,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/surfMesh/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools \
|
||||
-lsurfMesh
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,768 @@
|
||||
-1
|
||||
151
|
||||
D:\CFD Test Cases\FEMAP\block1.MOD
|
||||
D:\CFD Test Cases\FEMAP\block1.MOD
|
||||
NEiNastran for Windows
|
||||
20-Jan-07 04:54:48 9 20 0
|
||||
Never Never
|
||||
NEiNastran for Windows
|
||||
20-Jan-07 04:54:48 9 20 10 0 0
|
||||
-1
|
||||
-1
|
||||
180
|
||||
00 2000
|
||||
01 2001
|
||||
02 2002
|
||||
03 2003
|
||||
04 2004
|
||||
05 2005
|
||||
06 2006
|
||||
07 2007
|
||||
08 2008
|
||||
09 2009
|
||||
10 2010
|
||||
11 2011
|
||||
12 2012
|
||||
13 2013
|
||||
14 2014
|
||||
15 2015
|
||||
16 2016
|
||||
17 2017
|
||||
18 2018
|
||||
19 2019
|
||||
20 2020
|
||||
21 2021
|
||||
22 2022
|
||||
23 2023
|
||||
24 2024
|
||||
25 2025
|
||||
26 2026
|
||||
27 2027
|
||||
28 2028
|
||||
29 2029
|
||||
30 2030
|
||||
31 2031
|
||||
32 2032
|
||||
33 2033
|
||||
34 2034
|
||||
35 2035
|
||||
36 2036
|
||||
37 2037
|
||||
38 2038
|
||||
39 2039
|
||||
40 2040
|
||||
41 2041
|
||||
42 2042
|
||||
43 2043
|
||||
44 2044
|
||||
45 2045
|
||||
46 2046
|
||||
47 2047
|
||||
48 2048
|
||||
49 2049
|
||||
50 2050
|
||||
51 2051
|
||||
52 2052
|
||||
53 2053
|
||||
54 2054
|
||||
55 2055
|
||||
56 2056
|
||||
57 2057
|
||||
58 2058
|
||||
59 2059
|
||||
60 2060
|
||||
61 2061
|
||||
62 2062
|
||||
63 2063
|
||||
64 2064
|
||||
65 2065
|
||||
66 2066
|
||||
67 2067
|
||||
68 2068
|
||||
69 2069
|
||||
70 1970
|
||||
71 1971
|
||||
72 1972
|
||||
73 1973
|
||||
74 1974
|
||||
75 1975
|
||||
76 1976
|
||||
77 1977
|
||||
78 1978
|
||||
79 1979
|
||||
80 1980
|
||||
81 1981
|
||||
82 1982
|
||||
83 1983
|
||||
84 1984
|
||||
85 1985
|
||||
86 1986
|
||||
87 1987
|
||||
88 1988
|
||||
89 1989
|
||||
90 1990
|
||||
91 1991
|
||||
92 1992
|
||||
93 1993
|
||||
94 1994
|
||||
95 1995
|
||||
96 1996
|
||||
97 1997
|
||||
98 1998
|
||||
99 1999
|
||||
-1
|
||||
-1
|
||||
164
|
||||
1Meter (newton) 1
|
||||
1.00000000000000000E+0 1.00000000000000000E+0 1.00000000000000000E+0
|
||||
2.73149999999999980E+2
|
||||
-1
|
||||
-1
|
||||
1710
|
||||
================================================================================
|
||||
MATERIAL
|
||||
================================================================================
|
||||
1 fluid (1)
|
||||
0 LINE(S) OF TEXT
|
||||
0 MATERIAL CLASS(ES)
|
||||
0 MATERIAL ATTRIBUTE(S)
|
||||
0 MATERIAL COMPONENT(S)
|
||||
0 MATERIAL SPECIFICATION(S)
|
||||
--------------------------------------------------------------------------------
|
||||
0 MATERIAL VARIABLE(S)
|
||||
--------------------------------------------------------------------------------
|
||||
27 MATERIAL PROPERT(IES)
|
||||
--------------------------------------------------------------------------------
|
||||
MODULUS OF ELASTICITY
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
PRESSURE PASCAL
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
SHEAR MODULUS
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
PRESSURE PASCAL
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
POISSONS RATIO
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
DIMENSIONLESS UNITLESS
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
COEFFICIENT OF THERMAL EXPANSION
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
COEFFICIENT OF THERMAL EXPANSION 1/KELVIN
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
THERMAL CONDUCTIVITY
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
CONDUCTIVITY J/M/K/SEC
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
SPECIFIC HEAT
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
SPECIFIC HEAT J/KG/K
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
HEAT GENERATION RATE
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
HEAT FLUX PER UNIT VOLUME J/M^3/SEC
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
MASS DENSITY
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
MASS DENSITY KILOGRAM/METER^3
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
STRUCTURAL ELEMENT DAMPING COEFFICIENT
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
DIMENSIONLESS UNITLESS
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
THERMAL EXPANSION REFERENCE TEMPERATURE
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
TEMPERATURE KELVIN
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
ALLOWABLE STRESS IN TENSION X-DIR
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
PRESSURE PASCAL
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
ALLOWABLE STRESS IN COMPRESSION X-DIR
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
PRESSURE PASCAL
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
ALLOWABLE STRESS IN TENSION Y-DIR
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
PRESSURE PASCAL
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
ALLOWABLE STRESS IN COMPRESSION Y-DIR
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
PRESSURE PASCAL
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
ALLOWABLE IN-PLANE SHEAR STRESS
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
PRESSURE PASCAL
|
||||
CONSTANT
|
||||
0.00000000000000000E+0
|
||||
--------------------------------------------------------------------------------
|
||||
YIELD STRESS
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
PRESSURE PASCAL
|
||||
NULL_PROPERTY
|
||||
--------------------------------------------------------------------------------
|
||||
CONVECTIVE FILM COEFFICIENT
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
CONVECTION COEFFICIENT J/M^2/K/SEC
|
||||
NULL_PROPERTY
|
||||
--------------------------------------------------------------------------------
|
||||
THERMAL CAPACITY PER UNIT AREA
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
THERMAL CAPACITY PER UNIT AREA J/M^2/K
|
||||
NULL_PROPERTY
|
||||
--------------------------------------------------------------------------------
|
||||
SURFACE HEAT FLUX RATE
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
HEAT FLUX PER UNIT AREA J/M^2/SEC
|
||||
NULL_PROPERTY
|
||||
--------------------------------------------------------------------------------
|
||||
VISCOSITY
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
VISCOSITY KG/M/SEC
|
||||
NULL_PROPERTY
|
||||
--------------------------------------------------------------------------------
|
||||
COEFFICIENT OF FRICTION
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
DIMENSIONLESS UNITLESS
|
||||
NULL_PROPERTY
|
||||
--------------------------------------------------------------------------------
|
||||
AREA FACTOR
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
DIMENSIONLESS UNITLESS
|
||||
NULL_PROPERTY
|
||||
--------------------------------------------------------------------------------
|
||||
EMISSIVITY
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
DIMENSIONLESS UNITLESS
|
||||
NULL_PROPERTY
|
||||
--------------------------------------------------------------------------------
|
||||
ABSORPTIVITY
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
DIMENSIONLESS UNITLESS
|
||||
NULL_PROPERTY
|
||||
--------------------------------------------------------------------------------
|
||||
HEAT FLUX RATE
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
HEAT FLUX PER UNIT LENGTH J/M/SEC
|
||||
NULL_PROPERTY
|
||||
--------------------------------------------------------------------------------
|
||||
INTERACTION TERM FOR TSAI-WU
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
DIMENSIONLESS UNITLESS
|
||||
NULL_PROPERTY
|
||||
--------------------------------------------------------------------------------
|
||||
SWELLING COEFFICIENT
|
||||
1 VERSION NUMBER
|
||||
0 LINE(S) OF TEXT
|
||||
DIMENSIONS AND UNITS:
|
||||
DIMENSIONLESS UNITLESS
|
||||
NULL_PROPERTY
|
||||
--------------------------------------------------------------------------------
|
||||
DEFAULT MATERIAL PROPERT(IES):
|
||||
MODULUS OF ELASTICITY VERSION : 1
|
||||
SHEAR MODULUS VERSION : 1
|
||||
POISSONS RATIO VERSION : 1
|
||||
COEFFICIENT OF THERMAL EXPANSION VERSION : 1
|
||||
THERMAL CONDUCTIVITY VERSION : 1
|
||||
SPECIFIC HEAT VERSION : 1
|
||||
HEAT GENERATION RATE VERSION : 1
|
||||
MASS DENSITY VERSION : 1
|
||||
STRUCTURAL ELEMENT DAMPING COEFFICIENT VERSION : 1
|
||||
THERMAL EXPANSION REFERENCE TEMPERATURE VERSION : 1
|
||||
ALLOWABLE STRESS IN TENSION X-DIR VERSION : 1
|
||||
ALLOWABLE STRESS IN COMPRESSION X-DIR VERSION : 1
|
||||
ALLOWABLE STRESS IN TENSION Y-DIR VERSION : 1
|
||||
ALLOWABLE STRESS IN COMPRESSION Y-DIR VERSION : 1
|
||||
ALLOWABLE IN-PLANE SHEAR STRESS VERSION : 1
|
||||
YIELD STRESS VERSION : 1
|
||||
CONVECTIVE FILM COEFFICIENT VERSION : 1
|
||||
THERMAL CAPACITY PER UNIT AREA VERSION : 1
|
||||
SURFACE HEAT FLUX RATE VERSION : 1
|
||||
VISCOSITY VERSION : 1
|
||||
COEFFICIENT OF FRICTION VERSION : 1
|
||||
AREA FACTOR VERSION : 1
|
||||
EMISSIVITY VERSION : 1
|
||||
ABSORPTIVITY VERSION : 1
|
||||
HEAT FLUX RATE VERSION : 1
|
||||
INTERACTION TERM FOR TSAI-WU VERSION : 1
|
||||
SWELLING COEFFICIENT VERSION : 1
|
||||
--------------------------------------------------------------------------------
|
||||
1 REFERENCE ENTITIES
|
||||
1 MATERIAL TYPES
|
||||
FEM ISOTROPIC MATERIALS
|
||||
================================================================================
|
||||
-1
|
||||
-1
|
||||
2420
|
||||
100
|
||||
Untitled
|
||||
1 0 8
|
||||
CS1
|
||||
1.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 1.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 1.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
4 0 15
|
||||
NEiNastran for Windows Global Rectangular (4)
|
||||
1.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 1.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 1.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
5 1 15
|
||||
NEiNastran for Windows Global Cylindrical (5)
|
||||
1.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 1.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 1.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
6 2 15
|
||||
NEiNastran for Windows Global Spherical (6)
|
||||
1.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 1.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 1.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
3 0 2
|
||||
Coordinate System 3
|
||||
1.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 1.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 1.00000000000000000E+0
|
||||
5.00000000000000000E-1 5.00000000000000000E-1 1.00000000000000000E+0
|
||||
-1
|
||||
-1
|
||||
2411
|
||||
5 4 3 7
|
||||
0.5 0.5 1.
|
||||
6 4 4 7
|
||||
0. 0.5 1.
|
||||
9 4 4 7
|
||||
0. 0. 1.
|
||||
10 4 3 7
|
||||
0.5 -0.5 0.
|
||||
11 4 3 7
|
||||
0.5 -0.5 0.5
|
||||
12 4 3 7
|
||||
0.5 -0.5 1.
|
||||
13 4 4 7
|
||||
0. -0.5 1.
|
||||
15 4 4 7
|
||||
-0.5 -0.5 0.5
|
||||
16 4 4 7
|
||||
-0.5 -0.5 0.
|
||||
17 4 4 7
|
||||
0. -0.5 0.
|
||||
18 4 4 7
|
||||
0. -0.5 0.5
|
||||
21 4 4 7
|
||||
-0.5 -0.5 1.
|
||||
22 4 4 7
|
||||
-0.5 0. 1.
|
||||
24 4 4 7
|
||||
-0.5 0.5 0.5
|
||||
27 4 4 7
|
||||
-0.5 0. 0.5
|
||||
28 4 4 7
|
||||
-0.5 0.5 0.
|
||||
30 4 4 7
|
||||
-0.5 0.5 1.
|
||||
35 4 4 7
|
||||
0. 0.5 0.
|
||||
36 4 4 7
|
||||
0. 0.5 0.5
|
||||
37 4 3 7
|
||||
0.5 0.5 0.
|
||||
38 4 3 7
|
||||
0.5 0. 0.
|
||||
42 4 4 7
|
||||
-0.5 0. 0.
|
||||
45 4 4 7
|
||||
0. 0. 0.
|
||||
49 4 3 7
|
||||
0.5 0.5 0.5
|
||||
51 4 3 7
|
||||
0.5 0. 1.
|
||||
54 4 3 7
|
||||
0.5 0. 0.5
|
||||
55 4 4 7
|
||||
0. 0. 0.5
|
||||
60 4 3 7
|
||||
0.5 0.5 1.
|
||||
61 4 4 7
|
||||
0. 0.5 1.
|
||||
64 4 4 7
|
||||
0. 0. 1.
|
||||
65 4 3 7
|
||||
0.5 -0.5 0.
|
||||
66 4 3 7
|
||||
0.5 -0.5 0.5
|
||||
67 4 3 7
|
||||
0.5 -0.5 1.
|
||||
68 4 4 7
|
||||
0. -0.5 1.
|
||||
70 4 4 7
|
||||
-0.5 -0.5 0.5
|
||||
71 4 4 7
|
||||
-0.5 -0.5 0.
|
||||
72 4 4 7
|
||||
0. -0.5 0.
|
||||
73 4 4 7
|
||||
0. -0.5 0.5
|
||||
76 4 4 7
|
||||
-0.5 -0.5 1.
|
||||
77 4 4 7
|
||||
-0.5 0. 1.
|
||||
79 4 4 7
|
||||
-0.5 0.5 0.5
|
||||
82 4 4 7
|
||||
-0.5 0. 0.5
|
||||
83 4 4 7
|
||||
-0.5 0.5 0.
|
||||
85 4 4 7
|
||||
-0.5 0.5 1.
|
||||
90 4 4 7
|
||||
0. 0.5 0.
|
||||
91 4 4 7
|
||||
0. 0.5 0.5
|
||||
92 4 3 7
|
||||
0.5 0.5 0.
|
||||
93 4 3 7
|
||||
0.5 0. 0.
|
||||
97 4 4 7
|
||||
-0.5 0. 0.
|
||||
100 4 4 7
|
||||
0. 0. 0.
|
||||
104 4 3 7
|
||||
0.5 0.5 0.5
|
||||
106 4 3 7
|
||||
0.5 0. 1.
|
||||
109 4 3 7
|
||||
0.5 0. 0.5
|
||||
110 4 4 7
|
||||
0. 0. 0.5
|
||||
-1
|
||||
-1
|
||||
2431
|
||||
-1
|
||||
-1
|
||||
2437
|
||||
1 110 0
|
||||
Property 1
|
||||
-1
|
||||
-1
|
||||
776
|
||||
-1
|
||||
-1
|
||||
2412
|
||||
57 115 1 1 15 8
|
||||
76 77 64 68 70 82 110 73
|
||||
58 115 1 1 15 8
|
||||
68 64 106 67 73 110 109 66
|
||||
59 115 1 1 15 8
|
||||
77 85 61 64 82 79 91 110
|
||||
60 115 1 1 15 8
|
||||
64 61 60 106 110 91 104 109
|
||||
61 115 1 1 15 8
|
||||
70 82 110 73 71 97 100 72
|
||||
62 115 1 1 15 8
|
||||
73 110 109 66 72 100 93 65
|
||||
63 115 1 1 15 8
|
||||
82 79 91 110 97 83 90 100
|
||||
64 115 1 1 15 8
|
||||
110 91 104 109 100 90 92 93
|
||||
-1
|
||||
-1
|
||||
748
|
||||
57 115
|
||||
1.0000000E+0 0.0000000E+0 0.0000000E+0 0.0000000E+0 1.0000000E+0 0.0000000E+0
|
||||
58 115
|
||||
1.0000000E+0 0.0000000E+0 0.0000000E+0 0.0000000E+0 1.0000000E+0 0.0000000E+0
|
||||
59 115
|
||||
1.0000000E+0 0.0000000E+0 0.0000000E+0 0.0000000E+0 1.0000000E+0 0.0000000E+0
|
||||
60 115
|
||||
1.0000000E+0 0.0000000E+0 0.0000000E+0 0.0000000E+0 1.0000000E+0 0.0000000E+0
|
||||
61 115
|
||||
1.0000000E+0 0.0000000E+0 0.0000000E+0 0.0000000E+0 1.0000000E+0 0.0000000E+0
|
||||
62 115
|
||||
1.0000000E+0 0.0000000E+0 0.0000000E+0 0.0000000E+0 1.0000000E+0 0.0000000E+0
|
||||
63 115
|
||||
1.0000000E+0 0.0000000E+0 0.0000000E+0 0.0000000E+0 1.0000000E+0 0.0000000E+0
|
||||
64 115
|
||||
1.0000000E+0 0.0000000E+0 0.0000000E+0 0.0000000E+0 1.0000000E+0 0.0000000E+0
|
||||
-1
|
||||
-1
|
||||
757
|
||||
1
|
||||
inlet ( 1)
|
||||
15 4 1 1 1 1 1 1
|
||||
16 4 1 1 1 1 1 1
|
||||
21 4 1 1 1 1 1 1
|
||||
22 4 1 1 1 1 1 1
|
||||
24 4 1 1 1 1 1 1
|
||||
27 4 1 1 1 1 1 1
|
||||
28 4 1 1 1 1 1 1
|
||||
30 4 1 1 1 1 1 1
|
||||
42 4 1 1 1 1 1 1
|
||||
70 4 1 1 1 1 1 1
|
||||
71 4 1 1 1 1 1 1
|
||||
76 4 1 1 1 1 1 1
|
||||
77 4 1 1 1 1 1 1
|
||||
79 4 1 1 1 1 1 1
|
||||
82 4 1 1 1 1 1 1
|
||||
83 4 1 1 1 1 1 1
|
||||
85 4 1 1 1 1 1 1
|
||||
97 4 1 1 1 1 1 1
|
||||
-1
|
||||
-1
|
||||
757
|
||||
2
|
||||
Outlet ( 2)
|
||||
5 4 1 0 0 0 0 0
|
||||
10 4 1 0 0 0 0 0
|
||||
11 4 1 0 0 0 0 0
|
||||
12 4 1 0 0 0 0 0
|
||||
37 4 1 0 0 0 0 0
|
||||
38 4 1 0 0 0 0 0
|
||||
49 4 1 0 0 0 0 0
|
||||
51 4 1 0 0 0 0 0
|
||||
54 4 1 0 0 0 0 0
|
||||
60 4 1 0 0 0 0 0
|
||||
65 4 1 0 0 0 0 0
|
||||
66 4 1 0 0 0 0 0
|
||||
67 4 1 0 0 0 0 0
|
||||
92 4 1 0 0 0 0 0
|
||||
93 4 1 0 0 0 0 0
|
||||
104 4 1 0 0 0 0 0
|
||||
106 4 1 0 0 0 0 0
|
||||
109 4 1 0 0 0 0 0
|
||||
-1
|
||||
-1
|
||||
791
|
||||
1 1
|
||||
inlet (1)
|
||||
15 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
16 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
21 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
22 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
24 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
27 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
28 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
30 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
42 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
70 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
71 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
76 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
77 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
79 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
82 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
83 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
85 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
97 4 1 1 1 1 1 1 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
-1
|
||||
-1
|
||||
791
|
||||
2 1
|
||||
Outlet (2)
|
||||
5 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
10 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
11 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
12 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
37 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
38 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
49 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
51 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
54 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
60 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
65 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
66 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
67 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
92 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
93 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
104 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
106 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
109 4 1 0 0 0 0 0 0 7 0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0.00000000000000000E+0 0.00000000000000000E+0 0.00000000000000000E+0
|
||||
0 0 0 0 0 0
|
||||
-1
|
||||
File diff suppressed because it is too large
Load Diff
23394
applications/utilities/mesh/conversion/ideasUnvToFoam/unv/iniettore1.unv
Normal file
23394
applications/utilities/mesh/conversion/ideasUnvToFoam/unv/iniettore1.unv
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user