Skip to content

Commit 122912b

Browse files
committed
Added: Overload the constrain methods for mixed to also allow specifying
DOFs to constrain for all bases (when invoked with basis=0)
1 parent 4fc9727 commit 122912b

11 files changed

Lines changed: 345 additions & 98 deletions

File tree

src/ASM/ASMmxBase.C

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//==============================================================================
1313

1414
#include "ASMmxBase.h"
15+
#include "Utilities.h"
1516
#include "GoTools/geometry/SplineSurface.h"
1617
#include "GoTools/geometry/SurfaceInterpolator.h"
1718
#include "GoTools/trivariate/SplineVolume.h"
@@ -250,8 +251,8 @@ ASMmxBase::SurfaceVec ASMmxBase::establishBases (Go::SplineSurface* surf,
250251
}
251252

252253

253-
ASMmxBase::VolumeVec ASMmxBase::establishBases(Go::SplineVolume* svol,
254-
MixedType type)
254+
ASMmxBase::VolumeVec ASMmxBase::establishBases (Go::SplineVolume* svol,
255+
MixedType type)
255256
{
256257
VolumeVec result(2);
257258
// With mixed methods we need two separate spline spaces
@@ -500,3 +501,21 @@ Go::SplineVolume* ASMmxBase::raiseBasis (Go::SplineVolume* svol)
500501
// Project the coordinates onto the new basis (the 2nd XYZ is dummy here)
501502
return Go::VolumeInterpolator::regularInterpolation(basis[0],basis[1],basis[2],ug[0],ug[1],ug[2],XYZ,ndim,false,XYZ);
502503
}
504+
505+
506+
int ASMmxBase::maskDOFs (int dofs, char basis) const
507+
{
508+
unsigned char ofs = std::accumulate(nfx.begin(),nfx.begin()+basis-1,0u);
509+
std::set<int> allDofs = utl::getDigits(dofs);
510+
dofs = 0;
511+
512+
// Convert the DOF digits to local values of this basis,
513+
// and mask off those not residing on this basis
514+
for (int dof : allDofs)
515+
{
516+
dofs *= 10;
517+
if (dof > ofs && dof <= ofs+nfx[basis-1])
518+
dofs += dof - ofs;
519+
}
520+
return dofs;
521+
}

src/ASM/ASMmxBase.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,10 @@ class ASMmxBase
7676
static char geoBasis; //!< 1-based index of basis representing the geometry
7777

7878
protected:
79-
typedef std::vector<std::shared_ptr<Go::SplineSurface>> SurfaceVec; //!< Convenience type
80-
typedef std::vector<std::shared_ptr<Go::SplineVolume>> VolumeVec; //!< Convenience type
79+
typedef std::shared_ptr<Go::SplineSurface> SurfacePtr; //!< Pointer to spline
80+
typedef std::shared_ptr<Go::SplineVolume> VolumePtr; //!< Pointer to spline
81+
typedef std::vector<SurfacePtr> SurfaceVec; //!< Convenience type
82+
typedef std::vector<VolumePtr> VolumeVec; //!< Convenience type
8183

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

101+
//! \brief Mask off DOFs not residing on the specified basis
102+
//! \param[in] dofs Encoded DOF indices (like 123456 meaning dofs 1 to 6)
103+
//! \param[in] basis Which basis to return DOF indices for
104+
//! \return Encoded DOF indices related to the specified basis only
105+
int maskDOFs(int dofs, char basis) const;
106+
99107
private:
100108
std::vector<int> MADOF; //!< Matrix of accumulated DOFs for this patch
101109

src/ASM/ASMs2Dmx.C

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,32 @@ bool ASMs2Dmx::generateFEMTopology ()
341341
}
342342

343343

