introduce support for an alternative projection basis
This commit is contained in:
@@ -682,6 +682,8 @@ public:
|
||||
virtual bool createProjectionBasis(bool) { return false; }
|
||||
//! \brief Checks if a separate projection basis is used for this patch.
|
||||
virtual bool separateProjectionBasis() const { return false; }
|
||||
//! \brief Swap between main and alternative projection basis.
|
||||
virtual void swapProjectionBasis() {}
|
||||
|
||||
|
||||
// Methods for result extraction
|
||||
|
||||
@@ -44,6 +44,12 @@ ASMs2Dmx::ASMs2Dmx (const ASMs2Dmx& patch, const CharVec& n_f)
|
||||
}
|
||||
|
||||
|
||||
ASMs2Dmx::~ASMs2Dmx ()
|
||||
{
|
||||
delete altProjBasis;
|
||||
}
|
||||
|
||||
|
||||
Go::SplineSurface* ASMs2Dmx::getBasis (int basis) const
|
||||
{
|
||||
if (basis < 1 || basis > (int)m_basis.size())
|
||||
@@ -206,9 +212,10 @@ bool ASMs2Dmx::generateFEMTopology ()
|
||||
ASMmxBase::Type == ASMmxBase::REDUCED_CONT_RAISE_BASIS2 ||
|
||||
ASMmxBase::Type == ASMmxBase::DIV_COMPATIBLE)
|
||||
projB = proj = ASMmxBase::raiseBasis(surf);
|
||||
else if (ASMmxBase::Type == ASMmxBase::SUBGRID)
|
||||
else if (ASMmxBase::Type == ASMmxBase::SUBGRID) {
|
||||
projB = proj = m_basis.front()->clone();
|
||||
else
|
||||
altProjBasis = ASMmxBase::raiseBasis(surf);
|
||||
} else
|
||||
projB = proj = m_basis[2-ASMmxBase::geoBasis]->clone();
|
||||
}
|
||||
delete surf;
|
||||
@@ -1237,3 +1244,13 @@ void ASMs2Dmx::getBoundaryNodes (int lIndex, IntVec& nodes, int basis,
|
||||
for (size_t b = 1; b <= m_basis.size(); b++)
|
||||
this->ASMs2D::getBoundaryNodes(lIndex, nodes, b, thick, 0, local);
|
||||
}
|
||||
|
||||
|
||||
void ASMs2Dmx::swapProjectionBasis ()
|
||||
{
|
||||
if (altProjBasis) {
|
||||
ASMmxBase::geoBasis = ASMmxBase::geoBasis == 1 ? 2 : 1;
|
||||
std::swap(proj, altProjBasis);
|
||||
surf = this->getBasis(ASMmxBase::geoBasis);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ public:
|
||||
ASMs2Dmx(unsigned char n_s, const CharVec& n_f);
|
||||
//! \brief Copy constructor.
|
||||
ASMs2Dmx(const ASMs2Dmx& patch, const CharVec& n_f = CharVec(2,0));
|
||||
//! \brief Empty destructor.
|
||||
virtual ~ASMs2Dmx() {}
|
||||
//! \brief Destructor.
|
||||
virtual ~ASMs2Dmx();
|
||||
|
||||
//! \brief Returns the spline surface representing the basis of this patch.
|
||||
virtual Go::SplineSurface* getBasis(int basis = 1) const;
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
//! \param glbInt The integrated quantity
|
||||
//! \param[in] time Parameters for nonlinear/time-dependent simulations
|
||||
virtual bool integrate(Integrand& integrand,
|
||||
GlobalIntegral& glbInt, const TimeDomain& time);
|
||||
GlobalIntegral& glbInt, const TimeDomain& time);
|
||||
|
||||
//! \brief Evaluates a boundary integral over a patch edge.
|
||||
//! \param integrand Object with problem-specific data and methods
|
||||
@@ -131,7 +131,7 @@ public:
|
||||
//! \param glbInt The integrated quantity
|
||||
//! \param[in] time Parameters for nonlinear/time-dependent simulations
|
||||
virtual bool integrate(Integrand& integrand, int lIndex,
|
||||
GlobalIntegral& glbInt, const TimeDomain& time);
|
||||
GlobalIntegral& glbInt, const TimeDomain& time);
|
||||
|
||||
//! \brief Evaluates an integral over element interfaces in the patch.
|
||||
//! \param integrand Object with problem-specific data and methods
|
||||
@@ -158,7 +158,7 @@ public:
|
||||
//! \param[in] locSol Solution vector local to current patch
|
||||
//! \param[in] nodes 1-based local node numbers to extract solution for
|
||||
virtual bool getSolution(Matrix& sField, const Vector& locSol,
|
||||
const IntVec& nodes) const;
|
||||
const IntVec& nodes) const;
|
||||
|
||||
using ASMs2D::evalSolution;
|
||||
//! \brief Evaluates the primary solution field at the given points.
|
||||
@@ -192,7 +192,10 @@ public:
|
||||
//! Otherwise, we assume that it contains the \a u and \a v parameters
|
||||
//! directly for each sampling point.
|
||||
virtual bool evalSolution(Matrix& sField, const IntegrandBase& integrand,
|
||||
const RealArray* gpar, bool regular) const;
|
||||
const RealArray* gpar, bool regular) const;
|
||||
|
||||
//! \brief Swap between main and alternative projection basis.
|
||||
virtual void swapProjectionBasis();
|
||||
|
||||
//! \brief Extracts nodal results for this patch from the global vector.
|
||||
//! \param[in] globVec Global solution vector in DOF-order
|
||||
@@ -234,6 +237,7 @@ public:
|
||||
|
||||
protected:
|
||||
std::vector<std::shared_ptr<Go::SplineSurface>> m_basis; //!< Vector of bases
|
||||
Go::SplineSurface* altProjBasis = nullptr; //!< Alternative projection basis
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -50,6 +50,12 @@ ASMs3Dmx::ASMs3Dmx (const ASMs3Dmx& patch, const CharVec& n_f)
|
||||
}
|
||||
|
||||
|
||||
ASMs3Dmx::~ASMs3Dmx ()
|
||||
{
|
||||
delete altProjBasis;
|
||||
}
|
||||
|
||||
|
||||
Go::SplineVolume* ASMs3Dmx::getBasis (int basis) const
|
||||
{
|
||||
if (basis < 1 || basis > (int)m_basis.size())
|
||||
@@ -207,9 +213,10 @@ bool ASMs3Dmx::generateFEMTopology ()
|
||||
ASMmxBase::Type == ASMmxBase::REDUCED_CONT_RAISE_BASIS2 ||
|
||||
ASMmxBase::Type == ASMmxBase::DIV_COMPATIBLE)
|
||||
projB = proj = ASMmxBase::raiseBasis(svol);
|
||||
else if (ASMmxBase::Type == ASMmxBase::SUBGRID)
|
||||
else if (ASMmxBase::Type == ASMmxBase::SUBGRID) {
|
||||
projB = proj = m_basis.front()->clone();
|
||||
else
|
||||
altProjBasis = ASMmxBase::raiseBasis(svol);
|
||||
} else
|
||||
projB = proj = m_basis[2-ASMmxBase::geoBasis]->clone();
|
||||
}
|
||||
delete svol;
|
||||
@@ -1359,3 +1366,13 @@ void ASMs3Dmx::getBoundaryNodes (int lIndex, IntVec& nodes, int basis,
|
||||
for (size_t b = 1; b <= m_basis.size(); b++)
|
||||
this->ASMs3D::getBoundaryNodes(lIndex, nodes, b, thick, 0, local);
|
||||
}
|
||||
|
||||
|
||||
void ASMs3Dmx::swapProjectionBasis ()
|
||||
{
|
||||
if (altProjBasis) {
|
||||
ASMmxBase::geoBasis = ASMmxBase::geoBasis == 1 ? 2 : 1;
|
||||
std::swap(proj, altProjBasis);
|
||||
svol = this->getBasis(ASMmxBase::geoBasis);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ public:
|
||||
explicit ASMs3Dmx(const CharVec& n_f);
|
||||
//! \brief Copy constructor.
|
||||
ASMs3Dmx(const ASMs3Dmx& patch, const CharVec& n_f = CharVec(2,0));
|
||||
//! \brief Empty destructor.
|
||||
virtual ~ASMs3Dmx() {}
|
||||
//! \brief Destructor.
|
||||
virtual ~ASMs3Dmx();
|
||||
|
||||
//! \brief Returns the spline surface representing the basis of this patch.
|
||||
virtual Go::SplineVolume* getBasis(int basis = 1) const;
|
||||
@@ -116,7 +116,7 @@ public:
|
||||
//! \param glbInt The integrated quantity
|
||||
//! \param[in] time Parameters for nonlinear/time-dependent simulations
|
||||
virtual bool integrate(Integrand& integrand,
|
||||
GlobalIntegral& glbInt, const TimeDomain& time);
|
||||
GlobalIntegral& glbInt, const TimeDomain& time);
|
||||
|
||||
//! \brief Evaluates a boundary integral over a patch edge.
|
||||
//! \param integrand Object with problem-specific data and methods
|
||||
@@ -124,7 +124,7 @@ public:
|
||||
//! \param glbInt The integrated quantity
|
||||
//! \param[in] time Parameters for nonlinear/time-dependent simulations
|
||||
virtual bool integrate(Integrand& integrand, int lIndex,
|
||||
GlobalIntegral& glbInt, const TimeDomain& time);
|
||||
GlobalIntegral& glbInt, const TimeDomain& time);
|
||||
|
||||
//! \brief Evaluates an integral over element interfaces in the patch.
|
||||
//! \param integrand Object with problem-specific data and methods
|
||||
@@ -150,7 +150,7 @@ public:
|
||||
//! \param[in] locSol Solution vector local to current patch
|
||||
//! \param[in] nodes 1-based local node numbers to extract solution for
|
||||
virtual bool getSolution(Matrix& sField, const Vector& locSol,
|
||||
const IntVec& nodes) const;
|
||||
const IntVec& nodes) const;
|
||||
|
||||
using ASMs3D::evalSolution;
|
||||
//! \brief Evaluates the primary solution field at the given points.
|
||||
@@ -184,7 +184,10 @@ public:
|
||||
//! Otherwise, we assume that it contains the \a u, \a v and \a w parameters
|
||||
//! directly for each sampling point.
|
||||
virtual bool evalSolution(Matrix& sField, const IntegrandBase& integrand,
|
||||
const RealArray* gpar, bool regular) const;
|
||||
const RealArray* gpar, bool regular) const;
|
||||
|
||||
//! \brief Swap between main and alternative projection basis.
|
||||
virtual void swapProjectionBasis();
|
||||
|
||||
//! \brief Extracts nodal results for this patch from the global vector.
|
||||
//! \param[in] globVec Global solution vector in DOF-order
|
||||
@@ -213,6 +216,7 @@ public:
|
||||
//! \param[out] n3 Number of nodes in third (w) direction
|
||||
//! \param[in] basis Which basis to return size parameters for
|
||||
virtual bool getSize(int& n1, int& n2, int& n3, int basis) const;
|
||||
|
||||
protected:
|
||||
//! \brief Returns the volume in the parameter space for an element.
|
||||
//! \param[in] iel Element index
|
||||
@@ -232,6 +236,7 @@ protected:
|
||||
int thick, int, bool local) const;
|
||||
|
||||
std::vector<std::shared_ptr<Go::SplineVolume>> m_basis; //!< Vector of bases
|
||||
Go::SplineVolume* altProjBasis = nullptr; //!< Alternative projection basis
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -227,6 +227,7 @@ bool ASMu2Dmx::generateFEMTopology ()
|
||||
refBasis.reset(new LR::LRSplineSurface(otherBasis));
|
||||
if (!projBasis)
|
||||
projBasis = m_basis.front();
|
||||
altProjBasis = refBasis;
|
||||
}
|
||||
else {
|
||||
if (!projBasis)
|
||||
@@ -1018,6 +1019,9 @@ bool ASMu2Dmx::refine (const LR::RefineData& prm, Vectors& sol)
|
||||
m_basis[0]->refineBasisFunction(elems);
|
||||
}
|
||||
|
||||
if (altProjBasis)
|
||||
altProjBasis->generateIDs();
|
||||
|
||||
size_t len = 0;
|
||||
for (size_t j = 0; j< m_basis.size(); ++j) {
|
||||
m_basis[j]->generateIDs();
|
||||
@@ -1099,6 +1103,8 @@ void ASMu2Dmx::generateThreadGroups (const Integrand& integrand, bool silence,
|
||||
|
||||
LR::generateThreadGroups(threadGroups,threadBasis,secConstraint);
|
||||
LR::generateThreadGroups(projThreadGroups,projBasis.get());
|
||||
if (altProjBasis)
|
||||
LR::generateThreadGroups(altProjThreadGroups,altProjBasis.get());
|
||||
|
||||
std::vector<const LR::LRSpline*> bases;
|
||||
for (const std::shared_ptr<LR::LRSplineSurface>& basis : m_basis)
|
||||
@@ -1223,3 +1229,13 @@ void ASMu2Dmx::copyRefinement (LR::LRSplineSurface* basis,
|
||||
line->start_, line->stop_, mult);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ASMu2Dmx::swapProjectionBasis ()
|
||||
{
|
||||
if (altProjBasis) {
|
||||
ASMmxBase::geoBasis = ASMmxBase::geoBasis == 1 ? 2 : 1;
|
||||
std::swap(projBasis, altProjBasis);
|
||||
std::swap(projThreadGroups, altProjThreadGroups);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,6 +215,9 @@ public:
|
||||
//! \param multiplicity Wanted multiplicity
|
||||
void copyRefinement(LR::LRSplineSurface* basis, int multiplicity) const;
|
||||
|
||||
//! \brief Swap between main and alternative projection basis.
|
||||
virtual void swapProjectionBasis();
|
||||
|
||||
protected:
|
||||
using ASMu2D::generateThreadGroups;
|
||||
//! \brief Generates element groups for multi-threading of interior integrals.
|
||||
@@ -228,6 +231,8 @@ private:
|
||||
std::vector<std::shared_ptr<LR::LRSplineSurface>> m_basis; //!< All bases
|
||||
LR::LRSplineSurface* threadBasis; //!< Basis for thread groups
|
||||
std::shared_ptr<LR::LRSplineSurface> refBasis; //!< Basis to refine based on
|
||||
std::shared_ptr<LR::LRSplineSurface> altProjBasis; //!< Alternative projection basis
|
||||
ThreadGroups altProjThreadGroups; //!< Element groups for multi-threaded assembly - alternative projection basis
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -215,6 +215,7 @@ bool ASMu3Dmx::generateFEMTopology ()
|
||||
refBasis.reset(new LR::LRSplineVolume(otherBasis.get()));
|
||||
projBasis = m_basis.front();
|
||||
refBasis->generateIDs();
|
||||
altProjBasis = refBasis;
|
||||
} else {
|
||||
projBasis.reset(new LR::LRSplineVolume(otherBasis.get()));
|
||||
refBasis = projBasis;
|
||||
@@ -231,6 +232,10 @@ bool ASMu3Dmx::generateFEMTopology ()
|
||||
lrspline = m_basis[geoBasis-1];
|
||||
projBasis->generateIDs();
|
||||
projBasis->getElementContaining(projBasis->getElement(0)->midpoint()); // to force cache generation
|
||||
if (altProjBasis) {
|
||||
altProjBasis->generateIDs();
|
||||
altProjBasis->getElementContaining(projBasis->getElement(0)->midpoint()); // to force cache generation
|
||||
}
|
||||
myGeoBasis = ASMmxBase::geoBasis;
|
||||
|
||||
nb.resize(m_basis.size());
|
||||
@@ -977,6 +982,9 @@ bool ASMu3Dmx::refine (const LR::RefineData& prm, Vectors& sol)
|
||||
m_basis[0]->refineBasisFunction(elems);
|
||||
}
|
||||
|
||||
if (altProjBasis)
|
||||
altProjBasis->generateIDs();
|
||||
|
||||
size_t len = 0;
|
||||
for (size_t j = 0; j< m_basis.size(); ++j) {
|
||||
m_basis[j]->generateIDs();
|
||||
@@ -1100,6 +1108,8 @@ void ASMu3Dmx::generateThreadGroups (const Integrand& integrand, bool silence,
|
||||
|
||||
LR::generateThreadGroups(threadGroups,threadBasis,secConstraint);
|
||||
LR::generateThreadGroups(projThreadGroups,projBasis.get());
|
||||
if (altProjBasis)
|
||||
LR::generateThreadGroups(altProjThreadGroups,altProjBasis.get());
|
||||
|
||||
std::vector<const LR::LRSpline*> bases;
|
||||
for (const std::shared_ptr<LR::LRSplineVolume>& basis : m_basis)
|
||||
@@ -1119,3 +1129,13 @@ void ASMu3Dmx::generateThreadGroups (const Integrand& integrand, bool silence,
|
||||
this->analyzeThreadGroups(threadGroups[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ASMu3Dmx::swapProjectionBasis ()
|
||||
{
|
||||
if (altProjBasis) {
|
||||
ASMmxBase::geoBasis = ASMmxBase::geoBasis == 1 ? 2 : 1;
|
||||
std::swap(projBasis, altProjBasis);
|
||||
std::swap(projThreadGroups, altProjThreadGroups);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,6 +181,9 @@ public:
|
||||
//! \param multiplicity Wanted multiplicity
|
||||
void copyRefinement(LR::LRSplineVolume* basis, int multiplicity) const;
|
||||
|
||||
//! \brief Swap between main and alternative projection basis.
|
||||
virtual void swapProjectionBasis();
|
||||
|
||||
protected:
|
||||
//! \brief Generates element groups for multi-threading of interior integrals.
|
||||
//! \param[in] integrand Object with problem-specific data and methods
|
||||
@@ -192,9 +195,11 @@ protected:
|
||||
private:
|
||||
std::vector<std::shared_ptr<LR::LRSplineVolume>> m_basis; //!< Spline bases
|
||||
std::shared_ptr<LR::LRSplineVolume> refBasis; //!< Basis to refine based on
|
||||
std::shared_ptr<LR::LRSplineVolume> altProjBasis; //!< Alternative projection basis
|
||||
LR::LRSplineVolume* threadBasis; //!< Basis for thread groups
|
||||
const std::vector<Matrices>& bezierExtractmx; //!< Bezier extraction matrices
|
||||
std::vector<Matrices> myBezierExtractmx; //!< Bezier extraction matrices
|
||||
ThreadGroups altProjThreadGroups; //!< Element groups for multi-threaded assembly - alternative projection basis
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user