OOFEM 3.0
Loading...
Searching...
No Matches
intmatbilinczfagerstrom.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"
44#include "dynamicinputrecord.h"
45
46
47namespace oofem {
48
50
51
52IntMatBilinearCZFagerstrom :: IntMatBilinearCZFagerstrom(int n, Domain *d) : StructuralInterfaceMaterial(n, d) { }
53
54
56IntMatBilinearCZFagerstrom :: giveFirstPKTraction_3d(const FloatArrayF<3> &d, const FloatMatrixF<3,3> &F, GaussPoint *gp, TimeStep *tStep) const
57{
59 // returns 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 FloatArrayF<3> Qold, Qtemp, Qtemp_comp;
74
75 if ( dJ.at(3) < 0 ) {
76 Qtemp_comp.at(3) = this->knc*dJ.at(3);
77 }
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
83 auto Kstiff = diag<3>({this->ks0, this->ks0, this->kn0});
84
85 dJ -= status->giveOldMaterialJump();
86 auto Qtrial = status->giveEffectiveMandelTraction() - dot(Kstiff, dJ);
87
88 double Qn = Qtrial.at(3);
89 FloatArrayF<2> QtrialShear = {Qtrial.at(1), Qtrial.at(2)};
90
91 double Qt = norm(QtrialShear);
92 double sigf = this->sigf;
93 double gamma = this->gamma;
94 double mu = this->mu;
95
96 double S = (this->GIc - pow(sigf,2)/(2*this->kn0))/sigf;
97 double gammaGf = gamma*(this->GIIc - pow(gamma*sigf,2)/(2*this->ks0))/(this->GIc - pow(sigf,2)/(2*this->kn0));
98
99 double Qn_M = 0.5*(Qn + fabs(Qn));
100 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
101
102 Qold = status->giveEffectiveMandelTraction();
103 Qtemp = Qtrial;
104
105 if ( loadFun/sigf < 1e-7 ) {
106 dAlpha = 0.0; // new_alpha=old_alpha
108 Qtemp *= 1 - oldDamage;
109 } else {
110 // dalpha = datr
111 double Qt1 = Qtemp.at(1);
112 double Qt2 = Qtemp.at(2);
113
114 FloatArrayF<3> M = { // M = (/2*Q_t/(sig_f*gamma**2), 2*Q_n/sig_f, 0.d0/)
115 2*Qt1/(pow(gamma,2)*sigf), // Qt = sqrt(Qt1^2 + Qt2^2)
116 2*Qt2/(pow(gamma,2)*sigf),
117 2*Qn_M/sigf,
118 };
119
120 auto dJElastic = dJ - S * dAlpha * M; // dJtn_e(1:2) = dJtn_v(1:2) - S*dalpha*M(1:2)
121
122 FloatMatrixF<4,4> Smati;
123
124 const double errorTol = 0.0001;
125 for( int iter = 1; fabs(loadFun)/sigf > errorTol; iter++) {
126 //printf("loadfun = %e \n",loadFun);
127 if (iter>40) {
128 OOFEM_ERROR("BilinearCZMaterialFagerstrom :: giveRealStressVector - no convergence in constitutive driver");
129 }
130 status->letTempDamageDevBe(true);
131
133 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))
134 R.at(2) = dJElastic.at(2) - (dJ.at(2) - gammaGf*S*dAlpha*M.at(2));
135 R.at(3) = dJElastic.at(3) - (dJ.at(3) - S*dAlpha*M.at(3));
136 R.at(4) = loadFun; // R(3) = F/sig_f
137
138 FloatMatrixF<4,4> Smat; // S_mat=0.d0
139 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)
140 Smat.at(2,2) = 1.0 + gammaGf*dAlpha*S*2*Kstiff.at(2,2)/(pow(gamma,2)*sigf);
141 //dJElastic.printYourself();
142 if (Qn_M>0) {
143 Smat.at(3,3) = 1.0 + dAlpha*S*2*Kstiff.at(3,3)/(sigf);
144 } else {
145 Smat.at(3,3) = 1.0;
146 }
147
148 Smat.at(1,4) = gammaGf*S*M.at(1); // S_mat(1:2,3) = S*M(1:2)
149 Smat.at(2,4) = gammaGf*S*M.at(2);
150 Smat.at(3,4) = S*M.at(3);
151
152 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))
153 Smat.at(4,2) = M.at(2)*Kstiff.at(2,2);
154 //Smat.at(4,3) = M.at(3)*Kstiff.at(3,3);
155 Smat.at(4,3) = (2*(gamma-mu)/(gamma*sigf)*Qn_M + mu/gamma)*Kstiff.at(3,3); //Martin: included parameter mu
156
157 //FloatArray inc;
158 //bool transpose = false;
159 //Smat.SolveforRhs(R, inc, transpose);
160
161 Smati = inv(Smat);
162
163 auto inc = dot(Smati, R);
164
165 dJElastic.at(1) -= inc.at(1);
166 dJElastic.at(2) -= inc.at(2);
167 dJElastic.at(3) -= inc.at(3);
168 dAlpha = dAlpha - inc.at(4);
169
170 Qtemp = Qold + dot(Kstiff, dJElastic);
171
172 double Qt1 = Qtemp.at(1);
173 double Qt2 = Qtemp.at(2);
174 Qt = sqrt(Qt1*Qt1 + Qt2*Qt2);
175 Qn = Qtemp.at(3); // Martin: included parameter mu
176 Qn_M = 0.5*(Qtemp.at(3)+fabs(Qtemp.at(3)));
177
178 M.at(1) = 2*Qt1/(pow(gamma,2)*sigf); // Qt = sqrt(Qt1^2 + Qt2^2)
179 M.at(2) = 2*Qt2/(pow(gamma,2)*sigf);
180 M.at(3) = 2*Qn_M/sigf;
181
182 //loadFun = sigf*pow(Qt/(gamma*sigf),2) + sigf*pow((Qn_M/sigf),2) - sigf;
183 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
184 }
185 //printf("converged, loadfun = %e, oldDamage = %e \n",loadFun, oldDamage);
186
187 if (oldDamage + dAlpha > 1) {
188 dAlpha = 1. - oldDamage;
189 }
190
191 FloatMatrixF<3,3> Iep = Smati({0,1,2},{0,1,2});
192 status->letTempIepBe(Iep);
193
194 FloatArrayF<3> alpha_v = {
195 Smati.at(4,1), // alpha_v(1:2) = S_mati(3,1:2)
196 Smati.at(4,2),
197 Smati.at(4,3),
198 };
199 status->letTempAlphavBe(alpha_v);
201 Qtemp *= 1 - oldDamage - dAlpha;
202
203 }
204
205 //Qtemp.rotatedWith(Rot,'t'); // Q=Qe
206 //status->letTempRotationMatrix(Rot);
207 } else {
208 dAlpha = 1.0 - oldDamage;
209 dJ = status->giveTempJump();
210 status->letTempEffectiveMandelTractionBe(Qtemp); // SHOULD NEVER BE USED!!
211 //if (dJ.at(3)<0) {
212 // Qtemp.at(3) = kn0*dJ.at(3);
213 //}
214 }
215
216 Qtemp += Qtemp_comp;
217
218 auto answer = Tdot(Finv, Qtemp); // t_1_hat = MATMUL(TRANSPOSE(Fci),Q)
219 //* (1-oldDamage-dAlpha); // t1_s = (1-al)*t_1_hat
220
221 status->letTempDamageBe(oldDamage + dAlpha);
222 //status->letTempEffectiveMandelTractionBe(Qtemp); // NEW!
223
224 status->letTempJumpBe(d);
225 status->letTempFirstPKTractionBe(answer);
226 status->letTempFBe(F);
227
228 return answer;
229}
230
231
233IntMatBilinearCZFagerstrom :: give3dStiffnessMatrix_dTdj(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) const
234{
236
237 FloatMatrixF<3,3> answer;
238 if ( status->giveOldDamageDev() ) {
239 answer = status->giveOlddTdJ();
240 //answer.printYourself();
241 status->letOldDamageDevBe(false);
242 } else {
243
244 double damage = status->giveTempDamage();
245 const auto &Finv = status->giveTempInverseDefGrad();
246 const auto &J = status->giveTempJump();
247
248 FloatMatrixF<3,3> Kstiff = diag<3>({this->ks0, this->ks0, this->kn0});
249 //FloatMatrix Rot = status->giveTempRotationMatrix();
250 //Kstiff = rotate(Kstiff, Rot);
251
252 if ( damage >= 1.0 ) {
253 if ( J.at(3) < 0 ) {
254 Kstiff = diag<3>({0.0, 0.0, this->knc});
255 answer = rotate(Kstiff, Finv);
256 //printf("fully damaged");
257 //answer.printYourself();
258 }
259 } else {
260 if ( status->giveTempDamage() - status->giveDamage()==0.0 ) {
261
262 if ( J.at(3) < 0 ) {
263 Kstiff.at(3,3) = Kstiff.at(3,3) + (this->knc)/(1-damage);
264 }
265
266 // Ea=(1-new_alpha)*MATMUL(TRANSPOSE(Fci),MATMUL(Keye3,Fci))
267 answer = (1-damage) * rotate(Kstiff, Finv);
268 //printf("elastic step");
269 } else {
270
271 const auto &Iep = status->giveTempIep();
272 //Iep.ourselfourself();
273
274 //if (J.at(3)<0) {
275 //Kstiff.at(1,1) = (1-damage)*Kstiff.at(1,1);
276 //Kstiff.at(2,2) = (1-damage)*Kstiff.at(2,2);
277 //Kstiff.at(3,3) = Kstiff.at(3,3);
278 //} else {
279 //Kstiff.times((1-damage));
280 //}
281
282 answer = (1 - damage) * dot(Kstiff, Iep);
283 //answer.rotatedWith(Rot);
284 // Ea_h = MATMUL(TRANSPOSE(Rot),MATMUL(Keye3,Iep))
285 // Ea_h = MATMUL(Ea_h,Rot)
286
287 const auto &alpha_v = status->giveTempAlphav();
288 //alpha_v = Tdot(Rot, alpha_v); // alpha_v = MATMUL(TRANSPOSE(Rot),alpha_v)
289
290 const auto &Qtemp = status->giveTempEffectiveMandelTraction();
291
292 auto temp1 = Tdot(Finv, Qtemp); // CALL gmopen33(MATMUL(TRANSPOSE(Fci),Q),MATMUL(alpha_v,Fci),t1halFci_o)
293 auto temp2 = Tdot(Finv, alpha_v);
294
295 auto t1hatFinvOpen = dyad(temp1, temp2);
296
297 if ( J.at(3) < 0 ) {
298 answer.at(3,3) = answer.at(3,3) + this->knc;
299 }
300
301 //printf("plastic step");
302 // Ea = (1-new_alpha)*MATMUL(TRANSPOSE(Fci),MATMUL(Ea_h,Fci)) - t1halFci_o
303 answer = rotate(answer, Finv) - t1hatFinvOpen;
304 }
305 }
306 }
307 status->letTempdTdJBe(answer);
308
309 return answer;
310}
311
312
313//const double tolerance = 1.0e-12; // small number
314void
315IntMatBilinearCZFagerstrom :: initializeFrom(InputRecord &ir)
316{
318 this->knc = kn0; // Defaults to the same stiffness in compression and tension
320
321 this->ks0 = kn0; // Defaults to kn0
323
325
326 this->GIIc = GIc; //Defaults to GIc
328
330
332
334
335 StructuralInterfaceMaterial ::initializeFrom(ir);
336
337 // check validity of the material paramters
338 if ( this->kn0 < 0.0 ) {
339 throw ValueInputException(ir, _IFT_IntMatBilinearCZFagerstrom_kn, "must be positive");
340 } else if ( this->ks0 < 0.0 ) {
341 throw ValueInputException(ir, _IFT_IntMatBilinearCZFagerstrom_ks, "must be positive");
342 } else if ( this->GIc < 0.0 ) {
343 throw ValueInputException(ir, _IFT_IntMatBilinearCZFagerstrom_g2c, "must be positive");
344 } else if ( this->GIIc < 0.0 ) {
345 throw ValueInputException(ir, _IFT_IntMatBilinearCZFagerstrom_g2c, "must be positive");
346 } else if ( this->gamma < 0.0 ) {
347 throw ValueInputException(ir, _IFT_IntMatBilinearCZFagerstrom_gamma, "must be positive");
348 }
349}
350
367
368int
369IntMatBilinearCZFagerstrom :: checkConsistency()
370{
371 return 1;
372}
373
374void
375IntMatBilinearCZFagerstrom :: printYourself()
376{
377 printf("Parameters for BilinearCZMaterial: \n");
378
379 printf("-Strength paramters \n");
380 printf(" sigf = %e \n", this->sigf);
381 printf(" GIc = %e \n", this->GIc);
382 printf(" GIIc = %e \n", this->GIIc);
383 printf(" gamma = sigfs/sigfn = %e \n", this->gamma);
384 printf(" mu = %e \n", this->mu);
385
386 printf("-Stiffness parameters \n");
387 printf(" kn0 = %e \n", this->kn0);
388 printf(" ks0 = %e \n", this->ks0);
389 printf(" knc = %e \n", this->knc);
390
391}
392
393
394IntMatBilinearCZFagerstromStatus :: IntMatBilinearCZFagerstromStatus(GaussPoint *g) : StructuralInterfaceMaterialStatus(g)
395{
396 tempFInv = eye<3>();
397 Iep = tempFInv;
398}
399
400
401void
402IntMatBilinearCZFagerstromStatus :: printOutputAt(FILE *file, TimeStep *tStep) const
403{
405 StructuralInterfaceMaterialStatus :: printOutputAt(file, tStep);
406 /*
407 fprintf(file, "status { ");
408 if ( this->damage > 0.0 ) {
409 fprintf(file, "kappa %f, damage %f ", this->kappa, this->damage);
410 }
411
412 fprintf(file, "}\n");
413 */
414}
415
416
417void
418IntMatBilinearCZFagerstromStatus :: initTempStatus()
419{
420 StructuralInterfaceMaterialStatus :: initTempStatus();
421
425
426 tempFInv = eye<3>();
427 Iep = tempFInv;
429
430 tempDamageDev = false;
431}
432
433void
434IntMatBilinearCZFagerstromStatus :: updateYourself(TimeStep *tStep)
435{
436 StructuralInterfaceMaterialStatus :: updateYourself(tStep);
442}
443
444
445} // end namespace oofem
#define REGISTER_Material(class)
void setField(int item, InputFieldType id)
double & at(std::size_t i)
double at(std::size_t i, std::size_t j) const
void letTempInverseDefGradBe(const FloatMatrixF< 3, 3 > &v)
void letTempEffectiveMandelTractionBe(const FloatArrayF< 3 > &v)
const FloatArrayF< 3 > & giveEffectiveMandelTraction() const
void letTempdTdJBe(const FloatMatrixF< 3, 3 > &v)
const FloatArrayF< 3 > & giveTempAlphav() const
const FloatArrayF< 3 > & giveTempEffectiveMandelTraction() const
const FloatMatrixF< 3, 3 > & giveOlddTdJ() const
void letTempAlphavBe(const FloatArrayF< 3 > &v)
const FloatMatrixF< 3, 3 > & giveTempInverseDefGrad() const
const FloatArrayF< 3 > & giveOldMaterialJump() const
void letTempMaterialJumpBe(const FloatArrayF< 3 > &v)
void letTempIepBe(const FloatMatrixF< 3, 3 > &v)
const FloatMatrixF< 3, 3 > & giveTempIep() 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...
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.
void giveInputRecord(DynamicInputRecord &input) override
#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 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, M > dyad(const FloatArrayF< N > &a, const FloatArrayF< M > &b)
Computes the dyadic product .
FloatMatrixF< M, M > rotate(FloatMatrixF< N, N > &a, const FloatMatrixF< N, M > &r)
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.
FloatMatrixF< N, N > eye()
Constructs an identity matrix.

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