Skip to content

Commit 83fffdd

Browse files
committed
Added: Element activation function
1 parent eb3a025 commit 83fffdd

File tree

5 files changed

+75
-22
lines changed

5 files changed

+75
-22
lines changed

src/ASM/ASMbase.C

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ ASMbase::ASMbase (unsigned char n_p, unsigned char n_s, unsigned char n_f)
6767
nel = nnod = 0;
6868
idx = 0;
6969
firstIp = 0;
70+
myElActive = nullptr;
7071
}
7172

7273

@@ -85,6 +86,7 @@ ASMbase::ASMbase (const ASMbase& patch, unsigned char n_f)
8586
idx = patch.idx;
8687
firstIp = patch.firstIp;
8788
// Note: Properties are _not_ copied
89+
myElActive = nullptr; // Element activation function is not copied
8890
}
8991

9092

@@ -123,6 +125,7 @@ ASMbase::ASMbase (const ASMbase& patch)
123125
std::cerr <<" ** ASMbase copy constructor: The copied patch has"
124126
<<" multi-point constraints, these are not copied.\n";
125127

128+
myElActive = nullptr; // Element activation function is not copied
126129
nLag = 0; // Lagrange multipliers are not copied
127130
}
128131

@@ -131,6 +134,7 @@ ASMbase::~ASMbase ()
131134
{
132135
for (MPC* mpc : mpcs)
133136
delete mpc;
137+
delete myElActive;
134138
}
135139

136140

@@ -1747,10 +1751,16 @@ void ASMbase::getBoundaryElms (int lIndex, IntVec& elms,
17471751
}
17481752

17491753

