Skip to content

Commit 7a5344f

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 0b88dbe commit 7a5344f

11 files changed

Lines changed: 397 additions & 182 deletions

File tree

src/ASM/ASMmxBase.C

Lines changed: 23 additions & 4 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"
@@ -123,8 +124,8 @@ bool ASMmxBase::getSolutionMx (Matrix& sField, const Vector& locSol,
123124
}
124125

125126

126-
ASMmxBase::SurfaceVec ASMmxBase::establishBases(Go::SplineSurface* surf,
127-
MixedType type)
127+
ASMmxBase::SurfaceVec ASMmxBase::establishBases (Go::SplineSurface* surf,
128+
MixedType type)
128129
{
129130
SurfaceVec result(2);
130131
// With mixed methods we need two separate spline spaces
@@ -248,8 +249,8 @@ ASMmxBase::SurfaceVec ASMmxBase::establishBases(Go::SplineSurface* surf,
248249
}
249250

250251

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

src/ASM/ASMmxBase.h

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

7676
protected:
77-
typedef std::vector<std::shared_ptr<Go::SplineSurface>> SurfaceVec; //!< Convenience type
78-
typedef std::vector<std::shared_ptr<Go::SplineVolume>> VolumeVec; //!< Convenience type
77+
typedef std::shared_ptr<Go::SplineSurface> SurfacePtr; //!< Pointer to spline
78+
typedef std::shared_ptr<Go::SplineVolume> VolumePtr; //!< Pointer to spline
79+
typedef std::vector<SurfacePtr> SurfaceVec; //!< Convenience type
80+
typedef std::vector<VolumePtr> VolumeVec; //!< Convenience type
7981

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

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

src/ASM/ASMs2Dmx.C

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

312312

313+
void ASMs2Dmx::constrainEdge (int dir, bool open, int dof, int code, char basis)
314+
{
315+
if (basis > 0)
316+
this->ASMs2D::constrainEdge(dir,open,dof,code,basis);
317+
else for (basis = 1; basis <= (char)nfx.size(); basis++)
318+
{
319+
int basisDofs = this->maskDOFs(dof,basis);
320+
if (basisDofs > 0)
321+
this->ASMs2D::constrainEdge(dir,open,basisDofs,code,basis);
322+
}
323+
}
324+
325+
326+
void ASMs2Dmx::constrainCorner (int I, int J, int dof, int code, char basis)
327+
{
328+
if (basis > 0)
329+
this->ASMs2D::constrainCorner(I,J,dof,code,basis);
330+
else for (basis = 1; basis <= (char)nfx.size(); basis++)
331+
{
332+
int basisDofs = this->maskDOFs(dof,basis);
333+
if (basisDofs > 0)
334+
this->ASMs2D::constrainCorner(I,J,basisDofs,code,basis);
335+
}
336+
}
337+
338+
313339
bool ASMs2Dmx::connectPatch (int edge, ASM2D& neighbor, int nedge, bool revers,
314340
int basis, bool coordCheck, int thick)
315341
{

src/ASM/ASMs2Dmx.h

Lines changed: 36 additions & 19 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 Empty destructor.
4039
virtual ~ASMs2Dmx() {}
4140

@@ -50,9 +49,6 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
5049
// Methods for model generation
5150
// ============================
5251

53-
//! \brief Writes the geometry/basis of the patch to given stream.
54-
virtual bool write(std::ostream& os, int basis = 0) const;
55-
5652
//! \brief Generates the finite element topology data for the patch.
5753
//! \details The data generated are the element-to-node connectivity array,
5854
//! the node-to-IJ-index array, as well as global node and element numbers.
@@ -73,6 +69,9 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
7369
//! \param[in] inod 1-based node index local to current patch
7470
virtual Vec3 getCoord(size_t inod) const;
7571

72+
//! \brief Writes the geometry/basis of the patch to given stream.
73+
virtual bool write(std::ostream& os, int basis = 0) const;
74+
7675
//! \brief Returns the number of bases.
7776
virtual size_t getNoBasis() const { return m_basis.size(); }
7877
//! \brief Returns the total number of nodes in this patch.
@@ -85,17 +84,25 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
8584
//! \brief Returns the classification of a node.
8685
//! \param[in] inod 1-based node index local to current patch
8786
virtual char getNodeType(size_t inod) const;
88-
//! \brief Returns the area in the parameter space for an element.
89-
//! \param[in] iel Element index
90-
virtual double getParametricArea(int iel) const;
91-
//! \brief Returns boundary edge length in the parameter space for an element.
92-
//! \param[in] iel Element index
93-
//! \param[in] dir Local index of the boundary edge
94-
double getParametricLength(int iel, int dir) const;
9587

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

91+
//! \brief Constrains all DOFs on a given boundary edge.
92+
//! \param[in] dir Parameter direction defining the edge to constrain
93+
//! \param[in] open If \e true, exclude the end points of the edge
94+
//! \param[in] dof Which DOFs to constrain at each node along the edge
95+
//! \param[in] code Inhomogeneous dirichlet condition code
96+
//! \param[in] basis Which basis to constrain edge for (0 means check all)
97+
virtual void constrainEdge(int dir, bool open, int dof, int code, char basis);
98+
//! \brief Constrains a corner node identified by the two parameter indices.
99+
//! \param[in] I Parameter index in u-direction
100+
//! \param[in] J Parameter index in v-direction
101+
//! \param[in] dof Which DOFs to constrain at the node
102+
//! \param[in] code Inhomogeneous dirichlet condition code
103+
//! \param[in] basis Which basis to constrain node for (0 means check all)
104+
virtual void constrainCorner(int I, int J, int dof, int code, char basis);
105+
99106
//! \brief Connects all matching nodes on two adjacent boundary edges.
100107
//! \param[in] edge Local edge index of this patch, in range [1,4]
101108
//! \param neighbor The neighbor patch
@@ -105,7 +112,7 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
105112
//! \param[in] coordCheck False to disable coordinate checks (periodic connections)
106113
//! \param[in] thick Thickness of connection
107114
virtual bool connectPatch(int edge, ASM2D& neighbor, int nedge, bool revers,
108-
int basis = 0, bool coordCheck = true, int thick = 1);
115+
int basis, bool coordCheck, int thick);
109116

110117
//! \brief Makes two opposite boundary edges periodic.
111118
//! \param[in] dir Parameter direction defining the periodic edges
@@ -137,7 +144,8 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
137144
//! \param[in] time Parameters for nonlinear/time-dependent simulations
138145
//! \param[in] iChk Object checking if an element interface has contributions
139146
virtual bool integrate(Integrand& integrand, GlobalIntegral& glbInt,
140-
const TimeDomain& time, const ASM::InterfaceChecker& iChk);
147+
const TimeDomain& time,
148+
const ASM::InterfaceChecker& iChk);
141149

