extrudeMesh improvements

This commit is contained in:
mattijs
2009-06-16 16:44:35 +01:00
parent 72d8456951
commit e92d84b7a9
8 changed files with 663 additions and 83 deletions

View File

@ -23,7 +23,8 @@ License
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description Description
Extrude mesh from existing patch or from patch read from file. Extrude mesh from existing patch (flipped so has inwards pointing
normals) or from patch read from file.
Note: Merges close points so be careful. Note: Merges close points so be careful.
Type of extrusion prescribed by run-time selectable model. Type of extrusion prescribed by run-time selectable model.
@ -52,43 +53,34 @@ using namespace Foam;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
#include "setRoots.H" #include "setRootCase.H"
#include "createTimeExtruded.H" #include "createTimeExtruded.H"
if (args.optionFound("sourceCase") == args.optionFound("surface"))
{
FatalErrorIn(args.executable())
<< "Specify either -sourceCase and -sourcePatch"
" or -surface options\n"
" to specify the source of the patch to extrude"
<< exit(FatalError);
}
autoPtr<extrudedMesh> meshPtr(NULL); autoPtr<extrudedMesh> meshPtr(NULL);
autoPtr<extrudeModel> model IOdictionary dict
( (
extrudeModel::New IOobject
( (
IOdictionary "extrudeProperties",
( runTimeExtruded.constant(),
IOobject runTimeExtruded,
( IOobject::MUST_READ
"extrudeProperties",
runTimeExtruded.constant(),
runTimeExtruded,
IOobject::MUST_READ
)
)
) )
); );
if (args.optionFound("sourceCase")) autoPtr<extrudeModel> model(extrudeModel::New(dict));
const word sourceType(dict.lookup("constructFrom"));
autoPtr<faceMesh> fMesh;
if (sourceType == "patch")
{ {
fileName sourceCasePath(args.option("sourceCase")); fileName sourceCasePath(dict.lookup("sourceCase"));
fileName sourceRootDir = sourceCasePath.path(); fileName sourceRootDir = sourceCasePath.path();
fileName sourceCaseDir = sourceCasePath.name(); fileName sourceCaseDir = sourceCasePath.name();
word patchName(args.option("sourcePatch")); word patchName(dict.lookup("sourcePatch"));
Info<< "Extruding patch " << patchName Info<< "Extruding patch " << patchName
<< " on mesh " << sourceCasePath << nl << " on mesh " << sourceCasePath << nl
@ -114,75 +106,69 @@ int main(int argc, char *argv[])
} }
const polyPatch& pp = mesh.boundaryMesh()[patchID]; const polyPatch& pp = mesh.boundaryMesh()[patchID];
fMesh.reset(new faceMesh(pp.localFaces(), pp.localPoints()));
fMesh().flip();
{ {
fileName surfName(patchName + ".sMesh"); fileName surfName(patchName + ".sMesh");
Info<< "Writing patch as surfaceMesh to " << surfName << nl << endl; Info<< "Writing (flipped) patch as surfaceMesh to "
<< surfName << nl << endl;
faceMesh fMesh(pp.localFaces(), pp.localPoints());
OFstream os(surfName); OFstream os(surfName);
os << fMesh << nl; os << fMesh() << nl;
} }
meshPtr.reset
(
new extrudedMesh
(
IOobject
(
extrudedMesh::defaultRegion,
runTimeExtruded.constant(),
runTimeExtruded
),
pp,
model()
)
);
} }
else else if (sourceType == "surface")
{ {
// Read from surface // Read from surface
fileName surfName(args.option("surface")); fileName surfName(dict.lookup("surface"));
Info<< "Extruding surfaceMesh read from file " << surfName << nl Info<< "Extruding surfaceMesh read from file " << surfName << nl
<< endl; << endl;
IFstream is(surfName); IFstream is(surfName);
faceMesh fMesh(is); fMesh.reset(new faceMesh(is));
Info<< "Read patch from file " << surfName << ':' << nl Info<< "Read patch from file " << surfName << nl
<< " points : " << fMesh.points().size() << nl << endl;
<< " faces : " << fMesh.size() << nl }
else
{
FatalErrorIn(args.executable())
<< "Illegal 'constructFrom' specification. Should either be "
<< "patch or surface." << exit(FatalError);
}
Info<< "Extruding patch with :" << nl
<< " points : " << fMesh().points().size() << nl
<< " faces : " << fMesh().size() << nl
<< " normals[0] : " << fMesh().faceNormals()[0]
<< nl
<< endl; << endl;
meshPtr.reset extrudedMesh mesh
(
IOobject
( (
new extrudedMesh extrudedMesh::defaultRegion,
( runTimeExtruded.constant(),
IOobject runTimeExtruded
( ),
extrudedMesh::defaultRegion, fMesh(),
runTimeExtruded.constant(), model()
runTimeExtruded );
),
fMesh,
model()
)
);
}
extrudedMesh& mesh = meshPtr();
const boundBox& bb = mesh.globalData().bb(); const boundBox& bb = mesh.globalData().bb();
const vector span = bb.span(); const vector span = bb.span();
const scalar mergeDim = 1E-4 * bb.minDim(); const scalar mergeDim = 1E-4 * bb.minDim();
Info<< "Mesh bounding box:" << bb << nl Info<< "Mesh bounding box : " << bb << nl
<< " with span:" << span << nl << " with span : " << span << nl
<< "Merge distance :" << mergeDim << nl << "Merge distance : " << mergeDim << nl
<< endl; << endl;
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
@ -250,7 +236,8 @@ int main(int argc, char *argv[])
// Merging front and back patch faces // Merging front and back patch faces
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (args.optionFound("mergeFaces")) Switch mergeFaces(dict.lookup("mergeFaces"));
if (mergeFaces)
{ {
Info<< "Assuming full 360 degree axisymmetric case;" Info<< "Assuming full 360 degree axisymmetric case;"
<< " stitching faces on patches " << " stitching faces on patches "

View File

@ -88,7 +88,8 @@ point wedge::operator()
} }
else else
{ {
sliceAngle = angle_*(layer + 1)/nLayers_; //sliceAngle = angle_*(layer + 1)/nLayers_;
sliceAngle = angle_*layer/nLayers_;
} }
// Find projection onto axis (or rather decompose surfacePoint // Find projection onto axis (or rather decompose surfacePoint

