OOFEM 3.0
Loading...
Searching...
No Matches
intmatbilinearcz.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 "gausspoint.h"
36#include "floatmatrix.h"
37#include "floatarray.h"
38#include "mathfem.h"
39#include "datastream.h"
40#include "contextioerr.h"
41#include "classfactory.h"
42#include "intmatbilinearcz.h"
43#include "dynamicinputrecord.h"
44
45namespace oofem {
47
48
50IntMatBilinearCZStatus :: IntMatBilinearCZStatus(GaussPoint *g) : StructuralInterfaceMaterialStatus(g)
51{}
52
53
54void IntMatBilinearCZStatus :: initTempStatus()
55{ }
56
57void IntMatBilinearCZStatus :: updateYourself(TimeStep *tStep)
58{
62
63 jump = mJumpNew;
64
66
67 StructuralInterfaceMaterialStatus ::updateYourself(tStep);
68}
69
70
71void IntMatBilinearCZStatus :: copyStateVariables(const MaterialStatus &iStatus)
72{
73 StructuralInterfaceMaterialStatus :: copyStateVariables(iStatus);
74
75 const IntMatBilinearCZStatus &structStatus = static_cast< const IntMatBilinearCZStatus & >(iStatus);
76
77 mDamageNew = structStatus.mDamageNew;
78 mDamageOld = structStatus.mDamageOld;
79 mTractionOld = structStatus.mTractionOld;
80 mTractionNew = structStatus.mTractionNew;
81 mJumpOld = structStatus.mJumpOld;
82 mJumpNew = structStatus.mJumpNew;
83
86}
87
88void IntMatBilinearCZStatus :: addStateVariables(const MaterialStatus &iStatus)
89{
90 OOFEM_ERROR("not implemented.");
91}
92
93
94IntMatBilinearCZ :: IntMatBilinearCZ(int n, Domain *d) : StructuralInterfaceMaterial(n, d)
95{ }
96
97
98int IntMatBilinearCZ :: checkConsistency()
99{
100 return 1;
101}
102
103FloatArrayF<3> IntMatBilinearCZ :: giveFirstPKTraction_3d(const FloatArrayF<3> &jump, const FloatMatrixF<3,3> &F, GaussPoint *gp, TimeStep *tStep) const
104{
105 double maxDamage = 0.99999999;
106
107 IntMatBilinearCZStatus *status = static_cast< IntMatBilinearCZStatus * >( this->giveStatus(gp) );
108
109 status->mJumpNew = jump;
110
111 auto jumpInc = status->mJumpNew - status->mJumpOld;
112
113 auto tractionTrial = status->mTractionOld + mPenaltyStiffness * jumpInc;
114
115 double TTrNormal = tractionTrial.at(3);
116 double TTrTang = sqrt( pow(tractionTrial.at(1), 2.0) + pow(tractionTrial.at(2), 2.0) );
117 double phiTr = computeYieldFunction(TTrNormal, TTrTang);
118
119 if ( status->mDamageOld > maxDamage ) {
120 status->mDamageNew = maxDamage;
121 status->mDamageOld = maxDamage;
122 status->mPlastMultIncNew = 0.0;
123 FloatArrayF<3> answer;
124 status->mTractionNew = answer;
125
126 status->letTempJumpBe(jump);
127 status->letTempFirstPKTractionBe(answer);
128 status->letTempTractionBe(answer);
129
130 return answer;
131 }
132
133
134 if ( phiTr < 0.0 ) {
135 status->mDamageNew = status->mDamageOld;
136 status->mPlastMultIncNew = 0.0;
137 status->mTractionNew = tractionTrial;
138
139
140 status->letTempJumpBe(jump);
141 status->letTempFirstPKTractionBe(tractionTrial);
142 status->letTempTractionBe(tractionTrial);
143
144 auto answer = tractionTrial;
145// answer.beScaled( ( 1.0 - status->mDamageNew ), answer );
146 answer.at(1) *= ( 1.0 - status->mDamageNew );
147 answer.at(2) *= ( 1.0 - status->mDamageNew );
148
149 if ( answer.at(3) > 0.0 ) {
150 answer.at(3) *= ( 1.0 - status->mDamageNew );
151 }
152
153 return answer;
154 } else {
155 // Iterate to find plastic strain increment.
156 int maxIter = 50;
157 int minIter = 1;
158 double absTol = 1.0e-9; // Absolute error tolerance
159 double relTol = 1.0e-9; // Relative error tolerance
160 double eps = 1.0e-12; // Small value for perturbation when computing numerical Jacobian
161 double plastMultInc = 0.0;
162 double initialRes = 0.0;
163
164 for ( int iter = 0; iter < maxIter; iter++ ) {
165 // Evaluate residual (i.e. yield function)
166 auto answer = computeTraction(tractionTrial, plastMultInc);
167
168 double TNormal = answer.at(3);
169 double TTang = sqrt( pow(answer.at(1), 2.0) + pow(answer.at(2), 2.0) );
170 double phi = computeYieldFunction(TNormal, TTang);
171
172 // if(iter > 20) {
173 // printf("iter: %d res: %e\n", iter, fabs(phi) );
174 // }
175
176 if ( iter == 0 ) {
177 initialRes = fabs(phi);
178 initialRes = max(initialRes, 1.0e-12);
179 }
180
181 if ( (iter >= minIter && fabs(phi) < absTol) || ( iter >= minIter && ( fabs(phi) / initialRes ) < relTol ) ) {
182 // Add damage evolution
183 double S = mGIc / mSigmaF;
184 status->mPlastMultIncNew = plastMultInc;
185
186 double damageInc = status->mPlastMultIncNew / S;
187 status->mDamageNew = status->mDamageOld + damageInc;
188
189 if ( status->mDamageNew > maxDamage ) {
190 status->mDamageNew = maxDamage;
191 }
192
193 status->mTractionNew = answer;
194
195 // Jim
196 status->letTempJumpBe(jump);
197 status->letTempFirstPKTractionBe(answer);
198 status->letTempTractionBe(answer);
199
200 if ( mSemiExplicit ) {
201 answer = computeTraction(tractionTrial, status->mPlastMultIncOld);
202
203// answer.beScaled( ( 1.0 - status->mDamageOld ), answer );
204
205 answer.at(1) *= ( 1.0 - status->mDamageOld );
206 answer.at(2) *= ( 1.0 - status->mDamageOld );
207
208 if ( answer.at(3) > 0.0 ) {
209 answer.at(3) *= ( 1.0 - status->mDamageOld );
210 }
211 } else {
212// answer.beScaled( ( 1.0 - status->mDamageNew ), answer );
213
214 answer.at(1) *= ( 1.0 - status->mDamageNew );
215 answer.at(2) *= ( 1.0 - status->mDamageNew );
216
217 if ( answer.at(3) > 0.0 ) {
218 answer.at(3) *= ( 1.0 - status->mDamageNew );
219 }
220 }
221
222 return answer;
223 }
224
225 // Numerical Jacobian
226 auto tractionPert = computeTraction(tractionTrial, plastMultInc + eps);
227 double TNormalPert = tractionPert.at(3);
228 double TTangPert = sqrt( pow(tractionPert.at(1), 2.0) + pow(tractionPert.at(2), 2.0) );
229 double phiPert = computeYieldFunction(TNormalPert, TTangPert);
230
231 double Jac = ( phiPert - phi ) / eps;
232 plastMultInc -= ( 1.0 / Jac ) * phi;
233 }
234 }
235
236 OOFEM_ERROR("No convergence in.");
237}
238
239FloatMatrixF<3,3> IntMatBilinearCZ :: give3dStiffnessMatrix_dTdj(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) const
240{
241 OOFEM_WARNING("not implemented. Use numerical Jacobian instead.");
242 return this->give3dStiffnessMatrix_dTdj_Num(gp, tStep);
243}
244
245double IntMatBilinearCZ :: computeYieldFunction(double iTractionNormal, double iTractionTang) const
246{
247 return mSigmaF * pow(fabs(iTractionTang) / ( mGamma * mSigmaF ), 2.0)
248 + ( mSigmaF / mGamma ) * ( mGamma - 2.0 * mMu ) * pow( ( max(iTractionNormal, 0.0) ) / mSigmaF, 2.0 )
249 - ( 1.0 / mGamma ) * ( mGamma * mSigmaF - 2.0 * mMu * iTractionNormal );
250}
251
252FloatArrayF<3> IntMatBilinearCZ :: computeTraction(const FloatArrayF<3> &iTTrial, double iPlastMultInc) const
253{
254 // Note that the traction vector is assumed to be decomposed into its tangential and normal part,
255 // with tangential directions (1,2) and normal direction (3).
256
257 double gammaF = mGIIc / mGIc;
258
260 // Tangential part
261 oT.at(1) = iTTrial.at(1) / ( 1.0 + ( 2.0 * mPenaltyStiffness * gammaF ) * iPlastMultInc / ( mGamma * mGamma * mSigmaF ) );
262 oT.at(2) = iTTrial.at(2) / ( 1.0 + ( 2.0 * mPenaltyStiffness * gammaF ) * iPlastMultInc / ( mGamma * mGamma * mSigmaF ) );
263
264 // Normal part
265 if ( iTTrial.at(3) <= 0.0 ) { // TODO: Check if-statement
266 oT.at(3) = iTTrial.at(3);
267 } else {
268 oT.at(3) = iTTrial.at(3) / ( 1.0 + 2.0 * mPenaltyStiffness * iPlastMultInc / mSigmaF );
269 }
270 return oT;
271}
272
273void IntMatBilinearCZ :: initializeFrom(InputRecord &ir)
274{
275 StructuralInterfaceMaterial :: initializeFrom(ir);
276
278
280
281 mGIIc = mGIc; //Defaults to GIc
283
285
287
289
291 mSemiExplicit = true;
292 printf("In IntMatBilinearCZ::initializeFrom: Semi-explicit time integration activated.\n");
293 }
294}
295
296void IntMatBilinearCZ :: giveInputRecord(DynamicInputRecord &input)
297{
298 StructuralInterfaceMaterial :: giveInputRecord(input);
299
301
304
308}
309
310void IntMatBilinearCZ :: printYourself()
311{
312 printf("\nInitializing IntMatBilinearCZ:\n");
313 printf("mPenaltyStiffness: %e\n", mPenaltyStiffness);
314 printf("mGIc: %e\n", mGIc);
315 printf("mGIIc: %e\n", mGIIc);
316 printf("mSigmaF: %e\n", mSigmaF);
317 printf("mMu: %e\n", mMu);
318 printf("mGamma: %e\n\n", mGamma);
319}
320} /* namespace oofem */
#define REGISTER_Material(class)
void setField(int item, InputFieldType id)
double & at(std::size_t i)
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
FloatArrayF< 3 > mTractionOld
Traction.
double mDamageNew
damage variable
FloatArrayF< 3 > mJumpOld
Discontinuity.
FloatArrayF< 3 > computeTraction(const FloatArrayF< 3 > &iTTrial, double iPlastMultInc) const
double computeYieldFunction(double iTractionNormal, double iTractionTang) const
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
StructuralInterfaceMaterialStatus(GaussPoint *g)
Constructor. Creates new StructuralInterfaceMaterialStatus with number n, belonging to domain d and I...
FloatArrayF< 3 > jump
Equilibrated jump (discontinuity).
void letTempFirstPKTractionBe(const FloatArrayF< 3 > v)
Assigns tempFirstPKTraction to given vector v.
void letTempTractionBe(const FloatArrayF< 3 > v)
Assigns tempTraction to given vector v.
void letTempJumpBe(const FloatArrayF< 3 > v)
Assigns tempJump to given vector v.
FloatMatrixF< 3, 3 > give3dStiffnessMatrix_dTdj_Num(GaussPoint *gp, TimeStep *tStep) const
#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_IntMatBilinearCZ_semiexplicit
#define _IFT_IntMatBilinearCZ_gamma
#define _IFT_IntMatBilinearCZ_g2c
#define _IFT_IntMatBilinearCZ_g1c
#define _IFT_IntMatBilinearCZ_mu
#define _IFT_IntMatBilinearCZ_PenaltyStiffness
#define _IFT_IntMatBilinearCZ_sigf
#define S(p)
Definition mdm.C:469
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)

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