fixed: extract proper components from field vectors with more components in field classes
- a field can be now instanced for a given component of a vector field - a field can now be instanced for a given basis of a vector field - fields can now be instanced for a field vector holding extra components / bases. used for directly registering dependency fields from solution vectors in coupled simulations (RANS, Boussinesq, Chorin, ..)
This commit is contained in:
@@ -96,10 +96,10 @@ public:
|
||||
virtual void registerDependency(SIMdependency* sim, const std::string& name,
|
||||
short int nvc,
|
||||
const std::vector<ASMbase*>& patches,
|
||||
char diffBasis = 0)
|
||||
char diffBasis = 0, int component = 1)
|
||||
{
|
||||
S1.registerDependency(sim, name, nvc, patches, diffBasis);
|
||||
S2.registerDependency(sim, name, nvc, patches, diffBasis);
|
||||
S1.registerDependency(sim, name, nvc, patches, diffBasis, component);
|
||||
S2.registerDependency(sim, name, nvc, patches, diffBasis, component);
|
||||
}
|
||||
|
||||
//! \brief Registers a dependency on a field from another SIM object.
|
||||
|
||||
@@ -69,11 +69,11 @@ public:
|
||||
const ProcessAdm& getProcessAdm() const { return base.getProcessAdm(); }
|
||||
|
||||
//! \copydoc SIMdependency::registerDependency(SIMdependency*,const std::string&,short int,const PatchVec&,char)
|
||||
virtual void registerDependency(SIMdependency* sim, const std::string& name,
|
||||
short int nvc, const PatchVec& patches,
|
||||
char diffBasis = 0)
|
||||
void registerDependency(SIMdependency* sim, const std::string& name,
|
||||
short int nvc, const PatchVec& patches,
|
||||
char diffBasis = 0, int component = 1) override
|
||||
{
|
||||
base.registerDependency(sim, name, nvc, patches, diffBasis);
|
||||
base.registerDependency(sim, name, nvc, patches, diffBasis, component);
|
||||
}
|
||||
|
||||
//! \copydoc SIMdependency::registerDependency(SIMdependency*,const std::string&,short int)
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
bool saveModel(char*, int&, int&) { return savemodel_called = true; }
|
||||
bool init(const TimeStep&) { return init_called = true; }
|
||||
void registerDependency(SIMdependency*, const std::string&,
|
||||
short int, const std::vector<ASMbase*>&, bool)
|
||||
short int, const std::vector<ASMbase*>&, char, int)
|
||||
{
|
||||
registerdependency1_called = true;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
return result;
|
||||
}
|
||||
void registerDependency(SIMdependency*, const std::string&, short int,
|
||||
const std::vector<ASMbase*>&, char)
|
||||
const std::vector<ASMbase*>&, char, int)
|
||||
{
|
||||
registerdependency_called = true;
|
||||
}
|
||||
|
||||
@@ -20,19 +20,19 @@
|
||||
|
||||
|
||||
Field* Field::create (const ASMbase* pch, const RealArray& v,
|
||||
char basis, const char* name)
|
||||
char basis, char cmp, const char* name)
|
||||
{
|
||||
const ASMs2DLag* pl2 = dynamic_cast<const ASMs2DLag*>(pch);
|
||||
if (pl2) return new LagrangeField2D(pl2,v,basis,name);
|
||||
if (pl2) return new LagrangeField2D(pl2,v,basis,cmp,name);
|
||||
|
||||
const ASMs2D* ps2 = dynamic_cast<const ASMs2D*>(pch);
|
||||
if (ps2) return new SplineField2D(ps2,v,basis,name);
|
||||
if (ps2) return new SplineField2D(ps2,v,basis,cmp,name);
|
||||
|
||||
const ASMs3DLag* pl3 = dynamic_cast<const ASMs3DLag*>(pch);
|
||||
if (pl3) return new LagrangeField3D(pl3,v,basis,name);
|
||||
if (pl3) return new LagrangeField3D(pl3,v,basis,cmp,name);
|
||||
|
||||
const ASMs3D* ps3 = dynamic_cast<const ASMs3D*>(pch);
|
||||
if (ps3) return new SplineField3D(ps3,v,basis,name);
|
||||
if (ps3) return new SplineField3D(ps3,v,basis,cmp,name);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -41,9 +41,11 @@ public:
|
||||
//! \param[in] pch The spline patch on which the field is to be defined on
|
||||
//! \param[in] v Array of nodal/control point field values
|
||||
//! \param[in] basis Basis to use from patch
|
||||
//! \param[in] cmp Component to use for field
|
||||
//! \param[in] name Name of field
|
||||
static Field* create(const ASMbase* pch, const RealArray& v,
|
||||
char basis = 1, const char* name = nullptr);
|
||||
char basis = 1, char cmp = 1,
|
||||
const char* name = nullptr);
|
||||
|
||||
//! \brief Returns the name of field.
|
||||
const char* getFieldName() const { return fname.c_str(); }
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
LagrangeField2D::LagrangeField2D (const ASMs2DLag* patch,
|
||||
const RealArray& v,
|
||||
char basis,
|
||||
char basis, char,
|
||||
const char* name) : FieldBase(name)
|
||||
{
|
||||
patch->getNodalCoordinates(coord);
|
||||
|
||||
@@ -33,9 +33,10 @@ public:
|
||||
//! \param[in] patch The spline patch on which the field is to be defined
|
||||
//! \param[in] v Array of control point field values
|
||||
//! \param[in] basis Basis to use from patch
|
||||
//! \param[in] cmp Component to use
|
||||
//! \param[in] name Name of field
|
||||
LagrangeField2D(const ASMs2DLag* patch, const RealArray& v,
|
||||
char basis = 1, const char* name = nullptr);
|
||||
char basis = 1, char cmp = 1, const char* name = nullptr);
|
||||
//! \brief Empty destructor.
|
||||
virtual ~LagrangeField2D() {}
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
|
||||
LagrangeField3D::LagrangeField3D (const ASMs3DLag* patch,
|
||||
const RealArray& v,
|
||||
char basis,
|
||||
const char* name) : FieldBase(name)
|
||||
char basis, char,
|
||||
const char* name) : FieldBase(name)
|
||||
{
|
||||
patch->getNodalCoordinates(coord);
|
||||
patch->getSize(n1,n2,n3);
|
||||
|
||||
@@ -33,9 +33,10 @@ public:
|
||||
//! \param[in] patch The spline patch on which the field is to be defined
|
||||
//! \param[in] v Array of control point field values
|
||||
//! \param[in] basis Basis to use from patch
|
||||
//! \param[in] cmp Component to use
|
||||
//! \param[in] name Name of field
|
||||
LagrangeField3D(const ASMs3DLag* patch, const RealArray& v,
|
||||
char basis = 1, const char* name = nullptr);
|
||||
char basis = 1, char cmp = 1, const char* name = nullptr);
|
||||
//! \brief Empty destructor.
|
||||
virtual ~LagrangeField3D() {}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
SplineField2D::SplineField2D (const ASMs2D* patch,
|
||||
const RealArray& v, char nbasis,
|
||||
const char* name)
|
||||
char cmp, const char* name)
|
||||
: FieldBase(name), basis(patch->getBasis(nbasis)), surf(patch->getSurface())
|
||||
{
|
||||
const int n1 = basis->numCoefs_u();
|
||||
@@ -36,9 +36,19 @@ SplineField2D::SplineField2D (const ASMs2D* patch,
|
||||
nelm = (n1-p1+1)*(n2-p2+1);
|
||||
|
||||
// Ensure the values array has compatible length, pad with zeros if necessary
|
||||
size_t ofs = 0;
|
||||
for (char i = 1; i < nbasis; ++i)
|
||||
ofs += patch->getNoNodes(i)*patch->getNoFields(i);
|
||||
auto vit = v.begin()+ofs;
|
||||
values.resize(nno);
|
||||
RealArray::const_iterator end = v.size() > nno ? v.begin()+nno : v.end();
|
||||
std::copy(v.begin(),end,values.begin());
|
||||
int nf = patch->getNoFields(nbasis);
|
||||
int ndof = nf > 1 && cmp > 0 ? nf*nno : nno;
|
||||
auto end = v.size() > ofs+ndof ? vit+ndof : v.end();
|
||||
if (nf == 1 || cmp == 0)
|
||||
std::copy(vit,end,values.begin());
|
||||
else
|
||||
for (size_t i = 0; i < nno && vit != end; ++i, vit += nf)
|
||||
values[i] = *(vit+cmp-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,9 +37,10 @@ public:
|
||||
//! \param[in] patch The spline patch on which the field is to be defined
|
||||
//! \param[in] v Array of control point field values
|
||||
//! \param[in] basis Basis to use from patch
|
||||
//! \param[in] cmp Component to use from source field. Pass 0 to use vector as-is.
|
||||
//! \param[in] name Name of spline field
|
||||
SplineField2D(const ASMs2D* patch, const RealArray& v,
|
||||
char basis = 1, const char* name = nullptr);
|
||||
char basis = 1, char cmp = 1, const char* name = nullptr);
|
||||
//! \brief Empty destructor.
|
||||
virtual ~SplineField2D() {}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
SplineField3D::SplineField3D (const ASMs3D* patch,
|
||||
const RealArray& v, char nbasis,
|
||||
const char* name)
|
||||
char cmp, const char* name)
|
||||
: FieldBase(name), basis(patch->getBasis(nbasis)), vol(patch->getVolume())
|
||||
{
|
||||
const int n1 = basis->numCoefs(0);
|
||||
@@ -37,10 +37,19 @@ SplineField3D::SplineField3D (const ASMs3D* patch,
|
||||
const int p3 = basis->order(2);
|
||||
nelm = (n1-p1+1)*(n2-p2+1)*(n3-p3+1);
|
||||
|
||||
// Ensure the values array has compatible length, pad with zeros if necessary
|
||||
size_t ofs = 0;
|
||||
for (char i = 1; i < nbasis; ++i)
|
||||
ofs += patch->getNoNodes(i)*patch->getNoFields(i);
|
||||
auto vit = v.begin()+ofs;
|
||||
values.resize(nno);
|
||||
RealArray::const_iterator end = v.size() > nno ? v.begin()+nno : v.end();
|
||||
std::copy(v.begin(),end,values.begin());
|
||||
int nf = patch->getNoFields(nbasis);
|
||||
int ndof = nf > 1 && cmp > 0 ? nf*nno : nno;
|
||||
auto end = v.size() > ofs+ndof ? vit+ndof : v.end();
|
||||
if (nf == 1 || cmp == 0)
|
||||
std::copy(vit,end,values.begin());
|
||||
else
|
||||
for (size_t i = 0; i < nno && vit != end; ++i, vit += nf)
|
||||
values[i] = *(vit+cmp-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,9 +37,10 @@ public:
|
||||
//! \param[in] patch The spline patch on which the field is to be defined
|
||||
//! \param[in] v Array of control point field values
|
||||
//! \param[in] basis Basis to use from patch
|
||||
//! \param[in] cmp Component to use from source field. Pass 0 to use vector as-is.
|
||||
//! \param[in] name Name of spline field
|
||||
SplineField3D(const ASMs3D* patch, const RealArray& v,
|
||||
char basis = 1, const char* name = nullptr);
|
||||
char basis = 1, char cmp = 1, const char* name = nullptr);
|
||||
//! \brief Empty destructor.
|
||||
virtual ~SplineField3D() {}
|
||||
|
||||
|
||||
@@ -34,11 +34,23 @@ SplineFields2D::SplineFields2D (const ASMs2D* patch,
|
||||
const int p2 = basis->order_v();
|
||||
nelm = (n1-p1+1)*(n2-p2+1);
|
||||
|
||||
size_t ofs = 0;
|
||||
for (char i = 1; i < nbasis; ++i)
|
||||
ofs += patch->getNoNodes(i)*patch->getNoFields(i);
|
||||
auto vit = v.begin()+ofs;
|
||||
|
||||
// Ensure the values array has compatible length, pad with zeros if necessary
|
||||
nf = v.size()/nno;
|
||||
values.resize(nf*nno);
|
||||
RealArray::const_iterator end = v.size() > nf*nno ? v.begin()+nf*nno:v.end();
|
||||
std::copy(v.begin(),end,values.begin());
|
||||
nf = 2;
|
||||
int nfc = patch->getNoFields(nbasis);
|
||||
values.resize(nno*nf);
|
||||
int ndof = nfc*nno;
|
||||
auto end = v.size() > ofs+ndof ? vit+ndof : v.end();
|
||||
if (nfc == 2)
|
||||
std::copy(vit,end,values.begin());
|
||||
else
|
||||
for (size_t i = 0; i < nno && vit != end; ++i, vit += nfc)
|
||||
for (size_t j = 0; j < 2; ++j)
|
||||
values[2*i+j] = *(vit+j);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -36,11 +36,22 @@ SplineFields3D::SplineFields3D (const ASMs3D* patch,
|
||||
const int p3 = basis->order(2);
|
||||
nelm = (n1-p1+1)*(n2-p2+1)*(n3-p3+1);
|
||||
|
||||
// Ensure the values array has compatible length, pad with zeros if necessary
|
||||
nf = v.size()/nno;
|
||||
values.resize(nf*nno);
|
||||
RealArray::const_iterator end = v.size() > nf*nno ? v.begin()+nf*nno:v.end();
|
||||
std::copy(v.begin(),end,values.begin());
|
||||
size_t ofs = 0;
|
||||
for (char i = 1; i < nbasis; ++i)
|
||||
ofs += patch->getNoNodes(i)*patch->getNoFields(i);
|
||||
auto vit = v.begin()+ofs;
|
||||
|
||||
nf = 3;
|
||||
int nfc = patch->getNoFields(nbasis);
|
||||
values.resize(nno*nf);
|
||||
int ndof = nfc*nno;
|
||||
auto end = v.size() > ofs+ndof ? vit+ndof : v.end();
|
||||
if (nfc == 3)
|
||||
std::copy(vit,end,values.begin());
|
||||
else
|
||||
for (size_t i = 0; i < nno && vit != end; ++i, vit += nfc)
|
||||
for (size_t j = 0; j < 3; ++j)
|
||||
values[3*i+j] = *(vit+j);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
//!
|
||||
//==============================================================================
|
||||
|
||||
#include "Field.h"
|
||||
#include "Fields.h"
|
||||
#include "FiniteElement.h"
|
||||
#include "SIM2D.h"
|
||||
@@ -31,6 +32,7 @@ TEST(TestSplineFields, Value2D)
|
||||
1.0, -1.0,
|
||||
3.0, 1.0};
|
||||
Fields* fvector = Fields::create(sim.getPatch(1), vc);
|
||||
Field* fscalar = Field::create(sim.getPatch(1), vc, 1, 2);
|
||||
static std::vector<std::array<double,4>> tests_vector =
|
||||
{{0.5, 0.5, 1.25, 0.25},
|
||||
{1.0, 0.0, 1.0, 1.0},
|
||||
@@ -44,7 +46,9 @@ TEST(TestSplineFields, Value2D)
|
||||
fvector->valueFE(fe, v);
|
||||
ASSERT_FLOAT_EQ(v(1), it[2]);
|
||||
ASSERT_FLOAT_EQ(v(2), it[3]);
|
||||
ASSERT_FLOAT_EQ(fscalar->valueFE(fe), it[3]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -90,6 +94,7 @@ TEST(TestSplineFields, Value3D)
|
||||
2.0, 0.0, 0.0,
|
||||
3.0, 1.0, 1.0};
|
||||
Fields* fvector = Fields::create(sim.getPatch(1), vc);
|
||||
Field* fscalar = Field::create(sim.getPatch(1), vc, 1, 2);
|
||||
static std::vector<std::array<double,6>> tests_scalar =
|
||||
{{0.5, 0.5, 0.5, 1.5, 0.5, 0.5},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
@@ -110,6 +115,7 @@ TEST(TestSplineFields, Value3D)
|
||||
ASSERT_FLOAT_EQ(v(1), it[3]);
|
||||
ASSERT_FLOAT_EQ(v(2), it[4]);
|
||||
ASSERT_FLOAT_EQ(v(3), it[5]);
|
||||
ASSERT_FLOAT_EQ(fscalar->valueFE(fe), it[4]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,13 @@
|
||||
|
||||
void SIMdependency::registerDependency (SIMdependency* sim,
|
||||
const std::string& name, short int nvc,
|
||||
const PatchVec& patches, char diffBasis)
|
||||
const PatchVec& patches,
|
||||
char diffBasis, int component)
|
||||
{
|
||||
this->SIMdependency::registerDependency(sim,name,nvc);
|
||||
depFields.back().patches = patches;
|
||||
depFields.back().differentBasis = diffBasis;
|
||||
depFields.back().comp_use = component;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +145,8 @@ bool SIMdependency::extractPatchDependencies (IntegrandBase* problem,
|
||||
if (it->differentBasis > 0) {
|
||||
if (it->components == 1)
|
||||
problem->setNamedField(it->name,Field::create(patch,*lvec,
|
||||
it->differentBasis));
|
||||
it->differentBasis,
|
||||
it->comp_use));
|
||||
else
|
||||
problem->setNamedFields(it->name,Fields::create(patch,*lvec,
|
||||
it->differentBasis));
|
||||
|
||||
@@ -40,11 +40,12 @@ private:
|
||||
PatchVec patches; //!< Patch geometry the field is defined over
|
||||
std::string name; //!< Field name
|
||||
short int components; //!< Number of field components per node
|
||||
short int comp_use; //!< Component to use from field
|
||||
char differentBasis; //!< Toggle usage of an independent basis
|
||||
//! \brief Default constructor.
|
||||
Dependency(SIMdependency* s = nullptr, const std::string& f = "",
|
||||
short int n = 1) : sim(s), name(f), components(n),
|
||||
differentBasis(0) {}
|
||||
comp_use(1), differentBasis(0) {}
|
||||
};
|
||||
|
||||
//! \brief SIM dependency container
|
||||
@@ -71,9 +72,10 @@ public:
|
||||
//! \param[in] nvc Number of components in field
|
||||
//! \param[in] patches The geometry the field is defined over
|
||||
//! \param[in] diffBasis If non-null, use diffBasis base from patch vector
|
||||
//! \param[in] component Component to use from field
|
||||
virtual void registerDependency(SIMdependency* sim, const std::string& name,
|
||||
short int nvc, const PatchVec& patches,
|
||||
char diffBasis = 0);
|
||||
char diffBasis = 0, int component = 1);
|
||||
//! \brief Registers a dependency on a field from another SIM object.
|
||||
//! \param[in] sim The SIM object holding the field we depend on
|
||||
//! \param[in] name Name of field we depend on
|
||||
|
||||
Reference in New Issue
Block a user