344+
void ASMs2Dmx::constrainEdge (int dir, bool open, int dof, int code, char basis)
345+
{
346+
if (basis > 0)
347+
this->ASMs2D::constrainEdge(dir,open,dof,code,basis);
348+
else for (basis = 1; basis <= (char)nfx.size(); basis++)
349+
{
350+
int basisDofs = this->maskDOFs(dof,basis);
351+
if (basisDofs > 0)
352+
this->ASMs2D::constrainEdge(dir,open,basisDofs,code,basis);
353+
}
354+
}
355+
356+
357+
void ASMs2Dmx::constrainCorner (int I, int J, int dof, int code, char basis)
358+
{
359+
if (basis > 0)
360+
this->ASMs2D::constrainCorner(I,J,dof,code,basis);
361+
else for (basis = 1; basis <= (char)nfx.size(); basis++)
362+
{
363+
int basisDofs = this->maskDOFs(dof,basis);
364+
if (basisDofs > 0)
365+
this->ASMs2D::constrainCorner(I,J,basisDofs,code,basis);
366+
}
367+
}
368+
369+
344370
bool ASMs2Dmx::connectPatch (int edge, ASM2D& neighbor, int nedge, bool revers,
345371
int basis, bool coordCheck, int thick)
346372
{

src/ASM/ASMs2Dmx.h

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
#include "ASMs2D.h"
1818
#include "ASMmxBase.h"
19-
#include <memory>
2019

2120

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

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

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

93+
//! \brief Constrains all DOFs on a given boundary edge.
94+
//! \param[in] dir Parameter direction defining the edge to constrain
95+
//! \param[in] open If \e true, exclude the end points of the edge
96+
//! \param[in] dof Which DOFs to constrain at each node along the edge
97+
//! \param[in] code Inhomogeneous dirichlet condition code
98+
//! \param[in] basis Which basis to constrain edge for (0 means check all)
99+
virtual void constrainEdge(int dir, bool open, int dof, int code, char basis);
100+
//! \brief Constrains a corner node identified by the two parameter indices.
101+
//! \param[in] I Parameter index in u-direction
102+
//! \param[in] J Parameter index in v-direction
103+
//! \param[in] dof Which DOFs to constrain at the node
104+
//! \param[in] code Inhomogeneous dirichlet condition code
105+
//! \param[in] basis Which basis to constrain node for (0 means check all)
106+
virtual void constrainCorner(int I, int J, int dof, int code, char basis);
107+
101108
//! \brief Connects all matching nodes on two adjacent boundary edges.
102109
//! \param[in] edge Local edge index of this patch, in range [1,4]
103110
//! \param neighbor The neighbor patch
@@ -139,7 +146,8 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
139146
//! \param[in] time Parameters for nonlinear/time-dependent simulations
140147
//! \param[in] iChk Object checking if an element interface has contributions
141148
virtual bool integrate(Integrand& integrand, GlobalIntegral& glbInt,
142-
const TimeDomain& time, const ASM::InterfaceChecker& iChk);
149+
const TimeDomain& time,
150+
const ASM::InterfaceChecker& iChk);
143151

144152

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

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

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

237+
protected:
238+
//! \brief Returns the area in the parameter space for an element.
239+
//! \param[in] iel Element index
240+
double getParametricArea(int iel) const;
241+
//! \brief Returns boundary edge length in the parameter space for an element.
242+
//! \param[in] iel Element index
243+
//! \param[in] dir Local index of the boundary edge
244+
double getParametricLength(int iel, int dir) const;
245+
229246
//! \brief Finds the global (or patch-local) node numbers on a patch boundary.
230247
//! \param[in] lIndex Local index of the boundary edge
231248
//! \param nodes Array of node numbers
@@ -235,7 +252,7 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
235252
virtual void getBoundaryNodes(int lIndex, IntVec& nodes, int basis,
236253
int thick, int, bool local) const;
237254

238-
protected:
255+
private:
239256
std::vector<std::shared_ptr<Go::SplineSurface>> m_basis; //!< Vector of bases
240257
Go::SplineSurface* altProjBasis = nullptr; //!< Alternative projection basis
241258
};

0 commit comments

Comments
 (0)