OOFEM 3.0
Loading...
Searching...
No Matches
basemixedpressureelement.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 *
14 * Copyright (C) 1993 - 2025 Borek Patzak
15 *
16 *
17 *
18 * Czech Technical University, Faculty of Civil Engineering,
19 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
20 *
21 * This library is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU Lesser General Public
23 * License as published by the Free Software Foundation; either
24 * version 2.1 of the License, or (at your option) any later version.
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 * Lesser General Public License for more details.
30 *
31 * You should have received a copy of the GNU Lesser General Public
32 * License along with this library; if not, write to the Free Software
33 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
34 */
35
36
39
40
43
44#include "material.h"
45#include "node.h"
46#include "gausspoint.h"
48#include "domain.h"
49#include "floatmatrix.h"
50#include "floatarray.h"
51#include "intarray.h"
52#include "mathfem.h"
54
55
56#include <cstdio>
57
58namespace oofem {
59BaseMixedPressureElement :: BaseMixedPressureElement()
60{}
61
62
63
64void
65BaseMixedPressureElement :: giveLocationArrayOfDofIDs(IntArray &locationArray_u, IntArray &locationArray_p, const UnknownNumberingScheme &s, const IntArray &dofIdArray_u, const IntArray &dofIdArray_p)
66{
67 // Routine to extract the location array of an element for given dofid array.
68 locationArray_u.clear();
69 locationArray_p.clear();
70 NLStructuralElement *el = this->giveElement();
71 int k = 0;
72 IntArray nodalArray;
73 for ( int i = 1; i <= el->giveNumberOfDofManagers(); i++ ) {
74 DofManager *dMan = el->giveDofManager(i);
75 int itt = 1;
76 for ( int j = 1; j <= dofIdArray_u.giveSize(); j++ ) {
77 if ( dMan->hasDofID( ( DofIDItem ) dofIdArray_u.at(j) ) ) {
78 // Dof *d = dMan->giveDofWithID( dofIdArray_u.at( j ) );
79 locationArray_u.followedBy(k + itt);
80 }
81 itt++;
82 }
83 for ( int j = 1; j <= dofIdArray_p.giveSize(); j++ ) {
84 if ( dMan->hasDofID( ( DofIDItem ) dofIdArray_p.at(j) ) ) {
85 //Dof *d = dMan->giveDofWithID( dofIdArray_m.at( j ) );
86 locationArray_p.followedBy(k + itt);
87 }
88 itt++;
89 }
90 k += dMan->giveNumberOfDofs();
91 }
92}
93
94
95void
96BaseMixedPressureElement :: computeStressVector(FloatArray &stress, GaussPoint *gp, TimeStep *tStep)
97{
98 NLStructuralElement *elem = this->giveElement();
100
102 if ( !mixedPressureMat ) {
103 OOFEM_ERROR("Material doesn't implement the required Micromorphic interface!");
104 }
105
106 double pressure;
107
108 if ( elem->giveGeometryMode() == 0 ) {
109 FloatArray strain;
110 this->computeStrainVector(strain, gp, tStep);
111 this->computePressure(pressure, gp, tStep);
112 mixedPressureMat->giveRealStressVector(stress, gp, strain, pressure, tStep);
113 } else {
114 /* FloatArray devF;
115 * elem->computeDeviatoricDeformationGradientVector(devF, gp, tStep);
116 * this->giveDofManDofIDMask_p( IdMask_p );
117 * this->computePressure(pressure,IdMask_p, gp, tStep);
118 * mixedPressureMat->giveFiniteStrainStressVectors(stress, gp, devF, pressure, tStep);
119 */
120 OOFEM_ERROR("Large-strain formulaton is not available yet")
121 }
122}
123
124
125void
126BaseMixedPressureElement :: computeStrainVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep)
127{
128 FloatArray d_u;
129 FloatMatrix B;
130 NLStructuralElement *elem = this->giveElement();
131 IntArray IdMask_u;
132 this->giveDofManDofIDMask_u(IdMask_u);
133 this->giveElement()->computeVectorOf(IdMask_u, VM_Total, tStep, d_u);
134 elem->computeBmatrixAt(gp, B);
135 answer.beProductOf(B, d_u);
136}
137
138
139void
140BaseMixedPressureElement :: computePressure(double &answer, GaussPoint *gp, TimeStep *tStep)
141{
142 IntArray IdMask_p;
143 FloatArray d_p, N_p;
144
145 this->giveDofManDofIDMask_p(IdMask_p);
146 this->giveElement()->computeVectorOf(IdMask_p, VM_Total, tStep, d_p);
147 this->computePressureNMatrixAt(gp, N_p);
148 answer = N_p.dotProduct(d_p);
149}
150
151
152
153void
154BaseMixedPressureElement :: giveInternalForcesVector_u(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord)
155{
156 NLStructuralElement *elem = this->giveElement();
158 FloatArray BS, vStress, s, M;
159 FloatMatrix B;
160 for ( GaussPoint *gp : *elem->giveIntegrationRule(0) ) {
161 if ( useUpdatedGpRecord == 1 ) {
162 if ( this->giveElement()->giveGeometryMode() == 0 ) {
163 vStress = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveTempStressVector();
164 } else {
165 vStress = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveTempPVector();
166 }
167 } else {
168 this->computeStressVector(vStress, gp, tStep);
169 }
170
172 if ( !mixedPressureMat ) {
173 OOFEM_ERROR("Material doesn't implement the required Micromorphic interface!");
174 }
175 // Compute nodal internal forces at nodes as f = B^T*Stress dV
176 double dV = elem->computeVolumeAround(gp);
177 elem->computeBmatrixAt(gp, B);
178 BS.beTProductOf(B, vStress);
179 answer.add(dV, BS);
180 }
181}
182
183
184void
185BaseMixedPressureElement :: giveInternalForcesVector_p(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord)
186{
187 double pressure, kappa, factor;
188 IntArray IdMask_u;
189 FloatArray N_p, Bvol, d_u;
190 NLStructuralElement *elem = this->giveElement();
192
193
194 for ( GaussPoint *gp : *elem->giveIntegrationRule(0) ) {
196 if ( !mixedPressureMat ) {
197 OOFEM_ERROR("Material doesn't implement the required Mixed pressure interface!");
198 }
199 // Compute nodal internal forces at nodes as f = B^T*Stress dV
200 double dV = elem->computeVolumeAround(gp);
201 this->computePressure(pressure, gp, tStep);
202 // this->computePressureNMatrixAt(gp, N_p);
203 this->computeVolumetricBmatrixAt(gp, Bvol, elem);
204 this->giveDofManDofIDMask_u(IdMask_u);
205 elem->computeVectorOf(IdMask_u, VM_Total, tStep, d_u);
206
207 double eps_V = Bvol.dotProduct(d_u);
208 mixedPressureMat->giveInverseOfBulkModulus(kappa, TangentStiffness, gp, tStep);
209 factor = eps_V + pressure * kappa;
210 answer.times(dV * factor);
211 }
212}
213
214void
215BaseMixedPressureElement :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord)
216{
217 answer.resize( this->giveNumberOfDofs() );
218 answer.zero();
219
220 FloatArray answer_u( this->giveNumberOfDisplacementDofs() );
221 answer_u.zero();
222 FloatArray answer_p( this->giveNumberOfPressureDofs() );
223 answer_p.zero();
224
225
226 this->giveInternalForcesVector_u(answer_u, tStep, 0);
227 this->giveInternalForcesVector_p(answer_p, tStep, 0);
228 answer.assemble(answer_u, locationArray_u);
229 answer.assemble(answer_p, locationArray_p);
230}
231
232void
233BaseMixedPressureElement :: computeForceLoadVector(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
234{
235 FloatArray localForces( this->giveNumberOfDisplacementDofs() );
236 answer.resize( this->giveNumberOfDofs() );
237 this->computeLocForceLoadVector(localForces, tStep, mode);
238 answer.assemble(localForces, locationArray_u);
239}
240
241
242/************************************************************************/
243void
244BaseMixedPressureElement :: computeLocForceLoadVector(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
245// computes the part of load vector, which is imposed by force loads acting
246// on element volume (surface).
247// When reactions forces are computed, they are computed from element::GiveRealStressVector
248// in this vector a real forces are stored (temperature part is subtracted).
249// so we need further sobstract part corresponding to non-nodeal loading.
250{
251 FloatMatrix T;
252 NLStructuralElement *elem = this->giveElement();
253 //@todo check this
254 // elem->computeLocalForceLoadVector(answer, tStep, mode);
255
256 // transform result from global cs to nodal cs. if necessary
257 if ( answer.isNotEmpty() ) {
258 if ( elem->computeGtoLRotationMatrix(T) ) {
259 // first back to global cs from element local
260 answer.rotatedWith(T, 't');
261 }
262 } else {
263 answer.resize( this->giveNumberOfDisplacementDofs() );
264 answer.zero();
265 }
266}
267
268
269void
270BaseMixedPressureElement :: computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
271{
272 //set displacement and nonlocal location array
273 answer.resize( this->giveNumberOfDofs(), this->giveNumberOfDofs() );
274 answer.zero();
275
276 FloatMatrix Kuu, Kup, Kpu, Kpp;
277 this->computeStiffnessMatrix_uu(Kuu, rMode, tStep);
278 this->computeStiffnessMatrix_up(Kup, rMode, tStep);
279 Kpu.beTranspositionOf(Kup);
280 this->computeStiffnessMatrix_pp(Kpp, rMode, tStep);
281
282 answer.assemble(Kuu, locationArray_u);
285 answer.assemble(Kpp, locationArray_p);
286}
287
288
289void
290BaseMixedPressureElement :: computeStiffnessMatrix_uu(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
291{
292 NLStructuralElement *elem = this->giveElement();
294 FloatMatrix B, D, DB;
295 bool matStiffSymmFlag = elem->giveCrossSection()->isCharacteristicMtrxSymmetric(rMode);
296 answer.clear();
297 for ( GaussPoint *gp : *elem->giveIntegrationRule(0) ) {
300 if ( !mixedPressureMat ) {
301 OOFEM_ERROR("Material doesn't implement the required Mixed Pressure Material interface!");
302 }
303
304
305 mixedPressureMat->giveDeviatoricConstitutiveMatrix(D, rMode, gp, tStep);
306 elem->computeBmatrixAt(gp, B);
307 double dV = elem->computeVolumeAround(gp);
308 DB.beProductOf(D, B);
309
310 if ( matStiffSymmFlag ) {
311 answer.plusProductSymmUpper(B, DB, dV);
312 } else {
313 answer.plusProductUnsym(B, DB, dV);
314 }
315 }
316
317 if ( matStiffSymmFlag ) {
318 answer.symmetrized();
319 }
320}
321
322
323
324void
325BaseMixedPressureElement :: computeStiffnessMatrix_up(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
326{
327 double dV;
328 FloatArray N_p, Bvol;
329 NLStructuralElement *elem = this->giveElement();
330
331 answer.clear();
332
333 for ( GaussPoint *gp : *elem->giveIntegrationRule(0) ) {
334 this->computeVolumetricBmatrixAt(gp, Bvol, elem);
335 this->computePressureNMatrixAt(gp, N_p);
336 FloatMatrix mNp=FloatMatrix::fromArray(N_p, true);
337 FloatMatrix mBvol=FloatMatrix::fromArray(Bvol, true);
338
339 dV = elem->computeVolumeAround(gp);
340 answer.plusProductUnsym(mBvol, mNp, -dV);
341 }
342}
343
344void
345BaseMixedPressureElement :: computeStiffnessMatrix_pp(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
346{
347 NLStructuralElement *elem = this->giveElement();
348 double dV, kappa;
349 FloatArray N_p;
351 answer.clear();
352
353 for ( GaussPoint *gp : *elem->giveIntegrationRule(0) ) {
355 if ( !mixedPressureMat ) {
356 OOFEM_ERROR("Material doesn't implement the required Mixed Pressure Material interface!");
357 }
358
359 mixedPressureMat->giveInverseOfBulkModulus(kappa, rMode, gp, tStep);
360 this->computePressureNMatrixAt(gp, N_p);
361 FloatMatrix mN_p=FloatMatrix::fromArray(N_p, true);
362 dV = elem->computeVolumeAround(gp);
363 answer.plusProductUnsym(mN_p, mN_p, -dV * kappa);
364 }
365}
366
367
368
369void
370BaseMixedPressureElement :: initializeFrom(InputRecord &ir)
371{
372 // @todo Is this function necessary???
373}
374
375void
376BaseMixedPressureElement :: updateInternalState(TimeStep *tStep)
377// Updates the receiver at end of step.
378{
379 FloatArray stress, strain;
380 /*
381 * // force updating strains & stresses
382 * for ( auto &iRule: integrationRulesArray ) {
383 * for ( GaussPoint *gp: *iRule ) {
384 * this->computeStrainVector(strain, gp, tStep);
385 * this->computeStressVector(stress, strain, gp, tStep);
386 * }
387 * }
388 */
389}
390
391
392void
393BaseMixedPressureElement :: postInitialize()
394{
395 IntArray IdMask_u, IdMask_p;
396 this->giveDofManDofIDMask_u(IdMask_u);
397 this->giveDofManDofIDMask_p(IdMask_p);
399}
400} // end namespace oofem
void computeStiffnessMatrix_uu(FloatMatrix &, MatResponseMode, TimeStep *)
void giveInternalForcesVector_u(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord)
void computeStiffnessMatrix_up(FloatMatrix &, MatResponseMode, TimeStep *)
void computeStiffnessMatrix_pp(FloatMatrix &, MatResponseMode, TimeStep *)
void giveLocationArrayOfDofIDs(IntArray &locationArray_u, IntArray &locationArray_p, const UnknownNumberingScheme &s, const IntArray &dofIdArray_u, const IntArray &dofIdArray_p)
virtual int giveNumberOfPressureDofs()=0
virtual void giveDofManDofIDMask_p(IntArray &answer)=0
void computePressure(double &answer, GaussPoint *gp, TimeStep *tStep)
void computeStressVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep)
virtual void giveDofManDofIDMask_u(IntArray &answer)=0
void computeStrainVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep)
virtual void computePressureNMatrixAt(GaussPoint *, FloatArray &)=0
virtual void computeVolumetricBmatrixAt(GaussPoint *gp, FloatArray &Bvol, NLStructuralElement *element)=0
virtual NLStructuralElement * giveElement()=0
Pure virtual functions.
void computeLocForceLoadVector(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
void giveInternalForcesVector_p(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord)
virtual int giveNumberOfDisplacementDofs()=0
virtual bool isCharacteristicMtrxSymmetric(MatResponseMode rMode) const
bool hasDofID(DofIDItem id) const
Definition dofmanager.C:174
int giveNumberOfDofs() const
Definition dofmanager.C:287
virtual bool computeGtoLRotationMatrix(FloatMatrix &answer)
Definition element.C:1710
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Definition element.C:103
virtual IntegrationRule * giveIntegrationRule(int i)
Definition element.h:899
virtual int giveNumberOfDofManagers() const
Definition element.h:695
DofManager * giveDofManager(int i) const
Definition element.C:553
CrossSection * giveCrossSection()
Definition element.C:534
virtual double computeVolumeAround(GaussPoint *gp)
Definition element.h:530
void assemble(const FloatArray &fe, const IntArray &loc)
Definition floatarray.C:616
void resize(Index s)
Definition floatarray.C:94
double dotProduct(const FloatArray &x) const
Definition floatarray.C:524
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void rotatedWith(FloatMatrix &r, char mode)
Definition floatarray.C:814
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:721
void add(const FloatArray &src)
Definition floatarray.C:218
void times(double s)
Definition floatarray.C:834
bool isNotEmpty() const
Returns true if receiver is not empty.
Definition floatarray.h:263
void plusProductSymmUpper(const FloatMatrix &a, const FloatMatrix &b, double dV)
static FloatMatrix fromArray(const FloatArray &vector, bool transpose=false)
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
*Sets size of receiver to be an empty matrix It will have zero rows and zero columns size void clear()
void plusProductUnsym(const FloatMatrix &a, const FloatMatrix &b, double dV)
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
void beTranspositionOf(const FloatMatrix &src)
void zero()
Zeroes all coefficient of receiver.
void assemble(const FloatMatrix &src, const IntArray &loc)
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
void giveRealStressVector(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrain, double pressure, TimeStep *tStep) const
virtual void giveDeviatoricConstitutiveMatrix(FloatMatrix &answer, MatResponseMode, GaussPoint *gp, TimeStep *tStep) const
virtual void giveInverseOfBulkModulus(double &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)=0
virtual Interface * giveMaterialInterface(InterfaceType t, IntegrationPoint *ip)
StructuralCrossSection * giveStructuralCrossSection()
Helper function which returns the structural cross-section for the element.
virtual void computeBmatrixAt(GaussPoint *gp, FloatMatrix &answer, int lowerIndx=1, int upperIndx=ALL_STRAINS)=0
const FloatArray & giveTempStressVector() const
Returns the const pointer to receiver's temporary stress vector.
const FloatArray & giveTempPVector() const
Returns the const pointer to receiver's temporary first Piola-Kirchhoff stress vector.
#define OOFEM_ERROR(...)
Definition error.h:79
@ MixedPressureMaterialExtensionInterfaceType

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