OOFEM 3.0
Loading...
Searching...
No Matches
intmatbilinczjansson.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"
43
44namespace oofem {
45
47
48
49IntMatBilinearCZJansson :: IntMatBilinearCZJansson(int n, Domain *d) : StructuralInterfaceMaterial(n, d)
50{ }
51
52
55IntMatBilinearCZJansson :: giveFirstPKTraction_3d(const FloatArrayF<3> &d, const FloatMatrixF<3,3> &F, GaussPoint *gp, TimeStep *tStep) const
56{
57 // returns real stress vector in 3d stress space of receiver according to
58 // previous level of stress and current
59 // strain increment, the only way, how to correctly update gp records
60
61 IntMatBilinearCZJanssonStatus *status = static_cast< IntMatBilinearCZJanssonStatus * >( this->giveStatus(gp) );
62
63 auto Finv = inv(F);
64 status->letTempInverseDefGradBe(Finv);
65
66 auto dJ = dot(Finv, d);
67 status->letTempMaterialJumpBe(dJ);
68
69 double oldDamage = status->giveDamage();
70 double dAlpha = 0.0;
71 FloatArrayF<3> Qold, Qtemp, Qtemp_comp;
72
73 if ( dJ.at(3) < 0 ) {
74 Qtemp_comp.at(3) = this->knc*dJ.at(3);
75 }
76
77 auto Qtrial = status->giveEffectiveMandelTraction();
78
79 if ( oldDamage < 0.99 ) {
80 //FloatArray Qtrial = status->giveEffectiveMandelTraction();
81
82
83 auto Kstiff = diag<3>({this->ks0, this->ks0, this->kn0});
84 //} else {
85 // Kstiff.at(3,3) = this->kn0/(1-oldDamage);
86 //}
87
88 dJ -= status->giveOldMaterialJump();
89
90 Qtrial += dot(Kstiff, dJ);
91 double Qn = Qtrial.at(3);
92 FloatArrayF<3> QtrialShear = {Qtrial[0], Qtrial[1], 0.};
93
94 double Qt = norm(QtrialShear);
95
96// double S = this->GIc/this->sigf;
97 double sigf = this->sigf;
98 double gamma = this->gamma;
99// double gammaGf = this->GIIc/this->GIc;
100 double mu = this->mu;
101 double c = mu/gamma;
102
103 double Qn_M = 0.5*(Qn + fabs(Qn));
104// double loadFun = sigf*pow(Qt/(gamma*sigf),2) + sigf*pow((Qn_M/sigf),2) - sigf; ///@todo Martin: no use of parameter mu!!!
105
106 double loadFun = sigf*pow(Qt/(gamma*sigf),2) + sigf*(1-c)*pow((Qn_M/sigf),2) + sigf*c*(Qn/sigf) - sigf;
107
108 // completely unused?
109 //auto Qold = status->giveEffectiveMandelTraction();
110 Qtemp = Qtrial;
111
112 //Qold.rotatedWith(Rot,'n');
113
114 if ( loadFun/sigf < 0.0000001 ) {
115 dAlpha = 0.0; // new_alpha=old_alpha
117 Qtemp *= 1-oldDamage;
118 } else {
119 status->letTempDamageDevBe(true);
120
121 // dalpha = datr
122 double C1 = (pow((Qt/gamma),2)+(1-c)*pow(Qn_M,2))/(pow(sigf,2));
123 double C2 = c*Qn_M/sigf;
124
125 //double xi = (-C2 + sqrt(pow(C2,2)+(1-c*Qn_M/sigf)*4*C1))/(2*C1);
126 double xi = 0.0;
127
128 if ( Qn >= 0 ) {
129 xi = (-C2 + sqrt(pow(C2,2)+4*C1))/(2*C1);
130 } else {
131 if (1-c*Qn/sigf>0) {
132 xi = (sigf*gamma/Qt)*sqrt(1-c*Qn/sigf);
133 } else {
134 OOFEM_ERROR("Inconsistent cohesive model specification, 1-c*Qn/sigf = %e", 1 - c*Qn / sigf);
135 }
136 }
137
138 Qt = xi*Qt;
139 Qn = 0.5*((1+xi)-(1-xi)*sgn(Qn))*Qn;
140 Qn_M = 0.5*(Qn + fabs(Qn));
141
142 double beta = pow(Qt,2)*Kstiff.at(3,3)/(pow(Qn_M,2)*Kstiff.at(1,1) + pow(Qt,2)*Kstiff.at(3,3));
143
144 double G_beta = beta*(this->GIIc - pow(gamma*sigf,2)/(2*this->ks0)) + (1-beta)*(this->GIc - pow(sigf,2)/(2*this->kn0)); // assuming linear interpolation between mode I and II
145
146
147 double eta = (pow(Qn_M,2) + pow(Qt,2)*Kstiff.at(3,3)/Kstiff.at(1,1))/(G_beta*sigf);
148
149 dAlpha = (1/xi-1)*sigf/(2*Kstiff.at(3,3))*eta;
150
151 if ( oldDamage + dAlpha > 1 ) {
152 dAlpha = 1-oldDamage;
153 }
154
155 double Qt_trial = norm(QtrialShear);
156
157 double Qt1, Qt2;
158
159 if ( Qt_trial > 0 ) {
160 Qt1 = Qt*QtrialShear.at(1)/Qt_trial;
161 Qt2 = Qt*QtrialShear.at(2)/Qt_trial;
162 } else {
163 Qt1 = 0.0;
164 Qt2 = 0.0;
165 }
166
167
168 FloatArrayF<3> Mstar, M;
169
170 Mstar.at(1) = 2*Qt1*this->kn0/Kstiff.at(1,1)/(sigf); // Qt = sqrt(Qt1^2 + Qt2^2)
171 Mstar.at(2) = 2*Qt2*this->kn0/Kstiff.at(2,2)/(sigf);
172 Mstar.at(3) = 2*Qn_M/sigf;
173
174 M.at(1) = 2*Qt1/(pow(gamma,2)*sigf);
175 M.at(2) = 2*Qt2/(pow(gamma,2)*sigf);
176 M.at(3) = 2*(1-c)/(sigf)*Qn_M + c;
177
178 FloatMatrix Smat(4,4), Smati(4,4);
179 Smat.zero(); // S_mat=0.d0
180
181 Smat.at(1,1) = 1.0 + dAlpha*(1/eta)*2*this->kn0/(sigf); // S_mat(1:2,1:2) = eye3(1:2,1:2)+ dalpha*S*dMdJtn_e(1:2,1:2)
182 Smat.at(2,2) = 1.0 + dAlpha*(1/eta)*2*this->kn0/(sigf);
183
184 if ( Qn_M > 0 ) {
185 Smat.at(3,3) = 1.0 + dAlpha*(1/eta)*2*Kstiff.at(3,3)/(sigf);
186 } else {
187 Smat.at(3,3) = 1.0;
188 }
189
190 Smat.at(1,4) = (1/eta)*Mstar.at(1); // S_mat(1:2,3) = S*M(1:2)
191 Smat.at(2,4) = (1/eta)*Mstar.at(2);
192 Smat.at(3,4) = (1/eta)*Mstar.at(3);
193
194 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))
195 Smat.at(4,2) = M.at(2)*Kstiff.at(2,2);
196 Smat.at(4,3) = M.at(3)*Kstiff.at(3,3);
197 //Smat.printYourself();
198 Smati.beInverseOf(Smat);
199
200 Qtemp.at(1) = Qt1;
201 Qtemp.at(2) = Qt2;
202 Qtemp.at(3) = Qn;
203
204 IntArray Indx(3);
205 Indx.at(1) = 1;
206 Indx.at(2) = 2;
207 Indx.at(3) = 3;
208
209 FloatMatrix Iep(3,3);
210 Iep.beSubMatrixOf(Smati,Indx,Indx);
211
212 status->letTempIepBe(Iep);
213
214 FloatArray alpha_v(3);
215 alpha_v.at(1) = Smati.at(4,1); // alpha_v(1:2) = S_mati(3,1:2)
216 alpha_v.at(2) = Smati.at(4,2);
217 alpha_v.at(3) = Smati.at(4,3);
218 status->letTempAlphavBe(alpha_v);
219
220 dJ = status->giveTempJump();
222
223 Qtemp *= 1 - oldDamage - dAlpha;
224
225#if 0
226 if (dJ.at(3)>=0) {
228 Qtemp.times(1-oldDamage-dAlpha);
229 } else {
230 if (oldDamage + dAlpha<1) {
231 Qtemp.at(3) = (1-oldDamage)/(1-oldDamage + dAlpha)*Qtemp.at(3);
233 Qtemp.times(1-oldDamage-dAlpha);
234 } else {
235 status->letTempEffectiveMandelTractionBe(Qtemp); // SHOULD NEVER BE USED
236 Qtemp.times(1-oldDamage-dAlpha);
237 Qtemp.at(3) = (1-oldDamage)*(Qold.at(3) + Kstiff.at(3,3)*dJElastic.at(3)); // dJElastic.at(3) is always equal to dJ.at(3) if dJ.at(3)<0
238 }
239 }
240#endif
241 }
242 } else {
243 dAlpha = 1.0 - oldDamage;
244 dJ = status->giveTempJump();
245 status->letTempEffectiveMandelTractionBe(Qtemp); // SHOULD NEVER BE USED!!
246 //if (dJ.at(3)<0) {
247 // Qtemp.at(3) = kn0*dJ.at(3);
248 //}
249 }
250
251 Qtemp += Qtemp_comp;
252
253 auto answer = Tdot(Finv, Qtemp); // t_1_hat = MATMUL(TRANSPOSE(Fci),Q)
254// answer *= 1-oldDamage-dAlpha; // t1_s = (1-al)*t_1_hat
255
256
257 status->letTempDamageBe(oldDamage + dAlpha);
258// status->letTempEffectiveMandelTractionBe(Qtemp); // NEW!
259
260 status->letTempJumpBe(d);
261 status->letTempFirstPKTractionBe(answer);
262 status->letTempFBe(F);
263
264 if ( mSemiExplicit ) {
265 Qtemp = (1-oldDamage) * Qtrial + Qtemp_comp;
266 answer = Tdot(Finv, Qtemp); // t_1_hat = MATMUL(TRANSPOSE(Fci),Q)
267 }
268
269 return answer;
270}
271
272
274IntMatBilinearCZJansson :: give3dStiffnessMatrix_dTdj(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) const
275{
276 IntMatBilinearCZJanssonStatus *status = static_cast< IntMatBilinearCZJanssonStatus * >( this->giveStatus(gp) );
277 //this->give3dStiffnessMatrix_dTdj_num(answer, rMode, gp, tStep);
278 //OOFEM_WARNING("numerical tangent");
279 //answer.printYourself();
280
281 FloatMatrixF<3,3> answer;
282
283 if ( status->giveOldDamageDev() ) {
284 answer = status->giveOlddTdJ();
285 //answer.printYourself();
286 status->letOldDamageDevBe(false);
287 } else {
288 double damage = status->giveTempDamage();
289 const auto &Finv = status->giveTempInverseDefGrad();
290 const auto &J = status->giveTempJump();
291
292 //FloatMatrix Rot = status->giveTempRotationMatrix();
293 auto Kstiff = diag<3>({this->ks0, this->ks0, this->kn0});
294 //Kstiff.rotatedWith(Rot);
295
296 FloatMatrix help;
297 if ( damage >= 1.0 ) {
298 if ( J.at(3) < 0 ) {
299 Kstiff.at(1,1) = 0.0;
300 Kstiff.at(2,2) = 0.0;
301 Kstiff.at(3,3) = this->knc;
302
303 answer = rotate(Kstiff, Finv);
304 }
305 } else {
306 if ( status->giveTempDamage() - status->giveDamage()==0.0 ) {
307 if ( J.at(3) < 0 ) {
308 Kstiff.at(3,3) += this->knc/(1-damage);
309 }
310
311 answer = (1-damage) * rotate(Kstiff, Finv);
312 } else {
313 const auto &Iep = status->giveTempIep();
314
315 //if (J.at(3)<0) {
316 // Kstiff.at(1,1) = (1-damage)*Kstiff.at(1,1);
317 // Kstiff.at(2,2) = (1-damage)*Kstiff.at(2,2);
318 // Kstiff.at(3,3) = Kstiff.at(3,3);
319 //} else {
320 // Kstiff.times((1-damage));
321 //}
322
323 answer = (1-damage) * dot(Kstiff, Iep);
324 //answer.rotatedWith(Rot); // Ea_h = MATMUL(TRANSPOSE(Rot),MATMUL(Keye3,Iep))
325 // Ea_h = MATMUL(Ea_h,Rot)
326
327 const auto &alpha_v = status->giveTempAlphav();
328 //alpha_v.rotatedWith(Rot, 't'); // alpha_v = MATMUL(TRANSPOSE(Rot),alpha_v)
329
330 const auto &Qtemp = status->giveTempEffectiveMandelTraction();
331
332 auto temp1 = Tdot(Finv, Qtemp); // CALL gmopen33(MATMUL(TRANSPOSE(Fci),Q),MATMUL(alpha_v,Fci),t1halFci_o)
333 auto temp2 = Tdot(Finv, alpha_v);
334
335 auto t1hatFinvOpen = dyad(temp1, temp2);
336
337 if ( J.at(3) < 0 ) {
338 answer.at(3,3) += this->knc;
339 }
340
341 // Ea = (1-new_alpha)*MATMUL(TRANSPOSE(Fci),MATMUL(Ea_h,Fci)) -&
342 answer = rotate(answer, Finv) - t1hatFinvOpen; // t1halFci_o
343 }
344 }
345 }
346 status->letTempdTdJBe(answer);
347
348 //Finv.printYourself();
349 //Kstiff.printYourself();
350 //printf("analytical tangent \n");
351 //answer.printYourself();
352 return answer;
353
354}
355
356
357//const double tolerance = 1.0e-12; // small number
358void
359IntMatBilinearCZJansson :: initializeFrom(InputRecord &ir)
360{
362 this->knc = kn0; // Defaults to the same stiffness in compression and tension
364
365 this->ks0 = kn0; // Defaults to kn0
367
369
370 this->GIIc = GIc; //Defaults to GIc
372
374
376
378
379 // check validity of the material paramters
380 if ( this->kn0 < 0.0 ) {
381 throw ValueInputException(ir, _IFT_IntMatBilinearCZJansson_kn, "must be positive");
382 } else if ( this->ks0 < 0.0 ) {
383 throw ValueInputException(ir, _IFT_IntMatBilinearCZJansson_ks, "must be positive");
384 } else if ( this->GIc < 0.0 ) {
385 throw ValueInputException(ir, _IFT_IntMatBilinearCZJansson_g1c, "must be positive");
386 } else if ( this->GIIc < 0.0 ) {
387 throw ValueInputException(ir, _IFT_IntMatBilinearCZJansson_g2c, "must be positive");
388 } else if ( this->gamma < 0.0 ) {
389 throw ValueInputException(ir, _IFT_IntMatBilinearCZJansson_gamma, "must be positive");
390 }
391
393 mSemiExplicit = true;
394 printf("In IntMatBilinearCZJansson::initializeFrom: Semi-explicit time integration activated.\n");
395 }
396}
397
398int
399IntMatBilinearCZJansson :: checkConsistency()
400{
401 return 1;
402}
403
404void
405IntMatBilinearCZJansson :: printYourself()
406{
407 printf("Paramters for BilinearCZMaterial: \n");
408
409 printf("-Strength paramters \n");
410 printf(" sigf = %e \n", this->sigf);
411 printf(" GIc = %e \n", this->GIc);
412 printf(" GIIc = %e \n", this->GIIc);
413 printf(" gamma = sigfs/sigfn = %e \n", this->gamma);
414 printf(" mu = %e \n", this->mu);
415
416 printf("-Stiffness parameters \n");
417 printf(" kn0 = %e \n", this->kn0);
418 printf(" ks0 = %e \n", this->ks0);
419 printf(" knc = %e \n", this->knc);
420
421}
422
423
424//IntMatBilinearCZJanssonStatus :: IntMatBilinearCZJanssonStatus(GaussPoint *g) : StructuralMaterialStatus(g)
425IntMatBilinearCZJanssonStatus :: IntMatBilinearCZJanssonStatus(GaussPoint *g) : StructuralInterfaceMaterialStatus(g)
426{
427 tempFInv = eye<3>();
428
429#if 0
431 //*************************************************************
432 FloatMatrix Gcov;
434
435 Shell7Base *shell = dynamic_cast< Shell7Base* >(gp->giveElement());
436 if ( !shell ) {
437 OOFEM_ERROR("BilinearCZMaterialJansson :: giveRealStressVector - oh no wrong element type");
438 }
439 FloatArray lCoords(3);
440 lCoords.at(1) = gp->giveCoordinate(1);
441 lCoords.at(2) = gp->giveCoordinate(2);
442 shell->evalInitialCovarBaseVectorsAt(lCoords, Gcov);
443
444 FloatArray G1, G2;
445 Gcov.copyColumn(G1,1);
446 Gcov.copyColumn(G2,2);
447 N.beVectorProductOf(G1,G2);
448 N.normalize();
449
450 tempRot.resize(3,3);
451 G1.normalize();
452 G2.beVectorProductOf(N, G1);
453 tempRot.setColumn(G1,1);
454 tempRot.setColumn(G2,2);
455 tempRot.setColumn(N,3);
456#endif
457
458 Iep = tempFInv;
459}
460
461
462void
463IntMatBilinearCZJanssonStatus :: printOutputAt(FILE *file, TimeStep *tStep) const
464{
466 StructuralInterfaceMaterialStatus :: printOutputAt(file, tStep);
467 /*
468 fprintf(file, "status { ");
469 if ( this->damage > 0.0 ) {
470 fprintf(file, "kappa %f, damage %f ", this->kappa, this->damage);
471 }
472
473 fprintf(file, "}\n");
474 */
475}
476
477
478void
479IntMatBilinearCZJanssonStatus :: initTempStatus()
480{
481 StructuralInterfaceMaterialStatus :: initTempStatus();
482
486
487 tempFInv = eye<3>();
488
489 Iep = tempFInv;
491
492 tempDamageDev = false;
493}
494
495void
496IntMatBilinearCZJanssonStatus :: updateYourself(TimeStep *atTime)
497{
498 StructuralInterfaceMaterialStatus :: updateYourself(atTime);
502
505}
506
507
508} // end namespace oofem
#define N(a, b)
#define REGISTER_Material(class)
double & at(std::size_t i)
double & at(Index i)
Definition floatarray.h:202
void beVectorProductOf(const FloatArray &v1, const FloatArray &v2)
Definition floatarray.C:476
double at(std::size_t i, std::size_t j) const
void copyColumn(FloatArray &dest, int c) const
void beSubMatrixOf(const FloatMatrix &src, Index topRow, Index bottomRow, Index topCol, Index bottomCol)
bool beInverseOf(const FloatMatrix &src)
double at(std::size_t i, std::size_t j) const
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
int & at(std::size_t i)
Definition intarray.h:104
const FloatMatrixF< 3, 3 > & giveTempInverseDefGrad() const
void letTempAlphavBe(const FloatArrayF< 3 > &v)
const FloatArrayF< 3 > & giveTempAlphav() const
void letTempInverseDefGradBe(const FloatMatrixF< 3, 3 > &v)
const FloatMatrixF< 3, 3 > & giveOlddTdJ() const
void letTempEffectiveMandelTractionBe(const FloatArrayF< 3 > &v)
void letTempMaterialJumpBe(const FloatArrayF< 3 > &v)
const FloatArrayF< 3 > & giveTempEffectiveMandelTraction() const
const FloatArrayF< 3 > & giveEffectiveMandelTraction() const
const FloatMatrixF< 3, 3 > & giveTempIep() const
const FloatArrayF< 3 > & giveOldMaterialJump() const
void letTempIepBe(const FloatMatrixF< 3, 3 > &v)
GaussPoint * gp
Associated integration point.
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
FloatMatrixF< 3, 3 > evalInitialCovarBaseVectorsAt(const FloatArrayF< 3 > &lCoords)
Definition shell7base.C:220
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.
#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_IntMatBilinearCZJansson_ks
#define _IFT_IntMatBilinearCZJansson_g2c
#define _IFT_IntMatBilinearCZJansson_sigf
#define _IFT_IntMatBilinearCZJansson_kn
#define _IFT_IntMatBilinearCZJansson_gamma
#define _IFT_IntMatBilinearCZJansson_semiexplicit
#define _IFT_IntMatBilinearCZJansson_g1c
#define _IFT_IntMatBilinearCZJansson_mu
#define _IFT_IntMatBilinearCZJansson_knc
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)
double sgn(double i)
Returns the signum of given value (if value is < 0 returns -1, otherwise returns 1).
Definition mathfem.h:104
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