added: extend getBasis method

allow obtaining additional bases, not just the FE bases
in particular geometry basis and projection basis.
add an enumeration to make things readable
This commit is contained in:
Arne Morten Kvarving 2023-08-23 09:52:51 +02:00
parent 4abf4c64a7
commit 957af79433
21 changed files with 186 additions and 46 deletions

View File

@ -46,6 +46,15 @@ namespace ASM //! Assembly scope
FULL_CACHE //!< Cache basis function values up front FULL_CACHE //!< Cache basis function values up front
}; };
//! \brief Enumeration of different basis types.
//! \details Entries should have non-positive values
enum BasisType {
GEOMETRY_BASIS = 0, //!< Geometry basis
PROJECTION_BASIS = -1, //!< Projection basis
PROJECTION_BASIS_2 = -2, //!< Second projection basis
REFINEMENT_BASIS = -3, //!< Refinement basis
INTEGRATION_BASIS = -4, //!< Integration basis
};
} }
#endif #endif

View File

@ -38,6 +38,7 @@
#include "MPC.h" #include "MPC.h"
#include "IFEM.h" #include "IFEM.h"
#include <array> #include <array>
#include <utility>
ASMs2D::ASMs2D (unsigned char n_s, unsigned char n_f) ASMs2D::ASMs2D (unsigned char n_s, unsigned char n_f)
@ -100,6 +101,29 @@ Go::SplineCurve* ASMs2D::getBoundary (int dir, int)
} }
const Go::SplineSurface* ASMs2D::getBasis (int basis) const
{
switch (basis) {
case ASM::GEOMETRY_BASIS:
return static_cast<const Go::SplineSurface*>(geomB);
case ASM::PROJECTION_BASIS:
return static_cast<const Go::SplineSurface*>(projB);
case ASM::PROJECTION_BASIS_2:
return static_cast<const Go::SplineSurface*>(projB2);
case ASM::REFINEMENT_BASIS:
return nullptr;
default:
return surf;
}
}
Go::SplineSurface* ASMs2D::getBasis (int basis)
{
return const_cast<Go::SplineSurface*>(std::as_const(*this).getBasis(basis));
}
void ASMs2D::copyParameterDomain (const ASMbase* other) void ASMs2D::copyParameterDomain (const ASMbase* other)
{ {
const ASMs2D* o = dynamic_cast<const ASMs2D*>(other); const ASMs2D* o = dynamic_cast<const ASMs2D*>(other);
@ -3061,7 +3085,7 @@ short int ASMs2D::InterfaceChecker::hasContribution (int,
bool ASMs2D::evaluate (const FunctionBase* func, RealArray& vec, bool ASMs2D::evaluate (const FunctionBase* func, RealArray& vec,
int basisNum, double time) const int basisNum, double time) const
{ {
Go::SplineSurface* oldSurf = this->getBasis(basisNum); const Go::SplineSurface* oldSurf = this->getBasis(basisNum);
Go::SplineSurface* newSurf = SplineUtils::project(oldSurf,*func, Go::SplineSurface* newSurf = SplineUtils::project(oldSurf,*func,
func->dim(),time); func->dim(),time);
if (!newSurf) if (!newSurf)

View File

@ -192,8 +192,10 @@ public:
//! \brief Returns the spline curve representing a boundary of this patch. //! \brief Returns the spline curve representing a boundary of this patch.
//! \param[in] dir Parameter direction defining which boundary to return //! \param[in] dir Parameter direction defining which boundary to return
virtual Go::SplineCurve* getBoundary(int dir, int = 1); virtual Go::SplineCurve* getBoundary(int dir, int = 1);
//! \brief Returns the spline surface representing the basis of this patch. //! \brief Returns the spline surface representing a basis of this patch.
virtual Go::SplineSurface* getBasis(int = 1) const { return surf; } virtual Go::SplineSurface* getBasis(int basis = 1);
//! \brief Returns the spline surface representing a basis of this patch.
virtual const Go::SplineSurface* getBasis(int basis = 1) const;
//! \brief Copies the parameter domain from the \a other patch. //! \brief Copies the parameter domain from the \a other patch.
virtual void copyParameterDomain(const ASMbase* other); virtual void copyParameterDomain(const ASMbase* other);

View File

@ -28,6 +28,7 @@
#include "Profiler.h" #include "Profiler.h"
#include <array> #include <array>
#include <numeric> #include <numeric>
#include <utility>
ASMs2Dmx::ASMs2Dmx (unsigned char n_s, const CharVec& n_f) ASMs2Dmx::ASMs2Dmx (unsigned char n_s, const CharVec& n_f)
@ -44,15 +45,24 @@ ASMs2Dmx::ASMs2Dmx (const ASMs2Dmx& patch, const CharVec& n_f)
} }
Go::SplineSurface* ASMs2Dmx::getBasis (int basis) const const Go::SplineSurface* ASMs2Dmx::getBasis (int basis) const
{ {
if (basis < 1 || basis > (int)m_basis.size()) if (basis < 1)
return surf; return this->ASMs2D::getBasis(basis);
if (basis > static_cast<int>(m_basis.size()))
return nullptr;
return m_basis[basis-1].get(); return m_basis[basis-1].get();
} }
Go::SplineSurface* ASMs2Dmx::getBasis (int basis)
{
return const_cast<Go::SplineSurface*>(std::as_const(*this).getBasis(basis));
}
Go::SplineCurve* ASMs2Dmx::getBoundary (int dir, int basis) Go::SplineCurve* ASMs2Dmx::getBoundary (int dir, int basis)
{ {
if (dir < -2 || dir == 0 || dir > 2) if (dir < -2 || dir == 0 || dir > 2)

View File

@ -39,8 +39,11 @@ public:
//! \brief Empty destructor. //! \brief Empty destructor.
virtual ~ASMs2Dmx() {} virtual ~ASMs2Dmx() {}
//! \brief Returns the spline surface representing the basis of this patch. //! \brief Returns the spline surface representing a basis of this patch.
virtual Go::SplineSurface* getBasis(int basis = 1) const; virtual const Go::SplineSurface* getBasis(int basis = 1) const;
//! \brief Returns the spline surface representing a basis of this patch.
virtual Go::SplineSurface* getBasis(int basis = 1);
//! \brief Returns the spline curve representing a boundary of this patch. //! \brief Returns the spline curve representing a boundary of this patch.
//! \param[in] dir Parameter direction defining which boundary to return //! \param[in] dir Parameter direction defining which boundary to return
//! \param[in] basis Basis of boundary to return //! \param[in] basis Basis of boundary to return

View File

@ -83,7 +83,7 @@ bool ASMs2D::evaluate (const ASMbase* basis, const Vector& locVec,
if (!pch->evalSolution(sValues,locVec,gpar.data())) if (!pch->evalSolution(sValues,locVec,gpar.data()))
return false; return false;
Go::SplineSurface* surf = this->getBasis(basisNum); const Go::SplineSurface* surf = this->getBasis(basisNum);
// Project the results onto the spline basis to find control point // Project the results onto the spline basis to find control point
// values based on the result values evaluated at the Greville points. // values based on the result values evaluated at the Greville points.

View File

@ -37,6 +37,7 @@
#include "MPC.h" #include "MPC.h"
#include "IFEM.h" #include "IFEM.h"
#include <array> #include <array>
#include <utility>
ASMs3D::ASMs3D (unsigned char n_f) : ASMstruct(3,3,n_f), nodeInd(myNodeInd) ASMs3D::ASMs3D (unsigned char n_f) : ASMstruct(3,3,n_f), nodeInd(myNodeInd)
@ -79,6 +80,29 @@ Go::SplineSurface* ASMs3D::getBoundary (int dir, int)
} }
const Go::SplineVolume* ASMs3D::getBasis (int basis) const
{
switch (basis) {
case ASM::GEOMETRY_BASIS:
return static_cast<const Go::SplineVolume*>(geomB);
case ASM::PROJECTION_BASIS:
return static_cast<const Go::SplineVolume*>(projB);
case ASM::PROJECTION_BASIS_2:
return static_cast<const Go::SplineVolume*>(projB2);
case ASM::REFINEMENT_BASIS:
return nullptr;
default:
return svol;
}
}
Go::SplineVolume* ASMs3D::getBasis (int basis)
{
return const_cast<Go::SplineVolume*>(std::as_const(*this).getBasis(basis));
}
void ASMs3D::copyParameterDomain (const ASMbase* other) void ASMs3D::copyParameterDomain (const ASMbase* other)
{ {
const ASMs3D* o = dynamic_cast<const ASMs3D*>(other); const ASMs3D* o = dynamic_cast<const ASMs3D*>(other);
@ -3572,7 +3596,7 @@ short int ASMs3D::InterfaceChecker::hasContribution (int, int I, int J, int K) c
bool ASMs3D::evaluate (const FunctionBase* func, RealArray& vec, bool ASMs3D::evaluate (const FunctionBase* func, RealArray& vec,
int basisNum, double time) const int basisNum, double time) const
{ {
Go::SplineVolume* oldVol = this->getBasis(basisNum); const Go::SplineVolume* oldVol = this->getBasis(basisNum);
Go::SplineVolume* newVol = SplineUtils::project(oldVol,*func, Go::SplineVolume* newVol = SplineUtils::project(oldVol,*func,
func->dim(),time); func->dim(),time);
if (!newVol) if (!newVol)

View File

@ -211,8 +211,10 @@ public:
//! \brief Returns the spline surface representing a boundary of this patch. //! \brief Returns the spline surface representing a boundary of this patch.
//! \param[in] dir Parameter direction defining which boundary to return //! \param[in] dir Parameter direction defining which boundary to return
virtual Go::SplineSurface* getBoundary(int dir, int = 1); virtual Go::SplineSurface* getBoundary(int dir, int = 1);
//! \brief Returns the spline volume representing the basis of this patch. //! \brief Returns the spline volume representing a basis of this patch.
virtual Go::SplineVolume* getBasis(int = 1) const { return svol; } virtual const Go::SplineVolume* getBasis(int basis = 1) const;
//! \brief Returns the spline volume representing a basis of this patch.
virtual Go::SplineVolume* getBasis(int basis = 1);
//! \brief Copies the parameter domain from the \a other patch. //! \brief Copies the parameter domain from the \a other patch.
virtual void copyParameterDomain(const ASMbase* other); virtual void copyParameterDomain(const ASMbase* other);

View File

@ -31,6 +31,7 @@
#include "Vec3Oper.h" #include "Vec3Oper.h"
#include <array> #include <array>
#include <numeric> #include <numeric>
#include <utility>
#ifdef USE_OPENMP #ifdef USE_OPENMP
#include <omp.h> #include <omp.h>
#endif #endif
@ -50,15 +51,24 @@ ASMs3Dmx::ASMs3Dmx (const ASMs3Dmx& patch, const CharVec& n_f)
} }
Go::SplineVolume* ASMs3Dmx::getBasis (int basis) const const Go::SplineVolume* ASMs3Dmx::getBasis (int basis) const
{ {
if (basis < 1 || basis > (int)m_basis.size()) if (basis < 1)
return svol; return this->ASMs3D::getBasis(basis);
if (basis > static_cast<int>(m_basis.size()))
return nullptr;
return m_basis[basis-1].get(); return m_basis[basis-1].get();
} }
Go::SplineVolume* ASMs3Dmx::getBasis (int basis)
{
return const_cast<Go::SplineVolume*>(std::as_const(*this).getBasis(basis));
}
Go::SplineSurface* ASMs3Dmx::getBoundary (int dir, int basis) Go::SplineSurface* ASMs3Dmx::getBoundary (int dir, int basis)
{ {
if (dir < -3 || dir == 0 || dir > 3) if (dir < -3 || dir == 0 || dir > 3)

View File

@ -39,8 +39,10 @@ public:
//! \brief Empty Destructor. //! \brief Empty Destructor.
virtual ~ASMs3Dmx() {} virtual ~ASMs3Dmx() {}
//! \brief Returns the spline surface representing the basis of this patch. //! \brief Returns the spline surface representing a basis of this patch.
virtual Go::SplineVolume* getBasis(int basis = 1) const; virtual const Go::SplineVolume* getBasis(int basis = 1) const;
//! \brief Returns the spline surface representing a basis of this patch.
virtual Go::SplineVolume* getBasis(int basis = 1);
//! \brief Returns the spline curve representing a boundary of this patch. //! \brief Returns the spline curve representing a boundary of this patch.
//! \param[in] dir Parameter direction defining which boundary to return //! \param[in] dir Parameter direction defining which boundary to return
//! \param[in] basis The basis to get the boundary for //! \param[in] basis The basis to get the boundary for

View File

@ -81,7 +81,7 @@ bool ASMs3D::evaluate (const ASMbase* basis, const Vector& locVec,
if (!pch->evalSolution(sValues,locVec,gpar.data())) if (!pch->evalSolution(sValues,locVec,gpar.data()))
return false; return false;
Go::SplineVolume* svol = this->getBasis(basisNum); const Go::SplineVolume* svol = this->getBasis(basisNum);
// Project the results onto the spline basis to find control point // Project the results onto the spline basis to find control point
// values based on the result values evaluated at the Greville points. // values based on the result values evaluated at the Greville points.

View File

@ -39,6 +39,7 @@
#include "IFEM.h" #include "IFEM.h"
#include <array> #include <array>
#include <fstream> #include <fstream>
#include <utility>
ASMu2D::ASMu2D (unsigned char n_s, unsigned char n_f) ASMu2D::ASMu2D (unsigned char n_s, unsigned char n_f)
@ -65,6 +66,32 @@ ASMu2D::ASMu2D (const ASMu2D& patch, unsigned char n_f)
} }
const LR::LRSplineSurface* ASMu2D::getBasis (int basis) const
{
switch (basis) {
case ASM::GEOMETRY_BASIS:
return static_cast<const LR::LRSplineSurface*>(geomB.get());
case ASM::PROJECTION_BASIS:
return static_cast<const LR::LRSplineSurface*>(projB.get());
case ASM::PROJECTION_BASIS_2:
return static_cast<const LR::LRSplineSurface*>(projB2.get());
case ASM::REFINEMENT_BASIS:
return static_cast<const LR::LRSplineSurface*>(refB.get());
default:
return lrspline.get();
}
}
LR::LRSplineSurface* ASMu2D::getBasis (int basis)
{
if (tensorspline)
this->createLRfromTensor();
return const_cast<LR::LRSplineSurface*>(std::as_const(*this).getBasis(basis));
}
bool ASMu2D::read (std::istream& is) bool ASMu2D::read (std::istream& is)
{ {
if (shareFE) return true; if (shareFE) return true;

View File

@ -138,10 +138,10 @@ public:
//! \brief Returns the spline surface representing the geometry of this patch. //! \brief Returns the spline surface representing the geometry of this patch.
const LR::LRSplineSurface* getSurface() const { return lrspline.get(); } const LR::LRSplineSurface* getSurface() const { return lrspline.get(); }
//! \brief Returns the spline surface representing the basis of this patch. //! \brief Returns the spline surface representing a basis of this patch.
virtual const LR::LRSplineSurface* getBasis(int = 1) const { return lrspline.get(); } virtual const LR::LRSplineSurface* getBasis(int basis = 1) const;
//! \brief Returns the spline surface representing the basis of this patch. //! \brief Returns the spline surface representing a basis of this patch.
virtual LR::LRSplineSurface* getBasis(int = 1) { return lrspline.get(); } virtual LR::LRSplineSurface* getBasis(int basis = 1);
// Methods for model generation and refinement // Methods for model generation and refinement

View File

@ -35,6 +35,7 @@
#include <array> #include <array>
#include <fstream> #include <fstream>
#include <numeric> #include <numeric>
#include <utility>
ASMu2Dmx::ASMu2Dmx (unsigned char n_s, const CharVec& n_f) ASMu2Dmx::ASMu2Dmx (unsigned char n_s, const CharVec& n_f)
@ -56,7 +57,10 @@ ASMu2Dmx::ASMu2Dmx (const ASMu2Dmx& patch, const CharVec& n_f)
const LR::LRSplineSurface* ASMu2Dmx::getBasis (int basis) const const LR::LRSplineSurface* ASMu2Dmx::getBasis (int basis) const
{ {
if (basis < 1 || basis > (int)m_basis.size()) if (basis < 1)
return this->ASMu2D::getBasis(basis);
if (basis > static_cast<int>(m_basis.size()))
return nullptr; return nullptr;
return m_basis[basis-1].get(); return m_basis[basis-1].get();
@ -65,10 +69,7 @@ const LR::LRSplineSurface* ASMu2Dmx::getBasis (int basis) const
LR::LRSplineSurface* ASMu2Dmx::getBasis (int basis) LR::LRSplineSurface* ASMu2Dmx::getBasis (int basis)
{ {
if (basis < 1 || basis > (int)m_basis.size()) return const_cast<LR::LRSplineSurface*>(std::as_const(*this).getBasis(basis));
return nullptr;
return m_basis[basis-1].get();
} }

View File

@ -65,11 +65,10 @@ public:
//! \brief Empty destructor. //! \brief Empty destructor.
virtual ~ASMu2Dmx() {} virtual ~ASMu2Dmx() {}
//! \brief Returns the spline surface representing the basis of this patch. //! \brief Returns the spline surface representing a basis of this patch.
virtual LR::LRSplineSurface* getBasis(int basis = 1);
//! \brief Returns the spline surface representing the basis of this patch.
virtual const LR::LRSplineSurface* getBasis(int basis = 1) const; virtual const LR::LRSplineSurface* getBasis(int basis = 1) const;
//! \brief Returns the spline surface representing a basis of this patch.
virtual LR::LRSplineSurface* getBasis(int basis = 1);
// Methods for model generation // Methods for model generation
// ============================ // ============================

View File

@ -38,6 +38,7 @@
#include "Point.h" #include "Point.h"
#include "IFEM.h" #include "IFEM.h"
#include <array> #include <array>
#include <utility>
ASMu3D::ASMu3D (unsigned char n_f) ASMu3D::ASMu3D (unsigned char n_f)
@ -63,6 +64,32 @@ ASMu3D::ASMu3D (const ASMu3D& patch, unsigned char n_f)
} }
const LR::LRSplineVolume* ASMu3D::getBasis (int basis) const
{
switch (basis) {
case ASM::GEOMETRY_BASIS:
return static_cast<const LR::LRSplineVolume*>(geomB.get());
case ASM::PROJECTION_BASIS:
return static_cast<const LR::LRSplineVolume*>(projB.get());
case ASM::PROJECTION_BASIS_2:
return static_cast<const LR::LRSplineVolume*>(projB2.get());
case ASM::REFINEMENT_BASIS:
return static_cast<const LR::LRSplineVolume*>(refB.get());
default:
return lrspline.get();
}
}
LR::LRSplineVolume* ASMu3D::getBasis (int basis)
{
if (tensorspline)
this->createLRfromTensor();
return const_cast<LR::LRSplineVolume*>(std::as_const(*this).getBasis(basis));
}
bool ASMu3D::read (std::istream& is) bool ASMu3D::read (std::istream& is)
{ {
if (shareFE) return true; if (shareFE) return true;

View File

@ -121,10 +121,10 @@ public:
//! \brief Returns the spline volume representing the geometry of this patch. //! \brief Returns the spline volume representing the geometry of this patch.
const LR::LRSplineVolume* getVolume() const { return lrspline.get(); } const LR::LRSplineVolume* getVolume() const { return lrspline.get(); }
//! \brief Returns the spline volume representing the basis of this patch. //! \brief Returns the spline volume representing a basis of this patch.
virtual const LR::LRSplineVolume* getBasis(int = 1) const { return lrspline.get(); } virtual const LR::LRSplineVolume* getBasis(int basis = 1) const;
//! \brief Returns the spline volume representing the basis of this patch. //! \brief Returns the spline volume representing a basis of this patch.
virtual LR::LRSplineVolume* getBasis(int = 1) { return lrspline.get(); } virtual LR::LRSplineVolume* getBasis(int basis = 1);
// Methods for model generation and refinement // Methods for model generation and refinement

View File

@ -34,6 +34,7 @@
#include <array> #include <array>
#include <numeric> #include <numeric>
#include <utility>
ASMu3Dmx::ASMu3Dmx (const CharVec& n_f) ASMu3Dmx::ASMu3Dmx (const CharVec& n_f)
@ -59,7 +60,10 @@ ASMu3Dmx::ASMu3Dmx (const ASMu3Dmx& patch, const CharVec& n_f)
const LR::LRSplineVolume* ASMu3Dmx::getBasis (int basis) const const LR::LRSplineVolume* ASMu3Dmx::getBasis (int basis) const
{ {
if (basis < 1 || basis > (int)m_basis.size()) if (basis < 1)
return this->ASMu3D::getBasis(basis);
if (basis > static_cast<int>(m_basis.size()))
return nullptr; return nullptr;
return m_basis[basis-1].get(); return m_basis[basis-1].get();
@ -68,10 +72,7 @@ const LR::LRSplineVolume* ASMu3Dmx::getBasis (int basis) const
LR::LRSplineVolume* ASMu3Dmx::getBasis (int basis) LR::LRSplineVolume* ASMu3Dmx::getBasis (int basis)
{ {
if (basis < 1 || basis > (int)m_basis.size()) return const_cast<LR::LRSplineVolume*>(std::as_const(*this).getBasis(basis));
return nullptr;
return m_basis[basis-1].get();
} }

View File

@ -65,11 +65,10 @@ public:
//! \brief Empty destructor. //! \brief Empty destructor.
virtual ~ASMu3Dmx() {} virtual ~ASMu3Dmx() {}
//! \brief Returns the spline surface representing the basis of this patch. //! \brief Returns the spline volume representing a basis of this patch.
virtual LR::LRSplineVolume* getBasis(int basis = 1);
//! \brief Returns the spline surface representing the basis of this patch.
virtual const LR::LRSplineVolume* getBasis(int basis = 1) const; virtual const LR::LRSplineVolume* getBasis(int basis = 1) const;
//! \brief Returns the spline volume representing a basis of this patch.
virtual LR::LRSplineVolume* getBasis(int basis = 1);
// Methods for model generation // Methods for model generation
// ============================ // ============================

View File

@ -79,7 +79,7 @@ bool SplineFields2Dmx::valueFE (const ItgPoint& x, Vector& vals) const
auto vit = values.begin(); auto vit = values.begin();
auto rit = vals.begin(); auto rit = vals.begin();
for (int b : bases) { for (int b : bases) {
Go::SplineSurface* basis = surf->getBasis(b); const Go::SplineSurface* basis = surf->getBasis(b);
Go::BasisPtsSf spline; Go::BasisPtsSf spline;
#pragma omp critical #pragma omp critical
basis->computeBasis(x.u,x.v,spline); basis->computeBasis(x.u,x.v,spline);

View File

@ -79,7 +79,7 @@ bool SplineFields3Dmx::valueFE (const ItgPoint& x, Vector& vals) const
auto vit = values.begin(); auto vit = values.begin();
auto rit = vals.begin(); auto rit = vals.begin();
for (int b : bases) { for (int b : bases) {
Go::SplineVolume* basis = svol->getBasis(b); const Go::SplineVolume* basis = svol->getBasis(b);
Go::BasisPts spline; Go::BasisPts spline;
#pragma omp critical #pragma omp critical
basis->computeBasis(x.u,x.v,x.w,spline); basis->computeBasis(x.u,x.v,x.w,spline);