OOFEM 3.0
Loading...
Searching...
No Matches
intmatbilinczfagerstromrate.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
36#include "gausspoint.h"
37#include "floatmatrix.h"
38#include "floatarray.h"
39#include "mathfem.h"
40#include "datastream.h"
41#include "contextioerr.h"
42#include "classfactory.h"
45//#include "vld.h"
46
47namespace oofem {
48
50
51IntMatBilinearCZFagerstromRate :: IntMatBilinearCZFagerstromRate(int n, Domain *d) : IntMatBilinearCZFagerstrom(n, d)
52{}
53
54
57IntMatBilinearCZFagerstromRate :: giveFirstPKTraction_3d(const FloatArrayF<3> &d, const FloatMatrixF<3,3> &F, GaussPoint *gp, TimeStep *tStep) const
58{
59 // returns real stress vector in 3d stress space of receiver according to
60 // previous level of stress and current
61 // strain increment, the only way, how to correctly update gp records
62 //
64
65 auto Finv = inv(F);
66 status->letTempInverseDefGradBe(Finv);
67
68 auto dJ = dot(Finv, d);
69 status->letTempMaterialJumpBe(dJ);
70
71 double oldDamage = status->giveDamage();
72 double dAlpha = 0.0;
73 double dt = tStep->giveTimeIncrement();
74
75 FloatArrayF<3> Qold, Qtemp, Qtemp_comp;
76 if ( dJ.at(3) < 0 ) {
77 Qtemp_comp.at(3) = this->knc*dJ.at(3);
78 }
79
80 // SUBROUTINE stress_damage_XFEM_direct_Mandel(dJ,N,Qold,old_alpha,Fci,Q,Ea,new_alpha,adtim,dalpha_new,dalpha_old,diss,sig_f,fall);
81 if ( oldDamage < 0.99 ) {
82 FloatArray Qtrial = status->giveEffectiveMandelTraction();
83
84 auto Kstiff = diag<3>({this->ks0, this->ks0, this->kn0});
85
86#if 0
87 if (dJ.at(3)>=0) {
88 Kstiff.at(3,3) = this->kn0;
89 } else {
90 Kstiff.at(3,3) = this->kn0/(1-oldDamage);
91 }
92#endif
93
94 dJ -= status->giveOldMaterialJump();
95 //dJ.rotatedWith(Rot,'n');
96 //dJ.printYourself();
97
98 Qtrial += dot(Kstiff, dJ);
99
100 double Qn = Qtrial.at(3);
101 auto QtrialShear = {Qtrial.at(1), Qtrial.at(2), 0.};
102
103 double Qt = norm(QtrialShear);
104
105 //double S = this->GIc/this->sigf;
106 double sigf = this->sigf;
107 double gamma = this->gamma;
108 //double gammaGf = this->GIIc/this->GIc;
109 double mu = this->mu;
110 double c_star = this->c_star;
111 double m = this->m;
112 //double S = this->GIc/this->sigf;
113 double S = (this->GIc - pow(sigf,2)/(2*this->kn0))/sigf;
114 double gammaGf = gamma*(this->GIIc - pow(gamma*sigf,2)/(2*this->ks0))/(this->GIc - pow(sigf,2)/(2*this->kn0));
115
116 double Qn_M = 0.5*(Qn + fabs(Qn));
117
118 //double loadFun = sigf*pow(Qt/(gamma*sigf),2) + sigf*pow((Qn_M/sigf),2) - sigf; ///@todo Martin: no use of parameter mu!!!
119 double loadFun = sigf*pow(Qt/(gamma*sigf),2) + (sigf/gamma)*(gamma-mu)*pow((Qn_M/sigf),2) - 1/gamma*(gamma*sigf-mu*Qn); // Added support for parameter mu
120
121 Qold = status->giveEffectiveMandelTraction();
122 Qtemp = Qtrial;
123
124 //Qold.rotatedWith(Rot,'n');
125
126 //double alphaOld = status->giveDamage();
127
128 //if (alphaOld>0.1) {
129 // double bbb=1; ///@todo Should this be used for anything Martin? /JB
130 //}
131
132 if ( loadFun/sigf < 0.0000001 ) {
133 dAlpha = 0.0; // new_alpha=old_alpha
135 Qtemp *= 1-oldDamage;
136 } else {
137 // dalpha = datr
138 double Qt1 = Qtemp.at(1);
139 double Qt2 = Qtemp.at(2);
140
141 FloatArrayF<3> M; // M = (/2*Q_t/(sig_f*gamma**2), 2*Q_n/sig_f, 0.d0/)
142 M.at(1) = 2*Qt1/(pow(gamma,2)*sigf); // Qt = sqrt(Qt1^2 + Qt2^2)
143 M.at(2) = 2*Qt2/(pow(gamma,2)*sigf);
144 M.at(3) = 2*Qn_M/sigf;
145
146 auto dJElastic = dJ - (S * dAlpha) * M; // dJtn_e(1:2) = dJtn_v(1:2) - S*dalpha*M(1:2)
147 //dAlpha = (dt/(c_star*S))*pow(loadFun_M/sigf,m)*(1/M_norm);
148
149 FloatMatrixF<4,4> Smati;
150 FloatArrayF<3> dJp;
151 double loadFunDyn = loadFun;
152
153 const double errorTol = 0.0001;
154 for( int iter = 1; fabs(loadFunDyn)/sigf > errorTol; iter++) {
155 //printf("loadfun = %e \n",loadFun);
156 //double loadFun_M = 0.5*(loadFun + fabs(loadFun));
157 //double M_norm = sqrt(M.computeSquaredNorm());
158
159 if ( iter > 40 ) {
160 OOFEM_ERROR("BilinearCZMaterialFagerstrom :: giveRealStressVector - no convergence in constitutive driver");
161 }
162 status->letTempDamageDevBe(true);
163
165 R.at(1) = dJElastic.at(1) - (dJ.at(1) - gammaGf*S*dAlpha*M.at(1)); // R(1:2) = dJtn_e(1:2) - (dJtn_v(1:2) - S*dalpha*M(1:2))
166 R.at(2) = dJElastic.at(2) - (dJ.at(2) - gammaGf*S*dAlpha*M.at(2));
167 R.at(3) = dJElastic.at(3) - (dJ.at(3) - S*dAlpha*M.at(3));
168 if ( fabs(c_star) > 0 ) {
169 //R.at(4) = loadFun - c_star*pow(dAlpha/dt, m);
170 //R.at(4) = loadFun - c_star*pow(norm(dJ)/dt, m);
171 dJp = dJ - dJElastic;
172 R.at(4) = loadFun - c_star*pow(norm(dJp)/dt, m);
173 //R.at(4) = dAlpha - (dt/(c_star*S))*pow(loadFun_M/sigf,m)*(1/M_norm);
174 } else {
175 R.at(4) = loadFun; // R(3) = F/sig_f
176 }
177
178 // dMdJtn_e(1,1:2) = (/2/(sig_f*gamma**2),0.d0/)
179 // IF (Q_nM>0) THEN
180 // dMdJtn_e(2,1:2) = (/0.d0,2/sig_f/)
181 // ELSE
182 // dMdJtn_e(2,1:2) = (/0.d0,0.d0/)
183 // END IF
184
185 // dMdJtn_e = MATMUL(dMdJtn_e,Keye3(1:2,1:2))
186
187 FloatMatrixF<4,4> Smat; // S_mat=0.d0
188 Smat.at(1,1) = 1.0 + gammaGf*dAlpha*S*2*Kstiff.at(1,1)/(pow(gamma,2)*sigf); // S_mat(1:2,1:2) = eye3(1:2,1:2)+ dalpha*S*dMdJtn_e(1:2,1:2)
189 Smat.at(2,2) = 1.0 + gammaGf*dAlpha*S*2*Kstiff.at(2,2)/(pow(gamma,2)*sigf);
190 //dJElastic.printYourself();
191 if ( Qn_M > 0 ) {
192 Smat.at(3,3) = 1.0 + dAlpha*S*2*Kstiff.at(3,3)/(sigf);
193 } else {
194 Smat.at(3,3) = 1.0;
195 }
196
197 Smat.at(1,4) = gammaGf*S*M.at(1); // S_mat(1:2,3) = S*M(1:2)
198 Smat.at(2,4) = gammaGf*S*M.at(2);
199 Smat.at(3,4) = S*M.at(3);
200
201 double fac1;
202 if ( norm(dJp) > 0 ) {
203 fac1 = c_star*m/pow(dt, m)*pow(norm(dJp), m-2);
204 } else {
205 fac1 = 0;
206 }
207
208 if ( fabs(c_star) > 0 ) { // Rate-dependent case
209 Smat.at(4,1) = M.at(1)*Kstiff.at(1,1) + fac1*dJp.at(1); // S_mat(3,1:2) = MATMUL(M(1:2),Keye3(1:2,1:2))
210 Smat.at(4,2) = M.at(2)*Kstiff.at(2,2) + fac1*dJp.at(2);
211 Smat.at(4,3) = (2*(gamma-mu)/(gamma*sigf)*Qn_M + mu/gamma)*Kstiff.at(3,3) + fac1*dJp.at(3); //Martin: included parameter mu
212 //Smat.at(4,4) = -c_star*m*pow((dAlpha/dt),m-1);
213 //Smat.at(4,1) = -fac1*(fac2*M.at(1)*Kstiff.at(1,1) - fac3*M.at(1)*Kstiff.at(1,1));
214 //Smat.at(4,2) = -fac1*(fac2*M.at(2)*Kstiff.at(2,2) - fac3*M.at(2)*Kstiff.at(2,2));
215 //Smat.at(4,1) = -fac1*(fac2*M.at(3)*Kstiff.at(3,3) - fac4*M.at(3)*Kstiff.at(3,3));
216 //Smat.at(4,4) = 1.0;
217 } else { // Rate-independent case
218 Smat.at(4,1) = M.at(1)*Kstiff.at(1,1); // S_mat(3,1:2) = MATMUL(M(1:2),Keye3(1:2,1:2))
219 Smat.at(4,2) = M.at(2)*Kstiff.at(2,2);
220 //Smat.at(4,3) = M.at(3)*Kstiff.at(3,3);
221 Smat.at(4,3) = (2*(gamma-mu)/(gamma*sigf)*Qn_M + mu/gamma)*Kstiff.at(3,3); //Martin: included parameter mu
222 }
223
224 //FloatArray inc;
225 //bool transpose = false;
226 //Smat.SolveforRhs(R, inc, transpose);
227
228 Smati = inv(Smat);
229
230 auto inc = dot(Smati,R);
231
232 dJElastic.at(1) -= inc.at(1);
233 dJElastic.at(2) -= inc.at(2);
234 dJElastic.at(3) -= inc.at(3);
235 //dJElastic.printYourself();
236 dAlpha -= inc.at(4);
237
238 Qtemp = Qold + dot(Kstiff, dJElastic);
239
240 double Qt1 = Qtemp.at(1);
241 double Qt2 = Qtemp.at(2);
242 Qt = sqrt(Qt1*Qt1 + Qt2*Qt2);
243 Qn = Qtemp.at(3); // Martin: included parameter mu
244 Qn_M = 0.5*(Qtemp.at(3)+fabs(Qtemp.at(3)));
245
246 M.at(1) = 2*Qt1/(pow(gamma,2)*sigf); // Qt = sqrt(Qt1^2 + Qt2^2)
247 M.at(2) = 2*Qt2/(pow(gamma,2)*sigf);
248 M.at(3) = 2*Qn_M/sigf;
249
250 //loadFun = sigf*pow(Qt/(gamma*sigf),2) + sigf*pow((Qn_M/sigf),2) - sigf;
251 loadFun = sigf*pow(Qt/(gamma*sigf),2) + (sigf/gamma)*(gamma-mu)*pow((Qn_M/sigf),2) - 1/gamma*(gamma*sigf-mu*Qn); //Martin: included parameter mu
252 loadFunDyn = loadFun - c_star*pow(norm(dJp)/dt, m);
253 }
254 //printf("converged, loadfun = %e, oldDamage = %e \n",loadFun, oldDamage);
255 if ( oldDamage + dAlpha > 1 ) {
256 dAlpha = 1. - oldDamage;
257 }
258
259 FloatMatrixF<3,3> Iep = Smati({0,1,2},{0,1,2});
260 status->letTempIepBe(Iep);
261
262 FloatArrayF<3> alpha_v {
263 Smati.at(4,1), // alpha_v(1:2) = S_mati(3,1:2)
264 Smati.at(4,2),
265 Smati.at(4,3),
266 };
267
268 status->letTempAlphavBe(alpha_v);
270 Qtemp *= 1 - oldDamage - dAlpha;
271 }
272
273 //Qtemp.rotatedWith(Rot,'t'); // Q=Qe
274 //status->letTempRotationMatrix(Rot);
275 } else {
276 dAlpha = 1.0 - oldDamage;
277 dJ = status->giveTempJump();
278 status->letTempEffectiveMandelTractionBe(Qtemp); // SHOULD NEVER BE USED!!
279 //if (dJ.at(3)<0) {
280 // Qtemp.at(3) = kn0*dJ.at(3);
281 //}
282 }
283
284 Qtemp += Qtemp_comp;
285
286 auto answer = Tdot(Finv,Qtemp); // t_1_hat = MATMUL(TRANSPOSE(Fci),Q)
287// answer *= 1 - oldDamage - dAlpha; // t1_s = (1-al)*t_1_hat
288
289 status->letTempDamageBe(oldDamage + dAlpha);
290// status->letTempEffectiveMandelTractionBe(Qtemp); // NEW!
291 status->letTempJumpBe(d);
292 status->letTempFirstPKTractionBe(answer);
293 status->letTempFBe(F);
294
295 return answer;
296}
297
298
299//const double tolerance = 1.0e-12; // small number
300void
301IntMatBilinearCZFagerstromRate :: initializeFrom(InputRecord &ir)
302{
304 this->knc = kn0; // Defaults to the same stiffness in compression and tension
306
307 this->ks0 = kn0; // Defaults to kn0
309
311
312 this->GIIc = GIc; //Defaults to GIc
314
316
318
320
322
324
325 StructuralInterfaceMaterial ::initializeFrom(ir);
326
327 this->checkConsistency(); // check validity of the material paramters
328 this->printYourself();
329}
330
331void IntMatBilinearCZFagerstromRate :: giveInputRecord(DynamicInputRecord &input)
332{
334
337}
338
339int
340IntMatBilinearCZFagerstromRate :: checkConsistency()
341{
342 if ( this->kn0 < 0.0 ) {
343 OOFEM_ERROR("stiffness kn0 is negative (%.2e)", this->kn0);
344 } else if ( this->ks0 < 0.0 ) {
345 OOFEM_ERROR("stiffness ks0 is negative (%.2e)", this->ks0);
346 } else if ( this->GIc < 0.0 ) {
347 OOFEM_ERROR("GIc is negative (%.2e)", this->GIc);
348 } else if ( this->GIIc < 0.0 ) {
349 OOFEM_ERROR("GIIc is negative (%.2e)", this->GIIc);
350 } else if ( this->gamma < 0.0 ) {
351 OOFEM_ERROR("gamma (%.2e) is below zero which is unphysical",
352 this->gamma);
353 }
354 return 1;
355}
356
357void
358IntMatBilinearCZFagerstromRate :: printYourself()
359{
360 IntMatBilinearCZFagerstrom :: printYourself();
361 printf("-Rate parameters \n");
362 printf(" c_star = %e \n", this->c_star);
363 printf(" m = %e \n", this->m);
364}
365
366
367} // end namespace oofem
#define REGISTER_Material(class)
void setField(int item, InputFieldType id)
double & at(std::size_t i)
double & at(Index i)
Definition floatarray.h:202
double at(std::size_t i, std::size_t j) const
void printYourself() override
Prints receiver state on stdout. Useful for debugging.
double c_star
Rate dependence coefficient.
void letTempInverseDefGradBe(const FloatMatrixF< 3, 3 > &v)
void letTempEffectiveMandelTractionBe(const FloatArrayF< 3 > &v)
const FloatArrayF< 3 > & giveEffectiveMandelTraction() const
void letTempAlphavBe(const FloatArrayF< 3 > &v)
const FloatArrayF< 3 > & giveOldMaterialJump() const
void letTempMaterialJumpBe(const FloatArrayF< 3 > &v)
void letTempIepBe(const FloatMatrixF< 3, 3 > &v)
IntMatBilinearCZFagerstrom(int n, Domain *d)
Constructor.
void giveInputRecord(DynamicInputRecord &input) override
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
const FloatArrayF< 3 > & giveTempJump() const
Returns the const pointer to receiver's temporary jump.
void letTempFBe(const FloatMatrixF< 3, 3 > &v)
Assigns tempFVector to given vector v.
void letTempFirstPKTractionBe(const FloatArrayF< 3 > v)
Assigns tempFirstPKTraction to given vector v.
void letTempJumpBe(const FloatArrayF< 3 > v)
Assigns tempJump to given vector v.
double giveTimeIncrement()
Returns solution step associated time increment.
Definition timestep.h:168
#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_IntMatBilinearCZFagerstrom_ks
#define _IFT_IntMatBilinearCZFagerstrom_kn
#define _IFT_IntMatBilinearCZFagerstrom_sigf
#define _IFT_IntMatBilinearCZFagerstrom_g1c
#define _IFT_IntMatBilinearCZFagerstrom_g2c
#define _IFT_IntMatBilinearCZFagerstrom_gamma
#define _IFT_IntMatBilinearCZFagerstrom_mu
#define _IFT_IntMatBilinearCZFagerstrom_knc
#define _IFT_IntMatBilinearCZFagerstromRate_cstar
#define _IFT_IntMatBilinearCZFagerstromRate_m
#define S(p)
Definition mdm.C:469
double norm(const FloatArray &x)
FloatMatrixF< N, P > Tdot(const FloatMatrixF< M, N > &a, const FloatMatrixF< M, P > &b)
Computes .
FloatMatrixF< N, N > diag(const FloatArrayF< N > &v)
double dot(const FloatArray &x, const FloatArray &y)
FloatMatrixF< N, N > inv(const FloatMatrixF< N, N > &mat, double zeropiv=1e-24)
Computes the inverse.

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