Changed: Removed reimplementation of identical createGeometry methods in the

ModelGenerator sub-classes. Instead, the createG2 method is made virtual.
Also let the createTopology method have an empty default implementation such
that it does not need to be overridden in the single-patch default generators.

And please don't use the override keyword (at least not in the IFEM kernel)
which is not supported i gcc 4.6. I still use that compiler for debugging.
This commit is contained in:
Knut Morten Okstad 2016-10-03 05:45:31 +02:00
parent ff557f5f86
commit 49bcd4f618
6 changed files with 131 additions and 204 deletions

View File

@ -108,16 +108,6 @@ std::string MultiPatchModelGenerator2D::createG2 (int nsd) const
}
SIMdependency::PatchVec
MultiPatchModelGenerator2D::createGeometry (const SIMbase& sim) const
{
std::istringstream rect(this->createG2(sim.getNoSpaceDim()));
SIMdependency::PatchVec result;
sim.readPatches(rect,result,"\t");
return result;
}
bool MultiPatchModelGenerator2D::createTopology (SIMbase& sim) const
{
auto&& IJ = [this](int i, int j) { return 1 + j*nx + i; };
@ -133,22 +123,24 @@ bool MultiPatchModelGenerator2D::createTopology (SIMbase& sim) const
return false;
if (periodic_x)
for (int i = 0; i < ny; ++i)
for (int j = 0; j < ny; ++j)
if (nx > 1) {
if (!sim.addConnection(IJ(0, i), IJ(nx-1, i), 1, 2, 0, 0, false))
if (!sim.addConnection(IJ(0,j), IJ(nx-1,j), 1, 2, 0, 0, false))
return false;
} else {
IFEM::cout <<"\tPeriodic I-direction P"<< IJ(0,i) << std::endl;
ASMs2D* pch = dynamic_cast<ASMs2D*>(sim.getPatch(IJ(0,i), true));
}
else {
IFEM::cout <<"\tPeriodic I-direction P"<< IJ(0,j) << std::endl;
ASMs2D* pch = dynamic_cast<ASMs2D*>(sim.getPatch(IJ(0,j), true));
if (pch)
pch->closeEdges(1);
}
if (periodic_y)
for (int i = 0; i < nx; ++i)
if (ny > 1)
if (ny > 1) {
if (!sim.addConnection(IJ(i,0), IJ(i,ny-1), 3, 4, 0, 0, false))
return false;
}
else {
IFEM::cout <<"\tPeriodic J-direction P"<< IJ(i,0)<< std::endl;
ASMs2D* pch = dynamic_cast<ASMs2D*>(sim.getPatch(IJ(i,0), true));
@ -163,10 +155,10 @@ bool MultiPatchModelGenerator2D::createTopology (SIMbase& sim) const
TopologySet
MultiPatchModelGenerator2D::createTopologySets (const SIMbase& sim) const
{
if (!sets)
return TopologySet();
TopologySet result;
if (!this->topologySets())
return result;
TopEntity& e1 = result["Edge1"];
TopEntity& e2 = result["Edge2"];
TopEntity& e3 = result["Edge3"];
@ -289,8 +281,8 @@ std::string MultiPatchModelGenerator3D::createG2 (int) const
for (size_t i = 0; i < nodes.size(); i += 3)
{
std::stringstream str;
std::array<int,3> N {x,y,z};
std::array<double,3> L {Lx,Ly,Lz};
std::array<int,3> N = {{x,y,z}};
std::array<double,3> L = {{Lx,Ly,Lz}};
for (size_t j = 0; j < 3; j++)
str << (j==0?"":" ") << X0[j]+N[j]*L[j]+nodes[i+j]*L[j];
g2.append(str.str());
@ -304,16 +296,6 @@ std::string MultiPatchModelGenerator3D::createG2 (int) const
}
SIMdependency::PatchVec
MultiPatchModelGenerator3D::createGeometry (const SIMbase& sim) const
{
std::istringstream hex(this->createG2(sim.getNoSpaceDim()));
SIMdependency::PatchVec result;
sim.readPatches(hex,result,"\t");
return result;
}
bool MultiPatchModelGenerator3D::createTopology (SIMbase& sim) const
{
auto&& IJK = [this](int i, int j, int k) { return 1 + (k*ny+j)*nx + i; };
@ -382,8 +364,9 @@ bool MultiPatchModelGenerator3D::createTopology (SIMbase& sim) const
TopologySet
MultiPatchModelGenerator3D::createTopologySets (const SIMbase& sim) const
{
if (!sets)
return TopologySet();
TopologySet result;
if (!this->topologySets())
return result;
// 0-based -> 1-based IJK
auto&& IJK = [this](int i, int j, int k) { return 1 + (k*ny+j)*nx + i; };
@ -405,8 +388,6 @@ MultiPatchModelGenerator3D::createTopologySets (const SIMbase& sim) const
// start/end K
auto&& IJK2K = [this,IJK](int i, int j, int k) { return IJK(i, j, k*(nz-1)); };
TopologySet result;
// insertion lambda
auto&& insertion = [&sim,&result](TopItem top,
const std::string& glob,

View File

@ -11,11 +11,10 @@
//!
//==============================================================================
#ifndef _MULTIPATCH_MODEL_GENERATOR_H
#define _MULTIPATCH_MODEL_GENERATOR_H
#ifndef _MULTI_PATCH_MODEL_GENERATOR_H
#define _MULTI_PATCH_MODEL_GENERATOR_H
#include "ModelGenerator.h"
#include <string>
/*!
@ -26,29 +25,22 @@
class MultiPatchModelGenerator2D : public ModelGenerator
{
public:
//! \brief Constructor initializes common members.
//! \brief The constructor initializes common members.
//!\ param[in] elem XML element to parse
MultiPatchModelGenerator2D(const TiXmlElement* elem);
//! \brief Empty destructor.
virtual ~MultiPatchModelGenerator2D() {}
//! \brief Creates a geometry.
//! \param[in] sim SIM with patch read function to use
SIMdependency::PatchVec createGeometry(const SIMbase& sim) const override;
//! \brief Creates topology for geometry.
//! \param sim Simulator to apply topology to
bool createTopology(SIMbase& sim) const override;
virtual bool createTopology(SIMbase& sim) const;
//! \brief Creates topology sets for geometry.
TopologySet createTopologySets(const SIMbase& sim) const override;
virtual TopologySet createTopologySets(const SIMbase& sim) const;
protected:
//! \brief Generates the G2 description of the geometry.
//! \param nsd Number of spatial dimension
std::string createG2 (int nsd = 2) const;
virtual std::string createG2(int nsd) const;
private:
int nx; //!< Number of blocks in x
int ny; //!< Number of blocks in y
int periodic_x; //!< If non-zero, make model periodic in x for given bases
@ -64,31 +56,22 @@ protected:
class MultiPatchModelGenerator3D : public ModelGenerator
{
public:
//! \brief Constructor initializes common members.
//! \brief The constructor initializes common members.
//! \param[in] elem XML element to parse
MultiPatchModelGenerator3D(const TiXmlElement* geo);
//! \brief Empty destructor.
virtual ~MultiPatchModelGenerator3D() {}
//! \brief Creates a geometry.
//! \param[in] sim SIM with patch read function to use
SIMdependency::PatchVec createGeometry(const SIMbase& sim) const override;
//! \brief Creates topology for geometry.
//! \param[in] geo XML element containing geometry defintion
//! \param sim Simulator to apply topology to
bool createTopology(SIMbase& sim) const override;
virtual bool createTopology(SIMbase& sim) const;
//! \brief Creates topology sets for geometry.
//! \param[in] SIM Simulator with patch ownerships
virtual TopologySet createTopologySets(const SIMbase& sim) const;
protected:
//! \brief Generates the G2 description of the geometry.
//! \param nsd Number of spatial dimension
std::string createG2 (int nsd = 3) const;
virtual std::string createG2(int) const;
private:
int nx; //!< Number of blocks in x
int ny; //!< Number of blocks in y
int nz; //!< Number of blocks in z

View File

@ -37,9 +37,9 @@ public:
virtual ~SIMMultiPatchModelGen() {}
protected:
//! \brief Instantiate a generator for the finite element model.
//! \brief Instantiates a generator for the finite element model.
//! \param[in] geo XML element containing geometry defintion
ModelGenerator* createModelGenerator(const TiXmlElement* geo) const override;
virtual ModelGenerator* createModelGenerator(const TiXmlElement* geo) const;
};
#endif

View File

@ -12,8 +12,8 @@
//==============================================================================
#include "ModelGenerator.h"
#include "IFEM.h"
#include "SIMbase.h"
#include "IFEM.h"
#include "Utilities.h"
#include "Vec3.h"
#include "Vec3Oper.h"
@ -21,10 +21,19 @@
#include <array>
ModelGenerator::ModelGenerator (const TiXmlElement* elem) :
sets(false), geo(elem)
bool ModelGenerator::topologySets () const
{
utl::getAttribute(geo, "sets", sets);
bool sets = false;
return utl::getAttribute(geo,"sets",sets) && sets;
}
SIMdependency::PatchVec ModelGenerator::createGeometry (const SIMbase& m) const
{
std::istringstream g2(this->createG2(m.getNoSpaceDim()));
SIMdependency::PatchVec result;
m.readPatches(g2,result,"\t");
return result;
}
@ -78,27 +87,18 @@ std::string DefaultGeometry1D::createG2 (int nsd) const
}
SIMdependency::PatchVec DefaultGeometry1D::createGeometry (const SIMbase& sim) const
{
std::istringstream unitLine(this->createG2(sim.getNoSpaceDim()));
SIMdependency::PatchVec result;
sim.readPatches(unitLine,result,"\t");
return result;
}
TopologySet DefaultGeometry1D::createTopologySets (const SIMbase&) const
{
if (!sets)
return TopologySet();
TopologySet result;
if (this->topologySets())
{
result["Vertex1"].insert(TopItem(1,1,0));
result["Vertex2"].insert(TopItem(1,2,0));
result["Boundary"].insert(TopItem(1,1,0));
result["Boundary"].insert(TopItem(1,2,0));
result["Corners"].insert(TopItem(1,1,0));
result["Corners"].insert(TopItem(1,2,0));
}
return result;
}
@ -160,29 +160,21 @@ std::string DefaultGeometry2D::createG2 (int nsd) const
}
SIMdependency::PatchVec DefaultGeometry2D::createGeometry (const SIMbase& sim) const
{
std::istringstream unitSquare(this->createG2(sim.getNoSpaceDim()));
SIMdependency::PatchVec result;
sim.readPatches(unitSquare,result,"\t");
return result;
}
TopologySet DefaultGeometry2D::createTopologySets (const SIMbase&) const
{
if (!sets)
return TopologySet();
TopologySet result;
if (this->topologySets())
{
std::string vert = "Vertex1";
std::string edge = "Edge1";
for (size_t i = 1; i <= 4; ++i, ++vert.back(), ++edge.back()) {
for (size_t i = 1; i <= 4; ++i, ++vert.back(), ++edge.back())
{
result[vert].insert(TopItem(1,i,0));
result[edge].insert(TopItem(1,i,1));
result["Corners"].insert(TopItem(1,i,0));
result["Boundary"].insert(TopItem(1,i,1));
}
}
return result;
}
@ -261,24 +253,14 @@ std::string DefaultGeometry3D::createG2 (int) const
}
SIMdependency::PatchVec DefaultGeometry3D::createGeometry (const SIMbase& sim) const
{
std::istringstream unitCube(this->createG2());
SIMdependency::PatchVec result;
sim.readPatches(unitCube,result,"\t");
return result;
}
TopologySet DefaultGeometry3D::createTopologySets (const SIMbase&) const
{
if (!sets)
return TopologySet();
TopologySet result;
if (this->topologySets())
{
std::string face = "Face1";
for (size_t i = 1; i <= 6; ++i, ++face.back()) {
for (size_t i = 1; i <= 6; ++i, ++face.back())
{
result[face].insert(TopItem(1,i,2));
result["Boundary"].insert(TopItem(1,i,2));
}
@ -296,6 +278,7 @@ TopologySet DefaultGeometry3D::createTopologySets (const SIMbase&) const
result[vert].insert(TopItem(1,i,0));
result["Corners"].insert(TopItem(1,i,0));
}
}
return result;
}

View File

@ -21,6 +21,7 @@
class SIMbase;
class TiXmlElement;
/*!
\brief Base class for model generators for FEM simulators.
*/
@ -28,120 +29,104 @@ class TiXmlElement;
class ModelGenerator
{
public:
//! \brief Constructor initializes common members
//! \brief The constructor initializes the common members.
//!\ param elem XML element to parse
ModelGenerator(const TiXmlElement* elem);
ModelGenerator(const TiXmlElement* elem) : geo(elem) {}
//! \brief Empty destructor.
virtual ~ModelGenerator() {}
//! \brief Creates a geometry.
//! \param[in] sim SIM with patch read function to use
virtual SIMdependency::PatchVec createGeometry(const SIMbase& sim) const = 0;
//! \param[in] m Simulator object with patch read function to use
virtual SIMdependency::PatchVec createGeometry(const SIMbase& m) const;
//! \brief Creates topology for geometry.
//! \param[in] geo XML element containing geometry defintion
//! \param sim Simulator to apply topology to
virtual bool createTopology(SIMbase& sim) const = 0;
//! \brief Creates topology for multi-patch geometries.
virtual bool createTopology(SIMbase&) const { return true; }
//! \brief Creates topology sets for geometry.
//! \param[in] sim Simulator with patch ownerships
//! \param[in] sim Simulator object with patch ownerships
virtual TopologySet createTopologySets(const SIMbase& sim) const = 0;
protected:
bool sets; //!< Whether to generate topologysets or not
//! \brief Generates the G2 description of the geometry.
//! \param nsd Number of spatial dimension
virtual std::string createG2(int nsd) const { return ""; }
//! \brief Returns \e true if topology sets is to be generated.
bool topologySets() const;
protected:
const TiXmlElement* geo; //!< Pointer to xml element describing geometry
};
/*!
\brief Default model generator for 1D FEM simulators.
\details Generates a line.
\details Generates a line domain.
*/
class DefaultGeometry1D : public ModelGenerator {
class DefaultGeometry1D : public ModelGenerator
{
public:
//! \brief The constructor forwards to the base class.
//! \param[in] geo XML element containing geometry defintion
DefaultGeometry1D(const TiXmlElement* geo) : ModelGenerator(geo) {}
//! \brief Creates a 1D single-patch geometry.
//! \param[in] sim SIM with patch read function to use
SIMdependency::PatchVec createGeometry(const SIMbase& sim) const override;
//! \brief Creates the topology
//! \details No topology information for single patch models
bool createTopology(SIMbase&) const override
{ return true; }
//! \brief Empty destructor.
virtual ~DefaultGeometry1D() {}
//! \brief Creates topology sets for geometry.
TopologySet createTopologySets(const SIMbase&) const override;
virtual TopologySet createTopologySets(const SIMbase&) const;
protected:
//! \brief Generates the G2 description of the geometry.
//! \param nsd Number of spatial dimension
std::string createG2 (int nsd = 2) const;
virtual std::string createG2(int nsd) const;
};
/*!
\brief Default model generator for 2D FEM simulators.
\details Generates a rectangle.
\details Generates a quadrilateral domain.
*/
class DefaultGeometry2D : public ModelGenerator {
class DefaultGeometry2D : public ModelGenerator
{
public:
//! \brief The constructor forwards to the base class.
//! \param[in] geo XML element containing geometry defintion
DefaultGeometry2D(const TiXmlElement* geo) : ModelGenerator(geo) {}
//! \brief Creates a 2D rectangular single-patch geometry.
//! \param[in] sim SIM with patch read function to use
SIMdependency::PatchVec createGeometry(const SIMbase& sim) const override;
//! \brief Creates the topology
//! \param sim Simulator to apply topology to
//! \details No topology information for single patch models
bool createTopology(SIMbase&) const override
{ return true; }
//! \brief Empty destructor.
virtual ~DefaultGeometry2D() {}
//! \brief Creates topology sets for geometry.
TopologySet createTopologySets(const SIMbase&) const override;
virtual TopologySet createTopologySets(const SIMbase&) const;
protected:
//! \brief Generates the G2 description of the geometry.
//! \param nsd Number of spatial dimension
std::string createG2 (int nsd = 3) const;
virtual std::string createG2(int nsd) const;
};
/*!
\brief Default model generator for 3D FEM simulators.
\details Generates a hexahedra.
\details Generates a hexahedral domain.
*/
class DefaultGeometry3D : public ModelGenerator {
class DefaultGeometry3D : public ModelGenerator
{
public:
//! \brief The constructor forwards to the base class.
//! \param[in] geo XML element containing geometry defintion
DefaultGeometry3D(const TiXmlElement* geo) : ModelGenerator(geo) {}
//! \brief Creates a 3D hexahedral single-patch geometry.
//! \param[in] sim Simulator with patch read function to use
SIMdependency::PatchVec createGeometry(const SIMbase& sim) const override;
//! \brief Creates the topology
//! \param sim Simulator to apply topology to
//! \details No topology information for single patch models
bool createTopology(SIMbase&) const override
{ return true; }
//! \brief Empty destructor.
virtual ~DefaultGeometry3D() {}
//! \brief Creates topology sets for geometry.
TopologySet createTopologySets(const SIMbase&) const override;
virtual TopologySet createTopologySets(const SIMbase&) const;
protected:
//! \brief Generates the G2 description of the geometry.
std::string createG2 (int = 3) const;
virtual std::string createG2(int) const;
};
#endif

View File

@ -10,10 +10,10 @@
//!
//==============================================================================
#include "IntegrandBase.h"
#include "IFEM.h"
#include "SIM2D.h"
#include "SIM3D.h"
#include "IntegrandBase.h"
#include "gtest/gtest.h"
#include "tinyxml.h"
@ -31,26 +31,21 @@ public:
{
return this->addMADOF(basis, nndof);
}
private:
class TestProjectIntegrand : public IntegrandBase {
public:
TestProjectIntegrand(int dim) : IntegrandBase(dim) {}
//! \brief Evaluates the secondary solution at a result point.
//! \param[out] s The solution field values at current point
//! \param[in] fe Finite element data at current point
//! \param[in] X Cartesian coordinates of current point
//! \param[in] MNPC Nodal point correspondance for the basis function values
bool evalSol(Vector& s, const FiniteElement& fe, const Vec3& X,
const std::vector<int>& MNPC) const override
virtual bool evalSol(Vector& s, const FiniteElement&, const Vec3& X,
const std::vector<int>&) const
{
s.resize(1);
s(1) = X[0] + X[1] + X[2];
return true;
}
size_t getNoFields(int = 2) const override { return 1; }
virtual size_t getNoFields(int) const { return 1; }
};
};