OOFEM 3.0
Loading...
Searching...
No Matches
tet1bubblestokes.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
35#include "tet1bubblestokes.h"
36#include "node.h"
37#include "domain.h"
39#include "gausspoint.h"
40#include "bcgeomtype.h"
41#include "load.h"
42#include "bodyload.h"
43#include "boundaryload.h"
44#include "mathfem.h"
46#include "fei3dtetlin.h"
47#include "masterdof.h"
48#include "fluidcrosssection.h"
49#include "assemblercallback.h"
50#include "classfactory.h"
51
52namespace oofem {
54
55FEI3dTetLin Tet1BubbleStokes :: interp;
56// Set up ordering vectors (for assembling)
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}
64};
65
66Tet1BubbleStokes :: Tet1BubbleStokes(int n, Domain *aDomain) : FMElement(n, aDomain), ZZNodalRecoveryModelInterface(this), SpatialLocalizerInterface(this)
67{
68 this->numberOfDofMans = 4;
69 this->numberOfGaussPoints = 24;
70
71 this->bubble = std::make_unique<ElementDofManager>(1, aDomain, this);
72 this->bubble->appendDof( new MasterDof(this->bubble.get(), V_u) );
73 this->bubble->appendDof( new MasterDof(this->bubble.get(), V_v) );
74 this->bubble->appendDof( new MasterDof(this->bubble.get(), V_w) );
75}
76
77void Tet1BubbleStokes :: computeGaussPoints()
78{
79 if ( integrationRulesArray.size() == 0 ) {
80 integrationRulesArray.resize(1);
81 integrationRulesArray [ 0 ] = std::make_unique<GaussIntegrationRule>(1, this, 1, 3);
82 this->giveCrossSection()->setupIntegrationPoints(* integrationRulesArray [ 0 ], this->numberOfGaussPoints, this);
83 }
84}
85
86int Tet1BubbleStokes :: computeNumberOfDofs()
87{
88 return 19;
89}
90
91void Tet1BubbleStokes :: giveDofManDofIDMask(int inode, IntArray &answer) const
92{
93 answer = {V_u, V_v, V_w, P_f};
94}
95
96void Tet1BubbleStokes :: giveInternalDofManDofIDMask(int i, IntArray &answer) const
97{
98 answer = {V_u, V_v, V_w};
99}
100
101double Tet1BubbleStokes :: computeVolumeAround(GaussPoint *gp)
102{
103 double detJ = fabs( this->interp.giveTransformationJacobian( gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) ) );
104 return detJ * gp->giveWeight();
105}
106
107void Tet1BubbleStokes :: giveCharacteristicVector(FloatArray &answer, CharType mtrx, ValueModeType mode,
108 TimeStep *tStep)
109{
110 // Compute characteristic vector for this element. I.e the load vector(s)
111 if ( mtrx == ExternalForcesVector ) {
112 this->computeExternalForcesVector(answer, tStep);
113 } else if ( mtrx == InternalForcesVector ) {
114 this->computeInternalForcesVector(answer, tStep);
115 } else {
116 OOFEM_ERROR("Unknown Type of characteristic mtrx.");
117 }
118}
119
120void Tet1BubbleStokes :: giveCharacteristicMatrix(FloatMatrix &answer,
121 CharType mtrx, TimeStep *tStep)
122{
123 // Compute characteristic matrix for this element. The only option is the stiffness matrix...
124 if ( mtrx == TangentStiffnessMatrix ) {
125 this->computeStiffnessMatrix(answer, TangentStiffness, tStep);
126 } else {
127 OOFEM_ERROR("Unknown Type of characteristic mtrx.");
128 }
129}
130
131void Tet1BubbleStokes :: computeInternalForcesVector(FloatArray &answer, TimeStep *tStep)
132{
133 FluidDynamicMaterial *mat = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveFluidMaterial();
134
135 FloatArrayF<15> a_velocity = this->computeVectorOfVelocities(VM_Total, tStep);
136 FloatArrayF<4> a_pressure = this->computeVectorOfPressures(VM_Total, tStep);
137
138 FloatArrayF<15> momentum;
139 FloatArrayF<4> conservation;
140
141 for ( auto &gp: *integrationRulesArray [ 0 ] ) {
142 const auto &lcoords = gp->giveNaturalCoordinates();
143
144 auto N = this->interp.evalN( lcoords );
145 auto detj_dn = this->interp.evaldNdx( FEIElementGeometryWrapper(this) );
146 auto dN = detj_dn.second;
147 auto detJ = detj_dn.first;
148 auto dV = std::abs(detJ) * gp->giveWeight();
149
150 FloatArrayF<15> dN_V;
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);
156 }
157
158 // Bubble contribution;
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);
162
163 auto pressure = dot(N, a_pressure);
164 auto epsp = dot(B, a_velocity);
165
166 auto s_r = mat->computeDeviatoricStress3D(epsp, pressure, gp, tStep);
167 auto devStress = s_r.first;
168 auto r_vol = s_r.second;
169
170 momentum += Tdot(B, devStress * dV) + dN_V * (-pressure * dV);
171 conservation += N * (r_vol * dV);
172 }
173
174 answer.resize(19);
175 answer.zero();
176 answer.assemble(momentum, this->momentum_ordering);
177 answer.assemble(conservation, this->conservation_ordering);
178}
179
180void Tet1BubbleStokes :: computeExternalForcesVector(FloatArray &answer, TimeStep *tStep)
181{
182 FloatArray vec;
183
184 int nLoads = this->boundaryLoadArray.giveSize() / 2;
185 answer.clear();
186 for ( int i = 1; i <= nLoads; i++ ) { // For each Neumann boundary condition
187 int load_number = this->boundaryLoadArray.at(2 * i - 1);
188 int load_id = this->boundaryLoadArray.at(2 * i);
189 Load *load = this->domain->giveLoad(load_number);
190 bcGeomType ltype = load->giveBCGeoType();
191
192 if ( ltype == SurfaceLoadBGT ) {
193 this->computeBoundarySurfaceLoadVector(vec, static_cast< BoundaryLoad * >(load), load_id, ExternalForcesVector, VM_Total, tStep);
194 } else {
195 OOFEM_ERROR("Unsupported boundary condition: %d", load_id);
196 }
197
198 answer.add(vec);
199 }
200
201 BodyLoad *bload;
202 nLoads = this->giveBodyLoadArray()->giveSize();
203 for ( int i = 1; i <= nLoads; i++ ) {
204 Load *load = domain->giveLoad( bodyLoadArray.at(i) );
205 if ((bload = dynamic_cast<BodyLoad*>(load))) {
206 bcGeomType ltype = load->giveBCGeoType();
207 if ( ltype == BodyLoadBGT && load->giveBCValType() == ForceLoadBVT ) {
208 this->computeLoadVector(vec, bload, ExternalForcesVector, VM_Total, tStep);
209 answer.add(vec);
210 }
211 } else {
212 OOFEM_ERROR("Unsupported body load: %d", i);
213 }
214 }
215}
216
217
218void Tet1BubbleStokes :: computeLoadVector(FloatArray &answer, BodyLoad *load, CharType type, ValueModeType mode, TimeStep *tStep)
219{
220 if ( type != ExternalForcesVector ) {
221 answer.clear();
222 return;
223 }
224
225 FloatArray N, gVector, temparray(15);
226 double dV, detJ, rho;
227
228 // This is assumed to be the dead weight (thus multiplied by rho)
229 load->computeComponentArrayAt(gVector, tStep, VM_Total);
230 temparray.zero();
231 if ( gVector.giveSize() ) {
232 for ( auto &gp: *integrationRulesArray [ 0 ] ) {
233 const FloatArray &lcoords = gp->giveNaturalCoordinates();
234
235 rho = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveDensity(gp);
236 detJ = fabs( this->interp.giveTransformationJacobian( lcoords, FEIElementGeometryWrapper(this) ) );
237 dV = detJ * gp->giveWeight() * rho;
238
239 this->interp.evalN( N, lcoords, FEIElementGeometryWrapper(this) );
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;
244 }
245
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;
249 }
250 }
251
252 answer.resize(19);
253 answer.zero();
254 answer.assemble(temparray, this->momentum_ordering);
255}
256
257
258 void Tet1BubbleStokes :: computeBoundarySurfaceLoadVector(FloatArray &answer, BoundaryLoad *load, int iSurf, CharType type, ValueModeType mode, TimeStep *tStep, bool global)
259{
260 if ( type != ExternalForcesVector ) {
261 answer.clear();
262 return;
263 }
264
265 if ( load->giveType() == TransmissionBC ) { // Neumann boundary conditions (traction)
266 int numberOfIPs = ( int ) ceil( ( load->giveApproxOrder() + 2. ) / 2. );
267
268 GaussIntegrationRule iRule(1, this, 1, 1);
269 FloatArray N, t, f(9);
270
271 f.zero();
272 iRule.SetUpPointsOnTriangle(numberOfIPs, _Unknown);
273
274 for ( auto &gp: iRule ) {
275 const FloatArray &lcoords = gp->giveNaturalCoordinates();
276
277 this->interp.surfaceEvalN( N, iSurf, lcoords, FEIElementGeometryWrapper(this) );
278 double detJ = fabs( this->interp.surfaceGiveTransformationJacobian( iSurf, lcoords, FEIElementGeometryWrapper(this) ) );
279 double dA = gp->giveWeight() * detJ;
280
281 if ( load->giveFormulationType() == Load :: FT_Entity ) { // Edge load in xi-eta system
282 load->computeValueAt(t, tStep, lcoords, VM_Total);
283 } else { // Edge load in x-y system
284 FloatArray gcoords;
285 this->interp.boundaryLocal2Global( gcoords, iSurf, lcoords, FEIElementGeometryWrapper(this) );
286 load->computeValueAt(t, tStep, gcoords, VM_Total);
287 }
288
289 // Reshape the vector
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;
294 }
295
296 this->interp.surfaceEvalNormal( N, iSurf, lcoords, FEIElementGeometryWrapper(this) );
297 }
298
299 answer.resize(19);
300 answer.zero();
301 answer.assemble(f, this->surf_ordering [ iSurf - 1 ]);
302 } else {
303 OOFEM_ERROR("Strange boundary condition type");
304 }
305}
306
307void Tet1BubbleStokes :: computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, TimeStep *tStep)
308{
309 // Note: Working with the components; [K, G+Dp; G^T+Dv^T, C] . [v,p]
310 FluidDynamicMaterial *mat = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveFluidMaterial();
312 FloatMatrixF<15,4> G, Dp;
315
316 for ( auto &gp: *integrationRulesArray [ 0 ] ) {
317 // Compute Gauss point and determinant at current element
318 const auto &lcoords = gp->giveNaturalCoordinates();
319
320 auto N = this->interp.evalN( lcoords );
321 auto detj_dn = this->interp.evaldNdx( FEIElementGeometryWrapper(this) );
322 auto dN = detj_dn.second;
323 auto detJ = detj_dn.first;
324 auto dA = std::abs(detJ) * gp->giveWeight();
325
326 FloatArrayF<15> dN_V;
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);
332 }
333
334 // Bubble contribution;
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);
338
339 // Computing the internal forces should have been done first.
340 // dsigma_dev/deps_dev dsigma_dev/dp deps_vol/deps_dev deps_vol/dp
341 auto tangents = mat->computeTangents3D(mode, gp, tStep);
342
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);
348 }
349
350 K.symmetrized();
351 C.symmetrized();
352 auto GTDvT = transpose(G) + DvT;
353 auto GDp = G + Dp;
354
355 answer.resize(19, 19);
356 answer.zero();
357 answer.assemble(K, this->momentum_ordering);
358 answer.assemble(GTDvT, this->conservation_ordering, this->momentum_ordering);
359 answer.assemble(GDp, this->momentum_ordering, this->conservation_ordering);
360 answer.assemble(C, this->conservation_ordering);
361}
362
363FEInterpolation *Tet1BubbleStokes :: giveInterpolation() const
364{
365 return & interp;
366}
367
368FEInterpolation *Tet1BubbleStokes :: giveInterpolation(DofIDItem id) const
369{
370 return & interp;
371}
372
373void Tet1BubbleStokes :: updateYourself(TimeStep *tStep)
374{
375 Element :: updateYourself(tStep);
376}
377
378// Some extension Interfaces to follow:
379
380Interface *Tet1BubbleStokes :: giveInterface(InterfaceType it)
381{
382 switch ( it ) {
384 return static_cast< ZZNodalRecoveryModelInterface * >(this);
385
387 return static_cast< SpatialLocalizerInterface * >(this);
388
389 default:
390 return FMElement :: giveInterface(it);
391 }
392}
393
394
395void Tet1BubbleStokes :: computeField(ValueModeType mode, TimeStep *tStep, const FloatArray &lcoords, FloatArray &answer)
396{
397 FloatArray n, n_lin, pressures, velocities;
398 this->interp.evalN( n, lcoords, FEIElementGeometryWrapper(this) );
399 this->interp.evalN( n_lin, lcoords, FEIElementGeometryWrapper(this) );
400 this->computeVectorOf({P_f}, mode, tStep, pressures);
401 this->computeVectorOf({V_u, V_v, V_w}, mode, tStep, velocities);
402
403 answer.resize(4);
404 answer.zero();
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);
409 }
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);
413
414 for ( int i = 1; i <= n_lin.giveSize(); i++ ) {
415 answer(3) += n_lin.at(i) * pressures.at(i);
416 }
417}
418
419} // end namespace oofem
#define N(a, b)
#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
Definition element.h:147
IntArray * giveBodyLoadArray()
Returns array containing load numbers of loads acting on element.
Definition element.C:411
int numberOfDofMans
Number of dofmanagers.
Definition element.h:136
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Definition element.C:103
std::vector< std ::unique_ptr< IntegrationRule > > integrationRulesArray
Definition element.h:157
int numberOfGaussPoints
Definition element.h:175
CrossSection * giveCrossSection()
Definition element.C:534
IntArray bodyLoadArray
Definition element.h:147
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition femcmpnn.h:79
void computeVectorOfPressures(ValueModeType mode, TimeStep *tStep, FloatArray &pressures)
Definition fmelement.C:51
void computeVectorOfVelocities(ValueModeType mode, TimeStep *tStep, FloatArray &velocities)
Definition fmelement.C:44
FMElement(int n, Domain *aDomain)
Definition fmelement.C:38
void assemble(const FloatArray &fe, const IntArray &loc)
Definition floatarray.C:616
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void add(const FloatArray &src)
Definition floatarray.C:218
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
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.
Definition gausspoint.h:138
double giveWeight()
Returns integration weight of receiver.
Definition gausspoint.h:180
virtual bcGeomType giveBCGeoType() const
virtual void computeComponentArrayAt(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
Definition load.C:84
virtual FormulationType giveFormulationType()
Definition load.h:170
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.
#define OOFEM_ERROR(...)
Definition error.h:79
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.
Definition bcgeomtype.h:40
@ SurfaceLoadBGT
Distributed surface load.
Definition bcgeomtype.h:45
@ BodyLoadBGT
Distributed body load.
Definition bcgeomtype.h:43
double dot(const FloatArray &x, const FloatArray &y)
@ ForceLoadBVT
Definition bcvaltype.h:43
@ ZZNodalRecoveryModelInterfaceType
@ SpatialLocalizerInterfaceType
@ TransmissionBC
Neumann type (prescribed flux).
Definition bctype.h:43

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011