View File

@ -14,23 +14,41 @@ FoamFile
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
extrudeModel wedge; // Where to get surface from: either from surface ('surface') or
// from (flipped) patch of existing case ('patch')
constructFrom patch; //surface;
// If construct from (flipped) patch
sourceCase "../cavity";
sourcePatch movingWall;
// If construct from surface
surface "movingWall.sMesh";
// Do front and back need to be merged?
mergeFaces false;
//- Linear extrusion in point-normal direction
//extrudeModel linearNormal; //extrudeModel linearNormal;
//- Wedge extrusion. If nLayers is 1 assumes symmetry around plane.
extrudeModel wedge;
//- Extrudes into sphere around (0 0 0)
//extrudeModel linearRadial; //extrudeModel linearRadial;
//extrudeModel sigmaRadial; //extrudeModel sigmaRadial;
nLayers 1; nLayers 6;
wedgeCoeffs wedgeCoeffs
{ {
axisPt (0 0 0); axisPt (0 0.1 0);
axis (0 -1 0); axis (1 0 0);
angle 2.0; angle 90.0; // For nLayers=1 assume symmetry so angle/2 on each side
} }
linearNormalCoeffs linearNormalCoeffs
{ {
thickness 0.1; thickness 0.05;
} }
linearRadialCoeffs linearRadialCoeffs
@ -47,3 +65,4 @@ sigmaRadialCoeffs
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -117,7 +117,7 @@ Foam::Xfer<Foam::faceList> Foam::extrudedMesh::extrudedFaces
quad[2] = surfaceEdges[i][0] + nextLayerOffset; quad[2] = surfaceEdges[i][0] + nextLayerOffset;
quad[3] = surfaceEdges[i][1] + nextLayerOffset; quad[3] = surfaceEdges[i][1] + nextLayerOffset;
eFaces[facei++] = face(quad); eFaces[facei++] = face(quad).reverseFace();
} }
// Faces between layer and layer+1 // Faces between layer and layer+1
@ -130,7 +130,7 @@ Foam::Xfer<Foam::faceList> Foam::extrudedMesh::extrudedFaces
( (
surfaceFaces[i].reverseFace() surfaceFaces[i].reverseFace()
+ nextLayerOffset + nextLayerOffset
); ).reverseFace();
} }
} }
} }
@ -152,7 +152,7 @@ Foam::Xfer<Foam::faceList> Foam::extrudedMesh::extrudedFaces
label ownerFace = extrudePatch.edgeFaces()[i][0]; label ownerFace = extrudePatch.edgeFaces()[i][0];
if (!sameOrder(surfaceFaces[ownerFace], e)) if (sameOrder(surfaceFaces[ownerFace], e))
{ {
reverse(quad); reverse(quad);
} }
@ -164,7 +164,7 @@ Foam::Xfer<Foam::faceList> Foam::extrudedMesh::extrudedFaces
// Top faces // Top faces
forAll(surfaceFaces, i) forAll(surfaceFaces, i)
{ {
eFaces[facei++] = face(surfaceFaces[i]); eFaces[facei++] = face(surfaceFaces[i]).reverseFace();
} }
// Bottom faces // Bottom faces
@ -175,7 +175,7 @@ Foam::Xfer<Foam::faceList> Foam::extrudedMesh::extrudedFaces
( (
surfaceFaces[i].reverseFace() surfaceFaces[i].reverseFace()
+ nLayers*surfacePoints.size() + nLayers*surfacePoints.size()
); ).reverseFace();
} }
// return points for transferring // return points for transferring