1750-
bool ASMbase::isElementActive (int elmId) const
1754+
bool ASMbase::isElementActive (int elmId, double time) const
17511755
{
1752-
if (elmId < 1) return false;
1753-
if (!myActiveEls) return true;
1756+
if (elmId < 1)
1757+
return false; // element with zero extension
1758+
1759+
if (myElActive && time < (*myElActive)(elmId))
1760+
return false; // element not activated yet
1761+
1762+
if (!myActiveEls)
1763+
return true; // all elements are active
17541764

17551765
return std::find(myActiveEls->begin(),
17561766
myActiveEls->end(),elmId) != myActiveEls->end();

src/ASM/ASMbase.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@
2121
#include <array>
2222
#include <string>
2323

24-
typedef std::vector<int> IntVec; //!< General integer vector
25-
typedef std::vector<IntVec> IntMat; //!< General 2D integer matrix
26-
typedef std::map<MPC*,int,MPCLess> MPCMap; //!< MPC-to-function code mapping
27-
typedef std::set<MPC*,MPCLess> MPCSet; //!< Sorted set of MPC-equations
28-
typedef MPCSet::const_iterator MPCIter; //!< Iterator over an MPC-equation set
24+
using IntVec = std::vector<int>; //!< General integer vector
25+
using IntMat = std::vector<IntVec>; //!< General 2D integer matrix
26+
27+
using MPCMap = std::map<MPC*,int,MPCLess>; //!< MPC-to-function code mapping
28+
using MPCSet = std::set<MPC*,MPCLess>; //!< Sorted set of MPC-equations
29+
using MPCIter = MPCSet::const_iterator; //!< Iterator over an MPC-equation set
2930

3031
struct TimeDomain;
3132
class ElementBlock;
@@ -43,9 +44,12 @@ class RealFunc;
4344
class VecFunc;
4445
class Vec3;
4546
class Tensor;
47+
4648
namespace ASM { class InterfaceChecker; }
49+
namespace utl { template<class Arg, class Result> class Function; }
4750

48-
typedef std::vector<ASMbase*> ASMVec; //!< Spline patch container
51+
using ASMVec = std::vector<ASMbase*>; //!< Spline patch container type
52+
using IntFunc = utl::Function<int,double>; //!< Real-valued integer function
4953

5054

5155
/*!
@@ -78,7 +82,7 @@ class ASMbase
7882
explicit BC(int n) : node(n), CX(1), CY(1), CZ(1), RX(1), RY(1), RZ(1) {}
7983
};
8084

81-
typedef std::vector<BC> BCVec; //!< Nodal boundary condition container
85+
using BCVec = std::vector<BC>; //!< Nodal boundary condition container
8286

8387
protected:
8488
//! \brief The constructor sets the number of space dimensions and fields.
@@ -167,6 +171,9 @@ class ASMbase
167171
//! It must be invoked only before SIMbase::preprocess() is invoked.
168172
void setNoFields(unsigned char n) { nf = n; }
169173

174+
//! \brief Sets the element activation function.
175+
void setElementActivator(IntFunc* efunc) { myElActive = efunc; }
176+
170177
//! \brief Sets the minimum element size for adaptive refinement.
171178
virtual void setMinimumSize(double) {}
172179
//! \brief Defines the minimum element size for adaptive refinement.
@@ -318,7 +325,7 @@ class ASMbase
318325
//! \brief Sets the list of active elements during assembly.
319326
void setActiveElements(IntVec* active) { myActiveEls = active; }
320327
//! \brief Returns \e true if element with global id \a elmId is active.
321-
bool isElementActive(int elmId) const;
328+
bool isElementActive(int elmId, double time = -1.0) const;
322329

323330
//! \brief Returns the nodal point correspondance array for an element.
324331
//! \param[in] iel 1-based element index local to current patch
@@ -1024,11 +1031,12 @@ class ASMbase
10241031
std::vector<char> myLMTypes; //!< Type of %Lagrange multiplier ('L' or 'G')
10251032
std::set<size_t> myLMs; //!< Nodal indices of the %Lagrange multipliers
10261033

1034+
IntFunc* myElActive; //!< Function returning activatiation time of element
10271035
IntVec* myActiveEls; //!< List of active elements during element assembly
10281036
static IntVec Empty; //!< Empty integer vector used when a reference is needed
10291037

10301038
protected:
1031-
typedef std::array<double,3> XYZ; //!< Convenience type definition
1039+
using XYZ = std::array<double,3>; //!< Convenience type definition
10321040
std::map<size_t,XYZ> myRmaster; //!< Rigid master nodal points
10331041
};
10341042

src/ASM/ASMs2D.C

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,7 +1755,8 @@ bool ASMs2D::integrate (Integrand& integrand,
17551755
{
17561756
int iel = groups[g][t][e];
17571757
fe.iel = MLGE[iel];
1758-
if (!this->isElementActive(fe.iel)) continue; // zero-area element
1758+
if (!this->isElementActive(fe.iel,time.t))
1759+
continue; // zero-area or inactive element
17591760

17601761
#ifdef SP_DEBUG
17611762
if (dbgElm < 0 && 1+iel != -dbgElm)
@@ -2039,10 +2040,12 @@ bool ASMs2D::integrate (Integrand& integrand,
20392040
for (size_t e = 0; e < groups[g][t].size() && ok; e++)
20402041
{
20412042
int iel = groups[g][t][e];
2042-
if (itgPts[iel].empty()) continue; // no points in this element
2043+
if (itgPts[iel].empty())
2044+
continue; // no points in this element
20432045

20442046
fe.iel = MLGE[iel];
2045-
if (!this->isElementActive(fe.iel)) continue; // zero-area element
2047+
if (!this->isElementActive(fe.iel,time.t))
2048+
continue; // zero-area or inactive element
20462049

20472050
#ifdef SP_DEBUG
20482051
if (dbgElm < 0 && 1+iel != -dbgElm)
@@ -2218,7 +2221,8 @@ bool ASMs2D::integrate (Integrand& integrand,
22182221
if (!hasInterfaceElms) jel = iel;
22192222

22202223
fe.iel = abs(MLGE[jel]);
2221-
if (!this->isElementActive(fe.iel)) continue; // zero-area element
2224+
if (!this->isElementActive(fe.iel,time.t))
2225+
continue; // zero-area element
22222226

22232227
short int status = iChk.hasContribution(iel,i1,i2);
22242228
if (!status) continue; // no interface contributions for this element
@@ -2421,7 +2425,8 @@ bool ASMs2D::integrate (Integrand& integrand, int lIndex,
24212425
for (int i1 = p1; i1 <= n1; i1++, iel++)
24222426
{
24232427
fe.iel = abs(MLGE[doXelms+iel-1]);
2424-
if (!this->isElementActive(fe.iel)) continue; // zero-area element
2428+
if (!this->isElementActive(fe.iel,time.t))
2429+
continue; // zero-area element
24252430

24262431
if (!myElms.empty() && !glInt.threadSafe() &&
24272432
std::find(myElms.begin(), myElms.end(), iel-1) == myElms.end())

src/ASM/ASMs3D.C

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,7 +2110,8 @@ bool ASMs3D::integrate (Integrand& integrand,
21102110
{
21112111
int iel = groups[g][t][l];
21122112
fe.iel = MLGE[iel];
2113-
if (!this->isElementActive(fe.iel)) continue; // zero-volume element
2113+
if (!this->isElementActive(fe.iel,time.t))
2114+
continue; // zero-volume or inactive element
21142115

21152116
#ifdef SP_DEBUG
21162117
if (dbgElm < 0 && 1+iel != -dbgElm)
@@ -2383,10 +2384,12 @@ bool ASMs3D::integrate (Integrand& integrand,
23832384
for (size_t e = 0; e < groups[g][t].size() && ok; e++)
23842385
{
23852386
int iel = groups[g][t][e];
2386-
if (itgPts[iel].empty()) continue; // no points in this element
2387+
if (itgPts[iel].empty())
2388+
continue; // no integration points in this element
23872389

23882390
fe.iel = MLGE[iel];
2389-
if (!this->isElementActive(fe.iel)) continue; // zero-volume element
2391+
if (!this->isElementActive(fe.iel,time.t))
2392+
continue; // zero-volume or inactive element
23902393

23912394
#ifdef SP_DEBUG
23922395
if (dbgElm < 0 && 1+iel != -dbgElm)
@@ -2642,7 +2645,8 @@ bool ASMs3D::integrate (Integrand& integrand, int lIndex,
26422645
{
26432646
int iel = threadGrp[g][t][l];
26442647
fe.iel = abs(MLGE[doXelms+iel]);
2645-
if (!this->isElementActive(fe.iel)) continue; // zero-volume element
2648+
if (!this->isElementActive(fe.iel,time.t))
2649+
continue; // zero-volume or inactive element
26462650

26472651
#ifdef SP_DEBUG
26482652
if (dbgElm < 0 && 1+iel != -dbgElm)
@@ -2875,7 +2879,8 @@ bool ASMs3D::integrateEdge (Integrand& integrand, int lEdge,
28752879
for (int i1 = p1; i1 <= n1; i1++, iel++)
28762880
{
28772881
fe.iel = MLGE[iel-1];
2878-
if (!this->isElementActive(fe.iel)) continue; // zero-volume element
2882+
if (!this->isElementActive(fe.iel,time.t))
2883+
continue; // zero-volume or inactive element
28792884

28802885
if (!myElms.empty() &&
28812886
std::find(myElms.begin(), myElms.end(), fe.iel-1) == myElms.end())

src/SIM/SIMinput.C

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,28 @@ bool SIMinput::parseGeometryTag (const tinyxml2::XMLElement* elem)
349349
}
350350
}
351351

352+
else if (!strcasecmp(elem->Value(),"activation") && elem->FirstChild())
353+
{
354+
int patch = 0;
355+
std::string type("expression");
356+
utl::getAttribute(elem,"patch",patch);
357+
utl::getAttribute(elem,"type",type,true);
358+
if (patch < 1 || patch > nGlPatches)
359+
{
360+
std::cerr <<" *** SIMinput::parse: Invalid patch index "
361+
<< patch <<"."<< std::endl;
362+
return false;
363+
}
364+
ASMbase* pch = this->getPatch(patch,true);
365+
if (pch)
366+
{
367+
const char* funcdef = elem->FirstChild()->Value();
368+
IFEM::cout <<"\tActivation function for P"<< patch
369+
<<": "<< funcdef << std::endl;
370+
pch->setElementActivator(utl::parseIntFunc(funcdef,type));
371+
}
372+
}
373+
352374
return true;
353375
}
354376

@@ -685,8 +707,11 @@ bool SIMinput::parseICTag (const tinyxml2::XMLElement* elem)
685707
bool SIMinput::parseLinSolTag (const tinyxml2::XMLElement* elem)
686708
{
687709
if (!strcasecmp(elem->Value(),"class"))
710+
{
688711
if (elem->FirstChild())
689712
opt.setLinearSolver(elem->FirstChild()->Value());
713+
utl::getAttribute(elem,"fixzeros",fixZeros);
714+
}
690715

691716
return true;
692717
}

0 commit comments

Comments
 (0)