OOFEM 3.0
Loading...
Searching...
No Matches
rankinematnl.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 "rankinematnl.h"
37#include "gausspoint.h"
38#include "floatmatrix.h"
39#include "floatarray.h"
40#include "sparsemtrx.h"
41#include "error.h"
42#include "nonlocalmaterialext.h"
43#include "contextioerr.h"
44#include "classfactory.h"
45#include "datastream.h"
46
47namespace oofem {
49
51{ }
52
54RankineMatNl :: giveRealStressVector_PlaneStress(const FloatArrayF<3> &totalStrain, GaussPoint *gp, TimeStep *tStep) const
55{
56 auto nlStatus = static_cast< RankineMatNlStatus * >( this->giveStatus(gp) );
57
58 //mj performPlasticityReturn(gp, totalStrain, mode);
59 // nonlocal method "computeDamage" performs the plastic return
60 // for all Gauss points when it is called for the first time
61 // in the iteration
62 double tempDam = this->computeDamage(gp, tStep);
63 FloatArrayF<6> stress = (1.0 - tempDam) * nlStatus->giveTempEffectiveStress();
64 nlStatus->setTempDamage(tempDam);
65 nlStatus->letTempStrainVectorBe(totalStrain);
66 nlStatus->letTempStressVectorBe(stress);
67#ifdef keep_track_of_dissipated_energy
68 double gf = sig0 * sig0 / E; // only estimated, but OK for this purpose
69 nlStatus->computeWork_PlaneStress(gp, gf);
70#endif
71 return stress[{0, 1, 5}];
72}
73
75RankineMatNl :: giveRealStressVector_1d(const FloatArrayF<1> &totalStrain, GaussPoint *gp, TimeStep *tStep) const
76{
77 auto nlStatus = static_cast< RankineMatNlStatus * >( this->giveStatus(gp) );
78
79 //mj performPlasticityReturn(gp, totalStrain, mode);
80 // nonlocal method "computeDamage" performs the plastic return
81 // for all Gauss points when it is called for the first time
82 // in the iteration
83 double tempDam = this->computeDamage(gp, tStep);
84 FloatArrayF<6> stress = (1.0 - tempDam) * nlStatus->giveTempEffectiveStress();
85 nlStatus->setTempDamage(tempDam);
86 nlStatus->letTempStrainVectorBe(totalStrain);
87 nlStatus->letTempStressVectorBe(stress);
88#ifdef keep_track_of_dissipated_energy
89 double gf = sig0 * sig0 / E; // only estimated, but OK for this purpose
90 nlStatus->computeWork_1d(gp, gf);
91#endif
92 return stress[0];
93}
94
95
97RankineMatNl :: givePlaneStressStiffMtrx(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
98{
99 if ( mode == ElasticStiffness ) {
100 return this->linearElasticMaterial->givePlaneStressStiffMtrx(mode, gp, tStep);
101 }
102
103 auto status = static_cast< RankineMatNlStatus * >( this->giveStatus(gp) );
104
105 if ( mode == SecantStiffness ) {
106 auto d = this->linearElasticMaterial->givePlaneStressStiffMtrx(mode, gp, tStep);
107 double damage = status->giveTempDamage();
108 return d * (1. - damage);
109 }
110
111 if ( mode == TangentStiffness ) {
112 double tempDamage = status->giveTempDamage();
113 double damage = status->giveDamage();
114 double gprime;
115 if ( tempDamage <= damage ) { // unloading
116 gprime = 0.;
117 } else { // loading
118 double kappa = computeCumPlasticStrain(gp, tStep);
119 gprime = computeDamageParamPrime(kappa);
120 gprime *= ( 1. - mm );
121 }
122
123 return evaluatePlaneStressStiffMtrx(mode, gp, tStep, gprime);
124 }
125
126 OOFEM_ERROR("unknown type of stiffness");
127}
128
129void
130RankineMatNl :: updateBeforeNonlocAverage(const FloatArray &strainVector, GaussPoint *gp, TimeStep *tStep) const
131{
132 /* Implements the service updating local variables in given integration points,
133 * which take part in nonlocal average process. Actually, no update is necessary,
134 * because the value used for nonlocal averaging is strain vector used for nonlocal secant stiffness
135 * computation. It is therefore necessary only to store local strain in corresponding status.
136 * This service is declared at StructuralNonlocalMaterial level.
137 */
138 auto nlstatus = static_cast< RankineMatNlStatus * >( this->giveStatus(gp) );
139
140 this->initTempStatus(gp);
141 this->performPlasticityReturn(gp, strainVector);
142 double cumPlasticStrain = this->computeLocalCumPlasticStrain(gp, tStep);
143 // standard formulation based on averaging of equivalent strain
144 nlstatus->setLocalCumPlasticStrainForAverage(cumPlasticStrain);
145 // influence of damage on weight function
146 if ( averType >= 2 && averType <= 6 ) {
148 }
149}
150
151double
152RankineMatNl :: giveNonlocalMetricModifierAt(GaussPoint *gp) const
153{
154 auto status = static_cast< RankineMatNlStatus * >( this->giveStatus(gp) );
155 double damage = status->giveTempDamage();
156 if ( damage == 0. ) {
157 damage = status->giveDamage();
158 }
159 return damage;
160}
161
162// returns in "kappa" the value of kappa_hat = m*kappa_nonlocal + (1-m)*kappa_local
163double
164RankineMatNl :: computeCumPlasticStrain(GaussPoint *gp, TimeStep *tStep) const
165{
166 auto status = static_cast< RankineMatNlStatus * >( this->giveStatus(gp) );
167 double nonlocalCumPlasticStrain = 0.0;
168
169 this->buildNonlocalPointTable(gp);
171 double localCumPlasticStrain = status->giveLocalCumPlasticStrainForAverage();
172 // compute nonlocal cumulative plastic strain
173 auto list = this->giveIPIntegrationList(gp);
174
175 for ( auto &lir: *list ) {
176 auto nonlocStatus = static_cast< RankineMatNlStatus * >( this->giveStatus(lir.nearGp) );
177 double nonlocalContribution = nonlocStatus->giveLocalCumPlasticStrainForAverage();
178 if ( nonlocalContribution > 0 ) {
179 nonlocalContribution *= lir.weight;
180 }
181
182 nonlocalCumPlasticStrain += nonlocalContribution;
183 }
184
185 double scale = status->giveIntegrationScale();
186 if ( scaling == ST_Standard ) { // standard rescaling
187 nonlocalCumPlasticStrain *= 1. / scale;
188 } else if ( scaling == ST_Borino ) { // Borino modification
189 if ( scale > 1. ) {
190 nonlocalCumPlasticStrain *= 1. / scale;
191 } else {
192 nonlocalCumPlasticStrain += ( 1. - scale ) * status->giveLocalCumPlasticStrainForAverage();
193 }
194 }
195
196 double kappa = mm * nonlocalCumPlasticStrain + ( 1. - mm ) * localCumPlasticStrain;
197 status->setKappa_nl(nonlocalCumPlasticStrain);
198 status->setKappa_hat(kappa);
199 return kappa;
200}
201
202Interface *
203RankineMatNl :: giveInterface(InterfaceType type)
204{
206 return static_cast< StructuralNonlocalMaterialExtensionInterface * >(this);
207 } else if ( type == NonlocalMaterialStiffnessInterfaceType ) {
208 return static_cast< NonlocalMaterialStiffnessInterface * >(this);
209 } else {
210 return nullptr;
211 }
212}
213
214
215void
216RankineMatNl :: initializeFrom(InputRecord &ir)
217{
218 RankineMat :: initializeFrom(ir);
219 StructuralNonlocalMaterialExtensionInterface :: initializeFrom(ir);
220}
221
222
223void
224RankineMatNl :: giveInputRecord(DynamicInputRecord &input)
225{
226 RankineMat :: giveInputRecord(input);
227 StructuralNonlocalMaterialExtensionInterface :: giveInputRecord(input);
228}
229
230
231
232double
233RankineMatNl :: computeDamage(GaussPoint *gp, TimeStep *tStep) const
234{
235 auto nlStatus = static_cast< RankineMatNlStatus * >( this->giveStatus(gp) );
236 double nlKappa = this->computeCumPlasticStrain(gp, tStep);
237 double dam = nlStatus->giveDamage();
238 double tempDam = this->computeDamageParam(nlKappa);
239 if ( tempDam < dam ) {
240 tempDam = dam;
241 }
242
243 return tempDam;
244}
245
246// this method is running over all neighboring Gauss points
247// and computes the contribution of the nonlocal interaction to tangent stiffness
248// it uses methods
249// giveLocalNonlocalStiffnessContribution
250// giveRemoteNonlocalStiffnessContribution
251// the first one computes m*gprime*Btransposed*sigmaeff for the present point
252// the second one computes Btransposed*eta for the neighboring point
253// (where eta is the derivative of cum. plastic strain wrt final strain)
254// THIS METHOD CAN BE USED IN THE SAME FORM FOR ALL NONLOCAL DAMAGE-PLASTIC MODELS
255void
256RankineMatNl :: NonlocalMaterialStiffnessInterface_addIPContribution(SparseMtrx &dest, const UnknownNumberingScheme &s,
257 GaussPoint *gp, TimeStep *tStep)
258{
259 auto status = static_cast< RankineMatNlStatus * >( this->giveStatus(gp) );
260 auto list = status->giveIntegrationDomainList();
261 FloatArray rcontrib, lcontrib;
262 IntArray loc, rloc;
263
264 FloatMatrix contrib;
265
266 if ( this->giveLocalNonlocalStiffnessContribution(gp, loc, s, lcontrib, tStep) == 0 ) {
267 return;
268 }
269
270 for ( auto &lir: *list ) {
271 auto rmat = dynamic_cast< RankineMatNl * >( lir.nearGp->giveMaterial() );
272 if ( rmat ) {
273 rmat->giveRemoteNonlocalStiffnessContribution(lir.nearGp, rloc, s, rcontrib, tStep);
274 double coeff = gp->giveElement()->computeVolumeAround(gp) * lir.weight / status->giveIntegrationScale();
275
276 contrib.clear();
277 contrib.plusDyadUnsym(lcontrib, rcontrib, - 1.0 * coeff);
278 dest.assemble(loc, rloc, contrib);
279 }
280 }
281}
282
283std :: vector< localIntegrationRecord > *
284RankineMatNl :: NonlocalMaterialStiffnessInterface_giveIntegrationDomainList(GaussPoint *gp)
285{
286 auto status = static_cast< RankineMatNlStatus * >( this->giveStatus(gp) );
287 this->buildNonlocalPointTable(gp);
288 return status->giveIntegrationDomainList();
289}
290
291
292// computes m*gprime*Btransposed*sigmaeff for the given Gauss point
293// and returns 0 of damage is not growing, 1 if it is growing
294// (if damage is not growing, the contribution is not considered at all)
295int
296RankineMatNl :: giveLocalNonlocalStiffnessContribution(GaussPoint *gp, IntArray &loc, const UnknownNumberingScheme &s,
297 FloatArray &lcontrib, TimeStep *tStep)
298{
299 int nrows, nsize;
300 double sum, damage, tempDamage;
301 RankineMatNlStatus *status = static_cast< RankineMatNlStatus * >( this->giveStatus(gp) );
302 StructuralElement *elem = static_cast< StructuralElement * >( gp->giveElement() );
303 FloatMatrix b;
304
305 damage = status->giveDamage();
306 tempDamage = status->giveTempDamage();
307 if ( tempDamage <= damage ) {
308 return 0; // no contribution if damage is not growing
309 }
310
311 elem->giveLocationArray(loc, s);
312 const FloatArray &stress = status->giveTempEffectiveStress();
313 elem->computeBmatrixAt(gp, b);
314 double nlKappa = this->computeCumPlasticStrain(gp, tStep);
315 double factor = computeDamageParamPrime(nlKappa);
316 factor *= mm; // this factor is m*gprime
317 nrows = b.giveNumberOfColumns();
318 nsize = stress.giveSize();
319 lcontrib.resize(nrows);
320 // compute the product Btransposed*stress and multiply by factor
321 for ( int i = 1; i <= nrows; i++ ) {
322 sum = 0.0;
323 for ( int j = 1; j <= nsize; j++ ) {
324 sum += b.at(j, i) * stress.at(j);
325 }
326
327 lcontrib.at(i) = sum * factor;
328 }
329
330 return 1; // contribution will be considered
331}
332
333// computes Btransposed*eta for the given Gauss point
334// (where eta is the derivative of cum. plastic strain wrt final strain)
335void
336RankineMatNl :: giveRemoteNonlocalStiffnessContribution(GaussPoint *gp, IntArray &rloc, const UnknownNumberingScheme &s,
337 FloatArray &rcontrib, TimeStep *tStep)
338{
339 RankineMatNlStatus *status = static_cast< RankineMatNlStatus * >( this->giveStatus(gp) );
340 StructuralElement *elem = static_cast< StructuralElement * >( gp->giveElement() );
341 elem->giveLocationArray(rloc, s);
342 FloatMatrix b;
343 elem->computeBmatrixAt(gp, b);
344 int ncols = b.giveNumberOfColumns();
345 rcontrib.resize(ncols);
346
347 double kappa = status->giveCumulativePlasticStrain();
348 double tempKappa = status->giveTempCumulativePlasticStrain();
349 if ( tempKappa <= kappa ) {
350 rcontrib.zero();
351 return;
352 }
353
354 double sum;
355 int nsize = 3;
356 FloatArray eta(3);
357 computeEta(eta, status);
358 for ( int i = 1; i <= ncols; i++ ) {
359 sum = 0.;
360 for ( int j = 1; j <= nsize; j++ ) {
361 sum += eta.at(j) * b.at(j, i);
362 }
363
364 rcontrib.at(i) = sum;
365 }
366}
367
368
369int
370RankineMatNl :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
371{
372 if ( type == IST_CumPlasticStrain_2 ) {
373 answer.resize(1);
374 // this method also stores the nonlocal kappa in status ... kappa_nl
375 computeCumPlasticStrain(gp, tStep);
376 RankineMatNlStatus *status = static_cast< RankineMatNlStatus * >( this->giveStatus(gp) );
377 answer.at(1) = status->giveKappa_nl();
378 return 1;
379 } else if ( type == IST_MaxEquivalentStrainLevel ) {
380 answer.resize(1);
381 answer.at(1) = computeCumPlasticStrain(gp, tStep);
382 return 1;
383 } else {
384 return RankineMat :: giveIPValue(answer, gp, type, tStep);
385 }
386}
387
388
389//*******************************
390//*************status************
391//*******************************
392
393RankineMatNlStatus :: RankineMatNlStatus(GaussPoint *g) :
395{}
396
397
398void
399RankineMatNlStatus :: printOutputAt(FILE *file, TimeStep *tStep) const
400{
401 StructuralMaterialStatus :: printOutputAt(file, tStep);
402 fprintf(file, "status { ");
403 fprintf(file, "damage %g, kappa %g, kappa_nl %g, kappa_hat %g", damage, kappa, kappa_nl, kappa_hat);
404#ifdef keep_track_of_dissipated_energy
405 fprintf(file, ", dissW %g, freeE %g, stressW %g", this->dissWork, ( this->stressWork ) - ( this->dissWork ), this->stressWork);
406#endif
407 fprintf(file, " }\n");
408}
409
410void
411RankineMatNlStatus :: initTempStatus()
412//
413// initializes temp variables according to variables form previous equlibrium state.
414// builds new crackMap
415//
416{
417 RankineMatStatus :: initTempStatus();
418}
419
420
421void
422RankineMatNlStatus :: updateYourself(TimeStep *tStep)
423//
424// updates variables (nonTemp variables describing situation at previous equilibrium state)
425// after a new equilibrium state has been reached
426// temporary variables are having values corresponding to newly reched equilibrium.
427//
428{
429 RankineMatStatus :: updateYourself(tStep);
430}
431
432
433void
434RankineMatNlStatus :: saveContext(DataStream &stream, ContextMode mode)
435{
436 RankineMatStatus :: saveContext(stream, mode);
437 //if (!stream.write(localEquivalentStrainForAverage,1)) THROW_CIOERR(CIO_IOERR);
438}
439
440void
441RankineMatNlStatus :: restoreContext(DataStream &stream, ContextMode mode)
442{
443 RankineMatStatus :: restoreContext(stream, mode);
444 //if (!stream.read(localEquivalentStrainForAverage,1)) THROW_CIOERR(CIO_IOERR);
445}
446
447Interface *
448RankineMatNlStatus :: giveInterface(InterfaceType type)
449{
451 return static_cast< StructuralNonlocalMaterialStatusExtensionInterface * >(this);
452 } else {
453 return RankineMatStatus :: giveInterface(type);
454 }
455}
456
457
458int
459RankineMatNl :: packUnknowns(DataStream &buff, TimeStep *tStep, GaussPoint *ip)
460{
461 RankineMatNlStatus *nlStatus = static_cast< RankineMatNlStatus * >( this->giveStatus(ip) );
462
463 this->buildNonlocalPointTable(ip);
465
466 return buff.write( nlStatus->giveLocalCumPlasticStrainForAverage() );
467}
468
469int
470RankineMatNl :: unpackAndUpdateUnknowns(DataStream &buff, TimeStep *tStep, GaussPoint *ip)
471{
472 int result;
473 RankineMatNlStatus *nlStatus = static_cast< RankineMatNlStatus * >( this->giveStatus(ip) );
474 double localCumPlasticStrainForAverage;
475
476 result = buff.read(localCumPlasticStrainForAverage);
477 nlStatus->setLocalCumPlasticStrainForAverage(localCumPlasticStrainForAverage);
478 return result;
479}
480
481int
482RankineMatNl :: estimatePackSize(DataStream &buff, GaussPoint *ip)
483{
484 // Note: nlStatus localStrainVectorForAverage memeber must be properly sized!
485 // IDNLMaterialStatus *nlStatus = (IDNLMaterialStatus*) this -> giveStatus (ip);
486 return buff.givePackSizeOfDouble(1);
487}
488
489} // 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 givePackSizeOfDouble(std::size_t count)=0
virtual int write(const int *data, std::size_t count)=0
Writes count integer values from array pointed by data.
void giveLocationArray(IntArray &locationArray, const UnknownNumberingScheme &s, IntArray *dofIds=NULL) const
Definition element.C:429
virtual double computeVolumeAround(GaussPoint *gp)
Definition element.h:530
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
*Sets size of receiver to be an empty matrix It will have zero rows and zero columns size void clear()
int giveNumberOfColumns() const
Returns number of columns of receiver.
void plusDyadUnsym(const FloatArray &a, const FloatArray &b, double dV)
double at(std::size_t i, std::size_t j) const
Element * giveElement()
Returns corresponding element to receiver.
Definition gausspoint.h:187
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
virtual void initTempStatus(GaussPoint *gp) const
Definition material.C:221
int averType
Parameter specifying how the weight function should be adjusted due to damage.
void buildNonlocalPointTable(GaussPoint *gp) const
ScalingType scaling
Parameter specifying the type of scaling of nonlocal weight function.
double mm
For "undernonlocal" or "overnonlocal" formulation.
void updateDomainBeforeNonlocAverage(TimeStep *tStep) const
void modifyNonlocalWeightFunctionAround(GaussPoint *gp) const
std ::vector< localIntegrationRecord > * giveIPIntegrationList(GaussPoint *gp) const
std ::vector< localIntegrationRecord > * giveIntegrationDomainList()
double giveKappa_nl() const
void setLocalCumPlasticStrainForAverage(double ls)
double kappa_nl
For printing only.
double giveLocalCumPlasticStrainForAverage() const
int giveLocalNonlocalStiffnessContribution(GaussPoint *gp, IntArray &loc, const UnknownNumberingScheme &s, FloatArray &lcontrib, TimeStep *tStep)
double computeDamage(GaussPoint *gp, TimeStep *tStep) const
virtual double computeCumPlasticStrain(GaussPoint *gp, TimeStep *tStep) const
RankineMatNl(int n, Domain *d)
double computeLocalCumPlasticStrain(GaussPoint *gp, TimeStep *tStep) const
double giveTempDamage() const
Definition rankinemat.h:244
double giveDamage() const
Definition rankinemat.h:243
double giveTempCumulativePlasticStrain() const
Definition rankinemat.h:247
const FloatArray & giveTempEffectiveStress() const
Definition rankinemat.h:262
double stressWork
Density of total work done by stresses on strain increments.
Definition rankinemat.h:229
double kappa
Cumulative plastic strain (initial).
Definition rankinemat.h:206
double giveCumulativePlasticStrain() const
Definition rankinemat.h:246
double damage
Damage (initial).
Definition rankinemat.h:219
RankineMatStatus(GaussPoint *g)
Definition rankinemat.C:676
double dissWork
Density of dissipated work.
Definition rankinemat.h:233
LinearElasticMaterial * linearElasticMaterial
Reference to the basic elastic material.
Definition rankinemat.h:89
double computeDamageParamPrime(double tempKappa) const
Definition rankinemat.C:435
RankineMat(int n, Domain *d)
Definition rankinemat.C:52
FloatMatrixF< 3, 3 > evaluatePlaneStressStiffMtrx(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep, double gprime) const
Definition rankinemat.C:502
double sig0
Initial (uniaxial) yield stress.
Definition rankinemat.h:107
void computeEta(FloatArray &answer, RankineMatStatus *status)
Computes derivatives of final kappa with respect to final strain.
Definition rankinemat.C:587
double E
Young's modulus.
Definition rankinemat.h:92
double computeDamageParam(double tempKappa) const
Definition rankinemat.C:416
void performPlasticityReturn(GaussPoint *gp, const FloatArray &totalStrain) const
Definition rankinemat.C:263
virtual int assemble(const IntArray &loc, const FloatMatrix &mat)=0
virtual void computeBmatrixAt(GaussPoint *gp, FloatMatrix &answer, int lowerIndx=1, int upperIndx=ALL_STRAINS)=0
#define OOFEM_ERROR(...)
Definition error.h:79
long ContextMode
Definition contextmode.h:43
double sum(const FloatArray &x)
@ NonlocalMaterialStiffnessInterfaceType
@ NonlocalMaterialStatusExtensionInterfaceType
@ NonlocalMaterialExtensionInterfaceType

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