OOFEM 3.0
Loading...
Searching...
No Matches
planstrss.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
37#include "fei2dquadlin.h"
38#include "node.h"
39#include "crosssection.h"
40#include "gausspoint.h"
42#include "floatmatrix.h"
43#include "floatarray.h"
44#include "intarray.h"
45#include "domain.h"
46#include "mathfem.h"
47#include "strainvector.h"
48#include "classfactory.h"
49
50#ifdef __OOFEG
51 #include "oofeggraphiccontext.h"
52 #include "oofegutils.h"
53 #include "connectivitytable.h"
54 #include "sm/Materials/rcm2.h"
55#endif
56
57namespace oofem {
59
60FEI2dQuadLin PlaneStress2d :: interpolation(1, 2);
61
62PlaneStress2d :: PlaneStress2d(int n, Domain *aDomain) :
66 // Constructor.
67{
70}
71
72PlaneStress2d :: ~PlaneStress2d()
73// Destructor
74{ }
75
76FEInterpolation *PlaneStress2d :: giveInterpolation() const { return & interpolation; }
77
78void
79PlaneStress2d :: computeBmatrixAt(GaussPoint *gp, FloatMatrix &answer, int li, int ui)
80//
81// Returns the [3x8] strain-displacement matrix {B} of the receiver,
82// evaluated at gp.
83// (epsilon_x,epsilon_y,gamma_xy) = B . r
84// r = ( u1,v1,u2,v2,u3,v3,u4,v4)
85{
86 FloatMatrix dnx;
87
88 this->interpolation.evaldNdx( dnx, gp->giveNaturalCoordinates(), *this->giveCellGeometryWrapper() );
89
90 answer.resize(3, 8);
91 answer.zero();
92
93 for ( int i = 1; i <= 4; i++ ) {
94 answer.at(1, 2 * i - 1) = dnx.at(i, 1);
95 answer.at(2, 2 * i - 0) = dnx.at(i, 2);
96 }
97
98#ifdef PlaneStress2d_reducedShearIntegration
99 this->interpolation.evaldNdx( dnx, Vec2(0., 0.), *this->giveCellGeometryWrapper() );
100#endif
101
102 for ( int i = 1; i <= 4; i++ ) {
103 answer.at(3, 2 * i - 1) = dnx.at(i, 2);
104 answer.at(3, 2 * i - 0) = dnx.at(i, 1);
105 }
106}
107
108
109void
110PlaneStress2d :: computeBHmatrixAt(GaussPoint *gp, FloatMatrix &answer)
111//
112// Returns the [4x8] displacement gradient matrix {BH} of the receiver,
113// evaluated at gp.
114// @todo not checked if correct
115{
116 FloatMatrix dnx;
117
118 this->interpolation.evaldNdx( dnx, gp->giveNaturalCoordinates(), *this->giveCellGeometryWrapper() );
119
120 answer.resize(4, 8);
121
122 for ( int i = 1; i <= 4; i++ ) {
123 answer.at(1, 2 * i - 1) = dnx.at(i, 1); // du/dx -1
124 answer.at(2, 2 * i - 0) = dnx.at(i, 2); // dv/dy -2
125 }
126
127#ifdef PlaneStress2d_reducedShearIntegration
128 this->interpolation.evaldNdx( dnx, Vec2(0., 0.), *this->giveCellGeometryWrapper() );
129#endif
130
131 for ( int i = 1; i <= 4; i++ ) {
132 answer.at(3, 2 * i - 1) = dnx.at(i, 2); // du/dy -6
133 answer.at(4, 2 * i - 0) = dnx.at(i, 1); // dv/dx -9
134 }
135}
136
137
138
139void
140PlaneStress2d :: initializeFrom(InputRecord &ir, int priority)
141{
142 PlaneStressElement :: initializeFrom(ir, priority);
143}
144
145void
146PlaneStress2d :: postInitialize()
147{
148 PlaneStressElement :: postInitialize();
151 OOFEM_WARNING("Number of Gauss points enforced to 4");
152 }
153
154}
155
156
157double
158PlaneStress2d :: giveCharacteristicSize(GaussPoint *gp, FloatArray &normalToCrackPlane, ElementCharSizeMethod method)
159//
160// returns receiver's characteristic size at gp (for some material models)
161// for crack formed in plane with normal normalToCrackPlane
162// using the selected method
163//
164{
165 if ( method == ECSM_SquareRootOfArea ) {
166 // square root of element area
167 return this->computeMeanSize();
168 }
169
170 if ( method == ECSM_Projection ) {
171 // standard projection method
172 return this->giveCharacteristicLength(normalToCrackPlane);
173 }
174
175 // evaluate average strain and its maximum principal direction
176 FloatArray sumstrain, averageNormal;
177 for ( GaussPoint *gpi: *this->giveDefaultIntegrationRulePtr() ) {
178 StructuralMaterialStatus *matstatus = dynamic_cast< StructuralMaterialStatus * >( gpi->giveMaterialStatus() );
179 if ( matstatus ) {
180 sumstrain.add( matstatus->giveTempStrainVector() );
181 }
182 }
183
184 StrainVector sumstrainvec(sumstrain, _PlaneStress);
185 sumstrainvec.computeMaxPrincipalDir(averageNormal);
186
187 if ( method == ECSM_ProjectionCentered ) {
188 // projection method based on principal direction of average strain
189 normalToCrackPlane = averageNormal;
190 return this->giveLengthInDir(normalToCrackPlane);
191 }
192
193 if ( method == ECSM_Oliver1 || method == ECSM_Oliver1modified ) {
194 // method based on derivative of auxiliary function phi at each Gauss point
195 // in the maximum principal strain direction determined at
196 // ECSM_Oliver1 ... at each Gauss point
197 // ECSM_Oliver1modified ... at element center (from average strain)
198
199 // coordinates of the element center
200 FloatArray center(2);
201 double cx = 0., cy = 0.;
202 for ( int i = 1; i <= 4; i++ ) {
203 cx += giveNode(i)->giveCoordinate(1);
204 cy += giveNode(i)->giveCoordinate(2);
205 }
206
207 cx /= 4.;
208 cy /= 4.;
209
210 // nodal values of function phi (0 or 1)
211 FloatArray phi(4);
212 for ( int i = 1; i <= 4; i++ ) {
213 if ( ( ( giveNode(i)->giveCoordinate(1) - cx ) * averageNormal.at(1) + ( giveNode(i)->giveCoordinate(2) - cy ) * averageNormal.at(2) ) > 0. ) {
214 phi.at(i) = 1.;
215 } else {
216 phi.at(i) = 0.;
217 }
218 }
219
220 // gradient of function phi at the current GP
221 FloatMatrix dnx;
222 this->interpolation.evaldNdx( dnx, gp->giveNaturalCoordinates(), *this->giveCellGeometryWrapper() );
223 FloatArray gradPhi(2);
224 gradPhi.zero();
225 for ( int i = 1; i <= 4; i++ ) {
226 gradPhi.at(1) += phi.at(i) * dnx.at(i, 1);
227 gradPhi.at(2) += phi.at(i) * dnx.at(i, 2);
228 }
229
230 // scalar product of the gradient with crack normal (at GP)
231 double dPhidN = 0.;
232 if ( method == ECSM_Oliver1modified ) {
233 normalToCrackPlane = averageNormal;
234 }
235
236 for ( int i = 1; i <= 2; i++ ) {
237 dPhidN += gradPhi.at(i) * normalToCrackPlane.at(i);
238 }
239
240 if ( dPhidN == 0. ) {
241 OOFEM_ERROR("Zero value of dPhidN");
242 }
243
244 return 1. / fabs(dPhidN);
245 }
246
247 OOFEM_ERROR("invalid method");
248 return 0.;
249}
250
251
252
253Interface *
254PlaneStress2d :: giveInterface(InterfaceType interface)
255{
256 if ( interface == ZZNodalRecoveryModelInterfaceType ) {
257 return static_cast< ZZNodalRecoveryModelInterface * >(this);
258 } else if ( interface == SPRNodalRecoveryModelInterfaceType ) {
259 return static_cast< SPRNodalRecoveryModelInterface * >(this);
260 } else if ( interface == SpatialLocalizerInterfaceType ) {
261 return static_cast< SpatialLocalizerInterface * >(this);
262 } else if ( interface == HuertaErrorEstimatorInterfaceType ) {
263 return static_cast< HuertaErrorEstimatorInterface * >(this);
264 }
265
266 return NULL;
267}
268
269
270void
271PlaneStress2d :: HuertaErrorEstimatorI_setupRefinedElementProblem(RefinedElement *refinedElement, int level, int nodeId,
272 IntArray &localNodeIdArray, IntArray &globalNodeIdArray,
273 HuertaErrorEstimatorInterface :: SetupMode sMode, TimeStep *tStep,
274 int &localNodeId, int &localElemId, int &localBcId,
275 IntArray &controlNode, IntArray &controlDof,
276 HuertaErrorEstimator :: AnalysisMode aMode)
277{
278 int nodes = 4, sides = 4;
279 double x = 0.0, y = 0.0;
280
281 static int sideNode [ 4 ] [ 2 ] = { { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 1 } };
282
283 FloatArray corner [ 4 ], midSide [ 4 ], midNode, cor [ 4 ];
284 if ( sMode == HuertaErrorEstimatorInterface :: NodeMode ||
285 ( sMode == HuertaErrorEstimatorInterface :: BCMode && aMode == HuertaErrorEstimator :: HEE_linear ) ) {
286 for ( int inode = 0; inode < nodes; inode++ ) {
287 corner [ inode ] = this->giveNode(inode + 1)->giveCoordinates();
288 if ( corner [ inode ].giveSize() != 3 ) {
289 cor [ inode ].resize(3);
290 cor [ inode ].at(1) = corner [ inode ].at(1);
291 cor [ inode ].at(2) = corner [ inode ].at(2);
292 cor [ inode ].at(3) = 0.0;
293
294 corner [ inode ] = cor [ inode ];
295 }
296
297 x += corner [ inode ].at(1);
298 y += corner [ inode ].at(2);
299 }
300
301 for ( int iside = 0; iside < sides; iside++ ) {
302 midSide [ iside ].resize(3);
303
304 int nd1 = sideNode [ iside ] [ 0 ] - 1;
305 int nd2 = sideNode [ iside ] [ 1 ] - 1;
306
307 midSide [ iside ].at(1) = ( corner [ nd1 ].at(1) + corner [ nd2 ].at(1) ) / 2.0;
308 midSide [ iside ].at(2) = ( corner [ nd1 ].at(2) + corner [ nd2 ].at(2) ) / 2.0;
309 midSide [ iside ].at(3) = 0.0;
310 }
311
312 midNode.resize(3);
313
314 midNode.at(1) = x / nodes;
315 midNode.at(2) = y / nodes;
316 midNode.at(3) = 0.0;
317 }
318
319 this->setupRefinedElementProblem2D(this, refinedElement, level, nodeId, localNodeIdArray, globalNodeIdArray,
320 sMode, tStep, nodes, corner, midSide, midNode,
321 localNodeId, localElemId, localBcId,
322 controlNode, controlDof, aMode, "PlaneStress2d");
323}
324
325void PlaneStress2d :: HuertaErrorEstimatorI_computeNmatrixAt(GaussPoint *gp, FloatMatrix &answer)
326{
328}
329
330
331#ifdef __OOFEG
332 #define TR_LENGHT_REDUCT 0.3333
333
334void PlaneStress2d :: drawRawGeometry(oofegGraphicContext &gc, TimeStep *tStep)
335{
336 WCRec p [ 4 ];
337 GraphicObj *go;
338
339 if ( !gc.testElementGraphicActivity(this) ) {
340 return;
341 }
342
343 EASValsSetLineWidth(OOFEG_RAW_GEOMETRY_WIDTH);
344 EASValsSetColor( gc.getElementColor() );
345 EASValsSetEdgeColor( gc.getElementEdgeColor() );
346 EASValsSetEdgeFlag(true);
347 EASValsSetLayer(OOFEG_RAW_GEOMETRY_LAYER);
348 EASValsSetFillStyle(FILL_HOLLOW);
349 p [ 0 ].x = ( FPNum ) this->giveNode(1)->giveCoordinate(1);
350 p [ 0 ].y = ( FPNum ) this->giveNode(1)->giveCoordinate(2);
351 p [ 0 ].z = ( FPNum ) this->giveNode(1)->giveCoordinate(3);
352 p [ 1 ].x = ( FPNum ) this->giveNode(2)->giveCoordinate(1);
353 p [ 1 ].y = ( FPNum ) this->giveNode(2)->giveCoordinate(2);
354 p [ 1 ].z = ( FPNum ) this->giveNode(2)->giveCoordinate(3);
355 p [ 2 ].x = ( FPNum ) this->giveNode(3)->giveCoordinate(1);
356 p [ 2 ].y = ( FPNum ) this->giveNode(3)->giveCoordinate(2);
357 p [ 2 ].z = ( FPNum ) this->giveNode(3)->giveCoordinate(3);
358 p [ 3 ].x = ( FPNum ) this->giveNode(4)->giveCoordinate(1);
359 p [ 3 ].y = ( FPNum ) this->giveNode(4)->giveCoordinate(2);
360 p [ 3 ].z = ( FPNum ) this->giveNode(4)->giveCoordinate(3);
361
362 go = CreateQuad3D(p);
363 EGWithMaskChangeAttributes(WIDTH_MASK | FILL_MASK | COLOR_MASK | EDGE_COLOR_MASK | EDGE_FLAG_MASK | LAYER_MASK, go);
364 EGAttachObject(go, ( EObjectP ) this);
365 EMAddGraphicsToModel(ESIModel(), go);
366}
367
368
369void PlaneStress2d :: drawDeformedGeometry(oofegGraphicContext &gc, TimeStep *tStep, UnknownType type)
370{
371 WCRec p [ 4 ];
372 GraphicObj *go;
373 double defScale = gc.getDefScale();
374
375 if ( !gc.testElementGraphicActivity(this) ) {
376 return;
377 }
378
379 EASValsSetLineWidth(OOFEG_DEFORMED_GEOMETRY_WIDTH);
380 EASValsSetColor( gc.getDeformedElementColor() );
381 EASValsSetEdgeColor( gc.getElementEdgeColor() );
382 EASValsSetEdgeFlag(true);
383 EASValsSetLayer(OOFEG_DEFORMED_GEOMETRY_LAYER);
384 EASValsSetFillStyle(FILL_HOLLOW);
385 p [ 0 ].x = ( FPNum ) this->giveNode(1)->giveUpdatedCoordinate(1, tStep, defScale);
386 p [ 0 ].y = ( FPNum ) this->giveNode(1)->giveUpdatedCoordinate(2, tStep, defScale);
387 p [ 0 ].z = ( FPNum ) this->giveNode(1)->giveUpdatedCoordinate(3, tStep, defScale);
388 p [ 1 ].x = ( FPNum ) this->giveNode(2)->giveUpdatedCoordinate(1, tStep, defScale);
389 p [ 1 ].y = ( FPNum ) this->giveNode(2)->giveUpdatedCoordinate(2, tStep, defScale);
390 p [ 1 ].z = ( FPNum ) this->giveNode(2)->giveUpdatedCoordinate(3, tStep, defScale);
391 p [ 2 ].x = ( FPNum ) this->giveNode(3)->giveUpdatedCoordinate(1, tStep, defScale);
392 p [ 2 ].y = ( FPNum ) this->giveNode(3)->giveUpdatedCoordinate(2, tStep, defScale);
393 p [ 2 ].z = ( FPNum ) this->giveNode(3)->giveUpdatedCoordinate(3, tStep, defScale);
394 p [ 3 ].x = ( FPNum ) this->giveNode(4)->giveUpdatedCoordinate(1, tStep, defScale);
395 p [ 3 ].y = ( FPNum ) this->giveNode(4)->giveUpdatedCoordinate(2, tStep, defScale);
396 p [ 3 ].z = ( FPNum ) this->giveNode(4)->giveUpdatedCoordinate(3, tStep, defScale);
397
398 go = CreateQuad3D(p);
399 EGWithMaskChangeAttributes(WIDTH_MASK | FILL_MASK | COLOR_MASK | EDGE_COLOR_MASK | EDGE_FLAG_MASK | LAYER_MASK, go);
400 EMAddGraphicsToModel(ESIModel(), go);
401}
402
403
404
405void PlaneStress2d :: drawScalar(oofegGraphicContext &gc, TimeStep *tStep)
406{
407 int i, indx, result = 0;
408 WCRec p [ 4 ];
409 GraphicObj *tr;
410 FloatArray v [ 4 ];
411 double s [ 4 ], defScale;
412
413 if ( !gc.testElementGraphicActivity(this) ) {
414 return;
415 }
416
417 EASValsSetLayer(OOFEG_VARPLOT_PATTERN_LAYER);
418 if ( gc.giveIntVarMode() == ISM_recovered ) {
419 for ( i = 1; i <= 4; i++ ) {
420 result += this->giveInternalStateAtNode(v [ i - 1 ], gc.giveIntVarType(), gc.giveIntVarMode(), i, tStep);
421 }
422
423 if ( result != 4 ) {
424 return;
425 }
426
427 indx = gc.giveIntVarIndx();
428
429 for ( i = 1; i <= 4; i++ ) {
430 s [ i - 1 ] = v [ i - 1 ].at(indx);
431 }
432
433 if ( gc.getScalarAlgo() == SA_ISO_SURF ) {
434 for ( i = 0; i < 4; i++ ) {
435 if ( gc.getInternalVarsDefGeoFlag() ) {
436 // use deformed geometry
437 defScale = gc.getDefScale();
438 p [ i ].x = ( FPNum ) this->giveNode(i + 1)->giveUpdatedCoordinate(1, tStep, defScale);
439 p [ i ].y = ( FPNum ) this->giveNode(i + 1)->giveUpdatedCoordinate(2, tStep, defScale);
440 p [ i ].z = 0.;
441 } else {
442 p [ i ].x = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(1);
443 p [ i ].y = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(2);
444 p [ i ].z = 0.;
445 }
446 }
447
448 //EASValsSetColor(gc.getYieldPlotColor(ratio));
449 gc.updateFringeTableMinMax(s, 4);
450 tr = CreateQuadWD3D(p, s [ 0 ], s [ 1 ], s [ 2 ], s [ 3 ]);
451 EGWithMaskChangeAttributes(LAYER_MASK, tr);
452 EMAddGraphicsToModel(ESIModel(), tr);
453
454 /* } else if (gc.getScalarAlgo() == SA_ISO_LINE) {
455 *
456 * EASValsSetColor(context.getActiveCrackColor());
457 * EASValsSetLineWidth(OOFEG_ISO_LINE_WIDTH);
458 *
459 * for (i=0; i< 4; i++) {
460 * if (gc.getInternalVarsDefGeoFlag()) {
461 * // use deformed geometry
462 * defScale = gc.getDefScale();
463 * p[i].x = (FPNum) this->giveNode(i+1)->giveUpdatedCoordinate(1,tStep,defScale);
464 * p[i].y = (FPNum) this->giveNode(i+1)->giveUpdatedCoordinate(2,tStep,defScale);
465 * p[i].z = 0.;
466 *
467 * } else {
468 * p[i].x = (FPNum) this->giveNode(i+1)->giveCoordinate(1);
469 * p[i].y = (FPNum) this->giveNode(i+1)->giveCoordinate(2);
470 * p[i].z = 0.;
471 * }
472 * }
473 *
474 * // isoline implementation
475 * oofeg_drawIsoLinesOnQuad (p, s);
476 */
477 } else if ( ( gc.getScalarAlgo() == SA_ZPROFILE ) || ( gc.getScalarAlgo() == SA_COLORZPROFILE ) ) {
478 double landScale = gc.getLandScale();
479
480 for ( i = 0; i < 4; i++ ) {
481 if ( gc.getInternalVarsDefGeoFlag() ) {
482 // use deformed geometry
483 defScale = gc.getDefScale();
484 p [ i ].x = ( FPNum ) this->giveNode(i + 1)->giveUpdatedCoordinate(1, tStep, defScale);
485 p [ i ].y = ( FPNum ) this->giveNode(i + 1)->giveUpdatedCoordinate(2, tStep, defScale);
486 p [ i ].z = s [ i ] * landScale;
487 } else {
488 p [ i ].x = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(1);
489 p [ i ].y = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(2);
490 p [ i ].z = s [ i ] * landScale;
491 }
492
493 // this fixes a bug in ELIXIR
494 if ( fabs(s [ i ]) < 1.0e-6 ) {
495 s [ i ] = 1.0e-6;
496 }
497 }
498
499 if ( gc.getScalarAlgo() == SA_ZPROFILE ) {
500 EASValsSetColor( gc.getDeformedElementColor() );
501 EASValsSetLineWidth(OOFEG_DEFORMED_GEOMETRY_WIDTH);
502 tr = CreateQuad3D(p);
503 EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | LAYER_MASK, tr);
504 } else {
505 gc.updateFringeTableMinMax(s, 4);
506 tr = CreateQuadWD3D(p, s [ 0 ], s [ 1 ], s [ 2 ], s [ 3 ]);
507 EGWithMaskChangeAttributes(LAYER_MASK, tr);
508 }
509
510 EMAddGraphicsToModel(ESIModel(), tr);
511 }
512 } else if ( gc.giveIntVarMode() == ISM_local ) {
513 if ( integrationRulesArray [ 0 ]->giveNumberOfIntegrationPoints() != 4 ) {
514 return;
515 }
516
517 IntArray ind(4);
518 WCRec pp [ 9 ];
519
520 for ( i = 0; i < 4; i++ ) {
521 if ( gc.getInternalVarsDefGeoFlag() ) {
522 // use deformed geometry
523 defScale = gc.getDefScale();
524 pp [ i ].x = ( FPNum ) this->giveNode(i + 1)->giveUpdatedCoordinate(1, tStep, defScale);
525 pp [ i ].y = ( FPNum ) this->giveNode(i + 1)->giveUpdatedCoordinate(2, tStep, defScale);
526 pp [ i ].z = ( FPNum ) this->giveNode(i + 1)->giveUpdatedCoordinate(3, tStep, defScale);
527 } else {
528 pp [ i ].x = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(1);
529 pp [ i ].y = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(2);
530 pp [ i ].z = ( FPNum ) this->giveNode(i + 1)->giveCoordinate(3);
531 }
532 }
533
534 for ( i = 0; i < 3; i++ ) {
535 pp [ i + 4 ].x = 0.5 * ( pp [ i ].x + pp [ i + 1 ].x );
536 pp [ i + 4 ].y = 0.5 * ( pp [ i ].y + pp [ i + 1 ].y );
537 pp [ i + 4 ].z = 0.5 * ( pp [ i ].z + pp [ i + 1 ].z );
538 }
539
540 pp [ 7 ].x = 0.5 * ( pp [ 3 ].x + pp [ 0 ].x );
541 pp [ 7 ].y = 0.5 * ( pp [ 3 ].y + pp [ 0 ].y );
542 pp [ 7 ].z = 0.5 * ( pp [ 3 ].z + pp [ 0 ].z );
543
544 pp [ 8 ].x = 0.25 * ( pp [ 0 ].x + pp [ 1 ].x + pp [ 2 ].x + pp [ 3 ].x );
545 pp [ 8 ].y = 0.25 * ( pp [ 0 ].y + pp [ 1 ].y + pp [ 2 ].y + pp [ 3 ].y );
546 pp [ 8 ].z = 0.25 * ( pp [ 0 ].z + pp [ 1 ].z + pp [ 2 ].z + pp [ 3 ].z );
547
548 for ( GaussPoint *gp: *this->giveDefaultIntegrationRulePtr() ) {
549 const FloatArray& gpCoords = gp->giveNaturalCoordinates();
550 if ( ( gpCoords.at(1) > 0. ) && ( gpCoords.at(2) > 0. ) ) {
551 ind.at(1) = 0;
552 ind.at(2) = 4;
553 ind.at(3) = 8;
554 ind.at(4) = 7;
555 } else if ( ( gpCoords.at(1) < 0. ) && ( gpCoords.at(2) > 0. ) ) {
556 ind.at(1) = 4;
557 ind.at(2) = 1;
558 ind.at(3) = 5;
559 ind.at(4) = 8;
560 } else if ( ( gpCoords.at(1) < 0. ) && ( gpCoords.at(2) < 0. ) ) {
561 ind.at(1) = 5;
562 ind.at(2) = 2;
563 ind.at(3) = 6;
564 ind.at(4) = 8;
565 } else {
566 ind.at(1) = 6;
567 ind.at(2) = 3;
568 ind.at(3) = 7;
569 ind.at(4) = 8;
570 }
571
572 if ( giveIPValue(v [ 0 ], gp, gc.giveIntVarType(), tStep) == 0 ) {
573 return;
574 }
575
576 indx = gc.giveIntVarIndx();
577
578 for ( i = 1; i <= 4; i++ ) {
579 s [ i - 1 ] = v [ 0 ].at(indx);
580 }
581
582 for ( i = 0; i < 4; i++ ) {
583 p [ i ].x = pp [ ind.at(i + 1) ].x;
584 p [ i ].y = pp [ ind.at(i + 1) ].y;
585 p [ i ].z = pp [ ind.at(i + 1) ].z;
586 }
587
588 gc.updateFringeTableMinMax(s, 4);
589 tr = CreateQuadWD3D(p, s [ 0 ], s [ 1 ], s [ 2 ], s [ 3 ]);
590 EGWithMaskChangeAttributes(LAYER_MASK, tr);
591 EMAddGraphicsToModel(ESIModel(), tr);
592 }
593 }
594}
595
596
597
598
599void
600PlaneStress2d :: drawSpecial(oofegGraphicContext &gc, TimeStep *tStep)
601{
602 int i;
603 WCRec l [ 2 ];
604 GraphicObj *tr;
605 double defScale = gc.getDefScale();
606 FloatArray crackStatuses, cf;
607
608 if ( !gc.testElementGraphicActivity(this) ) {
609 return;
610 }
611
612 if ( gc.giveIntVarType() == IST_CrackState ) {
613 // ask if any active crack exist
614 int crackStatus;
615 double ax, ay, bx, by, norm, xc, yc, length;
616 FloatArray crackDir;
617 FloatArray gpglobalcoords;
618
619 for ( GaussPoint *gp: *this->giveDefaultIntegrationRulePtr() ) {
620
621 if ( this->giveIPValue(cf, gp, IST_CrackedFlag, tStep) == 0 ) {
622 return;
623 }
624
625 if ( ( int ) cf.at(1) == 0 ) {
626 return;
627 }
628
629 if ( this->giveIPValue(crackDir, gp, IST_CrackDirs, tStep) ) {
630 this->giveIPValue(crackStatuses, gp, IST_CrackStatuses, tStep);
631 for ( i = 1; i <= 3; i++ ) {
632 crackStatus = ( int ) crackStatuses.at(i);
633 if ( ( crackStatus != pscm_NONE ) && ( crackStatus != pscm_CLOSED ) ) {
634 // draw a crack
635 // this element is 2d element in x-y plane
636 //
637 // compute perpendicular line to normal in xy plane
638 ax = crackDir.at(i);
639 ay = crackDir.at(3 + i);
640 if ( fabs(ax) > 1.e-6 ) {
641 by = 1.;
642 bx = -ay * by / ax;
643 norm = sqrt(bx * bx + by * by);
644 bx = bx / norm; // normalize to obtain unit vector
645 by = by / norm;
646 } else {
647 by = 0.0;
648 bx = 1.0;
649 }
650
651 // obtain gp global coordinates
652 if ( gc.getInternalVarsDefGeoFlag() ) {
653 double ksi, eta, n1, n2, n3, n4;
654 ksi = gp->giveNaturalCoordinate(1);
655 eta = gp->giveNaturalCoordinate(2);
656
657 n1 = ( 1. + ksi ) * ( 1. + eta ) * 0.25;
658 n2 = ( 1. - ksi ) * ( 1. + eta ) * 0.25;
659 n3 = ( 1. - ksi ) * ( 1. - eta ) * 0.25;
660 n4 = ( 1. + ksi ) * ( 1. - eta ) * 0.25;
661
662 gpglobalcoords.resize(2);
663
664 gpglobalcoords.at(1) = ( n1 * this->giveNode(1)->giveUpdatedCoordinate(1, tStep, defScale) +
665 n2 * this->giveNode(2)->giveUpdatedCoordinate(1, tStep, defScale) +
666 n3 * this->giveNode(3)->giveUpdatedCoordinate(1, tStep, defScale) +
667 n4 * this->giveNode(4)->giveUpdatedCoordinate(1, tStep, defScale) );
668 gpglobalcoords.at(2) = ( n1 * this->giveNode(1)->giveUpdatedCoordinate(2, tStep, defScale) +
669 n2 * this->giveNode(2)->giveUpdatedCoordinate(2, tStep, defScale) +
670 n3 * this->giveNode(3)->giveUpdatedCoordinate(2, tStep, defScale) +
671 n4 * this->giveNode(4)->giveUpdatedCoordinate(2, tStep, defScale) );
672 } else {
673 computeGlobalCoordinates( gpglobalcoords, gp->giveNaturalCoordinates() );
674 }
675
676 xc = gpglobalcoords.at(1);
677 yc = gpglobalcoords.at(2);
678 length = sqrt( computeVolumeAround(gp) / this->giveCrossSection()->give(CS_Thickness, gp) ) / 2.;
679 l [ 0 ].x = ( FPNum ) xc + bx * length;
680 l [ 0 ].y = ( FPNum ) yc + by * length;
681 l [ 0 ].z = 0.;
682 l [ 1 ].x = ( FPNum ) xc - bx * length;
683 l [ 1 ].y = ( FPNum ) yc - by * length;
684 l [ 1 ].z = 0.;
685 EASValsSetLayer(OOFEG_CRACK_PATTERN_LAYER);
686 EASValsSetLineWidth(OOFEG_CRACK_PATTERN_WIDTH);
687 if ( ( crackStatus == pscm_SOFTENING ) || ( crackStatus == pscm_OPEN ) ) {
688 EASValsSetColor( gc.getActiveCrackColor() );
689 } else {
690 EASValsSetColor( gc.getCrackPatternColor() );
691 }
692
693 tr = CreateLine3D(l);
694 EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | LAYER_MASK, tr);
695 EMAddGraphicsToModel(ESIModel(), tr);
696 }
697 }
698 }
699 }
700 }
701}
702
703#endif
704
705void
706PlaneStress2d :: SPRNodalRecoveryMI_giveSPRAssemblyPoints(IntArray &pap)
707{
708 pap.resize(4);
709 for ( int i = 1; i < 5; i++ ) {
710 pap.at(i) = this->giveNode(i)->giveNumber();
711 }
712}
713
714void
715PlaneStress2d :: SPRNodalRecoveryMI_giveDofMansDeterminedByPatch(IntArray &answer, int pap)
716{
717 int found = 0;
718 answer.resize(1);
719
720 for ( int i = 1; i < 5; i++ ) {
721 if ( pap == this->giveNode(i)->giveNumber() ) {
722 found = 1;
723 }
724 }
725
726 if ( found ) {
727 answer.at(1) = pap;
728 } else {
729 OOFEM_ERROR("node unknown");
730 }
731}
732
733int
734PlaneStress2d :: SPRNodalRecoveryMI_giveNumberOfIP()
735{
736 return this->giveDefaultIntegrationRulePtr()->giveNumberOfIntegrationPoints();
737}
738
739
741PlaneStress2d :: SPRNodalRecoveryMI_givePatchType()
742{
743 return SPRPatchType_2dxy;
744}
745
746} // end namespace oofem
double length(const Vector &a)
Definition CSG.h:88
#define REGISTER_Element(class)
double computeMeanSize()
Definition element.C:1100
Node * giveNode(int i) const
Definition element.h:629
virtual int computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
Definition element.C:1225
virtual double giveLengthInDir(const FloatArray &normalToCrackPlane)
Definition element.C:1162
int numberOfDofMans
Number of dofmanagers.
Definition element.h:136
std::vector< std ::unique_ptr< IntegrationRule > > integrationRulesArray
Definition element.h:157
int numberOfGaussPoints
Definition element.h:175
CrossSection * giveCrossSection()
Definition element.C:534
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
Definition element.h:886
int giveNumber() const
Definition femcmpnn.h:104
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void add(const FloatArray &src)
Definition floatarray.C:218
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
void zero()
Zeroes all coefficient of receiver.
double at(std::size_t i, std::size_t j) const
const FloatArray & giveNaturalCoordinates() const
Returns coordinate array of receiver.
Definition gausspoint.h:138
const FloatArray & giveSubPatchCoordinates() const
Returns local sub-patch coordinates of the receiver.
Definition gausspoint.h:142
void setupRefinedElementProblem2D(Element *element, RefinedElement *refinedElement, int level, int nodeId, IntArray &localNodeIdArray, IntArray &globalNodeIdArray, HuertaErrorEstimatorInterface ::SetupMode mode, TimeStep *tStep, int nodes, FloatArray *corner, FloatArray *midSide, FloatArray &midNode, int &localNodeId, int &localElemId, int &localBcId, IntArray &controlNode, IntArray &controlDof, HuertaErrorEstimator ::AnalysisMode aMode, const char *quadtype)
void resize(int n)
Definition intarray.C:73
int & at(std::size_t i)
Definition intarray.h:104
static FEI2dQuadLin interpolation
Definition planstrss.h:61
PlaneStressElement(int n, Domain *d)
SpatialLocalizerInterface(Element *element)
void computeMaxPrincipalDir(FloatArray &answer) const
virtual FEICellGeometry * giveCellGeometryWrapper()
double computeVolumeAround(GaussPoint *gp) override
double giveCharacteristicLength(const FloatArray &normalToCrackPlane) override
virtual void computeNmatrixAt(const FloatArray &iLocCoord, FloatMatrix &answer)
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) override
int giveInternalStateAtNode(FloatArray &answer, InternalStateType type, InternalStateMode mode, int node, TimeStep *tStep) override
const FloatArray & giveTempStrainVector() const
Returns the const pointer to receiver's temporary strain vector.
ZZNodalRecoveryModelInterface(Element *element)
Constructor.
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
#define pscm_NONE
Definition fcm.h:56
#define pscm_CLOSED
Definition fcm.h:60
#define pscm_SOFTENING
Definition fcm.h:58
static FloatArray Vec2(const double &a, const double &b)
Definition floatarray.h:606
double norm(const FloatArray &x)
@ CS_Thickness
Thickness.
@ HuertaErrorEstimatorInterfaceType
@ SPRNodalRecoveryModelInterfaceType
@ ZZNodalRecoveryModelInterfaceType
@ SpatialLocalizerInterfaceType
@ ECSM_SquareRootOfArea
@ ECSM_ProjectionCentered
#define OOFEG_CRACK_PATTERN_LAYER
oofem::oofegGraphicContext gc[OOFEG_LAST_LAYER]
#define OOFEG_VARPLOT_PATTERN_LAYER
#define OOFEG_DEFORMED_GEOMETRY_LAYER
#define OOFEG_DEFORMED_GEOMETRY_WIDTH
#define OOFEG_RAW_GEOMETRY_WIDTH
#define OOFEG_RAW_GEOMETRY_LAYER
#define OOFEG_CRACK_PATTERN_WIDTH
#define pscm_OPEN
Definition rcm2.h:61

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