OOFEM 3.0
Loading...
Searching...
No Matches
qtrplanstrssxfem.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 "qtrplanstrssxfem.h"
36
39#include "vtkxmlexportmodule.h"
42#include "xfem/enrichmentitem.h"
43#include "xfem/delaunay.h"
44#include "xfem/XFEMDebugTools.h"
45#include "feinterpol.h"
46#include "node.h"
47#include "crosssection.h"
48#include "gausspoint.h"
50#include "floatmatrix.h"
51#include "floatarray.h"
52#include "intarray.h"
53#include "mathfem.h"
54#include "classfactory.h"
55#include "domain.h"
56#include "dynamicinputrecord.h"
57#include "parametermanager.h"
58#include "paramkey.h"
59
60#ifdef __OOFEG
61 #include "oofeggraphiccontext.h"
62 #include "oofegutils.h"
64#endif
65
66
67
68#include <string>
69#include <sstream>
70
71namespace oofem {
75
77 // TODO Auto-generated destructor stub
78}
79
81QTrPlaneStress2dXFEM :: giveInterface(InterfaceType it)
82{
83 if ( it == XfemElementInterfaceType ) {
84 return static_cast< XfemElementInterface * >(this);
85 } else if ( it == VTKXMLExportModuleElementInterfaceType ) {
86 return static_cast< VTKXMLExportModuleElementInterface * >(this);
87 } else {
88 return QTrPlaneStress2d :: giveInterface(it);
89 }
90}
91
92void QTrPlaneStress2dXFEM :: updateYourself(TimeStep *tStep)
93{
94 QTrPlaneStress2d :: updateYourself(tStep);
95 XfemStructuralElementInterface :: updateYourselfCZ(tStep);
96}
97
98void QTrPlaneStress2dXFEM :: postInitialize()
99{
100 QTrPlaneStress2d :: postInitialize();
101 XfemStructuralElementInterface :: initializeCZMaterial();
102}
103
104int QTrPlaneStress2dXFEM :: computeNumberOfDofs()
105{
106 int ndofs = 0;
107
108 for ( int i = 1; i <= this->giveNumberOfDofManagers(); i++ ) {
109 ndofs += this->giveDofManager(i)->giveNumberOfDofs();
110 }
111
112 return ndofs;
113}
114
115void QTrPlaneStress2dXFEM :: computeGaussPoints()
116{
117 if ( giveDomain()->hasXfemManager() ) {
118 XfemManager *xMan = giveDomain()->giveXfemManager();
119
120 if ( xMan->isElementEnriched(this) ) {
122 QTrPlaneStress2d :: computeGaussPoints();
123 }
124 } else {
125 QTrPlaneStress2d :: computeGaussPoints();
126 }
127 } else {
128 QTrPlaneStress2d :: computeGaussPoints();
129 }
130}
131
132void QTrPlaneStress2dXFEM :: computeNmatrixAt(const FloatArray &iLocCoord, FloatMatrix &answer)
133{
134 XfemElementInterface_createEnrNmatrixAt(answer, iLocCoord, * this, false);
135}
136
137void QTrPlaneStress2dXFEM :: computeBmatrixAt(GaussPoint *gp, FloatMatrix &answer, int li, int ui)
138{
139 XfemElementInterface_createEnrBmatrixAt(answer, * gp, * this);
140}
141
142void QTrPlaneStress2dXFEM :: computeBHmatrixAt(GaussPoint *gp, FloatMatrix &answer)
143{
144 XfemElementInterface_createEnrBHmatrixAt(answer, * gp, * this);
145}
146
147void
148QTrPlaneStress2dXFEM :: giveDofManDofIDMask(int inode, IntArray &answer) const
149{
150 // Continuous part
151 QTrPlaneStress2d :: giveDofManDofIDMask(inode, answer);
152
153 // Discontinuous part
154 if( this->giveDomain()->hasXfemManager() ) {
155 DofManager *dMan = giveDofManager(inode);
156 XfemManager *xMan = giveDomain()->giveXfemManager();
157
158 int placeInArray = domain->giveDofManPlaceInArray(dMan->giveGlobalNumber());
159 const std::vector<int> &nodeEiIndices = xMan->giveNodeEnrichmentItemIndices( placeInArray );
160 for ( size_t i = 0; i < nodeEiIndices.size(); i++ ) {
161 EnrichmentItem *ei = xMan->giveEnrichmentItem(nodeEiIndices[i]);
162 if ( ei->isDofManEnriched(* dMan) ) {
163 IntArray eiDofIdArray;
164 ei->computeEnrichedDofManDofIdArray(eiDofIdArray, *dMan);
165 answer.followedBy(eiDofIdArray);
166 }
167 }
168 }
169}
170
171void
172QTrPlaneStress2dXFEM :: computeConstitutiveMatrixAt(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep)
173{
174 XfemStructuralElementInterface :: XfemElementInterface_computeConstitutiveMatrixAt(answer, rMode, gp, tStep);
175}
176
177void
178QTrPlaneStress2dXFEM :: computeStressVector(FloatArray &answer, const FloatArray &strain, GaussPoint *gp, TimeStep *tStep)
179{
180 XfemStructuralElementInterface :: XfemElementInterface_computeStressVector(answer, strain, gp, tStep);
181}
182
183void QTrPlaneStress2dXFEM :: computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
184{
185 QTrPlaneStress2d :: computeStiffnessMatrix(answer, rMode, tStep);
186 XfemStructuralElementInterface :: computeCohesiveTangent(answer, tStep);
187
188 const double tol = mRegCoeffTol;
189 const double regularizationCoeff = mRegCoeff;
190 int numRows = answer.giveNumberOfRows();
191 for(int i = 0; i < numRows; i++) {
192 if( fabs(answer(i,i)) < tol ) {
193 answer(i,i) += regularizationCoeff;
194// printf("Found zero on diagonal.\n");
195 }
196 }
197}
198
199void QTrPlaneStress2dXFEM :: computeDeformationGradientVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep)
200{
202}
203
204void
205QTrPlaneStress2dXFEM :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord)
206{
207 QTrPlaneStress2d :: giveInternalForcesVector(answer, tStep, useUpdatedGpRecord);
208 XfemStructuralElementInterface :: computeCohesiveForces(answer, tStep);
209}
210
212QTrPlaneStress2dXFEM :: giveGeometryType() const
213{
214 if ( this->giveDomain()->hasXfemManager() ) {
215 XfemManager *xMan = this->giveDomain()->giveXfemManager();
216 if ( xMan->isElementEnriched(this) ) {
217 return EGT_Composite;
218 } else {
219 return EGT_Composite;
220 }
221 } else {
222 return EGT_triangle_2;
223 }
224}
225
226void
227QTrPlaneStress2dXFEM :: initializeFrom(InputRecord &ir, int priority)
228{
229 ParameterManager &ppm = this->giveDomain()->elementPPM;
230 QTrPlaneStress2d :: initializeFrom(ir, priority);
231 XfemStructuralElementInterface :: initializeCZFrom(ir, priority);
232
235}
236
237MaterialMode QTrPlaneStress2dXFEM :: giveMaterialMode()
238{
239 return XfemStructuralElementInterface :: giveMaterialMode();
240}
241
242void QTrPlaneStress2dXFEM :: giveInputRecord(DynamicInputRecord &input)
243{
244 QTrPlaneStress2d :: giveInputRecord(input);
245 XfemStructuralElementInterface :: giveCZInputRecord(input);
246
249
250}
251
252void
253QTrPlaneStress2dXFEM :: computeField(ValueModeType mode, TimeStep *tStep, const FloatArray &lcoords, FloatArray &answer)
254{
255 // TODO: Validate implementation.
256
257 FloatArray u;
258 FloatMatrix n;
259
260 XfemElementInterface_createEnrNmatrixAt(n, lcoords, * this, false);
261
262 this->computeVectorOf(mode, tStep, u);
263 answer.beProductOf(n, u);
264}
265
266void
267QTrPlaneStress2dXFEM :: giveCompositeExportData(std::vector< ExportRegion > &vtkPieces, IntArray &primaryVarsToExport, IntArray &internalVarsToExport, IntArray cellVarsToExport, TimeStep *tStep)
268{
269 vtkPieces.resize(1);
270
271 const int numCells = mSubTri.size();
272 if(numCells == 0) {
273 // Enriched but uncut element
274 // Visualize as a triangle
275 vtkPieces[0].setNumberOfCells(1);
276
277 int numTotalNodes = 6;
278 vtkPieces[0].setNumberOfNodes(numTotalNodes);
279
280 // Node coordinates
281 std :: vector< FloatArray >nodeCoords;
282 for(int i = 1; i <= 6; i++) {
283 const auto &x = giveDofManager(i)->giveCoordinates();
284 nodeCoords.push_back(x);
285
286 vtkPieces[0].setNodeCoords(i, x);
287 }
288
289 // Connectivity
290 IntArray nodes1 = {1, 2, 3, 4, 5, 6};
291 vtkPieces[0].setConnectivity(1, nodes1);
292
293 // Offset
294 int offset = 6;
295 vtkPieces[0].setOffset(1, offset);
296
297 // Cell types
298 vtkPieces[0].setCellType(1, 22); // Quadratic triangle
299
300
301
302
303 // Export nodal variables from primary fields
304 vtkPieces[0].setNumberOfPrimaryVarsToExport(primaryVarsToExport, numTotalNodes);
305
306 for ( int fieldNum = 1; fieldNum <= primaryVarsToExport.giveSize(); fieldNum++ ) {
307 UnknownType type = ( UnknownType ) primaryVarsToExport.at(fieldNum);
308
309 for ( int nodeInd = 1; nodeInd <= numTotalNodes; nodeInd++ ) {
310
311 if ( type == DisplacementVector ) { // compute displacement
312
313 FloatArray u = Vec3(0.0, 0.0, 0.0);
314
315 // Fetch global coordinates (in undeformed configuration)
316 const FloatArray &x = nodeCoords[nodeInd-1];
317
318 // Compute local coordinates
319 FloatArray locCoord;
320 computeLocalCoordinates(locCoord, x);
321
322 // Compute displacement in point
323 FloatMatrix NMatrix;
324 computeNmatrixAt(locCoord, NMatrix);
325 FloatArray solVec;
326 computeVectorOf(VM_Total, tStep, solVec);
327 FloatArray uTemp;
328 uTemp.beProductOf(NMatrix, solVec);
329
330 if(uTemp.giveSize() == 3) {
331 u = uTemp;
332 }
333 else {
334 u = Vec3(uTemp[0], uTemp[1], 0.0);
335 }
336
337 vtkPieces[0].setPrimaryVarInNode(type, nodeInd, u);
338 } else {
339 printf("fieldNum: %d\n", fieldNum);
340 // TODO: Implement
341// ZZNodalRecoveryMI_recoverValues(values, layer, ( InternalStateType ) 1, tStep); // does not work well - fix
342// for ( int j = 1; j <= numCellNodes; j++ ) {
343// vtkPiece.setPrimaryVarInNode(fieldNum, nodeNum, values [ j - 1 ]);
344// nodeNum += 1;
345// }
346 }
347 }
348 }
349
350
351 // Export nodal variables from internal fields
352 vtkPieces[0].setNumberOfInternalVarsToExport(internalVarsToExport, numTotalNodes);
353
354
355 // Export cell variables
356 vtkPieces[0].setNumberOfCellVarsToExport(cellVarsToExport, 1);
357 for ( int i = 1; i <= cellVarsToExport.giveSize(); i++ ) {
358 InternalStateType type = ( InternalStateType ) cellVarsToExport.at(i);
359 FloatArray average;
360 std :: unique_ptr< IntegrationRule > &iRule = integrationRulesArray [ 0 ];
361 VTKXMLExportModule :: computeIPAverage(average, iRule.get(), this, type, tStep);
362 if(average.giveSize() == 0) {
363 average = Vec6(0., 0., 0., 0., 0., 0.);
364 }
365
366 if(average.giveSize() == 1) {
367 vtkPieces[0].setCellVar( type, 1, average );
368 }
369
370 if(average.giveSize() == 6) {
371 FloatArray averageV9(9);
372 averageV9.at(1) = average.at(1);
373 averageV9.at(5) = average.at(2);
374 averageV9.at(9) = average.at(3);
375 averageV9.at(6) = averageV9.at(8) = average.at(4);
376 averageV9.at(3) = averageV9.at(7) = average.at(5);
377 averageV9.at(2) = averageV9.at(4) = average.at(6);
378
379 vtkPieces[0].setCellVar( type, 1, averageV9 );
380 }
381 }
382
383
384 // Export of XFEM related quantities
385 if ( domain->hasXfemManager() ) {
386 XfemManager *xMan = domain->giveXfemManager();
387
388 int nEnrIt = xMan->giveNumberOfEnrichmentItems();
389 vtkPieces[0].setNumberOfInternalXFEMVarsToExport(xMan->vtkExportFields.giveSize(), nEnrIt, numTotalNodes);
390
391 const int nDofMan = giveNumberOfDofManagers();
392
393
394 for ( int field = 1; field <= xMan->vtkExportFields.giveSize(); field++ ) {
395 XFEMStateType xfemstype = ( XFEMStateType ) xMan->vtkExportFields [ field - 1 ];
396
397 for ( int enrItIndex = 1; enrItIndex <= nEnrIt; enrItIndex++ ) {
398 EnrichmentItem *ei = xMan->giveEnrichmentItem(enrItIndex);
399 for ( int nodeInd = 1; nodeInd <= numTotalNodes; nodeInd++ ) {
400
401 const FloatArray &x = nodeCoords[nodeInd-1];
402 FloatArray locCoord;
403 computeLocalCoordinates(locCoord, x);
404
407 interp->evalN( N, locCoord, FEIElementGeometryWrapper(this) );
408
409
410 if ( xfemstype == XFEMST_LevelSetPhi ) {
411 double levelSet = 0.0, levelSetInNode = 0.0;
412
413 for(int elNodeInd = 1; elNodeInd <= nDofMan; elNodeInd++) {
414 DofManager *dMan = giveDofManager(elNodeInd);
415 ei->evalLevelSetNormalInNode(levelSetInNode, dMan->giveGlobalNumber(), dMan->giveCoordinates() );
416
417 levelSet += N.at(elNodeInd)*levelSetInNode;
418 }
419
420
421 FloatArray valueArray = Vec1(levelSet);
422 vtkPieces[0].setInternalXFEMVarInNode(field, enrItIndex, nodeInd, valueArray);
423
424 } else if ( xfemstype == XFEMST_LevelSetGamma ) {
425 double levelSet = 0.0, levelSetInNode = 0.0;
426
427 for(int elNodeInd = 1; elNodeInd <= nDofMan; elNodeInd++) {
428 DofManager *dMan = giveDofManager(elNodeInd);
429 ei->evalLevelSetTangInNode(levelSetInNode, dMan->giveGlobalNumber(), dMan->giveCoordinates() );
430
431 levelSet += N.at(elNodeInd)*levelSetInNode;
432 }
433
434
435 FloatArray valueArray = Vec1(levelSet);
436 vtkPieces[0].setInternalXFEMVarInNode(field, enrItIndex, nodeInd, valueArray);
437
438 } else if ( xfemstype == XFEMST_NodeEnrMarker ) {
439 double nodeEnrMarker = 0.0, nodeEnrMarkerInNode = 0.0;
440
441 for(int elNodeInd = 1; elNodeInd <= nDofMan; elNodeInd++) {
442 DofManager *dMan = giveDofManager(elNodeInd);
443 ei->evalNodeEnrMarkerInNode(nodeEnrMarkerInNode, dMan->giveGlobalNumber() );
444
445 nodeEnrMarker += N.at(elNodeInd)*nodeEnrMarkerInNode;
446 }
447
448
449 FloatArray valueArray = Vec1(nodeEnrMarker);
450 vtkPieces[0].setInternalXFEMVarInNode(field, enrItIndex, nodeInd, valueArray);
451 }
452
453 }
454 }
455 }
456 }
457
458 }
459 else {
460 // Enriched and cut element
461
462 XfemStructuralElementInterface::giveSubtriangulationCompositeExportData(vtkPieces, primaryVarsToExport, internalVarsToExport, cellVarsToExport, tStep);
463
464
465 }
466
467}
468
469
470} /* namespace OOFEM */
#define N(a, b)
#define REGISTER_Element(class)
int giveGlobalNumber() const
Definition dofmanager.h:515
const FloatArray & giveCoordinates() const
Definition dofmanager.h:390
void setField(int item, InputFieldType id)
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Definition element.C:103
std::vector< std ::unique_ptr< IntegrationRule > > integrationRulesArray
Definition element.h:157
virtual int giveNumberOfDofManagers() const
Definition element.h:695
DofManager * giveDofManager(int i) const
Definition element.C:553
virtual bool computeLocalCoordinates(FloatArray &answer, const FloatArray &gcoords)
Definition element.C:1240
bool evalNodeEnrMarkerInNode(double &oNodeEnrMarker, int iNodeInd) const
bool evalLevelSetTangInNode(double &oLevelSet, int iNodeInd, const FloatArray &iGlobalCoord) const
bool isDofManEnriched(const DofManager &iDMan) const
virtual void computeEnrichedDofManDofIdArray(IntArray &oDofIdArray, DofManager &iDMan)
bool evalLevelSetNormalInNode(double &oLevelSet, int iNodeInd, const FloatArray &iGlobalCoord) const
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
Domain * giveDomain() const
Definition femcmpnn.h:97
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition femcmpnn.h:79
int number
Component number.
Definition femcmpnn.h:77
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
int giveNumberOfRows() const
Returns number of rows of receiver.
void followedBy(const IntArray &b, int allocChunk=0)
Definition intarray.C:94
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
static ParamKey IPK_QTrPlaneStress2dXFEM_RegCoeffTol
void computeNmatrixAt(const FloatArray &iLocCoord, FloatMatrix &answer) override
static ParamKey IPK_QTrPlaneStress2dXFEM_RegCoeff
FEInterpolation * giveInterpolation() const override
Definition qtrplstr.C:66
void XfemElementInterface_createEnrBmatrixAt(FloatMatrix &oAnswer, GaussPoint &iGP, Element &iEl)
Creates enriched B-matrix.
void XfemElementInterface_createEnrBHmatrixAt(FloatMatrix &oAnswer, GaussPoint &iGP, Element &iEl)
Creates enriched BH-matrix.
void XfemElementInterface_createEnrNmatrixAt(FloatMatrix &oAnswer, const FloatArray &iLocCoord, Element &iEl, bool iSetDiscontContribToZero)
Creates enriched N-matrix.
bool isElementEnriched(const Element *elem)
IntArray vtkExportFields
const std ::vector< int > & giveNodeEnrichmentItemIndices(int iNodeIndex) const
EnrichmentItem * giveEnrichmentItem(int n)
int giveNumberOfEnrichmentItems() const
virtual void XfemElementInterface_computeDeformationGradientVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep)
void giveSubtriangulationCompositeExportData(std ::vector< ExportRegion > &vtkPieces, IntArray &primaryVarsToExport, IntArray &internalVarsToExport, IntArray cellVarsToExport, TimeStep *tStep)
VTK Interface.
bool XfemElementInterface_updateIntegrationRule() override
Updates integration rule based on the triangulation.
static FloatArray Vec6(const double &a, const double &b, const double &c, const double &d, const double &e, const double &f)
Definition floatarray.h:610
XFEMStateType
Definition xfemmanager.h:92
@ XfemElementInterfaceType
@ VTKXMLExportModuleElementInterfaceType
static FloatArray Vec1(const double &a)
Definition floatarray.h:605
static FloatArray Vec3(const double &a, const double &b, const double &c)
Definition floatarray.h:607
#define PM_UPDATE_PARAMETER(_val, _pm, _ir, _componentnum, _paramkey, _prio)
#define _IFT_QTrPlaneStress2dXFEM_RegCoeff
#define _IFT_QTrPlaneStress2dXFEM_RegCoeffTol

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