142150

143151
// Post-processing methods
@@ -199,18 +207,18 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
199207
virtual void extractNodeVec(const Vector& globVec, Vector& nodeVec,
200208
unsigned char = 0, int basis = 0) const;
201209

202-
//! \brief Inject nodal results for this patch into a global vector.
210+
//! \brief Injects nodal results for this patch into a global vector.
203211
//! \param[in] nodeVec Nodal result vector for this patch
204212
//! \param[out] globVec Global solution vector in DOF-order
205213
//! \param[in] basis Which basis (or 0 for both) to extract nodal values for
206214
virtual bool injectNodeVec(const Vector& nodeVec, Vector& globVec,
207-
unsigned char = 0, int basis = 0) const;
215+
unsigned char = 0, int basis = 0) const;
208216

209217
using ASMs2D::generateThreadGroups;
210218
//! \brief Generates element groups for multi-threading of interior integrals.
211219
//! \param[in] integrand Object with problem-specific data and methods
212220
//! \param[in] silence If \e true, suppress threading group outprint
213-
//! \param[in] ignoreGlobalLM If \e true, ignore global multipliers in sanity check
221+
//! \param[in] ignoreGlobalLM Sanity check option
214222
virtual void generateThreadGroups(const Integrand& integrand, bool silence,
215223
bool ignoreGlobalLM);
216224

@@ -221,16 +229,25 @@ class ASMs2Dmx : public ASMs2D, private ASMmxBase
221229
//! \param[in] basis Which basis to return size parameters for
222230
virtual bool getSize(int& n1, int& n2, int basis = 0) const;
223231

232+
protected:
233+
//! \brief Returns the area in the parameter space for an element.
234+
//! \param[in] iel Element index
235+
double getParametricArea(int iel) const;
236+
//! \brief Returns boundary edge length in the parameter space for an element.
237+
//! \param[in] iel Element index
238+
//! \param[in] dir Local index of the boundary edge
239+
double getParametricLength(int iel, int dir) const;
240+
224241
//! \brief Finds the global (or patch-local) node numbers on a patch boundary.
225242
//! \param[in] lIndex Local index of the boundary edge
226243
//! \param nodes Array of node numbers
227244
//! \param[in] basis Which basis to grab nodes for (0 for all)
228245
//! \param[in] thick Thickness of connection
229246
//! \param[in] local If \e true return patch-local node numbers
230247
virtual void getBoundaryNodes(int lIndex, IntVec& nodes, int basis,
231-
int thick = 1, int = 0, bool local = false) const;
248+
int thick, int, bool local) const;
232249

233-
protected:
250+
private:
234251
std::vector<std::shared_ptr<Go::SplineSurface>> m_basis; //!< Vector of bases
235252
};
236253

0 commit comments

Comments
 (0)