View File

@ -78,6 +78,18 @@ public:
{} {}
// Member Functions
void flip()
{
forAll(*this, i)
{
face& f = operator[](i);
f = f.reverseFace();
}
clearOut();
}
// IOstream Operators // IOstream Operators
friend Ostream& operator<<(Ostream& os, const faceMesh& fm) friend Ostream& operator<<(Ostream& os, const faceMesh& fm)
@ -85,7 +97,8 @@ public:
return os return os
<< fm.points() << fm.points()
<< token::NL << token::NL
<< static_cast<PrimitivePatch<face, Foam::List, pointField> >(fm); << static_cast<PrimitivePatch<face, Foam::List, pointField> >
(fm);
} }
}; };

View File

@ -0,0 +1,112 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "DynamicField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * //
template<class Type>
const char* const DynamicField<Type>::typeName("DynamicField");
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
DynamicField<Type>::DynamicField(Istream& is)
:
Field<Type>(is),
capacity_(Field<Type>::size())
{}
template<class Type>
tmp<DynamicField<Type> > DynamicField<Type>::clone() const
{
return tmp<DynamicField<Type> >(new DynamicField<Type>(*this));
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void DynamicField<Type>::setSize(const label nElem)
{
// allocate more capacity?
if (nElem > capacity_)
{
capacity_ = max(nElem, label(1 + capacity_*2));
Field<Type>::setSize(capacity_);
}
// adjust addressed size
Field<Type>::size(nElem);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * IOstream Operator * * * * * * * * * * * * * //
template<class Type>
Ostream& operator<<(Ostream& os, const DynamicField<Type>& f)
{
os << static_cast<const Field<Type>&>(f);
return os;
}
template<class Type>
Ostream& operator<<(Ostream& os, const tmp<DynamicField<Type> >& tf)
{
os << tf();
tf.clear();
return os;
}
template<class Type>
Istream& operator>>(Istream& is, DynamicField<Type>& lst)
{
is >> static_cast<Field<Type>&>(lst);
lst.capacity_ = lst.Field<Type>::size();
return is;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,227 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::DynamicField
Description
Dynamically sized Field. WIP.
SourceFiles
DynamicField.C
\*---------------------------------------------------------------------------*/
#ifndef DynamicField_H
#define DynamicField_H
#include "Field.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of friend functions and operators
template<class Type>
class DynamicField;
template<class Type>
Ostream& operator<<(Ostream&, const DynamicField<Type>&);
template<class Type>
Ostream& operator<<(Ostream&, const tmp<DynamicField<Type> >&);
template<class Type>
Istream& operator>>(Istream&, DynamicField<Type>&);
/*---------------------------------------------------------------------------*\
Class DynamicField Declaration
\*---------------------------------------------------------------------------*/
#include "CintDefs.H"
template<class Type>
class DynamicField
:
public Field<Type> //private Field<Type>
{
// Private data
//- The capacity (allocated size) of the underlying field.
label capacity_;
//- Construct given size and initial value
DynamicField(const label, const Type&);
//- Construct as copy of tmp<DynamicField>
# ifdef ConstructFromTmp
DynamicField(const tmp<DynamicField<Type> >&);
# endif
//- Construct from a dictionary entry
DynamicField(const word&, const dictionary&, const label);
public:
// Static data members
static const char* const typeName;
// Static Member Functions
//- Return a null field
inline static const DynamicField<Type>& null()
{
return *reinterpret_cast< DynamicField<Type>* >(0);
}
// Constructors
//- Construct null
// Used for temporary fields which are initialised after construction
DynamicField();
//- Construct given size
// Used for temporary fields which are initialised after construction
explicit inline DynamicField(const label);
//- Construct as copy of a UList\<Type\>
explicit inline DynamicField(const UList<Type>&);
//- Construct by transferring the List contents
explicit inline DynamicField(const Xfer<List<Type> >&);
//- Construct by 1 to 1 mapping from the given field
inline DynamicField
(
const UList<Type>& mapF,
const labelList& mapAddressing
);
//- Construct by interpolative mapping from the given field
inline DynamicField
(
const UList<Type>& mapF,
const labelListList& mapAddressing,
const scalarListList& weights
);
//- Construct by mapping from the given field
inline DynamicField
(
const UList<Type>& mapF,
const FieldMapper& map
);
//- Construct as copy
inline DynamicField(const DynamicField<Type>&);
//- Construct as copy or re-use as specified.
inline DynamicField(DynamicField<Type>&, bool reUse);
//- Construct by transferring the Field contents
inline DynamicField(const Xfer<DynamicField<Type> >&);
//- Construct from Istream
inline DynamicField(Istream&);
//- Clone
tmp<DynamicField<Type> > clone() const;
// Member Functions
//- Size of the underlying storage.
inline label capacity() const;
//- Append an element at the end of the list
inline void append(const Type&);
//- Alter the addressed list size.
// New space will be allocated if required.
// Use this to resize the list prior to using the operator[] for
// setting values (as per List usage).
void setSize(const label nElem);
// Member operators
inline void operator=(const DynamicField<Type>&);
inline void operator=(const UList<Type>&);
inline void operator=(const tmp<DynamicField<Type> >&);
//- Return element of Field.
inline Type& operator[](const label i);
//- Return element of constant Field.
inline const Type& operator[](const label) const;
// IOstream operators
friend Ostream& operator<<
#ifndef __CINT__
<Type>
#endif
(Ostream&, const DynamicField<Type>&);
friend Ostream& operator<<
#ifndef __CINT__
<Type>
#endif
(Ostream&, const tmp<DynamicField<Type> >&);
friend Istream& operator>>
#ifndef __CINT__
<Type>
#endif
(Istream&, DynamicField<Type>&);
};
#include "CintUndefs.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "DynamicFieldI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "DynamicField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,221 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "DynamicField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
DynamicField<Type>::DynamicField()
:
Field<Type>(),
capacity_(0)
{}
template<class Type>
DynamicField<Type>::DynamicField(const label size)
:
Field<Type>(size),
capacity_(Field<Type>::size())
{
Field<Type>::size(0);
}
template<class Type>
inline Foam::DynamicField<Type>::DynamicField
(
const UList<Type>& lst
)
:
Field<Type>(lst),
capacity_(Field<Type>::size())
{}
template<class Type>
inline Foam::DynamicField<Type>::DynamicField
(
const Xfer<List<Type> >& lst
)
:
Field<Type>(lst),
capacity_(Field<Type>::size())
{}
template<class Type>
DynamicField<Type>::DynamicField
(
const UList<Type>& mapF,
const labelList& mapAddressing
)
:
Field<Type>(mapF, mapAddressing),
capacity_(Field<Type>::size())
{}
template<class Type>
DynamicField<Type>::DynamicField
(
const UList<Type>& mapF,
const labelListList& mapAddressing,
const scalarListList& weights
)
:
Field<Type>(mapF, mapAddressing, weights),
capacity_(Field<Type>::size())
{}
//- Construct by mapping from the given field
template<class Type>
DynamicField<Type>::DynamicField
(
const UList<Type>& mapF,
const FieldMapper& map
)
:
DynamicField<Type>(mapF, map),
capacity_(Field<Type>::size())
{}
template<class Type>
DynamicField<Type>::DynamicField(const DynamicField<Type>& f)
:
Field<Type>(f),
capacity_(Field<Type>::size())
{}
template<class Type>
DynamicField<Type>::DynamicField(DynamicField<Type>& f, bool reUse)
:
Field<Type>(f, reUse),
capacity_(Field<Type>::size())
{}
template<class Type>
DynamicField<Type>::DynamicField(const Xfer<DynamicField<Type> >& f)
:
Field<Type>(f),
capacity_(Field<Type>::size())
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::label DynamicField<Type>::capacity() const
{
return capacity_;
}
template<class Type>
void DynamicField<Type>::append(const Type& t)
{
label elemI = Field<Type>::size();
setSize(elemI + 1);
this->operator[](elemI) = t;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type>
void DynamicField<Type>::operator=(const DynamicField<Type>& rhs)
{
if (this == &rhs)
{
FatalErrorIn("DynamicField<Type>::operator=(const DynamicField<Type>&)")
<< "attempted assignment to self"
<< abort(FatalError);
}
Field<Type>::operator=(rhs);
capacity_ = Field<Type>::size();
}
template<class Type>
void DynamicField<Type>::operator=(const UList<Type>& rhs)
{
Field<Type>::operator=(rhs);
capacity_ = Field<Type>::size();
}
template<class Type>
void DynamicField<Type>::operator=(const tmp<DynamicField>& rhs)
{
if (this == &(rhs()))
{
FatalErrorIn("DynamicField<Type>::operator=(const tmp<DynamicField>&)")
<< "attempted assignment to self"
<< abort(FatalError);
}
// This is dodgy stuff, don't try it at home.
DynamicField* fieldPtr = rhs.ptr();
List<Type>::transfer(*fieldPtr);
delete fieldPtr;
capacity_ = Field<Type>::size();
}
template<class Type>
Type& DynamicField<Type>::operator[](const label i)
{
return Field<Type>::operator[](i);
}
template<class Type>
const Type& DynamicField<Type>::operator[](const label i) const
{
return Field<Type>::operator[](i);
}
// * * * * * * * * * * * * * * * IOstream Operator * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //