OOFEM 3.0
Loading...
Searching...
No Matches
intelline1intpen.C
Go to the documentation of this file.
1/*
2 * intelline1intpen.C
3 *
4 * Created on: Nov 20, 2015
5 * Author: svennine
6 */
7
8#include "intelline1intpen.h"
9#include "gausspoint.h"
11#include "dofmanager.h"
12#include "fei2dlinelin.h"
13#include "fei2dlinequad.h"
14#include "feinterpol.h"
16
17namespace oofem {
19
25
26int IntElLine1IntPen :: computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
27{
30 interp->evalN( N, lcoords, FEIElementGeometryWrapper(this) );
31
32 answer.resize(this->giveDofManager(1)->giveCoordinates().giveSize());
33 answer.zero();
34
35 double xi_0 = 0.;
36 FloatArray xiScaled = {0.};
37
38 if ( lcoords.at(1) < xi_0 ) {
39 xiScaled = {lcoords.at(1)*2. + 1.};
40 interp->evalN( N, xiScaled, FEIElementGeometryWrapper(this) );
41
42 const auto &x1 = this->giveDofManager(1)->giveCoordinates();
43 answer.add(N.at(1), x1 );
44
45 const FloatArray &x3 = this->giveDofManager(3)->giveCoordinates();
46 answer.add(N.at(2), x3 );
47 } else {
48 xiScaled = {lcoords.at(1)*2. - 1.};
49 interp->evalN( N, xiScaled, FEIElementGeometryWrapper(this) );
50
51 const auto &x3 = this->giveDofManager(3)->giveCoordinates();
52 answer.add(N.at(1), x3 );
53
54 const auto &x2 = this->giveDofManager(2)->giveCoordinates();
55 answer.add(N.at(2), x2 );
56 }
57
58 return true;
59}
60
62IntElLine1IntPen :: computeCovarBaseVectorAt(IntegrationPoint *ip) const
63{
64 //printf("Entering IntElLine2IntPen :: computeCovarBaseVectorAt\n");
65
66 // Since we are averaging over the whole element, always evaluate the base vectors at xi = 0.
67
68 FloatArray xi_0 = {0.0};
69 //FloatArray xi_0 = {ip->giveNaturalCoordinate(1)};
70
71 FloatMatrix dNdxi;
73 //interp->evaldNdxi( dNdxi, ip->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) );
74 interp->evaldNdxi( dNdxi, xi_0, FEIElementGeometryWrapper(this) );
75
77
78 double X1_i = 0.5 * ( this->giveNode(1)->giveCoordinate(1) + this->giveNode(4)->giveCoordinate(1) ); // (mean) point on the fictious mid surface
79 double X2_i = 0.5 * ( this->giveNode(1)->giveCoordinate(2) + this->giveNode(4)->giveCoordinate(2) );
80 G.at(1) += dNdxi.at(1, 1) * X1_i;
81 G.at(2) += dNdxi.at(1, 1) * X2_i;
82
83 X1_i = 0.5 * ( this->giveNode(2)->giveCoordinate(1) + this->giveNode(5)->giveCoordinate(1) ); // (mean) point on the fictious mid surface
84 X2_i = 0.5 * ( this->giveNode(2)->giveCoordinate(2) + this->giveNode(5)->giveCoordinate(2) );
85 G.at(1) += dNdxi.at(2, 1) * X1_i;
86 G.at(2) += dNdxi.at(2, 1) * X2_i;
87 return G;
88}
89
90
91void
92IntElLine1IntPen :: computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
93{
94#if 1
95 // Computes the stiffness matrix of the receiver K_cohesive = int_A ( N^t * dT/dj * N ) dA
96 FloatMatrix N, D, DN;
97 bool matStiffSymmFlag = this->giveCrossSection()->isCharacteristicMtrxSymmetric(rMode);
98 answer.clear();
99
100 FloatMatrix rotationMatGtoL;
101 FloatArray u;
102
103 // First loop over GP: compute projection of test function and traction.
104 // The setting is as follows: we have an interface with quadratic interpolation and we
105 // wish to project onto the space of constant functions on each element.
106
107 // Projecting the basis functions gives a constant for each basis function.
108 FloatMatrix proj_N;
109 proj_N.clear();
110
111 FloatMatrix proj_DN;
112 proj_DN.clear();
113
114 double area = 0.;
115
116 for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
117
118 this->computeNmatrixAt(ip, N);
119
120 if ( this->nlGeometry == 0 ) {
121 this->giveStiffnessMatrix_Eng(D, rMode, ip, tStep);
122 } else if ( this->nlGeometry == 1 ) {
123 this->giveStiffnessMatrix_dTdj(D, rMode, ip, tStep);
124 } else {
125 OOFEM_ERROR("nlgeometry must be 0 or 1!")
126 }
127
128 this->computeTransformationMatrixAt(ip, rotationMatGtoL);
129 D.rotatedWith(rotationMatGtoL, 'n'); // transform stiffness to global coord system
130
131 this->computeNmatrixAt(ip, N);
132 DN.beProductOf(D, N);
133
134
135 double dA = this->computeAreaAround(ip);
136 area += dA;
137
138 proj_N.add(dA, N);
139 proj_DN.add(dA, DN);
140 }
141
142// printf("area: %e\n", area);
143 proj_N.times(1./area);
144 proj_DN.times(1./area);
145
146// printf("proj_N: "); proj_N.printYourself();
147
148 for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
149
150 if ( this->nlGeometry == 0 ) {
151 this->giveStiffnessMatrix_Eng(D, rMode, ip, tStep);
152 } else if ( this->nlGeometry == 1 ) {
153 this->giveStiffnessMatrix_dTdj(D, rMode, ip, tStep);
154 } else {
155 OOFEM_ERROR("nlgeometry must be 0 or 1!")
156 }
157
158 this->computeTransformationMatrixAt(ip, rotationMatGtoL);
159 D.rotatedWith(rotationMatGtoL, 'n'); // transform stiffness to global coord system
160
161 DN.beProductOf(D, proj_N);
162
163
164 double dA = this->computeAreaAround(ip);
165 if ( matStiffSymmFlag ) {
166 answer.plusProductSymmUpper(proj_N, DN, dA);
167 } else {
168 answer.plusProductUnsym(proj_N, DN, dA);
169 }
170 }
171
172
173 if ( matStiffSymmFlag ) {
174 answer.symmetrized();
175 }
176
177#else
178
179 // Computes the stiffness matrix of the receiver K_cohesive = int_A ( N^t * dT/dj * N ) dA
180 FloatMatrix N, D, DN;
181 bool matStiffSymmFlag = this->giveCrossSection()->isCharacteristicMtrxSymmetric(rMode);
182 answer.clear();
183
184 FloatMatrix rotationMatGtoL;
185 FloatArray u;
186
187 // First loop over GP: compute projection of test function and traction.
188 // The setting is as follows: we have an interface with quadratic interpolation and we
189 // wish to project onto the space of constant functions on each element.
190
191 // Projecting the basis functions gives a constant for each basis function.
192 FloatMatrix proj_N;
193 proj_N.clear();
194
195 FloatMatrix proj_DN;
196 proj_DN.clear();
197
198 double area = 0.;
199
200 for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
201
202 this->computeNmatrixAt(ip, N);
203
204 if ( this->nlGeometry == 0 ) {
205 this->giveStiffnessMatrix_Eng(D, rMode, ip, tStep);
206 } else if ( this->nlGeometry == 1 ) {
207 this->giveStiffnessMatrix_dTdj(D, rMode, ip, tStep);
208 } else {
209 OOFEM_ERROR("nlgeometry must be 0 or 1!")
210 }
211
212 this->computeTransformationMatrixAt(ip, rotationMatGtoL);
213 D.rotatedWith(rotationMatGtoL, 'n'); // transform stiffness to global coord system
214
215 this->computeNmatrixAt(ip, N);
216 DN.beProductOf(D, N);
217
218
219 double dA = this->computeAreaAround(ip);
220 area += dA;
221
222 proj_N.add(dA, N);
223 proj_DN.add(dA, DN);
224 }
225
226// printf("area: %e\n", area);
227 proj_N.times(1./area);
228 proj_DN.times(1./area);
229
230// printf("proj_N: "); proj_N.printYourself();
231
232 for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
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// this->computeTransformationMatrixAt(ip, rotationMatGtoL);
243// D.rotatedWith(rotationMatGtoL, 'n'); // transform stiffness to global coord system
244//
245// DN.beProductOf(D, proj_N);
246
247
248 double dA = this->computeAreaAround(ip);
249 if ( matStiffSymmFlag ) {
250 answer.plusProductSymmUpper(proj_N, proj_DN, dA);
251// answer.plusProductSymmUpper(proj_DN, proj_N, dA);
252 } else {
253 answer.plusProductUnsym(proj_N, proj_DN, dA);
254// answer.plusProductUnsym(proj_DN, proj_N, dA);
255 }
256 }
257
258 if ( matStiffSymmFlag ) {
259 answer.symmetrized();
260 }
261#endif
262}
263
264
265void
266IntElLine1IntPen :: giveInternalForcesVector(FloatArray &answer,
267 TimeStep *tStep, int useUpdatedGpRecord)
268{
269#if 1
270 // Computes internal forces
271 // For this element we use an "interior penalty" formulation, where
272 // the cohesive zone contribution is weakened, i.e. the traction and
273 // test function for the cohesive zone are projected onto a reduced
274 // space. The purpose of the projection is to improve the stability
275 // properties of the formulation, thereby avoiding traction oscilations.
276
278 FloatArray u, traction, jump;
279
280 this->computeVectorOf(VM_Total, tStep, u);
281 // subtract initial displacements, if defined
282 if ( initialDisplacements.giveSize() ) {
284 }
285
286 // zero answer will resize accordingly when adding first contribution
287 answer.clear();
288
289
290
291 // First loop over GP: compute projection of test function and traction.
292 // The setting is as follows: we have an interface with quadratic interpolation and we
293 // wish to project onto the space of constant functions on each element.
294
295 // The projection of t becomes a constant
296// FloatArray proj_t;
297// proj_t.clear();
298
299
300 FloatArray proj_jump;
301 proj_jump.clear();
302
303 // Projecting the basis functions gives a constant for each basis function.
304 FloatMatrix proj_N;
305 proj_N.clear();
306
307 double area = 0.;
308
309 for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
310
311 this->computeNmatrixAt(ip, N);
312 jump.beProductOf(N, u);
313// this->computeTraction(traction, ip, jump, tStep);
314
315 double dA = this->computeAreaAround(ip);
316 area += dA;
317
318 proj_jump.add(dA, jump);
319 proj_N.add(dA, N);
320 }
321
322// printf("area: %e\n", area);
323 proj_jump.times(1./area);
324 proj_N.times(1./area);
325
326// printf("proj_N: "); proj_N.printYourself();
327
328
330 //
331 // Find c2 such that c1 = t{c2}
332 //
334
335// // Initial guess
336// FloatArray c2 = proj_jump;
337// int maxIter = 10;
338// for(int iter = 0; iter < maxIter; iter++) {
339//
340// this->computeTraction(traction, ip, c2, tStep);
341//
342//
343// }
344
345
346 // Second loop over GP: assemble contribution to internal forces as we are used to.
347 for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
348// this->computeNmatrixAt(ip, N);
349// jump.beProductOf(N, u);
350 this->computeTraction(traction, ip, proj_jump, tStep);
351
352 // compute internal cohesive forces as f = N^T*traction dA
353 double dA = this->computeAreaAround(ip);
354 answer.plusProduct(proj_N, traction, dA);
355 }
356
357}
358
359#else
360// Computes internal forces
361// For this element we use an "interior penalty" formulation, where
362// the cohesive zone contribution is weakened, i.e. the traction and
363// test function for the cohesive zone are projected onto a reduced
364// space. The purpose of the projection is to improve the stability
365// properties of the formulation, thereby avoiding traction oscilations.
366
368FloatArray u, traction, jump;
369
370this->computeVectorOf(VM_Total, tStep, u);
371// subtract initial displacements, if defined
372if ( initialDisplacements.giveSize() ) {
373 u.subtract(initialDisplacements);
374}
375
376// zero answer will resize accordingly when adding first contribution
377answer.clear();
378
379
380
381// First loop over GP: compute projection of test function and traction.
382// The setting is as follows: we have an interface with quadratic interpolation and we
383// wish to project onto the space of constant functions on each element.
384
385// The projection of t becomes a constant
386 FloatArray proj_t;
387 proj_t.clear();
388
389
390//FloatArray proj_jump;
391//proj_jump.clear();
392
393// Projecting the basis functions gives a constant for each basis function.
394FloatMatrix proj_N;
395proj_N.clear();
396
397double area = 0.;
398
399for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
400
401 this->computeNmatrixAt(ip, N);
402 jump.beProductOf(N, u);
403 this->computeTraction(traction, ip, jump, tStep);
404
405 double dA = this->computeAreaAround(ip);
406 area += dA;
407
408// printf("traction: "); traction.printYourself();
409// proj_jump.add(dA, jump);
410 proj_t.add(dA, traction);
411 proj_N.add(dA, N);
412}
413
414// printf("area: %e\n", area);
415//proj_jump.times(1./area);
416proj_t.times(1./area);
417//printf("proj_t: "); proj_t.printYourself();
418//printf("\n\n");
419proj_N.times(1./area);
420
421// printf("proj_N: "); proj_N.printYourself();
422
423FloatMatrix rotationMatGtoL;
424
425// Second loop over GP: assemble contribution to internal forces as we are used to.
426for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
427 this->computeNmatrixAt(ip, N);
428// jump.beProductOf(N, u);
429// this->computeTraction(traction, ip, proj_jump, tStep);
430
431 // compute internal cohesive forces as f = N^T*traction dA
432 double dA = this->computeAreaAround(ip);
433 answer.plusProduct(proj_N, proj_t, dA);
434// answer.plusProduct(N, proj_t, dA);
435
436 StructuralInterfaceMaterialStatus *status = static_cast< StructuralInterfaceMaterialStatus * >( ip->giveMaterialStatus() );
437 FloatArray proj_t_gp = proj_t;
438
439 this->computeTransformationMatrixAt(ip, rotationMatGtoL);
440 proj_t_gp.rotatedWith(rotationMatGtoL, 'n'); // transform to local coord system
441
442 FloatArray proj_t_gp_3D = {proj_t_gp.at(1), 0., proj_t_gp.at(2)};
443 status->letProjectedTractionBe(proj_t_gp_3D);
444
445// FloatArray proj_t_gp = proj_t;
446// printf("proj_t_gp: "); proj_t_gp.printYourself();
447}
448
449}
450
451#endif
452
453void
454IntElLine1IntPen :: computeNmatrixAt(GaussPoint *ip, FloatMatrix &answer)
455{
456 // Returns the modified N-matrix which multiplied with u give the spatial jump.
457
460// interp->evalN( N, ip->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) );
461
462 double xi_0 = 0.;
463 FloatArray xiScaled = {0.};
464
465 answer.resize(2, 12);
466 answer.zero();
467
468 if ( ip->giveNaturalCoordinate(1) < xi_0 ) {
469 xiScaled = {ip->giveNaturalCoordinate(1)*2. + 1.};
470 interp->evalN( N, xiScaled, FEIElementGeometryWrapper(this) );
471
472 answer.at(1, 1) = answer.at(2, 2) = -N.at(1);
473 //answer.at(1, 3) = answer.at(2, 4) = -N.at(2);
474 answer.at(1, 5) = answer.at(2, 6) = -N.at(2);
475
476 answer.at(1, 7) = answer.at(2, 8) = N.at(1);
477 //answer.at(1, 9) = answer.at(2, 10) = N.at(2);
478 answer.at(1, 11) = answer.at(2, 12) = N.at(2);
479 } else {
480 xiScaled = {ip->giveNaturalCoordinate(1)*2. - 1.};
481 interp->evalN( N, xiScaled, FEIElementGeometryWrapper(this) );
482
483 //answer.at(1, 1) = answer.at(2, 2) = -N.at(1);
484 answer.at(1, 3) = answer.at(2, 4) = -N.at(2);
485 answer.at(1, 5) = answer.at(2, 6) = -N.at(1);
486
487 //answer.at(1, 7) = answer.at(2, 8) = N.at(1);
488 answer.at(1, 9) = answer.at(2, 10) = N.at(2);
489 answer.at(1, 11) = answer.at(2, 12) = N.at(1);
490 }
491
492}
493
494void
495IntElLine1IntPen :: computeGaussPoints()
496{
497 if ( integrationRulesArray.size() == 0 ) {
498 integrationRulesArray.resize( 1 );
499
500// integrationRulesArray[ 0 ] = std::make_unique<LobattoIntegrationRule>(1,this, 1, 2, false);
501// integrationRulesArray [ 0 ]->SetUpPointsOnLine(2, _2dInterface);
502
503 int numGP = 4;
504 integrationRulesArray [ 0 ] = std::make_unique<GaussIntegrationRule>(1, this, 1, 2);
505 integrationRulesArray [ 0 ]->SetUpPointsOnLine(numGP, _2dInterface);
506 }
507}
508
509
510} /* namespace oofem */
#define N(a, b)
#define REGISTER_Element(class)
Node * giveNode(int i) const
Definition element.h:629
int numberOfDofMans
Number of dofmanagers.
Definition element.h:136
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Definition element.C:103
std::vector< std ::unique_ptr< IntegrationRule > > integrationRulesArray
Definition element.h:157
int numberOfGaussPoints
Definition element.h:175
DofManager * giveDofManager(int i) const
Definition element.C:553
CrossSection * giveCrossSection()
Definition element.C:534
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
Definition element.h:886
double & at(std::size_t i)
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
void plusProduct(const FloatMatrix &b, const FloatArray &s, double dV)
Definition floatarray.C:288
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
void add(const FloatArray &src)
Definition floatarray.C:218
void subtract(const FloatArray &src)
Definition floatarray.C:320
void times(double s)
Definition floatarray.C:834
void times(double f)
void rotatedWith(const FloatMatrix &r, char mode='n')
void plusProductSymmUpper(const FloatMatrix &a, const FloatMatrix &b, double dV)
void add(const FloatMatrix &a)
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
*Sets size of receiver to be an empty matrix It will have zero rows and zero columns size void clear()
void plusProductUnsym(const FloatMatrix &a, const FloatMatrix &b, double dV)
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
void zero()
Zeroes all coefficient of receiver.
double at(std::size_t i, std::size_t j) const
double giveNaturalCoordinate(int i) const
Returns i-th natural element coordinate of receiver.
Definition gausspoint.h:136
void computeNmatrixAt(GaussPoint *gp, FloatMatrix &answer) override
IntElLine1IntPen(int n, Domain *d)
double computeAreaAround(GaussPoint *gp) override
Definition intelline1.C:120
void giveStiffnessMatrix_Eng(FloatMatrix &answer, MatResponseMode rMode, IntegrationPoint *ip, TimeStep *tStep) override
Definition intelline1.h:95
void computeTransformationMatrixAt(GaussPoint *gp, FloatMatrix &answer) override
Definition intelline1.C:189
IntElLine1(int n, Domain *d)
Definition intelline1.C:63
static FEI2dLineLin interp
Definition intelline1.h:61
FEInterpolation * giveInterpolation() const override
Definition intelline1.C:209
FloatArray initialDisplacements
Initial displacement vector, describes the initial nodal displacements when element has been casted.
bool nlGeometry
Flag indicating if geometrical nonlinearities apply.
virtual void giveStiffnessMatrix_dTdj(FloatMatrix &answer, MatResponseMode rMode, IntegrationPoint *ip, TimeStep *tStep)
virtual void computeTraction(FloatArray &traction, IntegrationPoint *ip, const FloatArray &jump, TimeStep *tStep)
#define OOFEM_ERROR(...)
Definition error.h:79
GaussPoint IntegrationPoint
Definition gausspoint.h:272

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