This repository has been archived on 2023-11-20. You can view files and clone it, but cannot push or open issues or pull requests.
foam-extend4.1-coherent-io/applications/utilities/mesh/conversion/cfx4ToFoam/cfx4ToFoam.C
Bernhard F.W. Gschaider a72b12ce8f This solves a compilation problem in Clang 3.5 where the class Time is
not completely instantiated in objectRegistry (see error message
below)

By including objectRegistry.H before Time.H the class Tiem gets
completely defined before objectRegistry.

The original Time.H could be omitted (as it is already included in
objectRegistry.H )

In file included from blockMeshApp.C:49:
In file included from /Users/bgschaid/OpenFOAM/foam-extend-3.1/src/foam/lnInclude/Time.H:42:
In file included from /Users/bgschaid/OpenFOAM/foam-extend-3.1/src/foam/lnInclude/objectRegistry.H:235:
/Users/bgschaid/OpenFOAM/foam-extend-3.1/src/foam/lnInclude/objectRegistryTemplates.C:94:25: error: 'const Foam::Time' is an incomplete type
        if (&parent_ != dynamic_cast<const objectRegistry*>(&time_))
                        ^                                   ~~~~~~
/Users/bgschaid/OpenFOAM/foam-extend-3.1/src/foam/lnInclude/IOobject.H:78:7: note: forward declaration of 'Foam::Time'
class Time;
      ^
In file included from blockMeshApp.C:49:
2014-06-02 18:05:03 +02:00

758 lines
22 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Application
cfx4ToFoam
Description
Converts a CFX 4 mesh to FOAM format
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "objectRegistry.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::validOptions.insert("scale", "scale factor");
argList args(argc, argv);
if (!args.check())
{
FatalError.exit();
}
scalar scaleFactor = 1.0;
args.optionReadIfPresent("scale", scaleFactor);
# include "createTime.H"
IFstream cfxFile(args.additionalArgs()[0]);
// 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 FOAM 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 FOAM 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;
}
// ************************************************************************* //