OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
intelline1PF.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 - 2013 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 
37 #include "node.h"
40 #include "gausspoint.h"
41 #include "gaussintegrationrule.h"
42 #include "floatmatrix.h"
43 #include "floatarray.h"
44 #include "intarray.h"
45 #include "mathfem.h"
46 #include "fei2dlinelin.h"
47 #include "classfactory.h"
48 
49 
50 namespace oofem {
51 REGISTER_Element(IntElLine1PF);
52 
53 FEI2dLineLin IntElLine1PF :: interp(1, 1);
54 
55 
57  StructuralInterfaceElement(n, aDomain), PhaseFieldElement(n, aDomain)
58 {
59  numberOfDofMans = 4;
60  alpha.resize(2);
61  alpha.zero();
62  this->oldAlpha.resize(2);
63  this->oldAlpha.zero();
64  this->deltaAlpha.resize(2);
65  this->deltaAlpha.zero();
66  this->prescribed_damage = -1.0;
67 }
68 
69 
70 
71 void
73 {
74  // Returns the modified N-matrix which multiplied with u give the spatial jump.
75 
76  FloatArray N;
78  interp->evalN( N, ip->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) );
79 
80  answer.resize(2, 8);
81  answer.zero();
82  answer.at(1, 1) = answer.at(2, 2) = -N.at(1);
83  answer.at(1, 3) = answer.at(2, 4) = -N.at(2);
84 
85  answer.at(1, 5) = answer.at(2, 6) = N.at(1);
86  answer.at(1, 7) = answer.at(2, 8) = N.at(2);
87 }
88 
89 
90 void
92 {
93  if ( integrationRulesArray.size() == 0 ) {
94  integrationRulesArray.resize( 1 );
95  //integrationRulesArray[ 0 ].reset( new LobattoIntegrationRule (1,domain, 1, 2) );
96  integrationRulesArray [ 0 ].reset( new GaussIntegrationRule(1, this, 1, 2) );
97  integrationRulesArray [ 0 ]->SetUpPointsOnLine(this->numberOfGaussPoints, _2dInterface);
98  }
99 }
100 
101 void
103 {
104  FloatMatrix dNdxi;
106  interp->evaldNdxi( dNdxi, ip->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) );
107  G.resize(2);
108  G.zero();
109  int numNodes = this->giveNumberOfNodes();
110  for ( int i = 1; i <= dNdxi.giveNumberOfRows(); i++ ) {
111  double X1_i = 0.5 * ( this->giveNode(i)->giveCoordinate(1) + this->giveNode(i + numNodes / 2)->giveCoordinate(1) ); // (mean) point on the fictious mid surface
112  double X2_i = 0.5 * ( this->giveNode(i)->giveCoordinate(2) + this->giveNode(i + numNodes / 2)->giveCoordinate(2) );
113  G.at(1) += dNdxi.at(i, 1) * X1_i;
114  G.at(2) += dNdxi.at(i, 1) * X2_i;
115  }
116 }
117 
118 double
120 {
121  FloatArray G;
122  this->computeCovarBaseVectorAt(ip, G);
123 
124  double weight = ip->giveWeight();
125  double ds = sqrt( G.dotProduct(G) ) * weight;
126 
127  double thickness = this->giveCrossSection()->give(CS_Thickness, ip);
128  return ds * thickness;
129 }
130 
131 
134 {
135  //const char *__proc = "initializeFrom"; // Required by IR_GIVE_FIELD macro
136  IRResultType result; // Required by IR_GIVE_FIELD macro
138  {
140  //this->alpha.setValues(2, damage, damage);
141  }
143 
144 
145 }
146 
147 
148 void
150 {
151  answer = {D_u, D_v, T_f};
152 }
153 
154 void
156 {
157  // Transformation matrix to the local coordinate system
158  FloatArray G;
159  this->computeCovarBaseVectorAt(gp, G);
160  G.normalize();
161 
162  answer.resize(2, 2);
163  answer.at(1, 1) = G.at(1);
164  answer.at(2, 1) = G.at(2);
165  answer.at(1, 2) = -G.at(2);
166  answer.at(2, 2) = G.at(1);
167 
168 }
169 
172 {
173  return & interp;
174 }
175 
176 
177 
178 
179 void
181 {
182  //set displacement and nonlocal location array
184  IntArray IdMask_u, IdMask_d;
185  this->giveDofManDofIDMask_u( IdMask_u );
186  this->giveDofManDofIDMask_d( IdMask_d );
187  this->computeLocationArrayOfDofIDs( IdMask_u, loc_u );
188  this->computeLocationArrayOfDofIDs( IdMask_d, loc_d );
189 
190  int nDofs = this->computeNumberOfDofs();
191  answer.resize( nDofs, nDofs );
192  answer.zero();
193 
194  // Set the solution vectors (a_u, a_d) for the element
195  this->computeDisplacementUnknowns( this->unknownVectorU, VM_Total, tStep );
196  this->computeDamageUnknowns( this->unknownVectorD, VM_Total, tStep );
197  this->computeDamageUnknowns( this->deltaUnknownVectorD, VM_Incremental, tStep );
198 
199  FloatMatrix temp;
200  solveForLocalDamage(temp, tStep);
201 
202 
203  FloatMatrix answer1, answer2, answer3, answer4;
204  this->computeStiffnessMatrix_uu(answer1, rMode, tStep);
205  //this->computeStiffnessMatrix_ud(answer2, rMode, tStep);
206  //this->computeStiffnessMatrix_du(answer3, rMode, tStep); //symmetric
207  answer3.beTranspositionOf( answer2 );
208  this->computeStiffnessMatrix_dd(answer4, rMode, tStep);
209 
210  answer.assemble( answer1, loc_u, loc_u );
211  //answer.assemble( answer2, loc_u, loc_d );
212  //answer.assemble( answer3, loc_d, loc_u );
213  answer.assemble( answer4, loc_d, loc_d );
214 }
215 
216 
217 void
219 {
220  // Computes the stiffness matrix of the receiver K_cohesive = int_A ( N^t * dT/dj * N ) dA
221  FloatMatrix N, D, DN, GD, Gmat;
222  bool matStiffSymmFlag = this->giveCrossSection()->isCharacteristicMtrxSymmetric(rMode);
223  answer.resize(0, 0);
224  FloatArray Nd;
225  //IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ];
226  FloatMatrix rotationMatGtoL;
227 
228  //for ( int j = 0; j < iRule->giveNumberOfIntegrationPoints(); j++ ) {
229  //IntegrationPoint *ip = iRule->getIntegrationPoint(j);
230  for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
231 
232 
233 
234  if ( this->nlGeometry == 0 ) {
235  this->giveStiffnessMatrix_Eng(D, rMode, ip, tStep);
236  } else if ( this->nlGeometry == 1 ) {
237  this->giveStiffnessMatrix_dTdj(D, rMode, ip, tStep);
238  } else {
239  OOFEM_ERROR("nlgeometry must be 0 or 1!")
240  }
241 
242 
243  this->computeNmatrixAt(ip, N);
244 
245  this->computeNd_vectorAt(ip->giveNaturalCoordinates(), Nd);
246  double d = Nd.dotProduct(this->alpha);
247  this->computeGMatrix(Gmat, d, ip, VM_Total, tStep);
248  GD.beProductOf(Gmat,D);
249 
250  this->computeTransformationMatrixAt(ip, rotationMatGtoL);
251  GD.rotatedWith(rotationMatGtoL, 't'); // transform stiffness to global coord system
252 
253  DN.beProductOf(GD, N);
254 
255  double dA = this->computeAreaAround(ip);
256  if ( matStiffSymmFlag ) {
257  answer.plusProductSymmUpper(N, DN, dA);
258  } else {
259  answer.plusProductUnsym(N, DN, dA);
260  }
261  }
262 
263 
264  if ( matStiffSymmFlag ) {
265  answer.symmetrized();
266  }
267 }
268 
269 
270 void
272 {
273  //IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ];
274 
275  FloatMatrix N, rotationMatGtoL;
276  FloatArray a_u, traction, tractionTemp, jump, fu, fd(2), fd4(4);
277 
278 
279  fd.zero();
280  FloatArray a_d_temp, a_d, Bd, Nd;
281  a_u = this->unknownVectorU;
282  a_d_temp = this->unknownVectorD;
283  a_d = { a_d_temp.at(1), a_d_temp.at(2) };
284 
285  FloatMatrix temp, Kud(8,2);
286  fu.zero();
287  Kud.zero();
288  //for ( int i = 0; i < iRule->giveNumberOfIntegrationPoints(); i++ ) {
289  for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
290  //IntegrationPoint *ip = iRule->getIntegrationPoint(i);
291  this->computeNmatrixAt(ip, N);
292  this->computeNd_vectorAt(ip->giveNaturalCoordinates(), Nd);
293  jump.beProductOf(N, a_u);
294  this->computeTraction(traction, ip, jump, tStep);
295 
296  // compute internal cohesive forces as f = N^T*traction dA
297  double Gprim = computeGPrim(ip, VM_Total, tStep);
298  double dA = this->computeAreaAround(ip);
299 
300  fu.plusProduct(N, traction, dA*Gprim);
301  temp.beDyadicProductOf(fu,Nd);
302  Kud.add(temp);
303 
304  }
305 
306  IntArray indxu, indx1, indx2;
307  indxu = {1, 2, 3, 4, 5, 6, 7, 8};
308  indx1 = {1, 2};
309  indx2 = {3, 4};
310  answer.resize(8,4);
311  answer.zero();
312  answer.assemble(Kud, indxu, indx1);
313  answer.assemble(Kud, indxu, indx2);
314 
315 
316  // Numerical tangent
317  // Set the solution vectors (a_u, a_d) for the element
318  FloatArray a_u_ref, a_d_pert, a_d_ref, fu_ref, fd_ref, fu_pert, K_col, fd_temp, delta_a_d_ref, delta_a_d_pert;
319  FloatMatrix K_num(8,2), Kdd_num;
320  double eps = 1.0e-6;
321 
322  a_u_ref = this->unknownVectorU;
323  a_d_ref = this->unknownVectorD;
324  delta_a_d_ref = this->deltaUnknownVectorD;
325  this->giveInternalForcesVectorUD(fu_ref, fd_ref, tStep, false);
326 
327  for ( int i = 1; i <=2; i++ ) {
328  a_d_pert = a_d_ref;
329  a_d_pert.at(i) += eps;
330  this->unknownVectorD = a_d_pert;
331 
332  delta_a_d_pert = delta_a_d_ref;
333  delta_a_d_pert.at(i) += eps;
334  this->deltaUnknownVectorD = delta_a_d_pert;
335 
336  this->giveInternalForcesVectorUD(fu_pert, fd_temp, tStep, false);
337  K_col = ( 1.0/eps ) * ( fu_pert - fu_ref );
338  K_num.addSubVectorCol(K_col, 1, i);
339  }
340 
341  answer.zero();
342  answer.assemble(K_num, indxu, indx1);
343  answer.assemble(K_num, indxu, indx2);
344 
345  this->unknownVectorU = a_u_ref;
346  this->unknownVectorD = a_d_ref;
347  this->deltaUnknownVectorD = delta_a_d_ref;
348 
349 }
350 
351 void
353 {
354  // Computation of tangent: K_dd = \int Nd^t * ( -kp*neg_Mac'(alpha_dot)/delta_t + g_c/l + G''*Psibar) * Nd +
355  // \int Bd^t * ( g_c * l * [G^1 G^2]^t * [G^1 G^2] ) * Bd
356  // = K_dd1 + K_dd2
357  int ndofs = 8 + 4;
358  int ndofs_u = 8;
359  int ndofs_d = 4;
360 
361  double l = this->giveInternalLength();
362  double g_c = this->giveCriticalEnergy();
363  double kp = this->givePenaltyParameter();
364  double Delta_t = tStep->giveTimeIncrement();
365 
366  answer.resize( ndofs_d, ndofs_d );
367  answer.zero();
368 
369 
370  //IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ];
371  FloatMatrix tempN(2,2), tempB(2,2), temp(2,2);
372  FloatArray Nd, Bd;
373  tempN.zero();
374  tempB.zero();
375  temp.zero();
376  //for ( int j = 0; j < iRule->giveNumberOfIntegrationPoints(); j++ ) {
377  // IntegrationPoint *ip = iRule->getIntegrationPoint(j);
378  for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
379  computeBd_vectorAt(ip, Bd);
380  computeNd_vectorAt(ip->giveNaturalCoordinates(), Nd);
381  double dA = this->computeAreaAround(ip);
382 
383  //double Gbis = this->computeGbis()
384  double Gbis = 2.0;
385  double Psibar = this->computeFreeEnergy( ip, tStep );
386 
387 
388  // K_dd1 = ( -kp*neg_Mac'(d_dot) / Delta_t + g_c/ l + G'' * Psibar ) * N^t*N;
389  double Delta_d = computeDamageAt(ip, VM_Incremental, tStep);
390  double factorN = -kp * neg_MaCauleyPrime(Delta_d/Delta_t)/Delta_t + g_c / l + Gbis * Psibar;
391  //double factorN = g_c / l + Gbis * Psibar;
392 
393  //double Psibar0 = this->givePsiBar0();
394  //double factorN = g_c / l + Gbis * this->MaCauley(Psibar-Psibar0);
395 
396 
397  tempN.beDyadicProductOf(Nd, Nd);
398  temp.add(factorN * dA, tempN);
399 
400  // K_dd2 = g_c * l * Bd^t * Bd;
401  double factorB = g_c * l;
402  tempB.beDyadicProductOf(Bd, Bd);
403  temp.add(factorB * dA, tempB);
404  }
405 
406  IntArray indx1, indx2;
407  indx1 = {1, 2};
408  indx2 = {3, 4};
409 
410  answer.assemble(temp, indx1, indx1);
411  answer.assemble(temp, indx2, indx2);
412 
413 #if 0
414  // Numerical tangent
415  // Set the solution vectors (a_u, a_d) for the element
416  FloatArray a_u_ref, a_d_ref, a_d_pert, fu_ref, fd_ref, fd_pert, K_col, fu_temp;
417  FloatMatrix K(4,4), Kdd_num;
418  double eps = 1.0e-6;
419 
420  a_u_ref = this->unknownVectorU;
421  a_d_ref = this->unknownVectorD;
422  this->giveInternalForcesVectorUD(fu_ref, fd_ref, tStep, false);
423 
424  for ( int i = 1; i <=2; i++ ) {
425  a_d_pert = a_d_ref;
426  a_d_pert.at(i) += eps;
427  this->unknownVectorD = a_d_pert;
428 
429  this->giveInternalForcesVectorUD(fu_temp, fd_pert, tStep, false);
430  K_col = ( 1.0/eps ) * ( fd_pert - fd_ref );
431  K.addSubVectorCol(K_col, 1, i);
432  }
433 
434  Kdd_num.beSubMatrixOf(K,1,2,1,2);
435 
436  answer.zero();
437  answer.assemble(Kdd_num, indx1, indx1);
438  answer.assemble(Kdd_num, indx2, indx2);
439 
440  this->unknownVectorU = a_u_ref;
441  this->unknownVectorD = a_d_ref;
442 #endif
443 }
444 
445 
446 
447 void
449 {
450  // approach with dame defined over the element only
451 
452  if (tStep->giveNumber() == 1 ){
453  return;
454  }
455  if ( this->prescribed_damage >-1.0e-8 ){
456  return;
457  }
458 
459  //IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ];
460 
461  FloatArray a_u, a_d_temp, a_d(2), traction, jump, fd(2), fd_ref(2), Nd, Bd;
462  FloatMatrix Kdd(2,2), tempN, tempB;
463  FloatArray delta_a_d;
464 
465 
466  double kp = this->givePenaltyParameter();
467  double Delta_t = tStep->giveTimeIncrement();
468  double l = this->giveInternalLength();
469  double g_c = this->giveCriticalEnergy();
470 
471  fd.zero();
472  Kdd.zero();
473  //a_d.zero();
474  a_d = this->alpha; // checked - evolves
475  this->oldAlpha = this->alpha;
476  for ( int nIter = 1; nIter <= 10; nIter++ ) {
477  fd.zero();
478  Kdd.zero();
479  fd_ref.zero();
480  //for ( int i = 0; i < iRule->giveNumberOfIntegrationPoints(); i++ ) {
481  // IntegrationPoint *ip = iRule->getIntegrationPoint(i);
482  for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
483 
484  this->computeBd_vectorAt(ip, Bd);
485  this->computeNd_vectorAt(ip->giveNaturalCoordinates(), Nd);
486  double dA = this->computeAreaAround(ip);
487 
488  // Internal force
489  //double d = computeDamageAt( ip, VM_Total, tStep);
490  double d = Nd.dotProduct(a_d);
491  double gradd = Bd.dotProduct(a_d); // Dalpha/Ds
492  //double Delta_d = computeDamageAt( ip, VM_Incremental, tStep);
493  double Delta_d = Nd.dotProduct(a_d-oldAlpha);
494  //double Gprim = computeGPrim(ip, VM_Total, tStep);
495  double Gprim = -2.0 * (1.0 - d);
496  double Psibar = this->computeFreeEnergy( ip, tStep );
497 
498 
499  double sectionalForcesScal = -kp * neg_MaCauley(Delta_d/Delta_t) + g_c / l * d + Gprim * Psibar;
500  double sectionalForcesVec = g_c * l * gradd;
501  fd = fd + ( Nd*sectionalForcesScal + Bd*sectionalForcesVec ) * dA;
502  fd_ref = fd_ref + ( Nd * (Gprim * Psibar + 1.0e-8 ) ) * dA;
503 
504  // Tangent
505  //double Gbis = this->computeGbis()
506  double Gbis = 2.0;
507 
508  // K_dd1 = ( -kp*neg_Mac'(d_dot) / Delta_t + g_c/ l + G'' * Psibar ) * N^t*N;
509  double factorN = -kp * neg_MaCauleyPrime(Delta_d/Delta_t)/Delta_t + g_c / l + Gbis * Psibar;
510  //double factorN = g_c / l + Gbis * Psibar;
511 
512  tempN.beDyadicProductOf(Nd, Nd);
513  Kdd.add(factorN * dA, tempN);
514 
515  // K_dd2 = g_c * l * Bd^t * Bd;
516  double factorB = g_c * l;
517  tempB.beDyadicProductOf(Bd, Bd);
518  Kdd.add(factorB * dA, tempB);
519 
520  }
521  //printf("norm %e \n", fd.computeNorm() );
522  //if( fd.computeNorm() < 1.0e-5 ) {
523  if( fd.computeNorm()/fd_ref.computeNorm() < 1.0e-3 ) {
524  this->alpha = a_d;
525  return;
526  }
527  Kdd.solveForRhs(fd, delta_a_d);
528  a_d.subtract(delta_a_d);
529  this->deltaAlpha += delta_a_d;
530  //this->alpha = a_d;
531  //a_d.printYourself();
532  }
533  printf("norm %e \n", fd.computeNorm()/fd_ref.computeNorm() );
534  OOFEM_ERROR("No convergence in phase field iterations")
535 }
536 
537 
538 void
539 IntElLine1PF :: computeGMatrix(FloatMatrix &answer, const double damage, GaussPoint *gp, ValueModeType valueMode, TimeStep *tStep)
540 {
541 
542  double d = damage;
543 
544  if ( this->prescribed_damage > -1.0e-8 ) {
545  d = prescribed_damage;
546  }
547 
548 
550  FloatArray strain;
551 
552  strain = matStat->giveTempJump();
553  double g2 = -1.0;
554  if ( strain.at(3) < 0.0 ) { // Damage does not affect compressive stresses
555  g2 = 1.0;
556  //printf("compression \n");
557  } else {
558  g2 = (1.0 - d) * (1.0 - d);
559  //printf("g %e \n", g2);
560  //g2 = 1;
561  }
562 
563  double g1 = (1.0 - d) * (1.0 - d);
564 
565  answer.resize(2,2);
566  answer.zero();
567  answer.at(1,1) = g1;
568  answer.at(2,2) = g2;
569 
570 }
571 
572 
573 double
575 {
576  // d = N_d * a_d
577  //NLStructuralElement *el = static_cast< NLStructuralElement* >(this->giveElement( ) );
579  FloatArray dVec;
580  if ( valueMode == VM_Total ) {
581  //dVec = this->unknownVectorD;
584  dVec = this->alpha;
585  } else if ( valueMode == VM_Incremental ) {
586  //dVec = this->deltaUnknownVectorD;
587  //dVec = this->deltaAlpha;
588  dVec = this->alpha - this->oldAlpha;
589  }
590  //dVec.resizeWithValues(2);
591  FloatArray Nvec;
593  return Nvec.dotProduct(dVec);
594 }
595 
596 
597 
598 void
599 IntElLine1PF :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord)
600 {
601  // Set the solution vectors (a_u, a_d) for the element
602  this->computeDisplacementUnknowns( this->unknownVectorU, VM_Total, tStep );
603  this->computeDamageUnknowns( this->unknownVectorD, VM_Total, tStep );
604  this->computeDamageUnknowns( this->deltaUnknownVectorD, VM_Incremental, tStep );
605 
606 
607 
608  FloatArray fu, fd;
609  this->giveInternalForcesVectorUD(fu, fd, tStep, useUpdatedGpRecord);
610 
611  // total vec
612  IntArray IdMask_u, IdMask_d;
613  this->giveDofManDofIDMask_u( IdMask_u );
614  this->giveDofManDofIDMask_d( IdMask_d );
615  this->computeLocationArrayOfDofIDs( IdMask_u, loc_u );
616  this->computeLocationArrayOfDofIDs( IdMask_d, loc_d );
617 
618  int nDofs = this->computeNumberOfDofs();
619  answer.resize( nDofs );
620  answer.zero();
621  answer.assemble(fu, loc_u);
622  //answer.assemble(fd, loc_d);
623 
624 }
625 void
627 {
628  // Computes internal forces
629  // if useGpRecnord == 1 then data stored in ip->giveStressVector() are used
630  // instead computing stressVector through this->ComputeStressVector();
631  // this must be done after you want internal forces after element->updateYourself()
632  // has been called for the same time step.
633 
634  //IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ];
635 
636  FloatMatrix Nu, rotationMatGtoL, Gmat;
637  FloatArray a_u, a_d_temp, a_d, traction, jump, fd(2), Nd, Bd, GTraction;
638 
639  a_u = this->unknownVectorU;
640  a_d_temp = this->unknownVectorD;
641  a_d = { a_d_temp.at(1), a_d_temp.at(2) };
642 
643  fu.zero();
644  fd.zero();
645 
646  for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
647  //for ( int i = 0; i < iRule->giveNumberOfIntegrationPoints(); i++ ) {
648  // IntegrationPoint *ip = iRule->getIntegrationPoint(i);
649  this->computeNmatrixAt(ip, Nu);
650  this->computeBd_vectorAt(ip, Bd);
651  this->computeNd_vectorAt(ip->giveNaturalCoordinates(), Nd);
652 
653 
654  // compute internal cohesive forces as f = N^T * g * traction dA
655  jump.beProductOf(Nu, a_u);
656  this->computeTraction(traction, ip, jump, tStep);
657 
658  //FloatMatrix temp;
659  //solveForLocalDamage(temp, tStep);
660  //double g = this->computeG(ip, VM_Total, tStep);
661 
662  this->computeNd_vectorAt(ip->giveNaturalCoordinates(), Nd);
663  double d = Nd.dotProduct(this->alpha);
664  // g = (1.0 - d) * (1.0 - d);
665 
666 
667  this->computeGMatrix(Gmat, d, ip, VM_Total, tStep);
668  GTraction.beProductOf(Gmat,traction);
669  //double g = this->computeOldG(ip, VM_Total, tStep);
670  double dA = this->computeAreaAround(ip);
671 
672  //fu.plusProduct(Nu, traction, dA*g);
673  fu.plusProduct(Nu, GTraction, dA);
674 
675 
676  // damage field
677 
678  double kp = this->givePenaltyParameter();
679  double Delta_t = tStep->giveTimeIncrement();
680  //double d = computeDamageAt( ip, VM_Total, tStep);
681  double Delta_d = computeDamageAt(ip, VM_Incremental, tStep);
682  double l = this->giveInternalLength();
683  double g_c = this->giveCriticalEnergy();
684  double Gprim = computeGPrim(ip, VM_Total, tStep);
685 
686  double Psibar = this->computeFreeEnergy( ip, tStep );
687  double gradd = Bd.dotProduct(a_d); // Dalpha/Ds
688 
689 
690  //double Psibar0 = this->givePsiBar0();
691  //double sectionalForcesScal = g_c / l * d + Gprim * this->MaCauley(Psibar-Psibar0);
692  double sectionalForcesScal = -kp * neg_MaCauley(Delta_d/Delta_t) + g_c / l * d + Gprim * Psibar;
693  //double sectionalForcesScal = g_c / l * d + Gprim * Psibar;
694  double sectionalForcesVec = g_c * l * gradd;
695  fd = fd + ( Nd*sectionalForcesScal + Bd*sectionalForcesVec ) * dA;
696 
697  }
698  fd4.resize(4);
699  fd4.zero();
700  IntArray indx1, indx2;
701  indx1 = {1, 2};
702  indx2 = {3, 4};
703  fd4.assemble(fd, indx1);
704  fd4.assemble(fd, indx2);
705 
706 }
707 
708 
709 
710 double
712 {
713 
715  FloatArray strain, stress;
716  stress = matStat->giveTempFirstPKTraction();
717  strain = matStat->giveTempJump();
718  //stress = matStat->giveFirstPKTraction();
719  //strain = matStat->giveJump();
720  //stress.printYourself();
721  //strain.printYourself();
722 
723  // Damage only for positive normal traction
724  if ( strain.at(3) < 0.0 ) {
725  return 0.5 * ( stress.at(1)*strain.at(1) + stress.at(2)*strain.at(2) );
726  } else {
727  return 0.5 * stress.dotProduct( strain );
728  }
729 }
730 
731 double
733 {
734  // computes Dg/Dd = (1-d)^2 + r0
735  //double d = this->computeDamageAt(gp, VM_Total, stepN) - this->computeDamageAt(gp, VM_Incremental, stepN);
736  double d = this->computeDamageAt(gp, VM_Total, stepN);
737  double r0 = 1.0e-10;
738  return (1.0 - d) * (1.0 - d) + r0;
739 }
740 
741 
742 void
744 {
745  //StructuralInterfaceElement :: giveDofManDofIDMask(-1, EID_MomentumBalance, answer);
746  //IntElLine1 :: giveDofManDofIDMask(-1, EID_MomentumBalance, answer);
747  answer = {D_u, D_v};
748 }
749 
750 void
752 {
753  answer = {T_f};
754 }
755 
756 
757 void
759 {
760  // Routine to extract compute the location array an element given an dofid array.
761  answer.resize( 0 );
762  //NLStructuralElement *el = this->giveElement();
764  int k = 0;
765  for(int i = 1; i <= el->giveNumberOfDofManagers(); i++) {
766  DofManager *dMan = el->giveDofManager( i );
767  for(int j = 1; j <= dofIdArray.giveSize( ); j++) {
768 
769  if(dMan->hasDofID( (DofIDItem) dofIdArray.at( j ) )) {
770  Dof *d = dMan->giveDofWithID( dofIdArray.at( j ) );
771  //answer.followedBy( k + d->giveNumber( ) );
772  }
773  }
774  k += dMan->giveNumberOfDofs( );
775  }
776 }
777 
778 void
780 {
782  FloatArray Nvec;
783  el->giveInterpolation( )->evalN( N, lCoords, FEIElementGeometryWrapper( el ) );
784 
785 }
786 
787 void
789 {
790  // Returns the [numSpaceDim x nDofs] gradient matrix {B_d} of the receiver,
791  // evaluated at gp.
792 
793  StructuralInterfaceElement *el = dynamic_cast< StructuralInterfaceElement* > ( this->giveElement() );
794  FloatMatrix dNdxi;
795  this->giveInterpolation()->evaldNdxi( dNdxi, aGaussPoint->giveNaturalCoordinates( ), FEIElementGeometryWrapper( this ) );
796 
797  answer.resize(2);
798  for (int i = 1; i <= dNdxi.giveNumberOfRows(); i++) {
799  answer.at(i) = dNdxi.at(i,1);
800  }
801  FloatArray G;
802  this->computeCovarBaseVectorAt(aGaussPoint, G);
803  answer.times( 1.0 / sqrt(G.dotProduct(G)) );
804 }
805 
806 } // end namespace oofem
CrossSection * giveCrossSection()
Definition: element.C:495
virtual void computeCovarBaseVectorAt(GaussPoint *gp, FloatArray &G)
Definition: intelline1PF.C:102
void subtract(const FloatArray &src)
Subtracts array src to receiver.
Definition: floatarray.C:258
virtual double computeDamageAt(GaussPoint *gp, ValueModeType valueMode, TimeStep *stepN)
Definition: intelline1PF.C:574
virtual void evaldNdxi(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the matrix of derivatives of interpolation functions (shape functions) at given point...
Definition: feinterpol.h:193
double neg_MaCauley(double par)
Definition: intelline1PF.h:113
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the array of interpolation functions (shape functions) at given point.
Class and object Domain.
Definition: domain.h:115
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
Access method for default integration rule.
Definition: element.h:822
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Definition: intelline1PF.C:133
void solveForLocalDamage(FloatMatrix &answer, TimeStep *tStep)
Definition: intelline1PF.C:448
virtual void computeStiffnessMatrix_ud(FloatMatrix &, MatResponseMode, TimeStep *)
Definition: intelline1PF.C:271
double computeGPrim(GaussPoint *gp, ValueModeType valueMode, TimeStep *stepN)
virtual void computeTraction(FloatArray &traction, IntegrationPoint *ip, const FloatArray &jump, TimeStep *tStep)
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
void computeGMatrix(FloatMatrix &answer, const double damage, GaussPoint *gp, ValueModeType valueMode, TimeStep *stepN)
Definition: intelline1PF.C:539
void beSubMatrixOf(const FloatMatrix &src, int topRow, int bottomRow, int topCol, int bottomCol)
Assigns to the receiver the sub-matrix of another matrix.
Definition: floatmatrix.C:962
ValueModeType
Type representing the mode of UnknownType or CharType, or similar types.
Definition: valuemodetype.h:78
Abstract class for phase field formulation.
FloatArray deltaAlpha
Definition: intelline1PF.h:143
virtual void giveDofManDofIDMask_u(IntArray &answer)
Definition: intelline1PF.C:743
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
FloatArray unknownVectorD
Definition: intelline1PF.h:140
Base class for dof managers.
Definition: dofmanager.h:113
virtual double giveCoordinate(int i)
Definition: node.C:82
StructuralInterfaceElement * giveElement()
Definition: intelline1PF.h:95
double computeOldG(GaussPoint *gp, ValueModeType valueMode, TimeStep *stepN)
Definition: intelline1PF.C:732
virtual void computeNd_vectorAt(const FloatArray &lCoords, FloatArray &N)
Definition: intelline1PF.C:779
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
MatResponseMode
Describes the character of characteristic material matrix.
virtual FEInterpolation * giveInterpolation() const
Definition: intelline1PF.C:171
virtual int giveNumberOfDofManagers() const
Definition: element.h:656
virtual void computeNmatrixAt(GaussPoint *gp, FloatMatrix &answer)
Computes modified interpolation matrix (N) for the element which multiplied with the unknowns vector ...
Definition: intelline1PF.C:72
void computeDamageUnknowns(FloatArray &answer, ValueModeType valueMode, TimeStep *stepN)
double neg_MaCauleyPrime(double par)
Definition: intelline1PF.h:118
double giveTimeIncrement()
Returns solution step associated time increment.
Definition: timestep.h:150
virtual int giveNumberOfNodes() const
Returns number of nodes of receiver.
Definition: element.h:662
virtual double computeAreaAround(GaussPoint *gp)
Definition: intelline1PF.C:119
virtual FEInterpolation * giveInterpolation() const
Class representing a general abstraction for finite element interpolation class.
Definition: feinterpol.h:132
void plusProductUnsym(const FloatMatrix &a, const FloatMatrix &b, double dV)
Adds to the receiver the product .
Definition: floatmatrix.C:780
virtual void giveInternalForcesVectorUD(FloatArray &fu, FloatArray &fd, TimeStep *tStep, int useUpdatedGpRecord=0)
Definition: intelline1PF.C:626
FloatArray deltaUnknownVectorD
Definition: intelline1PF.h:141
int giveNumber()
Returns receiver&#39;s number.
Definition: timestep.h:129
int giveNumberOfDofs() const
Definition: dofmanager.C:279
virtual void computeBd_vectorAt(GaussPoint *gp, FloatArray &B)
Definition: intelline1PF.C:788
double dotProduct(const FloatArray &x) const
Computes the dot product (or inner product) of receiver and argument.
Definition: floatarray.C:463
#define OOFEM_ERROR(...)
Definition: error.h:61
REGISTER_Element(LSpace)
DofIDItem
Type representing particular dof type.
Definition: dofiditem.h:86
virtual double giveWeight()
Returns integration weight of receiver.
Definition: gausspoint.h:181
void rotatedWith(const FloatMatrix &r, char mode= 'n')
Returns the receiver &#39;a&#39; transformed using give transformation matrix r.
Definition: floatmatrix.C:1557
void computeDisplacementUnknowns(FloatArray &answer, ValueModeType valueMode, TimeStep *stepN)
Wrapper around element definition to provide FEICellGeometry interface.
Definition: feinterpol.h:95
virtual bool isCharacteristicMtrxSymmetric(MatResponseMode rMode)
Check for symmetry of stiffness matrix.
Definition: crosssection.h:172
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
This class implements a structural interface material status information.
virtual void giveStiffnessMatrix_Eng(FloatMatrix &answer, MatResponseMode rMode, IntegrationPoint *ip, TimeStep *tStep)
Definition: intelline1PF.h:84
#define N(p, q)
Definition: mdm.C:367
void plusProductSymmUpper(const FloatMatrix &a, const FloatMatrix &b, double dV)
Adds to the receiver the product .
Definition: floatmatrix.C:698
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
void resize(int n)
Checks size of receiver towards requested bounds.
Definition: intarray.C:124
virtual void computeStiffnessMatrix_uu(FloatMatrix &, MatResponseMode, TimeStep *)
Definition: intelline1PF.C:218
virtual void giveStiffnessMatrix_dTdj(FloatMatrix &answer, MatResponseMode rMode, IntegrationPoint *ip, TimeStep *tStep)
#define _IFT_IntElLine1PF_prescribedDamage
Definition: intelline1PF.h:41
int numberOfGaussPoints
Number of integration points as specified by nip.
Definition: element.h:188
Class representing vector of real numbers.
Definition: floatarray.h:82
bool hasDofID(DofIDItem id) const
Checks if receiver contains dof with given ID.
Definition: dofmanager.C:166
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
IntElLine1PF(int n, Domain *d)
Definition: intelline1PF.C:56
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
virtual double give(CrossSectionProperty a, GaussPoint *gp)
Returns the value of cross section property at given point.
Definition: crosssection.C:151
virtual int computeNumberOfDofs()
Computes or simply returns total number of element&#39;s local DOFs.
Definition: intelline1PF.h:63
IntegrationPointStatus * giveMaterialStatus()
Returns reference to associated material status (NULL if not defined).
Definition: gausspoint.h:205
virtual void computeGaussPoints()
Initializes the array of integration rules member variable.
Definition: intelline1PF.C:91
void assemble(const FloatArray &fe, const IntArray &loc)
Assembles the array fe (typically, the load vector of a finite element) into the receiver, using loc as location array.
Definition: floatarray.C:551
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
Class representing the general Input Record.
Definition: inputrecord.h:101
virtual void computeTransformationMatrixAt(GaussPoint *gp, FloatMatrix &answer)
Definition: intelline1PF.C:155
void add(const FloatMatrix &a)
Adds matrix to the receiver.
Definition: floatmatrix.C:1023
Dof * giveDofWithID(int dofID) const
Returns DOF with given dofID; issues error if not present.
Definition: dofmanager.C:119
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
void beDyadicProductOf(const FloatArray &vec1, const FloatArray &vec2)
Assigns to the receiver the dyadic product .
Definition: floatmatrix.C:492
const FloatArray & giveTempFirstPKTraction() const
Returns the const pointer to receiver&#39;s temporary first Piola-Kirchhoff traction vector.
virtual double computeFreeEnergy(GaussPoint *gp, TimeStep *tStep)
Definition: intelline1PF.C:711
virtual void giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord=0)
Returns equivalent nodal forces vectors.
Definition: intelline1PF.C:599
void times(double s)
Multiplies receiver with scalar.
Definition: floatarray.C:818
void beTranspositionOf(const FloatMatrix &src)
Assigns to the receiver the transposition of parameter.
Definition: floatmatrix.C:323
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
std::vector< std::unique_ptr< IntegrationRule > > integrationRulesArray
List of integration rules of receiver (each integration rule contains associated integration points a...
Definition: element.h:170
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
FloatArray unknownVectorU
Definition: intelline1PF.h:139
Abstract base class for all structural interface elements.
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:337
int giveSize() const
Definition: intarray.h:203
the oofem namespace is to define a context or scope in which all oofem names are defined.
DofManager * giveDofManager(int i) const
Definition: element.C:514
void assemble(const FloatMatrix &src, const IntArray &loc)
Assembles the contribution using localization array into receiver.
Definition: floatmatrix.C:251
#define IR_GIVE_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:69
Abstract class Dof represents Degree Of Freedom in finite element mesh.
Definition: dof.h:93
const FloatArray & giveTempJump() const
Returns the const pointer to receiver&#39;s temporary jump.
static FEI2dLineLin interp
Definition: intelline1PF.h:55
double normalize()
Normalizes receiver.
Definition: floatarray.C:828
Node * giveNode(int i) const
Returns reference to the i-th node of element.
Definition: element.h:610
virtual void computeLocationArrayOfDofIDs(const IntArray &dofIdArray, IntArray &answer)
Definition: intelline1PF.C:758
int giveNumberOfRows() const
Returns number of rows of receiver.
Definition: floatmatrix.h:156
void symmetrized()
Initializes the lower half of the receiver according to the upper half.
Definition: floatmatrix.C:1576
int nlGeometry
Flag indicating if geometrical nonlinearities apply.
virtual void computeStiffnessMatrix_dd(FloatMatrix &, MatResponseMode, TimeStep *)
Definition: intelline1PF.C:352
Class representing integration point in finite element program.
Definition: gausspoint.h:93
virtual void giveDofManDofIDMask_d(IntArray &answer)
Definition: intelline1PF.C:751
Class representing solution step.
Definition: timestep.h:80
virtual void computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
Computes the stiffness/tangent matrix of receiver.
Definition: intelline1PF.C:180
int numberOfDofMans
Number of dofmanagers.
Definition: element.h:149
virtual void giveDofManDofIDMask(int inode, IntArray &answer) const
Returns dofmanager dof mask for node.
Definition: intelline1PF.C:149
const FloatArray & giveNaturalCoordinates()
Returns coordinate array of receiver.
Definition: gausspoint.h:138
Class representing Gaussian-quadrature integration rule.
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631
void plusProduct(const FloatMatrix &b, const FloatArray &s, double dV)
Adds the product .
Definition: floatarray.C:226

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:29 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011