2010-05-12 13:27:55 +00:00
|
|
|
/*---------------------------------------------------------------------------*\
|
|
|
|
========= |
|
2013-12-11 16:09:41 +00:00
|
|
|
\\ / F ield | foam-extend: Open Source CFD
|
2010-05-12 13:27:55 +00:00
|
|
|
\\ / O peration |
|
2013-12-11 16:09:41 +00:00
|
|
|
\\ / A nd | For copyright notice see file Copyright
|
2010-05-12 13:27:55 +00:00
|
|
|
\\/ M anipulation |
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
License
|
2013-12-11 16:09:41 +00:00
|
|
|
This file is part of foam-extend.
|
2010-05-12 13:27:55 +00:00
|
|
|
|
2013-12-11 16:09:41 +00:00
|
|
|
foam-extend is free software: you can redistribute it and/or modify it
|
2010-05-12 13:27:55 +00:00
|
|
|
under the terms of the GNU General Public License as published by the
|
2013-12-11 16:09:41 +00:00
|
|
|
Free Software Foundation, either version 3 of the License, or (at your
|
2010-05-12 13:27:55 +00:00
|
|
|
option) any later version.
|
|
|
|
|
2013-12-11 16:09:41 +00:00
|
|
|
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.
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2013-12-11 16:09:41 +00:00
|
|
|
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
Application
|
|
|
|
cfx4ToFoam
|
|
|
|
|
|
|
|
Description
|
|
|
|
Converts a CFX 4 mesh to FOAM format
|
|
|
|
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
#include "argList.H"
|
2014-06-02 16:05:03 +00:00
|
|
|
#include "objectRegistry.H"
|
2010-05-12 13:27:55 +00:00
|
|
|
#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;
|
2010-08-25 21:42:57 +00:00
|
|
|
args.optionReadIfPresent("scale", scaleFactor);
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
# 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;
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "Reading blocks" << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
PtrList<hexBlock> blocks(nblock);
|
|
|
|
|
|
|
|
{
|
|
|
|
word blockName;
|
|
|
|
label nx, ny, nz;
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blocks, blockI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
cfxFile >> blockName;
|
|
|
|
cfxFile >> nx >> ny >> nz;
|
|
|
|
|
|
|
|
blocks.set(blockI, new hexBlock(nx, ny, nz));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "Reading patch definitions" << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
wordList cfxPatchTypes(npatch);
|
|
|
|
wordList cfxPatchNames(npatch);
|
|
|
|
labelList patchMasterBlocks(npatch);
|
|
|
|
labelList patchDirections(npatch);
|
|
|
|
labelListList patchRanges(npatch);
|
|
|
|
|
|
|
|
{
|
|
|
|
label no, blkNo, patchLabel;
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(cfxPatchTypes, patchI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
// Grab patch type and name
|
|
|
|
cfxFile >> cfxPatchTypes[patchI] >> cfxPatchNames[patchI] >> no;
|
|
|
|
|
|
|
|
// Grab patch range
|
|
|
|
patchRanges[patchI].setSize(6);
|
|
|
|
labelList& curRange = patchRanges[patchI];
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(curRange, rI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "Reading block glueing information" << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "Reading block points" << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blocks, blockI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "block " << blockI << " is a ";
|
2010-05-12 13:27:55 +00:00
|
|
|
blocks[blockI].readPoints(cfxFile);
|
|
|
|
}
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "Calculating block offsets" << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "Assembling patches" << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
faceListList rawPatches(npatch);
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(rawPatches, patchI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
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]
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "Merging points ";
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
labelList pointMergeList(nMeshPoints, -1);
|
|
|
|
|
|
|
|
// In order to ensure robust merging, it is necessary to traverse
|
|
|
|
// the patch glueing list until the pointMergeList stops changing.
|
2013-07-18 01:02:34 +00:00
|
|
|
//
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
// For efficiency, create merge pairs in the first pass
|
|
|
|
labelListListList glueMergePairs(glueMasterPatches.size());
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(glueMasterPatches, glueI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blockPFaces, blockPFaceLabel)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
const labelList& blockPFacePoints =
|
|
|
|
blockPFaces[blockPFaceLabel];
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blockPFacePoints, blockPFacePointI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blockPFacePoints, blockPFacePointI2)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
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
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blockPFaces, blockPFaceLabel)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
const labelList& blockPFacePoints =
|
|
|
|
blockPFaces[blockPFaceLabel];
|
|
|
|
|
|
|
|
labelList& cp = curPairs[blockPFaceLabel];
|
|
|
|
cp.setSize(blockPFacePoints.size());
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blockPFacePoints, blockPFacePointI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
found = false;
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blockNFaces, blockNFaceLabel)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
const labelList& blockNFacePoints =
|
|
|
|
blockNFaces[blockNFaceLabel];
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blockNFacePoints, blockNFacePointI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
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++;
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(glueMasterPatches, glueI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
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];
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blockPFaces, blockPFaceLabel)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
const labelList& blockPFacePoints =
|
|
|
|
blockPFaces[blockPFaceLabel];
|
|
|
|
|
|
|
|
const labelList& cp = curPairs[blockPFaceLabel];
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(cp, blockPFacePointI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
label PpointLabel =
|
|
|
|
blockPFacePoints[blockPFacePointI]
|
|
|
|
+ blockOffsets[blockPlabel];
|
|
|
|
|
|
|
|
label NpointLabel =
|
|
|
|
cp[blockPFacePointI]
|
|
|
|
+ blockOffsets[blockNlabel];
|
|
|
|
|
|
|
|
if
|
|
|
|
(
|
|
|
|
pointMergeList[PpointLabel]
|
|
|
|
!= pointMergeList[NpointLabel]
|
|
|
|
)
|
|
|
|
{
|
|
|
|
changedPointMerge = true;
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
pointMergeList[PpointLabel]
|
|
|
|
= pointMergeList[NpointLabel]
|
|
|
|
= min
|
|
|
|
(
|
|
|
|
pointMergeList[PpointLabel],
|
|
|
|
pointMergeList[NpointLabel]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "." << flush;
|
2010-05-12 13:27:55 +00:00
|
|
|
}
|
|
|
|
while (changedPointMerge && nPasses < 8);
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
if (changedPointMerge == true)
|
|
|
|
{
|
|
|
|
FatalErrorIn(args.executable())
|
|
|
|
<< "Point merging failed after max number of passes."
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(glueMasterPatches, glueI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
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];
|
|
|
|
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blockPFaces, blockPFaceLabel)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
const labelList& blockPFacePoints
|
|
|
|
= blockPFaces[blockPFaceLabel];
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blockPFacePoints, blockPFacePointI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blockNFaces, blockNFaceLabel)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
const labelList& blockNFacePoints
|
|
|
|
= blockNFaces[blockNFaceLabel];
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blockNFacePoints, blockNFacePointI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(pointMergeList, pointLabel)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "Creating points" << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
pointField points(nMeshPoints);
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blocks, blockI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
const pointField& blockPoints = blocks[blockI].points();
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blockPoints, blockPointLabel)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
points
|
|
|
|
[
|
|
|
|
pointMergeList
|
|
|
|
[
|
|
|
|
blockPointLabel
|
|
|
|
+ blockOffsets[blockI]
|
|
|
|
]
|
|
|
|
] = blockPoints[blockPointLabel];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Scale the points
|
|
|
|
if (scaleFactor > 1.0 + SMALL || scaleFactor < 1.0 - SMALL)
|
|
|
|
{
|
|
|
|
points *= scaleFactor;
|
|
|
|
}
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "Creating cells" << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
cellShapeList cellShapes(nMeshCells);
|
|
|
|
|
|
|
|
const cellModel& hex = *(cellModeller::lookup("hex"));
|
|
|
|
|
|
|
|
label nCreatedCells = 0;
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(blocks, blockI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
labelListList curBlockCells = blocks[blockI].blockCells();
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(curBlockCells, blockCellI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
labelList cellPoints(curBlockCells[blockCellI].size());
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(cellPoints, pointI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
cellPoints[pointI] =
|
|
|
|
pointMergeList
|
|
|
|
[
|
|
|
|
curBlockCells[blockCellI][pointI]
|
|
|
|
+ blockOffsets[blockI]
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
cellShapes[nCreatedCells] = cellShape(hex, cellPoints);
|
|
|
|
|
|
|
|
nCreatedCells++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "Creating boundary patches" << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
faceListList boundary(npatch);
|
|
|
|
wordList patchNames(npatch);
|
|
|
|
wordList patchTypes(npatch);
|
|
|
|
word defaultFacesName = "defaultFaces";
|
|
|
|
word defaultFacesType = wallPolyPatch::typeName;
|
|
|
|
|
|
|
|
label nCreatedPatches = 0;
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(rawPatches, patchI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
2010-08-25 21:42:57 +00:00
|
|
|
if (rawPatches[patchI].size() && cfxPatchTypes[patchI] != "BLKBDY")
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
// 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)
|
|
|
|
{
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "CFX patch " << patchI
|
2010-05-12 13:27:55 +00:00
|
|
|
<< ", 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());
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(curRawPatch, faceI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
const face& oldFace = curRawPatch[faceI];
|
|
|
|
|
|
|
|
face& newFace = renumberedPatch[oldSize + faceI];
|
|
|
|
newFace.setSize(oldFace.size());
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(oldFace, pointI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
newFace[pointI] =
|
|
|
|
pointMergeList
|
|
|
|
[
|
|
|
|
oldFace[pointI]
|
|
|
|
+ blockOffsets[curBlock]
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Real patch to be created
|
|
|
|
faceList& renumberedPatch = boundary[nCreatedPatches];
|
|
|
|
renumberedPatch.setSize(curRawPatch.size());
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(curRawPatch, faceI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
const face& oldFace = curRawPatch[faceI];
|
|
|
|
|
|
|
|
face& newFace = renumberedPatch[faceI];
|
|
|
|
newFace.setSize(oldFace.size());
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
forAll(oldFace, pointI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
newFace[pointI] =
|
|
|
|
pointMergeList
|
|
|
|
[
|
|
|
|
oldFace[pointI]
|
|
|
|
+ blockOffsets[curBlock]
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "CFX patch " << patchI
|
2010-05-12 13:27:55 +00:00
|
|
|
<< ", of type " << cfxPatchTypes[patchI]
|
|
|
|
<< ", name " << cfxPatchNames[patchI]
|
|
|
|
<< " converted into FOAM patch " << nCreatedPatches
|
|
|
|
<< " type ";
|
|
|
|
|
|
|
|
if (cfxPatchTypes[patchI] == "WALL")
|
|
|
|
{
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "wall." << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
patchTypes[nCreatedPatches] = wallPolyPatch::typeName;
|
|
|
|
patchNames[nCreatedPatches] = cfxPatchNames[patchI];
|
|
|
|
nCreatedPatches++;
|
|
|
|
}
|
|
|
|
else if (cfxPatchTypes[patchI] == "SYMMET")
|
|
|
|
{
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "symmetryPlane." << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
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"
|
|
|
|
)
|
|
|
|
{
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "generic." << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
PtrList<dictionary> patchDicts;
|
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
preservePatchTypes
|
|
|
|
(
|
|
|
|
runTime,
|
|
|
|
runTime.constant(),
|
2014-05-28 11:49:49 +00:00
|
|
|
polyMesh::meshSubDir,
|
2010-05-12 13:27:55 +00:00
|
|
|
patchNames,
|
2014-05-28 11:49:49 +00:00
|
|
|
patchDicts,
|
2010-05-12 13:27:55 +00:00
|
|
|
defaultFacesName,
|
2014-05-28 11:49:49 +00:00
|
|
|
defaultFacesType
|
2010-05-12 13:27:55 +00:00
|
|
|
);
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
polyMesh pShapeMesh
|
|
|
|
(
|
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
polyMesh::defaultRegion,
|
|
|
|
runTime.constant(),
|
|
|
|
runTime
|
|
|
|
),
|
2010-09-22 18:13:13 +00:00
|
|
|
xferMove(points),
|
2010-05-12 13:27:55 +00:00
|
|
|
cellShapes,
|
|
|
|
boundary,
|
|
|
|
patchNames,
|
2014-05-28 11:49:49 +00:00
|
|
|
patchDicts,
|
2010-05-12 13:27:55 +00:00
|
|
|
defaultFacesName,
|
2014-05-28 11:49:49 +00:00
|
|
|
defaultFacesType
|
2010-05-12 13:27:55 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
// Set the precision of the points data to 10
|
2014-05-28 11:49:49 +00:00
|
|
|
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
|
2010-05-12 13:27:55 +00:00
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "Writing polyMesh" << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
pShapeMesh.write();
|
|
|
|
|
2014-05-28 11:49:49 +00:00
|
|
|
Info<< "End\n" << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ************************************************************************* //
|