FEAT: foamMeshToElmer & fluentMeshToElmer utilities
This commit is contained in:
parent
662e58aa06
commit
78877f0930
10 changed files with 2240 additions and 0 deletions
|
@ -0,0 +1,3 @@
|
||||||
|
fluent3DMeshToElmer.L
|
||||||
|
|
||||||
|
EXE = $(FOAM_APPBIN)/fluent3DMeshToElmer
|
|
@ -0,0 +1,9 @@
|
||||||
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
|
-I$(LIB_SRC)/conversion/lnInclude \
|
||||||
|
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude
|
||||||
|
|
||||||
|
EXE_LIBS = \
|
||||||
|
-lmeshTools \
|
||||||
|
-lconversion \
|
||||||
|
-ldynamicMesh
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,3 @@
|
||||||
|
foamMeshToElmer.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_APPBIN)/foamMeshToElmer
|
|
@ -0,0 +1,6 @@
|
||||||
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
|
-I$(LIB_SRC)/conversion/lnInclude
|
||||||
|
|
||||||
|
EXE_LIBS = \
|
||||||
|
-lconversion
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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
|
||||||
|
foamMeshToElmer
|
||||||
|
|
||||||
|
Description
|
||||||
|
Reads an foam mesh and writes a CSC/Elmer .nodes/.elements/.boundary format.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
- foamMeshToElmer [OPTION] \n
|
||||||
|
Reads an foam mesh and writes a CSC/Elmer .nodes/.elements/.boundary format.
|
||||||
|
|
||||||
|
@param -scale \<factor\>\n
|
||||||
|
Specify an alternative geometry scaling factor.
|
||||||
|
The default is @b 1.
|
||||||
|
|
||||||
|
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::Elmer
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "argList.H"
|
||||||
|
#include "timeSelector.H"
|
||||||
|
#include "objectRegistry.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "polyMesh.H"
|
||||||
|
#include "ElmerMeshWriter.H"
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
// Main program:
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
argList::noParallel();
|
||||||
|
timeSelector::addOptions();
|
||||||
|
|
||||||
|
argList::validOptions.insert("scale" , "factor" );
|
||||||
|
argList::validOptions.insert("exclude", "pattern");
|
||||||
|
|
||||||
|
# include "setRootCase.H"
|
||||||
|
# include "createTime.H"
|
||||||
|
|
||||||
|
instantList timeDirs = timeSelector::select0(runTime, args);
|
||||||
|
|
||||||
|
|
||||||
|
// default: do not rescale
|
||||||
|
scalar scaleFactor = 1;
|
||||||
|
if (args.optionReadIfPresent("scale", scaleFactor))
|
||||||
|
{
|
||||||
|
if (scaleFactor <= 0)
|
||||||
|
{
|
||||||
|
scaleFactor = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wordRe excludePattern;
|
||||||
|
args.optionReadIfPresent("exclude", excludePattern);
|
||||||
|
Info<<"Exclude pattern: \"" << excludePattern << "\"." <<endl;
|
||||||
|
excludePattern.compile(wordRe::DETECT_NOCASE);
|
||||||
|
|
||||||
|
# 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::Elmer writer(mesh, scaleFactor,&excludePattern);
|
||||||
|
fileName dirName("elmerMesh");
|
||||||
|
if (state != polyMesh::UNCHANGED)
|
||||||
|
{
|
||||||
|
dirName += '_' + runTime.timeName();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!writer.write(dirName))
|
||||||
|
break; // Conversion failed
|
||||||
|
}
|
||||||
|
|
||||||
|
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() != "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,
|
||||||
|
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;
|
||||||
|
|
|
@ -18,6 +18,7 @@ meshReader/starcd/STARCDMeshReader.C
|
||||||
|
|
||||||
meshWriter/meshWriter.C
|
meshWriter/meshWriter.C
|
||||||
meshWriter/starcd/STARCDMeshWriter.C
|
meshWriter/starcd/STARCDMeshWriter.C
|
||||||
|
meshWriter/elmer/ElmerMeshWriter.C
|
||||||
|
|
||||||
polyDualMesh/polyDualMesh.C
|
polyDualMesh/polyDualMesh.C
|
||||||
|
|
||||||
|
|
560
src/conversion/meshWriter/elmer/ElmerMeshWriter.C
Normal file
560
src/conversion/meshWriter/elmer/ElmerMeshWriter.C
Normal file
|
@ -0,0 +1,560 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "ElmerMeshWriter.H"
|
||||||
|
|
||||||
|
#include "Time.H"
|
||||||
|
#include "SortableList.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
|
||||||
|
#include "hexMatcher.H"
|
||||||
|
#include "wedgeMatcher.H"
|
||||||
|
#include "prismMatcher.H"
|
||||||
|
#include "pyrMatcher.H"
|
||||||
|
#include "tetWedgeMatcher.H"
|
||||||
|
#include "tetMatcher.H"
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::meshWriters::Elmer::getCellTable()
|
||||||
|
{
|
||||||
|
// read constant/polyMesh/propertyName
|
||||||
|
IOList<label> ioList
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"cellTableId",
|
||||||
|
"constant",
|
||||||
|
polyMesh::meshSubDir,
|
||||||
|
mesh_,
|
||||||
|
IOobject::READ_IF_PRESENT,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
bool useCellZones = false;
|
||||||
|
cellTableId_.setSize(mesh_.nCells(), -1);
|
||||||
|
|
||||||
|
// get information from constant/polyMesh/cellTableId if possible
|
||||||
|
if (ioList.headerOk())
|
||||||
|
{
|
||||||
|
if (ioList.size() == mesh_.nCells())
|
||||||
|
{
|
||||||
|
cellTableId_.transfer(ioList);
|
||||||
|
|
||||||
|
if (cellTable_.empty())
|
||||||
|
{
|
||||||
|
Info<< "No cellTable information available" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WarningIn("Elmer::getCellTable()")
|
||||||
|
<< ioList.objectPath() << " has incorrect number of cells "
|
||||||
|
<< " - use cellZone information"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
ioList.clear();
|
||||||
|
useCellZones = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
useCellZones = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (useCellZones)
|
||||||
|
{
|
||||||
|
if (cellTable_.empty())
|
||||||
|
{
|
||||||
|
Info<< "Created cellTable from cellZones" << endl;
|
||||||
|
cellTable_ = mesh_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// track if there are unzoned cells
|
||||||
|
label nUnzoned = mesh_.nCells();
|
||||||
|
|
||||||
|
// get the cellZone <-> cellTable correspondence
|
||||||
|
Info<< "Matching cellZones to cellTable" << endl;
|
||||||
|
|
||||||
|
forAll (mesh_.cellZones(), zoneI)
|
||||||
|
{
|
||||||
|
const cellZone& cZone = mesh_.cellZones()[zoneI];
|
||||||
|
if (cZone.size())
|
||||||
|
{
|
||||||
|
nUnzoned -= cZone.size();
|
||||||
|
|
||||||
|
label tableId = cellTable_.findIndex(cZone.name());
|
||||||
|
if (tableId < 0)
|
||||||
|
{
|
||||||
|
dictionary dict;
|
||||||
|
|
||||||
|
dict.add("Label", cZone.name());
|
||||||
|
dict.add("MaterialType", "fluid");
|
||||||
|
tableId = cellTable_.append(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll (cZone, i)
|
||||||
|
{
|
||||||
|
cellTableId_[cZone[i]] = tableId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nUnzoned)
|
||||||
|
{
|
||||||
|
dictionary dict;
|
||||||
|
|
||||||
|
dict.add("Label", "__unZonedCells__");
|
||||||
|
dict.add("MaterialType", "fluid");
|
||||||
|
label tableId = cellTable_.append(dict);
|
||||||
|
|
||||||
|
forAll (cellTableId_, i)
|
||||||
|
{
|
||||||
|
if (cellTableId_[i] < 0)
|
||||||
|
{
|
||||||
|
cellTableId_[i] = tableId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the Elmer face element type ID based on the number of vertices of a face
|
||||||
|
//
|
||||||
|
Foam::label Foam::meshWriters::Elmer::getFaceType(const label nvert, const word &zname) const
|
||||||
|
{
|
||||||
|
switch(nvert)
|
||||||
|
{
|
||||||
|
case 3:
|
||||||
|
return ELMER_ETYPE_TRIA;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
return ELMER_ETYPE_QUAD;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Info<< "Found a bad face with " << nvert
|
||||||
|
<< " vertices on zone " << zname
|
||||||
|
<< "." << endl;
|
||||||
|
return ELMER_ETYPE_BAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Save the mesh.names file containing the names of all zones & patches
|
||||||
|
//
|
||||||
|
void Foam::meshWriters::Elmer::writeNames() const
|
||||||
|
{
|
||||||
|
OFstream os("mesh.names");
|
||||||
|
|
||||||
|
const cellZoneMesh& czones = mesh_.cellZones();
|
||||||
|
const faceZoneMesh& fzones = mesh_.faceZones();
|
||||||
|
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||||
|
label boundaryID = 0;
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "Writing " << os.name() << "." << endl;
|
||||||
|
|
||||||
|
os << "! ----- Names for bodies -----" << nl;
|
||||||
|
forAll (czones, zoneI)
|
||||||
|
{
|
||||||
|
os << "$ " << czones[zoneI].name() << " = " << zoneI+1 << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "! ----- Names for exterior boundaries -----" << nl;
|
||||||
|
forAll(patches, patchI)
|
||||||
|
{
|
||||||
|
os << "$ " << patches[patchI].name() << " = " << ++boundaryID << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "! ----- Names for interior boundaries -----" << nl;
|
||||||
|
forAll(fzones, fzoneI)
|
||||||
|
{
|
||||||
|
if (!faceZoneExcludePattern || !faceZoneExcludePattern->match(fzones[fzoneI].name()))
|
||||||
|
{
|
||||||
|
os << "$ " << fzones[fzoneI].name() << " = " << ++boundaryID << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Save the mesh.header file containing the global counters
|
||||||
|
//
|
||||||
|
bool Foam::meshWriters::Elmer::writeHeader() const
|
||||||
|
{
|
||||||
|
OFstream os("mesh.header");
|
||||||
|
|
||||||
|
const pointField& points = mesh_.points();
|
||||||
|
const cellList& cells = mesh_.cells();
|
||||||
|
const faceList& faces = mesh_.faces();
|
||||||
|
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||||
|
const faceZoneMesh& fzones = mesh_.faceZones();
|
||||||
|
label extZones = 0; // Count exterior boundary zones
|
||||||
|
label extFaces = 0; // Count exterior boundary faces
|
||||||
|
label intZones = 0; // Used interior boundary zones
|
||||||
|
label intFaces = 0; // Used interior boundary faces
|
||||||
|
|
||||||
|
// Count the different cell types
|
||||||
|
hexMatcher hex;
|
||||||
|
prismMatcher pri;
|
||||||
|
pyrMatcher pyr;
|
||||||
|
tetMatcher tet;
|
||||||
|
|
||||||
|
label nHex = 0;
|
||||||
|
label nPri = 0;
|
||||||
|
label nPyr = 0;
|
||||||
|
label nTet = 0;
|
||||||
|
label nTri = 0;
|
||||||
|
label nQua = 0;
|
||||||
|
label nBad = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "Writing " << os.name() << "." << endl;
|
||||||
|
|
||||||
|
// Count all exterior boundary zone + faces + the types
|
||||||
|
forAll(patches, patchI)
|
||||||
|
{
|
||||||
|
const label patchStart = patches[patchI].start();
|
||||||
|
const label patchEnd = patchStart + patches[patchI].size();
|
||||||
|
|
||||||
|
extZones++;
|
||||||
|
extFaces += patches[patchI].size();
|
||||||
|
|
||||||
|
// Count triangles and quads
|
||||||
|
for(label faceI = patchStart; faceI < patchEnd; ++faceI)
|
||||||
|
{
|
||||||
|
if (faces[faceI].size() == 4)
|
||||||
|
{
|
||||||
|
nQua++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nTri++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count all interior boundary zones + faces with names not matching the exclude pattern
|
||||||
|
forAll(fzones, fzoneI)
|
||||||
|
{
|
||||||
|
if (faceZoneExcludePattern && faceZoneExcludePattern->match(fzones[fzoneI].name()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const faceZone& fzone = fzones[fzoneI];
|
||||||
|
|
||||||
|
intZones++;
|
||||||
|
intFaces += fzone.size();
|
||||||
|
|
||||||
|
// Count triangles and quads
|
||||||
|
forAll(fzone, i)
|
||||||
|
{
|
||||||
|
if (faces[fzone[i]].size() == 4)
|
||||||
|
{
|
||||||
|
nQua++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nTri++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os << points.size() << " "
|
||||||
|
<< cells.size() << " "
|
||||||
|
<< extFaces+intFaces << nl;
|
||||||
|
|
||||||
|
// Count the volume element types
|
||||||
|
for(label cellI = 0; cellI < mesh_.nCells(); cellI++)
|
||||||
|
{
|
||||||
|
if (hex.isA(mesh_, cellI)) nHex++;
|
||||||
|
else if (tet.isA(mesh_, cellI)) nTet++;
|
||||||
|
else if (pyr.isA(mesh_, cellI)) nPyr++;
|
||||||
|
else if (pri.isA(mesh_, cellI)) nPri++;
|
||||||
|
else nBad++; // No valid element type for Elmer
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the number of different element types used
|
||||||
|
os << (nTet>0) + (nPri>0) + (nPyr>0) + (nHex>0) + (nQua>0) + (nTri>0) + (nBad>0) << endl;
|
||||||
|
|
||||||
|
// Save type and count if count > 0
|
||||||
|
if (nTet > 0) os << ELMER_ETYPE_TET << " " << nTet << endl;
|
||||||
|
if (nPri > 0) os << ELMER_ETYPE_PRISM << " " << nPri << endl;
|
||||||
|
if (nPyr > 0) os << ELMER_ETYPE_PYRAM << " " << nPyr << endl;
|
||||||
|
if (nHex > 0) os << ELMER_ETYPE_HEX << " " << nHex << endl;
|
||||||
|
if (nQua > 0) os << ELMER_ETYPE_QUAD << " " << nQua << endl;
|
||||||
|
if (nTri > 0) os << ELMER_ETYPE_TRIA << " " << nTri << endl;
|
||||||
|
if (nBad > 0) os << ELMER_ETYPE_BAD << " " << nBad << endl;
|
||||||
|
|
||||||
|
Info<< "Mesh statistics:" << nl
|
||||||
|
<< " Nodes : " << points.size() << nl
|
||||||
|
<< " Elements : " << cells.size() << nl
|
||||||
|
<< " Hexahedra : " << nHex << nl
|
||||||
|
<< " Wedges : " << nPri << nl
|
||||||
|
<< " Pyramids : " << nPyr << nl
|
||||||
|
<< " Tetrahedra : " << nTet << nl
|
||||||
|
<< " Polyhedra : " << nBad << nl
|
||||||
|
<< " Regions : " << mesh_.cellZones().size() << nl
|
||||||
|
<< " Ext. boundaries: " << extZones << ", " << extFaces << " faces" << nl
|
||||||
|
<< " Int. boundaries: " << intZones << ", " << intFaces << " faces" << nl
|
||||||
|
<< " Tri faces : " << nTri << nl
|
||||||
|
<< " Quad faces : " << nQua << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
os.flush();
|
||||||
|
return (!nBad); // Conversion impossble if nBad > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Save the mesh.nodes file
|
||||||
|
//
|
||||||
|
void Foam::meshWriters::Elmer::writeNodes() const
|
||||||
|
{
|
||||||
|
OFstream os("mesh.nodes");
|
||||||
|
|
||||||
|
// Set the precision of the points data to 10
|
||||||
|
os.precision(10);
|
||||||
|
|
||||||
|
// Force decimal point for Fortran90 input style
|
||||||
|
os.setf(std::ios::showpoint);
|
||||||
|
|
||||||
|
const pointField& points = mesh_.points();
|
||||||
|
|
||||||
|
Info<< "Writing " << os.name() << ": scale=" << scaleFactor_ << endl;
|
||||||
|
|
||||||
|
forAll(points, ptI)
|
||||||
|
{
|
||||||
|
os << ptI + 1 << " -1 "
|
||||||
|
<< scaleFactor_ * points[ptI].x() << " "
|
||||||
|
<< scaleFactor_ * points[ptI].y() << " "
|
||||||
|
<< scaleFactor_ * points[ptI].z() << nl;
|
||||||
|
}
|
||||||
|
os.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Save the mesh.elements file. This file contains only the volume elements, not the
|
||||||
|
// faces on the boundaries
|
||||||
|
//
|
||||||
|
void Foam::meshWriters::Elmer::writeElements() const
|
||||||
|
{
|
||||||
|
OFstream os("mesh.elements");
|
||||||
|
|
||||||
|
// map foam cellModeller index -> Elmer element types
|
||||||
|
Map<label> shapeLookupIndex;
|
||||||
|
shapeLookupIndex.insert(tetModel->index() , ELMER_ETYPE_TET );
|
||||||
|
shapeLookupIndex.insert(prismModel->index(), ELMER_ETYPE_PRISM);
|
||||||
|
shapeLookupIndex.insert(pyrModel->index() , ELMER_ETYPE_PYRAM);
|
||||||
|
shapeLookupIndex.insert(hexModel->index() , ELMER_ETYPE_HEX );
|
||||||
|
|
||||||
|
const cellShapeList& shapes = mesh_.cellShapes();
|
||||||
|
const cellList& cells = mesh_.cells();
|
||||||
|
|
||||||
|
Info<< "Writing " << os.name() << "." << endl;
|
||||||
|
|
||||||
|
forAll(cells, cellId)
|
||||||
|
{
|
||||||
|
const cellShape& shape = shapes[cellId];
|
||||||
|
label mapIndex = shape.model().index();
|
||||||
|
|
||||||
|
// a registered primitive type
|
||||||
|
if (shapeLookupIndex.found(mapIndex))
|
||||||
|
{
|
||||||
|
os << cellId+1 << " " << cellTableId_[cellId] << " " << shapeLookupIndex[mapIndex];
|
||||||
|
|
||||||
|
const labelList& vrtList = shapes[cellId];
|
||||||
|
forAll(vrtList, i)
|
||||||
|
{
|
||||||
|
os << " " << vrtList[i] + 1;
|
||||||
|
}
|
||||||
|
os << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "***WARNING: polyhedron " << cellId << " ignored." << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Save the mesh.boundary file. This file contains only the faces elements on boundaries.
|
||||||
|
//
|
||||||
|
void Foam::meshWriters::Elmer::writeBoundary() const
|
||||||
|
{
|
||||||
|
OFstream os("mesh.boundary");
|
||||||
|
|
||||||
|
const faceList& faces = mesh_.faces();
|
||||||
|
const labelList& owner = mesh_.faceOwner();
|
||||||
|
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||||
|
label bfaceID = 0;
|
||||||
|
label boundaryID = 0;
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "Writing " << os.name() << "." << endl;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Write all patches == exterior boundary faces
|
||||||
|
//
|
||||||
|
forAll(patches, patchI)
|
||||||
|
{
|
||||||
|
const word& pname = patches[patchI].name();
|
||||||
|
const label patchStart = patches[patchI].start();
|
||||||
|
const label patchEnd = patchStart + patches[patchI].size();
|
||||||
|
|
||||||
|
boundaryID++;
|
||||||
|
for(label faceI = patchStart; faceI < patchEnd; ++faceI)
|
||||||
|
{
|
||||||
|
const labelList& vrtList = faces[faceI];
|
||||||
|
|
||||||
|
os << ++bfaceID
|
||||||
|
<< " " << boundaryID
|
||||||
|
<< " " << owner[faceI] + 1 // ID of parent cell
|
||||||
|
<< " 0 " // 0 == exterior boundary face
|
||||||
|
<< getFaceType(vrtList.size(),pname);
|
||||||
|
|
||||||
|
forAll(vrtList, i)
|
||||||
|
{
|
||||||
|
os << " " << vrtList[i] + 1;
|
||||||
|
}
|
||||||
|
os << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Write face zones (== interior boundary faces) with names not matching the exclude pattern
|
||||||
|
//
|
||||||
|
const faceZoneMesh& fzones = mesh_.faceZones();
|
||||||
|
forAll(fzones, fzoneI)
|
||||||
|
{
|
||||||
|
if (faceZoneExcludePattern && faceZoneExcludePattern->match(fzones[fzoneI].name()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const faceZone& fzone = fzones[fzoneI];
|
||||||
|
const labelList& master = fzone.masterCells();
|
||||||
|
const labelList& slave = fzone.slaveCells();
|
||||||
|
const word& zname = fzone.name();
|
||||||
|
|
||||||
|
boundaryID++;
|
||||||
|
forAll(fzone, i)
|
||||||
|
{
|
||||||
|
const labelList& vrtList = faces[fzone[i]];
|
||||||
|
|
||||||
|
os << ++bfaceID
|
||||||
|
<< " " << boundaryID
|
||||||
|
<< " " << master[i] + 1 // ID of parent cell
|
||||||
|
<< " " << slave[i] + 1 // ID of neigbour cell
|
||||||
|
<< " " << getFaceType(vrtList.size(),zname);
|
||||||
|
|
||||||
|
forAll(vrtList, j)
|
||||||
|
{
|
||||||
|
os << " " << vrtList[j] + 1;
|
||||||
|
}
|
||||||
|
os << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::meshWriters::Elmer::Elmer
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const scalar scaleFactor,
|
||||||
|
const wordRe* excludePattern
|
||||||
|
)
|
||||||
|
:
|
||||||
|
meshWriter(mesh, scaleFactor), faceZoneExcludePattern(excludePattern)
|
||||||
|
{
|
||||||
|
boundaryRegion_.readDict(mesh_);
|
||||||
|
cellTable_.readDict(mesh_);
|
||||||
|
getCellTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::meshWriters::Elmer::~Elmer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::meshWriters::Elmer::write(const fileName& dirName) const
|
||||||
|
{
|
||||||
|
fileName baseName(dirName);
|
||||||
|
bool success;
|
||||||
|
|
||||||
|
if (baseName.empty())
|
||||||
|
{
|
||||||
|
baseName = meshWriter::defaultMeshName;
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
mesh_.time().timeName() != "0"
|
||||||
|
&& mesh_.time().timeName() != "constant"
|
||||||
|
)
|
||||||
|
{
|
||||||
|
baseName += "_" + mesh_.time().timeName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the mesh directory (elemerMesh), chdir into and cleanup
|
||||||
|
mkDir(baseName);
|
||||||
|
chDir(baseName);
|
||||||
|
rm("mesh.header" );
|
||||||
|
rm("mesh.nodes" );
|
||||||
|
rm("mesh.elements");
|
||||||
|
rm("mesh.boundary");
|
||||||
|
rm("mesh.names" );
|
||||||
|
success = writeHeader();
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
writeNodes ();
|
||||||
|
writeElements();
|
||||||
|
writeBoundary();
|
||||||
|
writeNames ();
|
||||||
|
}
|
||||||
|
chDir("..");
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
93
src/conversion/meshWriter/elmer/ElmerMeshWriter.H
Normal file
93
src/conversion/meshWriter/elmer/ElmerMeshWriter.H
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::meshWriters::Elmer
|
||||||
|
|
||||||
|
Description
|
||||||
|
Writes polyMesh in CSC/Elmer format: generates the files
|
||||||
|
|
||||||
|
elmerMesh.header
|
||||||
|
elmerMesh.nodes
|
||||||
|
elmerMesh.elements
|
||||||
|
elmerMesh.boundary
|
||||||
|
elmerMesh.names
|
||||||
|
|
||||||
|
The cellTableId and cellTable information are used (if available).
|
||||||
|
Otherwise the cellZones are used (if available).
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
ElmerMeshWriter.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef ElmerMeshWriter_H
|
||||||
|
#define ElmerMeshWriter_H
|
||||||
|
|
||||||
|
#include "meshWriter.H"
|
||||||
|
#include "wordReList.H"
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace meshWriters
|
||||||
|
{
|
||||||
|
class Elmer: public meshWriter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Elmer element type labels
|
||||||
|
#define ELMER_ETYPE_BAD 0 // Not a valid element type
|
||||||
|
#define ELMER_ETYPE_TRIA 303
|
||||||
|
#define ELMER_ETYPE_QUAD 404
|
||||||
|
#define ELMER_ETYPE_TET 504
|
||||||
|
#define ELMER_ETYPE_PRISM 706
|
||||||
|
#define ELMER_ETYPE_PYRAM 605
|
||||||
|
#define ELMER_ETYPE_HEX 808
|
||||||
|
|
||||||
|
const wordRe* faceZoneExcludePattern;
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
Elmer(const Elmer&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const Elmer&);
|
||||||
|
|
||||||
|
label getFaceType(const label nvert, const word &zname) const;
|
||||||
|
bool writeHeader () const;
|
||||||
|
void writeNames () const;
|
||||||
|
void writeNodes () const;
|
||||||
|
void writeElements () const;
|
||||||
|
void writeBoundary () const;
|
||||||
|
void getCellTable ();
|
||||||
|
|
||||||
|
public:
|
||||||
|
Elmer(const polyMesh&, const scalar scaleFactor = 1.0, const wordRe* excludePattern = 0);
|
||||||
|
virtual ~Elmer();
|
||||||
|
virtual bool write(const fileName& dirName = fileName::null) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
Reference in a new issue