ASMu2Dmx: add rational support

This commit is contained in:
Arne Morten Kvarving 2023-05-24 08:52:47 +02:00
parent 6a227741d6
commit 933bc34944
2 changed files with 32 additions and 19 deletions

View File

@ -653,6 +653,14 @@ protected:
//! \brief Generate bezier extraction operators. //! \brief Generate bezier extraction operators.
void generateBezierExtraction(); void generateBezierExtraction();
//! \brief Write NURBS elements as postscript file.
void writePostscriptElementsNurbs (std::shared_ptr<LR::LRSplineSurface> mesh,
std::ostream& out, bool close = true,
int nu = 2, int nv = 2);
//! \brief Write NURBS elements as postscript file.
void writePostscriptMeshWithControlPointsNurbs (std::shared_ptr<LR::LRSplineSurface> mesh,
std::ostream& out, int nu = 2, int nv = 2);
public: public:
//! \brief Returns the number of elements on a boundary. //! \brief Returns the number of elements on a boundary.
virtual size_t getNoBoundaryElms(char lIndex, char ldim) const; virtual size_t getNoBoundaryElms(char lIndex, char ldim) const;
@ -721,14 +729,6 @@ private:
//! \param[in] derivs Derivative order of the basis functions //! \param[in] derivs Derivative order of the basis functions
bool evaluateBasisNurbs(int iel, FiniteElement& fe, bool evaluateBasisNurbs(int iel, FiniteElement& fe,
int derivs) const; int derivs) const;
//! \brief Write NURBS elements as postscript file.
void writePostscriptElementsNurbs (std::shared_ptr<LR::LRSplineSurface> mesh,
std::ostream& out, bool close = true,
int nu = 2, int nv = 2);
//! \brief Write NURBS elements as postscript file.
void writePostscriptMeshWithControlPointsNurbs (std::shared_ptr<LR::LRSplineSurface> mesh,
std::ostream& out, int nu = 2, int nv = 2);
}; };
#endif #endif

View File

@ -201,9 +201,15 @@ bool ASMu2Dmx::generateFEMTopology ()
if (!myMLGN.empty()) if (!myMLGN.empty())
return true; return true;
auto createLR = [this](Go::SplineSurface& srf)
{
return srf.rational() ? this->createLRNurbs(srf)
: new LR::LRSplineSurface(&srf);
};
if (tensorPrjBas) if (tensorPrjBas)
{ {
projBasis.reset(new LR::LRSplineSurface(tensorPrjBas)); projBasis.reset(createLR(*tensorPrjBas));
delete tensorPrjBas; delete tensorPrjBas;
tensorPrjBas = nullptr; tensorPrjBas = nullptr;
} }
@ -212,7 +218,7 @@ bool ASMu2Dmx::generateFEMTopology ()
SurfaceVec svec = ASMmxBase::establishBases(tensorspline, ASMmxBase::Type); SurfaceVec svec = ASMmxBase::establishBases(tensorspline, ASMmxBase::Type);
m_basis.resize(svec.size()); m_basis.resize(svec.size());
for (size_t b = 0; b < svec.size(); b++) for (size_t b = 0; b < svec.size(); b++)
m_basis[b].reset(new LR::LRSplineSurface(svec[b].get())); m_basis[b].reset(createLR(*svec[b]));
// we need to project on something that is not one of our bases // we need to project on something that is not one of our bases
if (ASMmxBase::Type == ASMmxBase::REDUCED_CONT_RAISE_BASIS1 || if (ASMmxBase::Type == ASMmxBase::REDUCED_CONT_RAISE_BASIS1 ||
@ -224,14 +230,14 @@ bool ASMu2Dmx::generateFEMTopology ()
otherBasis = ASMmxBase::raiseBasis(tensorspline); otherBasis = ASMmxBase::raiseBasis(tensorspline);
if (ASMmxBase::Type == ASMmxBase::SUBGRID) { if (ASMmxBase::Type == ASMmxBase::SUBGRID) {
refBasis.reset(new LR::LRSplineSurface(otherBasis)); refBasis.reset(createLR(*otherBasis));
if (!projBasis) if (!projBasis)
projBasis = m_basis.front(); projBasis = m_basis.front();
altProjBasis = refBasis; altProjBasis = refBasis;
} }
else { else {
if (!projBasis) if (!projBasis)
projBasis.reset(new LR::LRSplineSurface(otherBasis)); projBasis.reset(createLR(*otherBasis));
refBasis = projBasis; refBasis = projBasis;
} }
delete otherBasis; delete otherBasis;
@ -242,6 +248,7 @@ bool ASMu2Dmx::generateFEMTopology ()
refBasis = projBasis; refBasis = projBasis;
} }
is_rational = tensorspline->rational();
delete tensorspline; delete tensorspline;
tensorspline = nullptr; tensorspline = nullptr;
} }
@ -1183,8 +1190,8 @@ size_t ASMu2Dmx::getNoRefineElms() const
void ASMu2Dmx::storeMesh (const std::string& fName, int fType) const void ASMu2Dmx::storeMesh (const std::string& fName, int fType) const
{ {
auto&& writeBasis = [fName,fType](const LR::LRSplineSurface* patch, auto&& writeBasis = [fName,fType,this](std::shared_ptr<LR::LRSplineSurface> patch,
const std::string& tag) const std::string& tag)
{ {
std::string fileName = "_patch_" + tag + "_" + fName + ".eps"; std::string fileName = "_patch_" + tag + "_" + fName + ".eps";
if (fType%2) { if (fType%2) {
@ -1193,7 +1200,10 @@ void ASMu2Dmx::storeMesh (const std::string& fName, int fType) const
} }
if ((fType/2)%2) { if ((fType/2)%2) {
std::ofstream meshFile("physical"+fileName); std::ofstream meshFile("physical"+fileName);
patch->writePostscriptElements(meshFile); if (is_rational)
const_cast<ASMu2Dmx*>(this)->writePostscriptElementsNurbs(patch, meshFile);
else
patch->writePostscriptElements(meshFile);
} }
if ((fType/4)%2) { if ((fType/4)%2) {
std::ofstream meshFile("param_dot"+fileName); std::ofstream meshFile("param_dot"+fileName);
@ -1201,18 +1211,21 @@ void ASMu2Dmx::storeMesh (const std::string& fName, int fType) const
} }
if ((fType/8)%2) { if ((fType/8)%2) {
std::ofstream meshFile("physical_dot"+fileName); std::ofstream meshFile("physical_dot"+fileName);
patch->writePostscriptMeshWithControlPoints(meshFile); if (is_rational)
const_cast<ASMu2Dmx*>(this)->writePostscriptMeshWithControlPointsNurbs(patch, meshFile);
else
patch->writePostscriptMeshWithControlPoints(meshFile);
} }
}; };
std::string btag("basis1"); std::string btag("basis1");
for (const auto& patch : m_basis) for (const auto& patch : m_basis)
{ {
writeBasis(patch.get(), btag); writeBasis(patch, btag);
++btag.back(); ++btag.back();
} }
writeBasis(projBasis.get(), "proj"); writeBasis(projBasis, "proj");
writeBasis(refBasis.get(), "ref"); writeBasis(refBasis, "ref");
} }