57IntArray Tet1BubbleStokes :: momentum_ordering = {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18, 19};
58IntArray Tet1BubbleStokes :: conservation_ordering = {4, 8, 12, 16};
59IntArray Tet1BubbleStokes :: surf_ordering [ 4 ] = {
60 {1, 2, 3, 9, 10, 11, 5, 6, 7},
61 {1, 2, 3, 5, 6, 7, 13, 14, 15},
62 {5, 6, 7, 9, 10, 11, 13, 14, 15},
63 {1, 2, 3, 13, 14, 15, 9, 10, 11}
71 this->
bubble = std::make_unique<ElementDofManager>(1, aDomain,
this);
77void Tet1BubbleStokes :: computeGaussPoints()
86int Tet1BubbleStokes :: computeNumberOfDofs()
91void Tet1BubbleStokes :: giveDofManDofIDMask(
int inode,
IntArray &answer)
const
93 answer = {V_u, V_v, V_w, P_f};
96void Tet1BubbleStokes :: giveInternalDofManDofIDMask(
int i,
IntArray &answer)
const
98 answer = {V_u, V_v, V_w};
101double Tet1BubbleStokes :: computeVolumeAround(
GaussPoint *gp)
107void Tet1BubbleStokes :: giveCharacteristicVector(
FloatArray &answer,
CharType mtrx, ValueModeType mode,
111 if ( mtrx == ExternalForcesVector ) {
113 }
else if ( mtrx == InternalForcesVector ) {
116 OOFEM_ERROR(
"Unknown Type of characteristic mtrx.");
120void Tet1BubbleStokes :: giveCharacteristicMatrix(
FloatMatrix &answer,
124 if ( mtrx == TangentStiffnessMatrix ) {
127 OOFEM_ERROR(
"Unknown Type of characteristic mtrx.");
142 const auto &lcoords = gp->giveNaturalCoordinates();
144 auto N = this->
interp.evalN( lcoords );
146 auto dN = detj_dn.second;
147 auto detJ = detj_dn.first;
148 auto dV = std::abs(detJ) * gp->giveWeight();
152 for ( std::size_t j = 0, k = 0; j < dN.rows(); j++, k += 3 ) {
153 dN_V[k + 0] = B(0, k + 0) = B(5, k + 1) = B(4, k + 2) = dN(0, j);
154 dN_V[k + 1] = B(1, k + 1) = B(5, k + 0) = B(3, k + 2) = dN(1, j);
155 dN_V[k + 2] = B(2, k + 2) = B(4, k + 0) = B(3, k + 1) = dN(2, j);
159 dN_V[12] = B(0, 12) = B(5, 13) = B(4, 14) = dN(0, 0) *
N[1] *
N[2] *
N[3] +
N[0] * dN(1, 0) *
N[2] *
N[3] +
N[0] *
N[1] * dN(2, 0) *
N[3] +
N[0] *
N[1] *
N[2] * dN(3, 0);
160 dN_V[13] = B(1, 13) = B(5, 12) = B(3, 14) = dN(0, 1) *
N[1] *
N[2] *
N[3] +
N[0] * dN(1, 1) *
N[2] *
N[3] +
N[0] *
N[1] * dN(2, 1) *
N[3] +
N[0] *
N[1] *
N[2] * dN(3, 1);
161 dN_V[14] = B(2, 14) = B(4, 12) = B(3, 13) = dN(0, 2) *
N[1] *
N[2] *
N[3] +
N[0] * dN(1, 2) *
N[2] *
N[3] +
N[0] *
N[1] * dN(2, 2) *
N[3] +
N[0] *
N[1] *
N[2] * dN(3, 2);
163 auto pressure =
dot(
N, a_pressure);
164 auto epsp =
dot(B, a_velocity);
167 auto devStress = s_r.first;
168 auto r_vol = s_r.second;
170 momentum +=
Tdot(B, devStress * dV) + dN_V * (-pressure * dV);
171 conservation +=
N * (r_vol * dV);
186 for (
int i = 1; i <= nLoads; i++ ) {
189 Load *load = this->
domain->giveLoad(load_number);
195 OOFEM_ERROR(
"Unsupported boundary condition: %d", load_id);
203 for (
int i = 1; i <= nLoads; i++ ) {
205 if ((bload =
dynamic_cast<BodyLoad*
>(load))) {
220 if ( type != ExternalForcesVector ) {
226 double dV, detJ, rho;
233 const FloatArray &lcoords = gp->giveNaturalCoordinates();
237 dV = detJ * gp->giveWeight() * rho;
240 for (
int j = 0; j <
N.giveSize(); j++ ) {
241 temparray(3 * j + 0) +=
N(j) * rho * gVector(0) * dV;
242 temparray(3 * j + 1) +=
N(j) * rho * gVector(1) * dV;
243 temparray(3 * j + 2) +=
N(j) * rho * gVector(2) * dV;
246 temparray(12) +=
N(0) *
N(1) *
N(2) *
N(3) * rho * gVector(0) * dV;
247 temparray(13) +=
N(0) *
N(1) *
N(2) *
N(3) * rho * gVector(1) * dV;
248 temparray(14) +=
N(0) *
N(1) *
N(2) *
N(3) * rho * gVector(1) * dV;
260 if ( type != ExternalForcesVector ) {
266 int numberOfIPs = ( int ) ceil( ( load->
giveApproxOrder() + 2. ) / 2. );
274 for (
auto &gp: iRule ) {
275 const FloatArray &lcoords = gp->giveNaturalCoordinates();
279 double dA = gp->giveWeight() * detJ;
290 for (
int j = 0; j <
N.giveSize(); j++ ) {
291 f(3 * j + 0) +=
N(j) * t(0) * dA;
292 f(3 * j + 1) +=
N(j) * t(1) * dA;
293 f(3 * j + 2) +=
N(j) * t(2) * dA;
307void Tet1BubbleStokes :: computeStiffnessMatrix(
FloatMatrix &answer, MatResponseMode mode,
TimeStep *tStep)
318 const auto &lcoords = gp->giveNaturalCoordinates();
320 auto N = this->
interp.evalN( lcoords );
322 auto dN = detj_dn.second;
323 auto detJ = detj_dn.first;
324 auto dA = std::abs(detJ) * gp->giveWeight();
328 for ( std::size_t j = 0, k = 0; j < dN.rows(); j++, k += 3 ) {
329 dN_V[k + 0] = B(0, k + 0) = B(5, k + 1) = B(4, k + 2) = dN(0, j);
330 dN_V[k + 1] = B(1, k + 1) = B(5, k + 0) = B(3, k + 2) = dN(1, j);
331 dN_V[k + 2] = B(2, k + 2) = B(4, k + 0) = B(3, k + 1) = dN(2, j);
335 dN_V[12] = B(0, 12) = B(5, 13) = B(4, 14) = dN(0, 0) *
N[1] *
N[2] *
N[3] +
N[0] * dN(1, 0) *
N[2] *
N[3] +
N[0] *
N[1] * dN(2, 0) *
N[3] +
N[0] *
N[1] *
N[2] * dN(3, 0);
336 dN_V[13] = B(1, 13) = B(5, 12) = B(3, 14) = dN(0, 1) *
N[1] *
N[2] *
N[3] +
N[0] * dN(1, 1) *
N[2] *
N[3] +
N[0] *
N[1] * dN(2, 1) *
N[3] +
N[0] *
N[1] *
N[2] * dN(3, 1);
337 dN_V[14] = B(2, 14) = B(4, 12) = B(3, 13) = dN(0, 2) *
N[1] *
N[2] *
N[3] +
N[0] * dN(1, 2) *
N[2] *
N[3] +
N[0] *
N[1] * dN(2, 2) *
N[3] +
N[0] *
N[1] *
N[2] * dN(3, 2);
343 K.plusProductSymmUpper(B,
dot(tangents.dsdd, B), dA);
344 G.plusDyadUnsym(dN_V,
N, -dA);
345 Dp.plusDyadUnsym(
Tdot(B, tangents.dsdp),
N, dA);
346 DvT.plusDyadUnsym(
N,
Tdot(B, tangents.dedd), dA);
347 C.plusDyadSymmUpper(
N, tangents.dedp * dA);
373void Tet1BubbleStokes :: updateYourself(
TimeStep *tStep)
375 Element :: updateYourself(tStep);
390 return FMElement :: giveInterface(it);
405 for (
int i = 1; i <= n.
giveSize(); i++ ) {
406 answer(0) += n.
at(i) * velocities.
at(i*3-2);
407 answer(1) += n.
at(i) * velocities.
at(i*3-1);
408 answer(2) += n.
at(i) * velocities.
at(i*3);
410 answer(0) += n.
at(1) * n.
at(2) * n.
at(3) * n.
at(4) * velocities.
at(13);
411 answer(1) += n.
at(1) * n.
at(2) * n.
at(3) * n.
at(4) * velocities.
at(14);
412 answer(2) += n.
at(1) * n.
at(2) * n.
at(3) * n.
at(4) * velocities.
at(15);
414 for (
int i = 1; i <= n_lin.
giveSize(); i++ ) {
415 answer(3) += n_lin.
at(i) * pressures.
at(i);
#define REGISTER_Element(class)
bcType giveType() const override
void computeValueAt(FloatArray &answer, TimeStep *tStep, const FloatArray &coords, ValueModeType mode) override
int giveApproxOrder() override=0
IntArray boundaryLoadArray
IntArray * giveBodyLoadArray()
Returns array containing load numbers of loads acting on element.
int numberOfDofMans
Number of dofmanagers.
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
std::vector< std ::unique_ptr< IntegrationRule > > integrationRulesArray
CrossSection * giveCrossSection()
Domain * domain
Link to domain object, useful for communicating with other FEM components.
void computeVectorOfPressures(ValueModeType mode, TimeStep *tStep, FloatArray &pressures)
void computeVectorOfVelocities(ValueModeType mode, TimeStep *tStep, FloatArray &velocities)
FMElement(int n, Domain *aDomain)
void assemble(const FloatArray &fe, const IntArray &loc)
Index giveSize() const
Returns the size of receiver.
void zero()
Zeroes all coefficients of receiver.
void add(const FloatArray &src)
void resize(Index rows, Index cols)
void zero()
Zeroes all coefficient of receiver.
void assemble(const FloatMatrix &src, const IntArray &loc)
virtual Tangents< 6 > computeTangents3D(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
virtual std::pair< FloatArrayF< 6 >, double > computeDeviatoricStress3D(const FloatArrayF< 6 > &eps, double pressure, GaussPoint *gp, TimeStep *tStep) const
int SetUpPointsOnTriangle(int nPoints, MaterialMode mode) override
const FloatArray & giveNaturalCoordinates() const
Returns coordinate array of receiver.
double giveWeight()
Returns integration weight of receiver.
virtual bcGeomType giveBCGeoType() const
virtual bcValType giveBCValType() const
virtual void computeComponentArrayAt(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
virtual FormulationType giveFormulationType()
SpatialLocalizerInterface(Element *element)
void computeInternalForcesVector(FloatArray &answer, TimeStep *tStep)
static FEI3dTetLin interp
Interpolation for pressure.
void computeLoadVector(FloatArray &answer, BodyLoad *load, CharType type, ValueModeType mode, TimeStep *tStep) override
std ::unique_ptr< ElementDofManager > bubble
The extra dofs from the bubble.
static IntArray momentum_ordering
Ordering of dofs in element. Used to assemble the element stiffness.
void computeBoundarySurfaceLoadVector(FloatArray &answer, BoundaryLoad *load, int boundary, CharType type, ValueModeType mode, TimeStep *tStep, bool global=true) override
static IntArray conservation_ordering
void computeExternalForcesVector(FloatArray &answer, TimeStep *tStep)
static IntArray surf_ordering[4]
Ordering of dofs on surfaces. Used to assemble surface loads.
void computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, TimeStep *tStep)
ZZNodalRecoveryModelInterface(Element *element)
Constructor.
FloatMatrixF< M, N > transpose(const FloatMatrixF< N, M > &mat)
Constructs transposed matrix.
FloatMatrixF< N, P > Tdot(const FloatMatrixF< M, N > &a, const FloatMatrixF< M, P > &b)
Computes .
bcGeomType
Type representing the geometric character of loading.
@ SurfaceLoadBGT
Distributed surface load.
@ BodyLoadBGT
Distributed body load.
double dot(const FloatArray &x, const FloatArray &y)
@ ZZNodalRecoveryModelInterfaceType
@ SpatialLocalizerInterfaceType
@ TransmissionBC
Neumann type (prescribed flux).