Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added: Overload the constrain methods for mixed #397

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions src/ASM/ASMmxBase.C
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//==============================================================================

#include "ASMmxBase.h"
#include "Utilities.h"
#include "GoTools/geometry/SplineSurface.h"
#include "GoTools/geometry/SurfaceInterpolator.h"
#include "GoTools/trivariate/SplineVolume.h"
Expand Down Expand Up @@ -250,8 +251,8 @@ ASMmxBase::SurfaceVec ASMmxBase::establishBases (Go::SplineSurface* surf,
}


ASMmxBase::VolumeVec ASMmxBase::establishBases(Go::SplineVolume* svol,
MixedType type)
ASMmxBase::VolumeVec ASMmxBase::establishBases (Go::SplineVolume* svol,
MixedType type)
{
VolumeVec result(2);
// With mixed methods we need two separate spline spaces
Expand Down Expand Up @@ -500,3 +501,21 @@ Go::SplineVolume* ASMmxBase::raiseBasis (Go::SplineVolume* svol)
// Project the coordinates onto the new basis (the 2nd XYZ is dummy here)
return Go::VolumeInterpolator::regularInterpolation(basis[0],basis[1],basis[2],ug[0],ug[1],ug[2],XYZ,ndim,false,XYZ);
}


int ASMmxBase::maskDOFs (int dofs, char basis) const
{
unsigned char ofs = std::accumulate(nfx.begin(),nfx.begin()+basis-1,0u);
std::set<int> allDofs = utl::getDigits(dofs);
dofs = 0;

// Convert the DOF digits to local values of this basis,
// and mask off those not residing on this basis
for (int dof : allDofs)
{
dofs *= 10;
if (dof > ofs && dof <= ofs+nfx[basis-1])
dofs += dof - ofs;
}
return dofs;
}
12 changes: 10 additions & 2 deletions src/ASM/ASMmxBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,10 @@ class ASMmxBase
static char geoBasis; //!< 1-based index of basis representing the geometry

protected:
typedef std::vector<std::shared_ptr<Go::SplineSurface>> SurfaceVec; //!< Convenience type
typedef std::vector<std::shared_ptr<Go::SplineVolume>> VolumeVec; //!< Convenience type
typedef std::shared_ptr<Go::SplineSurface> SurfacePtr; //!< Pointer to spline
typedef std::shared_ptr<Go::SplineVolume> VolumePtr; //!< Pointer to spline
typedef std::vector<SurfacePtr> SurfaceVec; //!< Convenience type
typedef std::vector<VolumePtr> VolumeVec; //!< Convenience type

//! \brief Establish mixed bases in 2D.
//! \param[in] surf The base basis to use
Expand All @@ -96,6 +98,12 @@ class ASMmxBase
//! \brief Returns a C^p-1 basis of one degree higher than \a *svol.
static Go::SplineVolume* raiseBasis(Go::SplineVolume* svol);

//! \brief Mask off DOFs not residing on the specified basis
//! \param[in] dofs Encoded DOF indices (like 123456 meaning dofs 1 to 6)
//! \param[in] basis Which basis to return DOF indices for
//! \return Encoded DOF indices related to the specified basis only
int maskDOFs(int dofs, char basis) const;

private:
std::vector<int> MADOF; //!< Matrix of accumulated DOFs for this patch

Expand Down
26 changes: 26 additions & 0 deletions src/ASM/ASMs2Dmx.C
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,32 @@ bool ASMs2Dmx::generateFEMTopology ()
}


void ASMs2Dmx::constrainEdge (int dir, bool open, int dof, int code, char basis)
{
if (basis > 0)
this->ASMs2D::constrainEdge(dir,open,dof,code,basis);
else for (basis = 1; basis <= (char)nfx.size(); basis++)
{
int basisDofs = this->maskDOFs(dof,basis);
if (basisDofs > 0)
this->ASMs2D::constrainEdge(dir,open,basisDofs,code,basis);
}
}


void ASMs2Dmx::constrainCorner (int I, int J, int dof, int code, char basis)
{
if (basis > 0)
this->ASMs2D::constrainCorner(I,J,dof,code,basis);
else for (basis = 1; basis <= (char)nfx.size(); basis++)
{
int basisDofs = this->maskDOFs(dof,basis);
if (basisDofs > 0)
this->ASMs2D::constrainCorner(I,J,basisDofs,code,basis);
}
}


