OOFEM 3.0
Loading...
Searching...
No Matches
latticeplasticitydamage.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 program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (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
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 */
34
36#include "gausspoint.h"
37#include "floatmatrix.h"
38#include "floatmatrixf.h"
39#include "floatarray.h"
40#include "floatarrayf.h"
41#include "engngm.h"
42#include "mathfem.h"
43#include <math.h>
44#include "latticematstatus.h"
45#include "intarray.h"
47#include "datastream.h"
48#include "contextioerr.h"
49#include "classfactory.h"
50
51namespace oofem {
53
56
57
58bool
60{
61 return mode == _3dLattice;
62}
63
64void
66{
68
69 yieldTol = 1.e-6;
71
72 newtonIter = 100;
74
77
79
81
82 this->frictionAngleOne = 0.23; //Based on fc = 10*ft and fq= ft
84 if ( this->frictionAngleOne > 0.5 ) {
85 OOFEM_WARNING("Friction angle angle1 very large. Really intended? Default value is 0.23");
86 }
87
88 this->frictionAngleTwo = 0.5;
90
91 this->flowAngleOne = this->frictionAngleOne;
93 if ( this->flowAngleOne > this->frictionAngleOne ) {
94 OOFEM_WARNING("Flow angle flow exceeds friction angle angle1. Set flow equal to angle1.\n");
95 this->flowAngleOne = this->frictionAngleOne;
96 }
97
98 this->flowAngleTwo = this->frictionAngleTwo;
99
100 softeningType = 0;
102
103 if ( softeningType > 1 ) {
104 OOFEM_ERROR("Unknown softening type");
105 }
106
108
109 double ftOne = 0.;
110 if ( softeningType == 1 ) { //bilinear softening
111 ftOne = 0.15 * this->ft;
113 this->ftOneRatio = ftOne / this->ft;
114 this->wfOne = 0.1 * this->wf;
116 }
117
118 this->aHard = 0.1;
120
121 this->damageFlag = 1;
123}
124
125double
126LatticePlasticityDamage::computeDamageParam(double kappaDOne, double kappaDTwo, GaussPoint *gp, TimeStep *tStep) const
127{
128 double ftLocal = giveTensileStrength(gp, tStep);
129 double fcLocal = giveCompressiveStrength(gp, tStep);
130
131 double le = static_cast< LatticeStructuralElement * >( gp->giveElement() )->giveLength();
132 double strength;
133 if ( ftLocal == 0 ) {
134 strength = ( fcLocal - this->frictionAngleOne * this->frictionAngleTwo * ftLocal ) / ( 1 + this->frictionAngleOne * this->frictionAngleTwo );
135 } else {
136 strength = ftLocal;
137 }
138
139 double omega = 0.;
140 if ( softeningType == 0 ) { //Default: Exponential
141 omega = 0;
142 double R = 0.;
143 int nite = 0;
144 do {
145 nite++;
146 double help = le * ( kappaDOne + omega * kappaDTwo ) / this->wf;
147 double Lhs = le * kappaDTwo / this->wf * strength * exp(-help) - kappaDTwo * this->eNormalMean;
148 R = ( 1 - omega ) * kappaDTwo * this->eNormalMean - strength * exp(-help);
149 omega -= R / Lhs;
150 if ( nite > 40 ) {
151 OOFEM_ERROR("computeDamageParam: algorithm not converging");
152 }
153 } while ( fabs(R) >= 1.e-6 || omega < 0.0 );
154 } else if ( softeningType == 1 ) { //bilinear: Calculate all damage parameters and check which makes sense
155 double omegaOne = ( this->eNormalMean * kappaDTwo * this->wfOne - ftLocal * this->wfOne - ( this->ftOneRatio * ftLocal - ftLocal ) * kappaDOne * le ) /
156 ( this->eNormalMean * kappaDTwo * this->wfOne + ( this->ftOneRatio * ftLocal - this->ftOneRatio * ftLocal ) * le * kappaDTwo );
157 double helpOne = le * kappaDOne + le * omegaOne * kappaDTwo;
158
159
160 double omegaTwo = ( this->eNormalMean * kappaDTwo * ( this->wf - this->wfOne ) - this->ftOneRatio * ftLocal * ( this->wf - this->wfOne ) +
161 this->ftOneRatio * ftLocal * kappaDOne * le - this->ftOneRatio * ftLocal * this->wfOne ) /
162 ( this->eNormalMean * kappaDTwo * ( this->wf - this->wfOne ) - this->ftOneRatio * ftLocal * le * kappaDTwo );
163 double helpTwo = le * kappaDOne + le * omegaTwo * kappaDTwo;
164
165
166 if ( helpOne >= 0. && helpOne < wfOne ) {
167 omega = omegaOne;
168 } else if ( helpTwo > wfOne && helpTwo < wf ) {
169 omega = omegaTwo;
170 } else if ( helpTwo > wf ) {
171 omega = 0.99999;
172 }
173 } else {
174 OOFEM_ERROR("Unknown softening type\n");
175 }
176
177 if ( omega > 1.0 ) {
178 omega = 0.99999;
179 } else if ( omega < 0.0 ) {
180 omega = 0.;
181 }
182
183 return omega;
184}
185
186
187std::unique_ptr<MaterialStatus>
189{
190 return std::make_unique<LatticePlasticityDamageStatus>(1, LatticePlasticityDamage::domain, gp);
191}
192
193
194double
196 const double kappa,
197 GaussPoint *gp,
198 TimeStep *tStep) const
199{
200 double ftLocal = giveTensileStrength(gp, tStep);
201 double fcLocal = giveCompressiveStrength(gp, tStep);
202
203 double yieldValue = 0;
204 double hardening = computeHardening(kappa, gp);
205 double shearNorm = norm(stress [ { 1, 2 } ]);
206 double transition = -( fcLocal - this->frictionAngleOne * this->frictionAngleTwo * ftLocal ) / ( 1. + this->frictionAngleOne * this->frictionAngleTwo ) * hardening;
207
208 if ( stress.at(1) >= transition ) { //main ellipse
209 yieldValue = pow(shearNorm, 2.) + pow(this->frictionAngleOne, 2.) * pow(stress.at(1), 2.) +
210 2. * ( fcLocal - this->frictionAngleOne * this->frictionAngleTwo * ftLocal ) * pow(this->frictionAngleOne, 2.) / ( 1. + this->frictionAngleOne * this->frictionAngleTwo ) * hardening * stress.at(1) -
211 ( 2. * fcLocal * ftLocal * pow(this->frictionAngleOne, 2.) + ( 1. - this->frictionAngleOne * this->frictionAngleTwo ) * pow(ftLocal, 2.) * pow(this->frictionAngleOne, 2.) ) / ( 1. + this->frictionAngleOne * this->frictionAngleTwo ) * pow(hardening, 2.);
212 } else { //cap ellipse
213 yieldValue = pow(shearNorm, 2.) + pow(stress.at(1) / this->frictionAngleTwo, 2.) +
214 2. * ( fcLocal - this->frictionAngleOne * this->frictionAngleTwo * ftLocal ) / ( pow(this->frictionAngleTwo, 2.) * ( 1. + this->frictionAngleOne * this->frictionAngleTwo ) ) * hardening * stress.at(1) +
215 ( pow(fcLocal, 2.) * ( 1. - pow(this->frictionAngleOne * this->frictionAngleTwo, 2.) ) -
216 2. * fcLocal * ftLocal * this->frictionAngleOne * this->frictionAngleTwo * ( 1. + this->frictionAngleOne * this->frictionAngleTwo ) ) / ( pow(this->frictionAngleTwo, 2.) * pow(1. + this->frictionAngleOne * this->frictionAngleTwo, 2.) ) * pow(hardening, 2.);
217 }
218
219 return yieldValue;
220}
221
222double
224{
225 return exp(kappa / this->aHard);
226}
227
228double
230{
231 return 1. / this->aHard * exp(kappa / this->aHard);
232}
233
234double
236{
237 return 1. / pow(this->aHard, 2.) * exp(kappa / this->aHard);
238}
239
242 const double kappa,
243 GaussPoint *gp,
244 TimeStep *tStep) const
245{
246 double ftLocal = giveTensileStrength(gp, tStep);
247 double fcLocal = giveCompressiveStrength(gp, tStep);
248
249 double hardening = computeHardening(kappa, gp);
250 double dHardeningDKappa = computeDHardeningDKappa(kappa, gp);
251 double shearNorm = norm(stress [ { 1, 2 } ]);
252 double transition = -( fcLocal - this->frictionAngleOne * this->frictionAngleTwo * ftLocal ) / ( 1. + this->frictionAngleOne * this->frictionAngleTwo ) * hardening;
253
255 if ( stress.at(1) >= transition ) { //main ellipse
256 f.at(1) = 2. * pow(this->frictionAngleOne, 2.) * stress.at(1) + 2. * ( fcLocal - this->frictionAngleOne * this->frictionAngleTwo * ftLocal ) * pow(this->frictionAngleOne, 2.) / ( 1. + this->frictionAngleOne * this->frictionAngleTwo ) * hardening;
257 f.at(2) = 2. * shearNorm;
258 f.at(3) = 2. * ( fcLocal - this->frictionAngleOne * this->frictionAngleTwo * ftLocal ) * pow(this->frictionAngleOne, 2.) / ( 1. + this->frictionAngleOne * this->frictionAngleTwo ) * stress.at(1) * dHardeningDKappa -
259 2. * ( 2. * fcLocal * ftLocal * pow(this->frictionAngleOne, 2.) + ( 1. - this->frictionAngleOne * this->frictionAngleTwo ) * pow(ftLocal, 2.) * pow(this->frictionAngleOne, 2.) ) / ( 1. + this->frictionAngleOne * this->frictionAngleTwo ) * hardening * dHardeningDKappa;
260 } else { //cap ellipse
261 f.at(1) = 2. * stress.at(1) / pow(this->frictionAngleTwo, 2.) + 2. * ( fcLocal - this->frictionAngleOne * this->frictionAngleTwo * ftLocal ) / ( pow(this->frictionAngleTwo, 2.) * ( 1. + this->frictionAngleOne * this->frictionAngleTwo ) ) * hardening;
262 f.at(2) = 2. * shearNorm;
263 f.at(3) = 2. * ( fcLocal - this->frictionAngleOne * this->frictionAngleTwo * ftLocal ) / ( pow(this->frictionAngleTwo, 2.) * ( 1. + this->frictionAngleOne * this->frictionAngleTwo ) ) * stress.at(1) * dHardeningDKappa +
264 2. * ( pow(fcLocal, 2.) * ( 1. - pow(this->frictionAngleOne * this->frictionAngleTwo, 2.) ) -
265 2. * fcLocal * ftLocal * this->frictionAngleOne * this->frictionAngleTwo * ( 1. + this->frictionAngleOne * this->frictionAngleTwo ) ) /
266 ( pow(frictionAngleTwo, 2.) * pow(1. + this->frictionAngleOne * this->frictionAngleTwo, 2.) ) * hardening * dHardeningDKappa;
267 }
268
269 return f;
270}
271
274 const double kappa,
275 GaussPoint *gp,
276 TimeStep *tStep) const
277{
278 double ftLocal = giveTensileStrength(gp, tStep);
279 double fcLocal = giveCompressiveStrength(gp, tStep);
280
281 double hardening = computeHardening(kappa, gp);
282 double shearNorm = norm(stress [ { 1, 2 } ]);
283 double transition = -( fcLocal - this->flowAngleOne * this->frictionAngleTwo * ftLocal ) / ( 1. + this->flowAngleOne * this->frictionAngleTwo ) * hardening;
284
286 if ( stress.at(1) >= transition ) { //ellipse
287 m.at(1) = 2. * pow(this->flowAngleOne, 2.) * stress.at(1) + 2. * ( fcLocal - this->flowAngleOne * this->flowAngleTwo * ftLocal ) * pow(this->flowAngleOne, 2.) / ( 1. + this->flowAngleOne * this->flowAngleTwo ) * hardening;
288 m.at(2) = 2. * shearNorm;
289 m.at(3) = fabs( m.at(1) );
290 } else { //circle
291 m.at(1) = 2. * stress.at(1) / pow(this->flowAngleTwo, 2.) + 2. * ( fcLocal - this->flowAngleTwo * this->flowAngleOne * ftLocal ) / ( pow(this->flowAngleTwo, 2.) * ( 1. + this->flowAngleOne * this->flowAngleTwo ) ) * hardening;
292 m.at(2) = 2. * shearNorm;
293 m.at(3) = fabs( m.at(1) );
294 }
295
296 return m;
297}
298
299
301LatticePlasticityDamage::computeDMMatrix(const FloatArrayF< 3 > &stress, const double kappa, GaussPoint *gp, TimeStep *tStep) const
302{
303 double ftLocal = giveTensileStrength(gp, tStep);
304 double fcLocal = giveCompressiveStrength(gp, tStep);
305
306 double hardening = computeHardening(kappa, gp);
307 double dHardeningDKappa = computeDHardeningDKappa(kappa, gp);
308 double transition = -( fcLocal - this->flowAngleOne * this->flowAngleTwo * this->ft ) / ( 1. + this->flowAngleOne * this->flowAngleTwo ) * hardening;
309
311 if ( stress.at(1) >= transition ) { //main ellipse
312 //Derivatives of dGDSig
313 dm.at(1, 1) = 2. * pow(this->flowAngleOne, 2.);
314 dm.at(1, 2) = 0.;
315 dm.at(1, 3) = 2. * ( fcLocal - this->flowAngleOne * this->flowAngleTwo * ftLocal ) * pow(this->flowAngleOne, 2.) / ( 1. + this->flowAngleOne * this->flowAngleTwo ) * dHardeningDKappa;
316
317 //Derivatives of dGDTau
318 dm.at(2, 1) = 0.;
319 dm.at(2, 2) = 2.;
320 dm.at(2, 3) = 0;
321
322 //Derivates of evolution law
323 dm.at(3, 1) = dm.at(1, 1);
324 dm.at(3, 2) = dm.at(1, 2);
325 dm.at(3, 3) = dm.at(1, 3);
326 } else { //cap ellipse
327 //Derivatives of dGDSig
328 dm.at(1, 1) = 2. / pow(this->flowAngleTwo, 2.);
329 dm.at(1, 2) = 0.;
330 dm.at(1, 3) = 2. * ( fcLocal - this->flowAngleOne * this->flowAngleTwo * ftLocal ) / ( pow(this->flowAngleTwo, 2.) * ( 1. + this->flowAngleOne * this->flowAngleTwo ) ) * dHardeningDKappa;
331
332 //Derivatives of dGDTau
333 dm.at(2, 1) = 0.;
334 dm.at(2, 2) = 2.;
335 dm.at(2, 3) = 0;
336
337 //Derivates of evolution law
338 dm.at(3, 1) = -dm.at(1, 1);
339 dm.at(3, 2) = -dm.at(1, 2);
340 dm.at(3, 3) = -dm.at(1, 3);
341 }
342 return dm;
343}
344
345
348{
349 auto status = static_cast< LatticePlasticityDamageStatus * >( this->giveStatus(gp) );
350 return status->giveReducedLatticeStrain();
351}
352
353
356 const FloatArrayF< 6 > &reducedStrain,
357 TimeStep *tStep) const
358{
360
361 double fcLocal = giveCompressiveStrength(gp, tStep);
362 auto status = static_cast< LatticePlasticityDamageStatus * >( this->giveStatus(gp) );
363
364 //Get kappa from the status
365 double tempKappa = status->giveKappaP();
366
367 //Subset of reduced strain.
368 //Rotational components are not used for plasticity return
369 auto strain = reducedStrain [ { 0, 1, 2 } ];
370
371
372 /* Get plastic strain vector from status*/
373 auto tempPlasticStrain = status->givePlasticLatticeStrain() [ { 0, 1, 2 } ];
374
375 FloatArrayF< 3 >tangent = { this->eNormalMean, this->alphaOne * this->eNormalMean, this->alphaOne * this->eNormalMean };
376 /* Compute trial stress*/
377 auto stress = mult(tangent, strain - tempPlasticStrain);
378
379 //Introduce variables for subincrementation
380 //Only _3dLattice is possible
381
382 auto oldStrain = this->giveReducedStrain(gp, tStep) [ { 0, 1, 2 } ];
383
384 /* Compute yield value*/
385 double yieldValue = computeYieldValue(stress, tempKappa, gp, tStep);
386 int subIncrementCounter = 0;
387
388 /* Check yield condition, i.e. if the yield value is less than the yield tolerance.
389 * If yield condition is valid. Do perform regular return (closest point return)*/
390
391 if ( yieldValue / pow(fcLocal, 2.) > yieldTol ) {
392 // introduce a subincrementation flag
393 int subIncrementFlag = 0;
394 auto convergedStrain = oldStrain;
395 auto tempStrain = strain;
396 auto deltaStrain = strain - oldStrain;
397 //To get into the loop
398 returnResult = RR_NotConverged;
399 while ( returnResult == RR_NotConverged || subIncrementFlag == 1 ) {
400 stress = mult(tangent, tempStrain - tempPlasticStrain);
401
402 tempKappa = performRegularReturn(stress, returnResult, yieldValue, gp, tStep);
403
404 if ( returnResult == RR_NotConverged ) {
405 subIncrementCounter++;
406 if ( subIncrementCounter > numberOfSubIncrements ) {
407 OOFEM_LOG_INFO( "Unstable element %d \n", gp->giveElement()->giveGlobalNumber() );
408 OOFEM_LOG_INFO("Yield value %e \n", yieldValue);
409 OOFEM_LOG_INFO( "ConvergedStrain value %e %e %e\n", convergedStrain.at(1), convergedStrain.at(2), convergedStrain.at(3) );
410 OOFEM_LOG_INFO( "tempStrain value %e %e %e\n", tempStrain.at(1), tempStrain.at(2), tempStrain.at(3) );
411 OOFEM_LOG_INFO( "deltaStrain value %e %e %e\n", deltaStrain.at(1), deltaStrain.at(2), deltaStrain.at(3) );
412 OOFEM_LOG_INFO( "targetstrain value %e %e %e\n", strain.at(1), strain.at(2), strain.at(3) );
413
414 OOFEM_ERROR("LatticePlasticityDamage :: performPlasticityReturn - Could not reach convergence with small deltaStrain, giving up.");
415 }
416
417 subIncrementFlag = 1;
418 deltaStrain *= 0.5;
419 tempStrain = convergedStrain + deltaStrain;
420 } else if ( returnResult == RR_Converged && subIncrementFlag == 1 ) {
421 tempPlasticStrain.at(1) = tempStrain.at(1) - stress.at(1) / eNormalMean;
422 tempPlasticStrain.at(2) = tempStrain.at(2) - stress.at(2) / ( this->alphaOne * eNormalMean );
423 tempPlasticStrain.at(3) = tempStrain.at(3) - stress.at(3) / ( this->alphaOne * eNormalMean );
424
425 status->letTempPlasticLatticeStrainBe( assemble< 6 >(tempPlasticStrain, { 0, 1, 2 }) );
426 status->setTempKappaP(tempKappa);
427
428 subIncrementFlag = 0;
429 returnResult = RR_NotConverged;
430 convergedStrain = tempStrain;
431 deltaStrain = strain - convergedStrain;
432 tempStrain = strain;
433 subIncrementCounter = 0;
434 } else {
435 status->setTempKappaP(tempKappa);
436 }
437 }
438 }
439
440
441 tempPlasticStrain.at(1) = strain.at(1) - stress.at(1) / eNormalMean;
442 tempPlasticStrain.at(2) = strain.at(2) - stress.at(2) / ( this->alphaOne * eNormalMean );
443 tempPlasticStrain.at(3) = strain.at(3) - stress.at(3) / ( this->alphaOne * eNormalMean );
444
445 status->letTempPlasticLatticeStrainBe( assemble< 6 >(tempPlasticStrain, { 0, 1, 2 }) );
446
447
448 // status->letTempLatticeStressBe(assemble< 6 >(stress, { 0, 1, 2 }) );
449
450 auto answer = assemble< 6 >(stress, { 0, 1, 2 });
451 answer.at(4) = this->alphaTwo * this->eNormalMean * reducedStrain.at(4);
452 answer.at(5) = this->alphaTwo * this->eNormalMean * reducedStrain.at(5);
453 answer.at(6) = this->alphaTwo * this->eNormalMean * reducedStrain.at(6);
454
455 return answer;
456}
457
458
459double
462 double yieldValue,
463 GaussPoint *gp,
464 TimeStep *tStep) const
465{
466 double fcLocal = giveCompressiveStrength(gp, tStep);
467
468 auto status = static_cast< LatticePlasticityDamageStatus * >( this->giveStatus(gp) );
469
470 double deltaLambda = 0.;
471
472 auto trialStress = stress;
473 auto tempStress = trialStress;
474
475 double trialShearStressNorm = norm(trialStress [ { 1, 2 } ]);
476
477 double tempShearStressNorm = trialShearStressNorm;
478
479 double thetaTrial = atan2( stress.at(3), stress.at(2) );
480
481 // Do the same for kappa
482 double kappa = status->giveKappaP();
483 double tempKappa = kappa;
484
485 //initialise unknowns
486 FloatArrayF< 4 >unknowns;
487 unknowns.at(1) = trialStress.at(1);
488 unknowns.at(2) = trialShearStressNorm;
489 unknowns.at(3) = tempKappa;
490 unknowns.at(4) = 0.;
491
492 // Look at the magnitudes of the residuals. You have to scale the yieldValue down.
493 yieldValue = computeYieldValue(tempStress, tempKappa, gp, tStep);
494
495 //initiate residuals
496 FloatArrayF< 4 >residuals;
497 residuals.at(4) = yieldValue;
498
499 double normOfResiduals = 1.; //just to get into the loop
500
501 int iterationCount = 0;
502 while ( normOfResiduals > yieldTol ) {
503 iterationCount++;
504 if ( iterationCount == newtonIter ) {
505 returnResult = RR_NotConverged;
506 return 0.;
507 }
508
509 //Normalize residuals. Think about it more.
510 FloatArrayF< 4 >residualsNorm;
511 residualsNorm.at(1) = residuals.at(1) / fcLocal;
512 residualsNorm.at(2) = residuals.at(2) / fcLocal;
513 residualsNorm.at(3) = residuals.at(3);
514 residualsNorm.at(4) = residuals.at(4) / pow(fcLocal, 2.);
515
516 normOfResiduals = norm(residualsNorm);
517
518 //First check if return has failed
519 if ( std::isnan(normOfResiduals) ) {
520 returnResult = RR_NotConverged;
521 return 0.;
522 }
523
524 if ( normOfResiduals > yieldTol ) {
525 // Test to run newton iteration using inverse of Jacobian
526 auto jacobian = computeJacobian(tempStress, tempKappa, deltaLambda, gp, tStep);
527
528 auto solution = solve_check(jacobian, residuals);
529 if ( solution.first ) {
530 unknowns -= solution.second;
531 } else {
532 returnResult = RR_NotConverged;
533 return kappa;
534 }
535
536 unknowns.at(2) = max(unknowns.at(2), 0.); //Keep rho greater than zero!
537 unknowns.at(3) = max(unknowns.at(3), kappa); //Keep deltaKappa greater than zero!
538 unknowns.at(4) = max(unknowns.at(4), 0.); //Keep deltaLambda greater than zero!
539
540 /* Update increments final values and DeltaLambda*/
541 tempStress.at(1) = unknowns.at(1);
542 tempShearStressNorm = unknowns.at(2);
543
544 tempStress.at(2) = tempShearStressNorm * cos(thetaTrial);
545 tempStress.at(3) = tempShearStressNorm * sin(thetaTrial);
546
547 tempKappa = unknowns.at(3);
548 deltaLambda = unknowns.at(4);
549
550 /* Compute the mVector holding the derivatives of the g function and the hardening function*/
551 auto mVector = computeMVector(tempStress, tempKappa, gp, tStep);
552
553 residuals.at(1) = tempStress.at(1) - trialStress.at(1) + this->eNormalMean * deltaLambda * mVector.at(1);
554 residuals.at(2) = tempShearStressNorm - trialShearStressNorm + this->alphaOne * this->eNormalMean * deltaLambda * mVector.at(2);
555 residuals.at(3) = -tempKappa + kappa + deltaLambda * mVector.at(3);
556 residuals.at(4) = computeYieldValue(tempStress, tempKappa, gp, tStep);
557 }
558 }
559
560 returnResult = RR_Converged;
561
562 stress = tempStress;
563
564 return tempKappa;
565}
566
567
568
571 const double kappa,
572 const double deltaLambda,
573 GaussPoint *gp,
574 TimeStep *tStep) const
575{
576 auto dMMatrix = computeDMMatrix(stress, kappa, gp, tStep);
577 auto mVector = computeMVector(stress, kappa, gp, tStep);
578 auto fVector = computeFVector(stress, kappa, gp, tStep);
579
580 /* Compute matrix*/
581 FloatMatrixF< 4, 4 >jacobian;
582 jacobian.at(1, 1) = 1. + this->eNormalMean * deltaLambda * dMMatrix.at(1, 1);
583 jacobian.at(1, 2) = this->eNormalMean * deltaLambda * dMMatrix.at(1, 2);
584 jacobian.at(1, 3) = this->eNormalMean * deltaLambda * dMMatrix.at(1, 3);
585 jacobian.at(1, 4) = this->eNormalMean * mVector.at(1);
586 /**/
587 jacobian.at(2, 1) = this->alphaOne * this->eNormalMean * deltaLambda * dMMatrix.at(2, 1);
588 jacobian.at(2, 2) = 1. + this->alphaOne * this->eNormalMean * deltaLambda * dMMatrix.at(2, 2);
589 jacobian.at(2, 3) = this->alphaOne * this->eNormalMean * deltaLambda * dMMatrix.at(2, 3);
590 jacobian.at(2, 4) = this->alphaOne * this->eNormalMean * mVector.at(2);
591 /**/
592 jacobian.at(3, 1) = deltaLambda * dMMatrix.at(3, 1);
593 jacobian.at(3, 2) = deltaLambda * dMMatrix.at(3, 2);
594 jacobian.at(3, 3) = deltaLambda * dMMatrix.at(3, 3) - 1.;
595 jacobian.at(3, 4) = mVector.at(3);
596 /**/
597 jacobian.at(4, 1) = fVector.at(1);
598 jacobian.at(4, 2) = fVector.at(2);
599 jacobian.at(4, 3) = fVector.at(3);
600 jacobian.at(4, 4) = 0.;
601
602 return jacobian;
603}
604
605double
607{
608 this->giveStatus(gp);
609
610 double answer;
611 if ( RandomMaterialExtensionInterface::give(aProperty, gp, answer) ) {
612 return answer;
613 } else if ( aProperty == fc_strength ) {
614 return 1.;
615 } else if ( aProperty == ft_strength ) {
616 return 1.;
617 } else {
618 return LatticeLinearElastic::give(aProperty, gp);
619 }
620}
621
622
625{
626 auto status = static_cast< LatticePlasticityDamageStatus * >( this->giveStatus(gp) );
627 status->initTempStatus();
628
629 auto reducedStrain = originalStrain;
630 auto thermalStrain = this->computeStressIndependentStrainVector(gp, tStep, VM_Total);
631 if ( thermalStrain.giveSize() ) {
632 reducedStrain -= FloatArrayF< 6 >(thermalStrain);
633 }
634
635 auto stress = this->performPlasticityReturn(gp, reducedStrain, tStep);
636
637 double omega = 0.;
638 if ( damageFlag == 1 ) {
639 this->performDamageEvaluation(gp, reducedStrain, tStep);
640 omega = status->giveTempDamage();
641 }
642
643 stress *= ( 1. - omega );
644
645 status->letTempLatticeStrainBe(originalStrain);
646 status->letTempReducedLatticeStrainBe(reducedStrain);
647 status->letTempLatticeStressBe(stress);
648
649 return stress;
650}
651
652
653void
655{
656 double ftLocal = giveTensileStrength(gp, tStep);
657 double fcLocal = giveCompressiveStrength(gp, tStep);
658
659 auto status = static_cast< LatticePlasticityDamageStatus * >( this->giveStatus(gp) );
660
661 double le = static_cast< LatticeStructuralElement * >( gp->giveElement() )->giveLength();
662
663 auto tempPlasticStrain = status->giveTempPlasticLatticeStrain();
664 auto plasticStrain = status->givePlasticLatticeStrain();
665 auto deltaPlasticStrain = tempPlasticStrain - plasticStrain;
666
667 //Compute the damage history variable
668 double omega = status->giveDamage();
669 double tempKappaDOne = status->giveKappaDOne();
670 double tempKappaDTwo = status->giveKappaDTwo();
671
672 // Compute deltaKappaP from the plastic Strain
673 double tempKappaP = status->giveTempKappaP();
674 double kappaP = status->giveKappaP();
675 double deltaKappaP = tempKappaP - kappaP;
676 double hardening = computeHardening(tempKappaP, gp);
677
678 double strength = ( fcLocal - this->frictionAngleOne * this->frictionAngleTwo * ftLocal ) / ( 1 + this->frictionAngleOne * this->frictionAngleTwo );
679
680 if ( deltaKappaP <= 0. ) { //unloading or reloading
681 tempKappaDOne = status->giveKappaDOne();
682 tempKappaDTwo = status->giveKappaDTwo();
683 omega = status->giveDamage();
684 if ( status->giveCrackFlag() != 0 ) {
685 status->setTempCrackFlag(2);
686 } else {
687 status->setTempCrackFlag(0);
688 }
689 } else { //plastic loading
690 if ( deltaPlasticStrain.at(1) <= 0. ) { //compressive side! No damage
691 tempKappaDOne = status->giveKappaDOne();
692 tempKappaDTwo = status->giveKappaDTwo();
693 omega = status->giveDamage();
694 status->setTempCrackFlag(3);
695 } else {
696 tempKappaDOne += deltaPlasticStrain.at(1);
697
698 if ( ftLocal == 0 ) {
699 tempKappaDTwo = hardening * strength / this->eNormalMean;
700 } else {
701 tempKappaDTwo = hardening * ftLocal / this->eNormalMean;
702 }
703
704 // evaluate damage parameter
705 omega = this->computeDamageParam(tempKappaDOne, tempKappaDTwo, gp, tStep);
706
707 //threshold for crack patterns
708 if ( ( tempKappaDOne + omega * tempKappaDTwo ) * le > 0. ) {
709 status->setTempCrackFlag(1);
710 } else {
711 status->setTempCrackFlag(0);
712 }
713 }
714 }
715
716 //Create history variables for the damage strain
717 FloatArrayF< 6 >elasticReducedStrain = reducedStrain - tempPlasticStrain;
718 FloatArrayF< 6 >tempDamageLatticeStrain = omega * elasticReducedStrain;
719 status->letTempDamageLatticeStrainBe(tempDamageLatticeStrain);
720
721 double crackWidth = norm( tempPlasticStrain + omega * ( reducedStrain - tempPlasticStrain ) ) * le;
722
723 //TODO: Compute dissipation
724 // double tempDissipation = status->giveDissipation();
725 // double tempDeltaDissipation = 0.;
726 // tempDeltaDissipation = computeDeltaDissipation(omega, reducedStrain, gp, atTime);
727 // tempDissipation += tempDeltaDissipation;
728
729 status->setTempKappaDOne(tempKappaDOne);
730 status->setTempKappaDTwo(tempKappaDTwo);
731 status->setTempDamage(omega);
732 status->setTempCrackWidth(crackWidth);
733}
734
735/*double LatticePlasticityDamage :: giveMaterialParameter()
736 * {
737 * return this->ft;
738 * }*/
739
740
741// double
742// LatticePlasticityDamage :: computeDeltaDissipation(double omega,
743// FloatArray &reducedStrain,
744// GaussPoint *gp,
745// TimeStep *atTime)
746// {
747// LatticeDamageStatus *status = static_cast< LatticeDamageStatus * >( this->giveStatus(gp) );
748// double length = ( static_cast< LatticeStructuralElement * >( gp->giveElement() ) )->giveLength();
749// const double e0 = this->give(e0_ID, gp) * this->e0Mean;
750// double eNormal = this->give(eNormal_ID, gp) * this->eNormalMean;
751
752// const double eShear = this->alphaOne * eNormal;
753// const double eTorsion = this->alphaTwo * eNormal / 12.;
754
755// FloatArray reducedStrainOld;
756
757// reducedStrainOld = status->giveReducedStrain();
758// double omegaOld = status->giveDamage();
759// double deltaOmega;
760
761// FloatArray crackOpeningOld(6);
762// crackOpeningOld.times(omegaOld);
763// crackOpeningOld.times(length);
764// FloatArray stressOld( status->giveStressVector() );
765// FloatArray intermediateStrain(6);
766
767// double tempDeltaDissipation = 0.;
768// double deltaTempDeltaDissipation = 0.;
769
770// double intermediateOmega = 0;
771// FloatArray oldIntermediateStrain(6);
772// oldIntermediateStrain = reducedStrainOld;
773// double oldIntermediateOmega = omegaOld;
774// deltaOmega = ( omega - omegaOld );
775// double testDissipation = 0.5 * length * ( pow( ( reducedStrain.at(1) + reducedStrainOld.at(1) ) / 2., 2. ) * eNormal +
776// pow( ( reducedStrain.at(2) + reducedStrainOld.at(2) ) / 2., 2. ) * eShear +
777// pow( ( reducedStrain.at(3) + reducedStrainOld.at(3) ) / 2., 2. ) * eShear +
778// pow( ( reducedStrain.at(4) + reducedStrainOld.at(4) ) / 2., 2. ) * eTorsion +
779// pow( ( reducedStrain.at(5) + reducedStrainOld.at(5) ) / 2., 2. ) * eTorsion +
780// pow( ( reducedStrain.at(6) + reducedStrainOld.at(6) ) / 2., 2. ) * eTorsion ) * deltaOmega;
781// double intervals = 0.;
782
783// double referenceGf = 0;
784
785// if ( softeningType == 1 ) {
786// referenceGf = e0 * eNormal * this->wf / 2.;
787// } else { //This is for the exponential law. Should also implement it for the bilinear one.
788// referenceGf = e0 * eNormal * this->wf;
789// }
790
791// if ( testDissipation / ( referenceGf ) > 0.001 ) {
792// intervals = 1000. * testDissipation / referenceGf;
793// } else {
794// intervals = 1.;
795// }
796
797// if ( intervals > 1000. ) {
798// intervals = 1000.;
799// }
800
801// double oldKappa = status->giveKappa();
802// double f, equivStrain;
803// if ( deltaOmega > 0 ) {
804// for ( int k = 0; k < intervals; k++ ) {
805// intermediateStrain(0) = reducedStrainOld(0) + ( k + 1 ) / intervals * ( reducedStrain(0) - reducedStrainOld(0) );
806// intermediateStrain(1) = reducedStrainOld(1) + ( k + 1 ) / intervals * ( reducedStrain(1) - reducedStrainOld(1) );
807// intermediateStrain(2) = reducedStrainOld(2) + ( k + 1 ) / intervals * ( reducedStrain(2) - reducedStrainOld(2) );
808// intermediateStrain(3) = reducedStrainOld(3) + ( k + 1 ) / intervals * ( reducedStrain(3) - reducedStrainOld(3) );
809// intermediateStrain(4) = reducedStrainOld(4) + ( k + 1 ) / intervals * ( reducedStrain(4) - reducedStrainOld(4) );
810// intermediateStrain(5) = reducedStrainOld(5) + ( k + 1 ) / intervals * ( reducedStrain(5) - reducedStrainOld(5) );
811
812// this->computeEquivalentStrain(equivStrain, intermediateStrain, gp, atTime);
813// f = equivStrain - oldKappa;
814// if ( f > 0 ) {
815// this->computeDamageParam(intermediateOmega, equivStrain, intermediateStrain, gp);
816// deltaOmega = ( intermediateOmega - oldIntermediateOmega );
817// deltaTempDeltaDissipation =
818// 0.5 * length * ( pow( ( intermediateStrain(0) + oldIntermediateStrain(0) ) / 2., 2. ) * eNormal +
819// pow( ( intermediateStrain(1) + oldIntermediateStrain(1) ) / 2., 2. ) * eShear +
820// pow( ( intermediateStrain(2) + oldIntermediateStrain(2) ) / 2., 2. ) * eShear +
821// pow( ( intermediateStrain(3) + oldIntermediateStrain(3) ) / 2., 2. ) * eTorsion +
822// pow( ( intermediateStrain(4) + oldIntermediateStrain(4) ) / 2., 2. ) * eTorsion +
823// pow( ( intermediateStrain(5) + oldIntermediateStrain(5) ) / 2., 2. ) * eTorsion ) * deltaOmega;
824
825// oldKappa = equivStrain;
826// oldIntermediateOmega = intermediateOmega;
827// } else {
828// deltaTempDeltaDissipation = 0.;
829// }
830
831// tempDeltaDissipation += deltaTempDeltaDissipation;
832// oldIntermediateStrain = intermediateStrain;
833// }
834// } else {
835// tempDeltaDissipation = 0.;
836// }
837
838// if ( tempDeltaDissipation >= 2. * referenceGf ) {
839// tempDeltaDissipation = 2. * referenceGf;
840// }
841
842// return tempDeltaDissipation;
843// }
844
845
848{
849 auto elastic = LatticeLinearElastic::give3dLatticeStiffnessMatrix(mode, gp, tStep);
850
851 if ( mode == ElasticStiffness ) {
852 return elastic;
853 } else if ( ( mode == SecantStiffness ) || ( mode == TangentStiffness ) ) {
854 auto status = static_cast< LatticePlasticityDamageStatus * >( this->giveStatus(gp) );
855 double omega = min(status->giveTempDamage(), 0.99999);
856 return elastic * ( 1. - omega );
857 } else {
858 OOFEM_ERROR("Unsupported stiffness mode\n");
859 }
860}
861
862int
864 GaussPoint *gp,
866 TimeStep *atTime)
867{
868 auto status = static_cast< LatticePlasticityDamageStatus * >( this->giveStatus(gp) );
869
870 if ( type == IST_DamageTensor ) {
871 answer.resize(6);
872 answer.zero();
873 answer.at(1) = answer.at(2) = answer.at(3) = status->giveDamage();
874 return 1;
875 } else if ( type == IST_DamageScalar ) {
876 answer.resize(1);
877 answer.zero();
878 answer.at(1) = status->giveDamage();
879 return 1;
880 } else if ( type == IST_CrackedFlag ) {
881 answer.resize(1);
882 answer.zero();
883 answer.at(1) = status->giveCrackFlag();
884 return 1;
885 } else if ( type == IST_DissWork ) {
886 answer.resize(1);
887 answer.zero();
888 answer.at(1) = status->giveDissipation();
889 return 1;
890 } else if ( type == IST_DeltaDissWork ) {
891 answer.resize(1);
892 answer.zero();
893 answer.at(1) = status->giveDeltaDissipation();
894 return 1;
895 } else if ( type == IST_CrackWidth ) {
896 answer.resize(1);
897 answer.zero();
898 answer.at(1) = status->giveCrackWidth();
899 return 1;
900 } else if ( type == IST_CharacteristicLength ) {
901 answer.resize(1);
902 answer.zero();
903 answer.at(1) = static_cast< LatticeStructuralElement * >( gp->giveElement() )->giveLength();
904 return 1;
905 } else if ( type == IST_PlasticLatticeStrain ) {
906 answer = status->givePlasticLatticeStrain();
907 return 1;
908 } else if ( type == IST_TensileStrength ) {
909 answer.resize(1);
910 answer.at(1);
911 answer.at(1) = giveTensileStrength(gp, atTime);
912 return 1;
913 } else {
914 return LatticeLinearElastic::giveIPValue(answer, gp, type, atTime);
915 }
916}
917
918
921
922void
931
932void
934{
936
937 fprintf(file, "plasticStrains ");
938 for ( double s : this->plasticLatticeStrain ) {
939 fprintf(file, "% .8e ", s);
940 }
941
942 fprintf(file, ", kappaP %.8e, kappaDOne %.8e, kappaDTwo %.8e, damage %.8e, deltaDissipation %.8e, dissipation %.8e, crackFlag %d, crackWidth %.8e \n", this->kappaP, this->kappaDOne, this->kappaDTwo, this->damage, this->deltaDissipation, this->dissipation, this->crackFlag, this->crackWidth);
943}
944
945
946void
948//
949// updates variables (nonTemp variables describing situation at previous equilibrium state)
950// after a new equilibrium state has been reached
951// temporary variables are having values corresponding to newly reached equilibrium.
952//
953{
955 this->kappaP = this->tempKappaP;
956 this->kappaDOne = this->tempKappaDOne;
957 this->kappaDTwo = this->tempKappaDTwo;
958 this->damage = this->tempDamage;
959}
960
961
962void
964//
965// saves full information stored in this Status
966// no temp variables stored
967//
968{
970
971 if ( !stream.write(& kappaP, 1) ) {
973 }
974 if ( !stream.write(& kappaDOne, 1) ) {
976 }
977 if ( !stream.write(& kappaDTwo, 1) ) {
979 }
980 if ( !stream.write(& damage, 1) ) {
982 }
983}
984
985
986void
988//
989// restores full information stored in stream to this Status
990//
991{
993
994 if ( !stream.read(& kappaP, 1) ) {
996 }
997 if ( !stream.read(& kappaDOne, 1) ) {
999 }
1000 if ( !stream.read(& kappaDTwo, 1) ) {
1002 }
1003 if ( !stream.read(& damage, 1) ) {
1005 }
1006}
1007} // end namespace oofem
#define REGISTER_Material(class)
virtual int read(int *data, std::size_t count)=0
Reads count integer values into array pointed by data.
virtual int write(const int *data, std::size_t count)=0
Writes count integer values from array pointed by data.
int giveGlobalNumber() const
Definition element.h:1129
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition femcmpnn.h:79
double & at(std::size_t i)
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
double at(std::size_t i, std::size_t j) const
Element * giveElement()
Returns corresponding element to receiver.
Definition gausspoint.h:187
double alphaOne
Ratio of shear and normal modulus.
double alphaTwo
Ratio of torsion and normal modulus.
void initializeFrom(InputRecord &ir) override
double eNormalMean
Normal modulus.
double give(int aProperty, GaussPoint *gp) const override
MaterialStatus * giveStatus(GaussPoint *gp) const override
FloatMatrixF< 6, 6 > give3dLatticeStiffnessMatrix(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) const override
void saveContext(DataStream &stream, ContextMode mode) override
FloatArrayF< 6 > plasticLatticeStrain
Equilibriated plastic lattice strain.
const FloatArrayF< 6 > & giveReducedLatticeStrain() const
Returns reduced lattice strain.
double deltaDissipation
Increment of dissipation.
void updateYourself(TimeStep *) override
void restoreContext(DataStream &stream, ContextMode mode) override
void printOutputAt(FILE *file, TimeStep *tStep) const override
Print receiver's output to given stream.
LatticePlasticityDamageStatus(int n, Domain *d, GaussPoint *g)
Constructor.
void printOutputAt(FILE *file, TimeStep *tStep) const override
Print receiver's output to given stream.
void restoreContext(DataStream &stream, ContextMode mode) override
void saveContext(DataStream &stream, ContextMode mode) override
FloatArrayF< 6 > giveLatticeStress3d(const FloatArrayF< 6 > &jump, GaussPoint *gp, TimeStep *tStep) override
double performRegularReturn(FloatArrayF< 3 > &stress, LatticePlasticityDamage_ReturnResult &returnResult, double yieldValue, GaussPoint *gp, TimeStep *tStep) const
double flowAngleTwo
frictional angle of the plastic potential
double computeDDHardeningDDKappa(const double kappa, GaussPoint *gp) const
double computeDHardeningDKappa(const double kappa, GaussPoint *gp) const
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *atTime) override
double ftOneRatio
ratio of tensile stress value for bilinear stress-crack opening curve
std::unique_ptr< MaterialStatus > CreateStatus(GaussPoint *gp) const override
bool hasMaterialModeCapability(MaterialMode mode) const override
double flowAngleOne
frictional angle of the plastic potential
virtual double giveTensileStrength(GaussPoint *gp, TimeStep *tStep) const
double computeHardening(const double kappa, GaussPoint *gp) const
FloatMatrixF< 4, 4 > computeJacobian(const FloatArrayF< 3 > &sigma, const double tempKappa, const double deltaLambda, GaussPoint *gp, TimeStep *tStep) const
virtual double giveCompressiveStrength(GaussPoint *gp, TimeStep *tStep) const
virtual double computeDamageParam(double kappaOne, double kappaTwo, GaussPoint *gp, TimeStep *tStep) const
int softeningType
softening type determines the type of softening. 0 is exponential and 1 is bilinear.
double give(int aProperty, GaussPoint *gp) const override
FloatMatrixF< 3, 3 > computeDMMatrix(const FloatArrayF< 3 > &sigma, const double deltaLambda, GaussPoint *gp, TimeStep *tStep) const
virtual FloatArrayF< 6 > giveReducedStrain(GaussPoint *gp, TimeStep *tStep) const
double frictionAngleTwo
frictional angle of the yield surface
FloatArrayF< 3 > computeMVector(const FloatArrayF< 3 > &sigma, const double deltaLambda, GaussPoint *gp, TimeStep *tStep) const
double frictionAngleOne
frictional angle of the yield surface
FloatMatrixF< 6, 6 > give3dLatticeStiffnessMatrix(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) const override
double computeYieldValue(const FloatArrayF< 3 > &sigma, const double tempKappa, GaussPoint *gp, TimeStep *tStep) const
FloatArrayF< 6 > performPlasticityReturn(GaussPoint *gp, const FloatArrayF< 6 > &reducedStrain, TimeStep *tStep) const
double wf
determines the softening -> corresponds to crack opening (not strain) when tension stress vanishes
FloatArrayF< 3 > computeFVector(const FloatArrayF< 3 > &sigma, const double deltaLambda, GaussPoint *gp, TimeStep *tStep) const
double wfOne
crack opening value for bilinear stress-crack opening curve
int newtonIter
maximum number of iterations for stress return
LatticePlasticityDamage(int n, Domain *d)
Constructor.
void initializeFrom(InputRecord &ir) override
void performDamageEvaluation(GaussPoint *gp, FloatArrayF< 6 > &reducedStrain, TimeStep *tStep) const
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Definition material.C:138
bool give(int key, GaussPoint *gp, double &value) const
virtual FloatArray computeStressIndependentStrainVector(GaussPoint *gp, TimeStep *tStep, ValueModeType mode) const
#define THROW_CIOERR(e)
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define _IFT_LatticePlasticityDamage_angle2
#define _IFT_LatticePlasticityDamage_sub
#define _IFT_LatticePlasticityDamage_tol
#define _IFT_LatticePlasticityDamage_ahard
#define _IFT_LatticePlasticityDamage_wf1
#define _IFT_LatticePlasticityDamage_iter
#define _IFT_LatticePlasticityDamage_ft1
#define _IFT_LatticePlasticityDamage_stype
#define _IFT_LatticePlasticityDamage_damage
#define _IFT_LatticePlasticityDamage_flow
#define _IFT_LatticePlasticityDamage_fc
#define _IFT_LatticePlasticityDamage_angle1
#define _IFT_LatticePlasticityDamage_wf
#define _IFT_LatticePlasticityDamage_ft
#define OOFEM_LOG_INFO(...)
Definition logger.h:143
#define fc_strength
Definition matconst.h:92
#define ft_strength
Definition matconst.h:91
long ContextMode
Definition contextmode.h:43
double norm(const FloatArray &x)
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
std::pair< bool, FloatArrayF< N > > solve_check(FloatMatrixF< N, N > mtrx, const FloatArrayF< N > &b, double zeropiv=1e-20)
FloatArrayF< N > assemble(const FloatArrayF< M > &x, int const (&c)[M])
Assemble components into zero matrix.
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
FloatArrayF< N > mult(const FloatArrayF< N > &x, const FloatArrayF< N > &y)
Element-wise multiplication.
@ CIO_IOERR
General IO error.

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