OOFEM 3.0
Loading...
Searching...
No Matches
structuralfe2material.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
36#include "gausspoint.h"
37#include "engngm.h"
38#include "oofemtxtdatareader.h"
39#include "floatmatrix.h"
40#include "floatarray.h"
41#include "dynamicinputrecord.h"
42#include "classfactory.h"
43#include "util.h"
44#include "contextioerr.h"
47#include "exportmodulemanager.h"
48#include "vtkxmlexportmodule.h"
49#include "nummet.h"
54#include "mathfem.h"
55
56#include "dynamicdatareader.h"
57
58#include <sstream>
59
60namespace oofem {
62
63int StructuralFE2Material :: n = 1;
64
65StructuralFE2Material :: StructuralFE2Material(int n, Domain *d) : StructuralMaterial(n, d)
66{}
67
68
69void
70StructuralFE2Material :: initializeFrom(InputRecord &ir)
71{
72 StructuralMaterial :: initializeFrom(ir);
74
76}
77
78
79void
80StructuralFE2Material :: giveInputRecord(DynamicInputRecord &input)
81{
82 StructuralMaterial :: giveInputRecord(input);
84
85 if ( useNumTangent ) {
87 }
88}
89
90
91std::unique_ptr<MaterialStatus>
92StructuralFE2Material :: CreateStatus(GaussPoint *gp) const
93{
94 int rank = -1;
95 auto emodel = this->domain->giveEngngModel();
96 if ( emodel->isParallel() && emodel->giveNumberOfProcesses() > 1 ) {
97 rank = emodel->giveRank();
98 }
99 return std::make_unique<StructuralFE2MaterialStatus>(rank, gp, this->inputfile);
100}
101
102
104StructuralFE2Material :: giveRealStressVector_3d(const FloatArrayF<6> &strain, GaussPoint *gp, TimeStep *tStep) const
105{
106 auto ms = static_cast< StructuralFE2MaterialStatus * >( this->giveStatus(gp) );
107
108#if 0
109 XfemStructureManager *xMan = dynamic_cast<XfemStructureManager*>( ms->giveRVE()->giveDomain(1)->giveXfemManager() );
110 if(xMan) {
111 printf("Total crack length in RVE: %e\n", xMan->computeTotalCrackLength() );
112 }
113#endif
114
115 ms->setTimeStep(tStep);
116 // Set input
117 ms->giveBC()->setPrescribedGradientVoigt(strain);
118 // Solve subscale problem
119 ms->giveRVE()->solveYourselfAt(tStep);
120 // Post-process the stress
121 FloatArray stress;
122 ms->giveBC()->computeField(stress, tStep);
123
124 FloatArrayF<6> answer;
125 if ( stress.giveSize() == 6 ) {
126 answer = stress;
127 } else if ( stress.giveSize() == 9 ) {
128 answer = {stress[0], stress[1], stress[2], 0.5*(stress[3]+stress[6]), 0.5*(stress[4]+stress[7]), 0.5*(stress[5]+stress[8])};
129 } else if ( stress.giveSize() == 4 ) {
130 // 2D mode is a bit wonky in FE2 code right now. It doesn't actually deal with plane strain out-of-plane component correctly.
131 // Instead gives just the 2D state, non-symmetrically.
132 // This needs to be cleared up and made consistent, to take out the guesswork on what computeField() actually computes.
133 answer = {stress[0], stress[1], 0., 0., 0., 0.5*(stress[2]+stress[3])};
134 } else {
135 answer = {stress[0], 0., 0., 0., 0., 0.};
136 }
137
138 // Update the material status variables
139 ms->letTempStressVectorBe(answer);
140 ms->letTempStrainVectorBe(strain);
141 ms->markOldTangent(); // Mark this so that tangent is reevaluated if they are needed.
142 return answer;
143}
144
145
147StructuralFE2Material :: give3dMaterialStiffnessMatrix(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
148{
149 auto status = static_cast<StructuralFE2MaterialStatus*>( this->giveStatus( gp ) );
150 if ( useNumTangent ) {
151 // Numerical tangent
152 double h = 1.0e-9;
153
154 FloatArrayF<6> eps = status->giveTempStrainVector();
155 FloatArrayF<6> sig = status->giveTempStressVector();
156
157 FloatMatrixF<6,6> answer;
158 for(int i = 0; i < 6; i++) {
159 // Add a small perturbation to the strain
160 auto epsPert = eps;
161 epsPert[i] += h;
162
163 auto sigPert = const_cast<StructuralFE2Material*>(this)->giveRealStressVector_3d(epsPert, gp, tStep);
164 answer.setColumn((sigPert - sig) / h, i);
165 }
166 const_cast<StructuralFE2Material*>(this)->giveRealStressVector_3d(eps, gp, tStep);
167 return answer;
168
169 } else {
170 status->computeTangent(tStep);
171 const auto &ans9 = status->giveTangent();
172 FloatMatrix answer;
174 return answer;
175
176// printf("ans9: "); ans9.printYourself();
177//
178// // Compute the (minor) symmetrized tangent:
179// answer.resize(6, 6);
180// for ( int i = 0; i < 6; ++i ) {
181// for ( int j = 0; j < 6; ++j ) {
182// answer(i, j) = ans9(i, j);
183// }
184// }
185// for ( int i = 0; i < 6; ++i ) {
186// for ( int j = 6; j < 9; ++j ) {
187// answer(i, j-3) += ans9(i, j);
188// answer(j-3, i) += ans9(j, i);
189// }
190// }
191// for ( int i = 6; i < 9; ++i ) {
192// for ( int j = 6; j < 9; ++j ) {
193// answer(j-3, i-3) += ans9(j, i);
194// }
195// }
196// for ( int i = 0; i < 6; ++i ) {
197// for ( int j = 3; j < 6; ++j ) {
198// answer(j, i) *= 0.5;
199// answer(i, j) *= 0.5;
200// }
201// }
202
203
204
205#if 0
206 // Numerical ATS for debugging
207 FloatMatrix numericalATS(6, 6);
208 FloatArray dsig;
209 // Note! We need a copy of the temp strain, since the pertubations might change it.
210 FloatArray tempStrain = ms->giveTempStrainVector();
211
212 FloatArray sig, strain, sigPert;
213 giveRealStressVector_3d(sig, gp, tempStrain, tStep);
214 double hh = 1e-6;
215 for ( int k = 1; k <= 6; ++k ) {
216 strain = tempStrain;
217 strain.at(k) += hh;
218 giveRealStressVector_3d(sigPert, gp, strain, tStep);
219 dsig.beDifferenceOf(sigPert, sig);
220 numericalATS.setColumn(dsig, k);
221 }
222 numericalATS.times(1. / hh);
223 giveRealStressVector_3d(sig, gp, tempStrain, tStep); // Reset
224
225 //answer.printYourself("Analytical deviatoric tangent");
226 //numericalATS.printYourself("Numerical deviatoric tangent");
227
228 numericalATS.subtract(answer);
229 double norm = numericalATS.computeFrobeniusNorm();
230 if ( norm > answer.computeFrobeniusNorm() * 1e-3 && norm > 0.0 ) {
231 OOFEM_ERROR("Error in deviatoric tangent");
232 }
233#endif
234 }
235}
236
238StructuralFE2Material :: givePlaneStrainStiffMtrx(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
239{
241 auto status = static_cast<StructuralFE2MaterialStatus*>( this->giveStatus( gp ) );
242 if ( useNumTangent ) {
243 // Numerical tangent
244 double h = 1.0e-9;
245
246 auto eps = FloatArrayF<6>(status->giveTempStrainVector())[{0, 1, 2, 5}];
247 auto sig = FloatArrayF<6>(status->giveTempStressVector())[{0, 1, 2, 5}];
248
249
250 FloatMatrixF<4,4> answer;
251 for(int i = 0; i < 4; i++) {
252 // Add a small perturbation to the strain
253 auto epsPert = eps;
254 epsPert[i] += h;
255
256 auto sigPert = this->giveRealStressVector_PlaneStrain(epsPert, gp, tStep);
257 answer.setColumn((sigPert - sig) / h, i);
258 }
259 this->giveRealStressVector_PlaneStrain(eps, gp, tStep);
260 return answer;
261
262 } else {
263 status->computeTangent(tStep);
264 return status->giveTangent();
265 }
266}
267
270{
271 auto ms = static_cast<StructuralFE2MaterialStatus*>( this->giveStatus(gp) );
272
273 ms->setTimeStep(tStep);
274 // Set input
275 ms->giveBC()->setPrescribedGradientVoigt(strain);
276 // Solve subscale problem
277 ms->giveRVE()->solveYourselfAt(tStep);
278 // Post-process the stress
279 FloatArray stress;
280 ms->giveBC()->computeField(stress, tStep);
281
282 FloatArrayF<6> updateStress;
283 updateStress = {stress[0], stress[1], 0., 0., 0., 0.5*(stress[2]+stress[3])};
284
285 FloatArrayF<6> updateStrain;
286 updateStrain = {strain[0], strain[1], 0., 0., 0., strain[2]};
287
288 FloatArrayF<3> answer;
289 answer = {stress[0], stress[1], 0.5*(stress[2]+stress[3])};
290
291 // Update the material status variables
292 ms->letTempStressVectorBe(updateStress);
293 ms->letTempStrainVectorBe(updateStrain);
294 ms->markOldTangent(); // Mark this so that tangent is reevaluated if they are needed.
295
296 return answer;
297
298}
299
301StructuralFE2Material::givePlaneStressStiffMtrx( MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep ) const
302{
303 if (useNumTangent) {
304 //Numerical tangent
305 auto status = static_cast<StructuralFE2MaterialStatus*>(this->giveStatus(gp));
306 double h = 1.0e-9;
307
308 FloatArrayF<6> eps = status->giveTempStrainVector();
309 FloatArrayF<6> sig = status->giveTempStressVector();
310
311 FloatArrayF<3> epsRed = {eps[0], eps[1], eps[5]};
312 FloatArrayF<3> sigRed = {sig[0], sig[1], sig[5]};
313
314 FloatMatrixF<3,3> answer;
315 for (int i=0; i < 3; i++) {
316 //Add a small perturbation to the strain
317 auto epsPert = epsRed;
318 epsPert[i] += h;
319
320 auto sigPert = const_cast<StructuralFE2Material*>(this)->giveRealStressVector_PlaneStress(epsPert, gp, tStep);
321 answer.setColumn((sigPert - sigRed) / h, i);
322 }
323 const_cast<StructuralFE2Material*>(this)->giveRealStressVector_PlaneStress(epsRed, gp, tStep);
324 return answer;
325 } else {
326 auto status = static_cast<StructuralFE2MaterialStatus*>(this->giveStatus(gp));
327 FloatMatrix tangent;
328 status->computeTangent(tStep); //implemented by BC
329 tangent.beSubMatrixOf(status->giveTangent(), {1,2,3}, {1,2,3});
330 FloatMatrixF<3,3> answer;
331 answer = tangent;
332 return answer;
333 }
334
335}
336
337
338//=============================================================================
339
340
341StructuralFE2MaterialStatus :: StructuralFE2MaterialStatus(int rank, GaussPoint * g, const std :: string & inputfile) :
343 mInputFile(inputfile)
344{
345 if ( !this->createRVE(1, inputfile, rank) ) {
346 OOFEM_ERROR("Couldn't create RVE");
347 }
348 stressVector.resize(6);
349 strainVector.resize(6);
350 tempStressVector.resize(6);
351 tempStrainVector.resize(6);
352}
353
355{
356 this->bc = dynamic_cast< PrescribedGradientHomogenization * >( this->rve->giveDomain(1)->giveBc(1) );
357 return this->bc;
358}
359
360
361bool
362StructuralFE2MaterialStatus :: createRVE(int n, const std :: string &inputfile, int rank)
363{
364 OOFEMTXTDataReader dr( inputfile.c_str() );
365 this->rve = InstanciateProblem(dr, _processor, 0); // Everything but nrsolver is updated.
366 dr.finish();
367 this->rve->setProblemScale(microScale);
368 this->rve->checkProblemConsistency();
369 this->rve->initMetaStepAttributes( this->rve->giveMetaStep(1) );
370 this->rve->giveNextStep(); // Makes sure there is a timestep (which we will modify before solving a step)
371 this->rve->init();
372
373 std :: ostringstream name;
374 name << this->rve->giveOutputBaseFileName() << "-gp" << n;
375 if ( rank >= 0 ) {
376 name << "." << rank;
377 }
378
379 this->rve->letOutputBaseFileNameBe( name.str() );
380
381 this->bc = dynamic_cast< PrescribedGradientHomogenization * >( this->rve->giveDomain(1)->giveBc(1) );
382 if ( !this->bc ) {
383 OOFEM_ERROR("RVE doesn't have necessary boundary condition; should have a type of PrescribedGradientHomogenization as first b.c.");
384 }
385
386 return true;
387}
388
389void
390StructuralFE2MaterialStatus :: setTimeStep(TimeStep *tStep)
391{
392 TimeStep *rveTStep = this->rve->giveCurrentStep(); // Should i create a new one if it is empty?
393 rveTStep->setNumber( tStep->giveNumber() );
394 rveTStep->setTime( tStep->giveTargetTime() );
395 rveTStep->setTimeIncrement( tStep->giveTimeIncrement() );
396}
397
398void
399StructuralFE2MaterialStatus :: initTempStatus()
400{
401 StructuralMaterialStatus :: initTempStatus();
402}
403
404void
405StructuralFE2MaterialStatus :: markOldTangent() { this->oldTangent = true; }
406
407void
408StructuralFE2MaterialStatus :: computeTangent(TimeStep *tStep)
409{
410 if ( !tStep->isTheCurrentTimeStep() ) {
411 OOFEM_ERROR("Only current timestep supported.");
412 }
413
414 if ( this->oldTangent ) {
415 bc->computeTangent(this->giveTangent(), tStep);
416 }
417
418 this->oldTangent = false;
419}
420
421void
422StructuralFE2MaterialStatus :: updateYourself(TimeStep *tStep)
423{
424 StructuralMaterialStatus :: updateYourself(tStep);
425 this->rve->updateYourself(tStep);
426 this->rve->terminate(tStep);
427
428 mNewlyInitialized = false;
429}
430
431
432void
433StructuralFE2MaterialStatus :: saveContext(DataStream &stream, ContextMode mode)
434{
435 StructuralMaterialStatus :: saveContext(stream, mode);
436 this->rve->saveContext(stream, mode);
437}
438
439
440void
441StructuralFE2MaterialStatus :: restoreContext(DataStream &stream, ContextMode mode)
442{
443 StructuralMaterialStatus :: restoreContext(stream, mode);
444 this->rve->restoreContext(stream, mode);
445}
446
447double StructuralFE2MaterialStatus :: giveRveLength()
448{
449 return sqrt( bc->domainSize() );
450}
451
452void StructuralFE2MaterialStatus :: copyStateVariables(const MaterialStatus &iStatus)
453{
454 //static int num = 0;
455 //printf("Entering StructuralFE2MaterialStatus :: copyStateVariables.\n");
456
457 this->oldTangent = true;
458
459// if ( !this->createRVE(this->giveNumber(), gp, mInputFile) ) {
460// OOFEM_ERROR("Couldn't create RVE");
461// }
462
463
464 StructuralMaterialStatus :: copyStateVariables(iStatus);
465
466
468 const StructuralFE2MaterialStatus *fe2ms = dynamic_cast<const StructuralFE2MaterialStatus*>(&iStatus);
469
470 if ( !fe2ms ) {
471 OOFEM_ERROR("Failed to cast StructuralFE2MaterialStatus.")
472 }
473
474
476
477 // The proper way to do this would be to clone the RVE from iStatus.
478 // However, this is a mess due to all pointers that need to be tracked.
479 // Therefore, we consider a simplified version: copy only the enrichment items.
480
481 Domain *ext_domain = fe2ms->giveRVE()->giveDomain(1);
482 if ( ext_domain->hasXfemManager() ) {
483
484 Domain *rve_domain = rve->giveDomain(1);
485
486 XfemManager *ext_xMan = ext_domain->giveXfemManager();
487 XfemManager *this_xMan = rve->giveDomain(1)->giveXfemManager();
488 DynamicDataReader dataReader("fe2");
489 if ( ext_xMan != NULL ) {
490
491 std::vector<std::unique_ptr<EnrichmentItem>> eiList;
492
493 //auto &xmanRec = std::make_unique<DynamicInputRecord>();
494 //ext_xMan->giveInputRecord(* xmanRec);
495 //dataReader.insertInputRecord(DataReader :: IR_xfemManRec, xmanRec);
496
497 // Enrichment items
498 int nEI = ext_xMan->giveNumberOfEnrichmentItems();
499 for ( int i = 1; i <= nEI; i++ ) {
500 EnrichmentItem *ext_ei = ext_xMan->giveEnrichmentItem(i);
501 ext_ei->appendInputRecords(dataReader);
502
503
504 auto &mir = dataReader.giveInputRecord(DataReader :: IR_enrichItemRec, i);
505 std :: string name;
506 mir.giveRecordKeywordField(name);
507
508 std :: unique_ptr< EnrichmentItem >ei( classFactory.createEnrichmentItem( name.c_str(), i, this_xMan, rve_domain ) );
509 if ( ei.get() == NULL ) {
510 OOFEM_ERROR( "unknown enrichment item (%s)", name.c_str() );
511 }
512
513 ei->initializeFrom(mir);
514 ei->instanciateYourself(dataReader);
515 eiList.push_back( std :: move(ei) );
516
517 }
518
519 this_xMan->clearEnrichmentItems();
520 this_xMan->appendEnrichmentItems(eiList);
521
522 rve_domain->postInitialize();
523 rve->forceEquationNumbering();
524 }
525
526 }
527
528 //printf("done.\n");
529
530#if 0
531 Domain *newDomain = fe2ms->giveRVE()->giveDomain(1)->Clone();
532 newDomain->SetEngngModel(rve.get());
533 bool deallocateOld = true;
534 rve->setDomain(1, newDomain, deallocateOld);
535
536 //rve->giveDomain(1)->postInitialize();
537 rve->giveNumericalMethod(NULL)->setDomain(newDomain);
538
539 rve->postInitialize();
540 //rve->forceEquationNumbering();
541
542 rve->initMetaStepAttributes( rve->giveMetaStep(1) );
543 rve->giveNextStep(); // Makes sure there is a timestep (which we will modify before solving a step)
544 rve->init();
545
546
547// std :: ostringstream name;
548// name << this->rve->giveOutputBaseFileName() << "-gp" << n;
549// this->rve->letOutputBaseFileNameBe( name.str() );
550// n++;
551
552 double crackLength = 0.0;
553 XfemStructureManager *xMan = dynamic_cast<XfemStructureManager*>( rve->giveDomain(1)->giveXfemManager() );
554 if ( xMan ) {
555 crackLength = xMan->computeTotalCrackLength();
556 }
557
558 std :: ostringstream name;
559 name << this->rve->giveOutputBaseFileName() << "-gp" << num << "crackLength" << crackLength;
560 if ( this->domain->giveEngngModel()->isParallel() && this->domain->giveEngngModel()->giveNumberOfProcesses() > 1 ) {
561 name << "." << this->domain->giveEngngModel()->giveRank();
562 }
563
564 num++;
565
566 this->rve->letOutputBaseFileNameBe( name.str() );
567
568
569 // Update BC
570 this->bc = dynamic_cast< PrescribedGradientHomogenization * >( this->rve->giveDomain(1)->giveBc(1) );
571
572#if 1
573
574 XfemSolverInterface *xfemSolInt = dynamic_cast<XfemSolverInterface*>(rve.get());
575 StaticStructural *statStruct = dynamic_cast<StaticStructural*>(rve.get());
576 if ( xfemSolInt && statStruct ) {
577 //printf("Successfully casted to XfemSolverInterface.\n");
578
579 TimeStep *tStep = rve->giveCurrentStep();
580
582 int numDofsNew = rve->giveNumberOfDomainEquations( 1, num );
583 FloatArray u;
584 u.resize(numDofsNew);
585 u.zero();
586
587 xfemSolInt->xfemUpdatePrimaryField(*statStruct, tStep, u);
588
589 // Set domain pointer to various components ...
590 rve->giveNumericalMethod(NULL)->setDomain(newDomain);
591 //ioEngngModel.nMethod->setDomain(domain);
592
593 }
594
595// TimeStep *tStep = rve->giveNextStep();
596// setTimeStep(tStep);
597// rve->solveYourselfAt(tStep);
598
599
600 int numExpModules = rve->giveExportModuleManager()->giveNumberOfModules();
601 for ( int i = 1; i <= numExpModules; i++ ) {
602 // ... by diving deep into the hierarchies ... :-/
603 VTKXMLExportModule *vtkxmlMod = dynamic_cast< VTKXMLExportModule * >( rve->giveExportModuleManager()->giveModule(i) );
604 if ( vtkxmlMod != NULL ) {
605 vtkxmlMod->giveSmoother()->setDomain(newDomain);
606 vtkxmlMod->givePrimVarSmoother()->setDomain(newDomain);
607 }
608 }
609#endif
610#endif
611}
612
613
614} // end namespace oofem
#define REGISTER_Material(class)
void SetEngngModel(EngngModel *ipEngngModel)
Definition domain.h:335
void postInitialize()
Definition domain.C:1023
XfemManager * giveXfemManager()
Definition domain.C:378
bool hasXfemManager()
Definition domain.C:389
InputRecord & giveInputRecord(InputRecordType, int recordId) override
void setField(int item, InputFieldType id)
Domain * giveDomain(int n)
Definition engngm.C:1936
virtual void appendInputRecords(DynamicDataReader &oDR)=0
Domain * giveDomain() const
Definition femcmpnn.h:97
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition femcmpnn.h:79
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 beDifferenceOf(const FloatArray &a, const FloatArray &b)
Definition floatarray.C:403
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void setColumn(const FloatArrayF< N > &src, std::size_t c)
void times(double f)
void beSubMatrixOf(const FloatMatrix &src, Index topRow, Index bottomRow, Index topCol, Index bottomCol)
void setColumn(const FloatArray &src, int c)
double computeFrobeniusNorm() const
void subtract(const FloatMatrix &a)
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
virtual void giveRecordKeywordField(std ::string &answer, int &value)=0
Reads the record id field (type of record) and its corresponding number.
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
void setDomain(Domain *ipDomain)
PrescribedGradientHomogenization * giveBC()
void setTimeStep(TimeStep *tStep)
Copies time step data to RVE.
StructuralFE2MaterialStatus(int rank, GaussPoint *g, const std ::string &inputfile)
bool createRVE(int n, const std ::string &inputfile, int rank)
Creates/Initiates the RVE problem.
PrescribedGradientHomogenization * bc
Boundary condition in RVE that performs the computational homogenization.
std ::unique_ptr< EngngModel > rve
The RVE.
FloatArrayF< 6 > giveRealStressVector_3d(const FloatArrayF< 6 > &strain, GaussPoint *gp, TimeStep *tStep) const override
Default implementation relies on giveRealStressVector for second Piola-Kirchoff stress.
FloatMatrixF< 3, 3 > givePlaneStressStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const override
FloatArrayF< 3 > giveRealStressVector_PlaneStress(const FloatArrayF< 3 > &strain, GaussPoint *gp, TimeStep *tStep) const override
Default implementation relies on giveRealStressVector_StressControl.
StructuralMaterialStatus(GaussPoint *g)
Constructor. Creates new StructuralMaterialStatus with IntegrationPoint g.
FloatArray tempStrainVector
Temporary strain vector in reduced form (to find balanced state).
FloatArray tempStressVector
Temporary stress vector in reduced form (increments are used mainly in nonlinear analysis).
FloatArray stressVector
Equilibrated stress vector in reduced form.
FloatArray strainVector
Equilibrated strain vector in reduced form.
StructuralMaterial(int n, Domain *d)
virtual FloatArrayF< 4 > giveRealStressVector_PlaneStrain(const FloatArrayF< 4 > &strain, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveRealStressVector_3d.
static void giveReducedSymMatrixForm(FloatMatrix &answer, const FloatMatrix &full, MaterialMode matMode)
Converts the full unsymmetric Voigt matrix (4th order tensor) to reduced form.
double giveTimeIncrement()
Returns solution step associated time increment.
Definition timestep.h:168
void setNumber(int i)
Set receiver's number.
Definition timestep.h:146
double giveTargetTime()
Returns target time.
Definition timestep.h:164
void setTimeIncrement(double newDt)
Sets solution step time increment.
Definition timestep.h:170
int giveNumber()
Returns receiver's number.
Definition timestep.h:144
bool isTheCurrentTimeStep()
Definition timestep.C:164
void setTime(double newt)
Sets target and intrinsic time to be equal.
Definition timestep.h:172
NodalRecoveryModel * givePrimVarSmoother()
Returns the smoother for primary variables (nodal averaging).
NodalRecoveryModel * giveSmoother()
Returns the internal smoother.
void clearEnrichmentItems()
Remove all enrichment items.
void appendEnrichmentItems(std ::vector< std ::unique_ptr< EnrichmentItem > > &iEIlist)
EnrichmentItem * giveEnrichmentItem(int n)
int giveNumberOfEnrichmentItems() const
double computeTotalCrackLength()
Compute the total length of all cracks in the domain.
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
long ContextMode
Definition contextmode.h:43
double norm(const FloatArray &x)
std::unique_ptr< EngngModel > InstanciateProblem(DataReader &dr, problemMode mode, int contextFlag, EngngModel *_master, bool parallelFlag)
Definition util.C:153
ClassFactory & classFactory
@ _processor
Definition problemmode.h:40
@ microScale
Definition problemmode.h:47
#define _IFT_StructuralFE2Material_fileName
#define _IFT_StructuralFE2Material_useNumericalTangent

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