bool ASMs2Dmx::connectPatch (int edge, ASM2D& neighbor, int nedge, bool revers,
int basis, bool coordCheck, int thick)
{
Expand Down
43 changes: 30 additions & 13 deletions src/ASM/ASMs2Dmx.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

#include "ASMs2D.h"
#include "ASMmxBase.h"
#include <memory>


/*!
Expand All @@ -35,7 +34,7 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
//! \brief The constructor initializes the dimension of each basis.
ASMs2Dmx(unsigned char n_s, const CharVec& n_f);
//! \brief Copy constructor.
ASMs2Dmx(const ASMs2Dmx& patch, const CharVec& n_f = CharVec(2,0));
ASMs2Dmx(const ASMs2Dmx& patch, const CharVec& n_f);
//! \brief Destructor.
virtual ~ASMs2Dmx();

Expand Down Expand Up @@ -87,17 +86,25 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
//! \brief Returns the classification of a node.
//! \param[in] inod 1-based node index local to current patch
virtual char getNodeType(size_t inod) const;
//! \brief Returns the area in the parameter space for an element.
//! \param[in] iel Element index
virtual double getParametricArea(int iel) const;
//! \brief Returns boundary edge length in the parameter space for an element.
//! \param[in] iel Element index
//! \param[in] dir Local index of the boundary edge
double getParametricLength(int iel, int dir) const;

//! \brief Initializes the patch level MADOF array for mixed problems.
virtual void initMADOF(const int* sysMadof);

//! \brief Constrains all DOFs on a given boundary edge.
//! \param[in] dir Parameter direction defining the edge to constrain
//! \param[in] open If \e true, exclude the end points of the edge
//! \param[in] dof Which DOFs to constrain at each node along the edge
//! \param[in] code Inhomogeneous dirichlet condition code
//! \param[in] basis Which basis to constrain edge for (0 means check all)
virtual void constrainEdge(int dir, bool open, int dof, int code, char basis);
//! \brief Constrains a corner node identified by the two parameter indices.
//! \param[in] I Parameter index in u-direction
//! \param[in] J Parameter index in v-direction
//! \param[in] dof Which DOFs to constrain at the node
//! \param[in] code Inhomogeneous dirichlet condition code
//! \param[in] basis Which basis to constrain node for (0 means check all)
virtual void constrainCorner(int I, int J, int dof, int code, char basis);

//! \brief Connects all matching nodes on two adjacent boundary edges.
//! \param[in] edge Local edge index of this patch, in range [1,4]
//! \param neighbor The neighbor patch
Expand Down Expand Up @@ -139,7 +146,8 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
//! \param[in] time Parameters for nonlinear/time-dependent simulations
//! \param[in] iChk Object checking if an element interface has contributions
virtual bool integrate(Integrand& integrand, GlobalIntegral& glbInt,
const TimeDomain& time, const ASM::InterfaceChecker& iChk);
const TimeDomain& time,
const ASM::InterfaceChecker& iChk);


// Post-processing methods
Expand Down Expand Up @@ -204,7 +212,7 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
virtual void extractNodeVec(const RealArray& globVec, RealArray& nodeVec,
unsigned char, int basis) const;

//! \brief Inject nodal results for this patch into a global vector.
//! \brief Injects nodal results for this patch into a global vector.
//! \param[in] nodeVec Nodal result vector for this patch
//! \param[out] globVec Global solution vector in DOF-order
//! \param[in] basis Which basis (or 0 for both) to extract nodal values for
Expand All @@ -215,7 +223,7 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
//! \brief Generates element groups for multi-threading of interior integrals.
//! \param[in] integrand Object with problem-specific data and methods
//! \param[in] silence If \e true, suppress threading group outprint
//! \param[in] ignoreGlobalLM If \e true, ignore global multipliers in sanity check
//! \param[in] ignoreGlobalLM Sanity check option
virtual void generateThreadGroups(const Integrand& integrand, bool silence,
bool ignoreGlobalLM);

Expand All @@ -226,6 +234,15 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
//! \param[in] basis Which basis to return size parameters for
virtual bool getSize(int& n1, int& n2, int basis) const;

protected:
//! \brief Returns the area in the parameter space for an element.
//! \param[in] iel Element index
double getParametricArea(int iel) const;
//! \brief Returns boundary edge length in the parameter space for an element.
//! \param[in] iel Element index
//! \param[in] dir Local index of the boundary edge
double getParametricLength(int iel, int dir) const;

//! \brief Finds the global (or patch-local) node numbers on a patch boundary.
//! \param[in] lIndex Local index of the boundary edge
//! \param nodes Array of node numbers
Expand All @@ -235,7 +252,7 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
virtual void getBoundaryNodes(int lIndex, IntVec& nodes, int basis,
int thick, int, bool local) const;

protected:
private:
std::vector<std::shared_ptr<Go::SplineSurface>> m_basis; //!< Vector of bases
Go::SplineSurface* altProjBasis = nullptr; //!< Alternative projection basis
};
Expand Down
Loading