OOFEM 3.0
Loading...
Searching...
No Matches
plprincipalstrain.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 "plprincipalstrain.h"
36#include "xfem/propagationlaw.h"
37#include "xfem/tipinfo.h"
38#include "classfactory.h"
39#include "mathfem.h"
40#include "dynamicinputrecord.h"
41#include "spatiallocalizer.h"
42#include "floatmatrix.h"
43#include "gausspoint.h"
44#include "xfem/enrichmentitem.h"
45#include "feinterpol.h"
46#include "xfem/xfemmanager.h"
47
50
51#include "xfem/XFEMDebugTools.h"
52
53namespace oofem {
55
57mRadius(0.0),mIncrementLength(0.0),mStrainThreshold(0.0), mUseRadialBasisFunc(false)
58{
59
60}
61
65
66void PLPrincipalStrain :: initializeFrom(InputRecord &ir)
67{
71
72 int useRadialBasisFunc = 0;
74 if ( useRadialBasisFunc == 1 ) {
76 }
77}
78
79void PLPrincipalStrain :: giveInputRecord(DynamicInputRecord &input)
80{
81 int number = 1;
82 input.setRecordKeywordField(this->giveInputRecordName(), number);
83
87
88 if ( mUseRadialBasisFunc ) {
90 }
91}
92
93
94bool PLPrincipalStrain :: propagateInterface(Domain &iDomain, EnrichmentFront &iEnrFront, TipPropagation &oTipProp)
95{
96 if ( !iEnrFront.propagationIsAllowed() ) {
97 return false;
98 }
99
100 // Fetch crack tip data
101 const TipInfo &tipInfo = iEnrFront.giveTipInfo();
102
103 SpatialLocalizer *localizer = iDomain.giveSpatialLocalizer();
104
105
106 const FloatArray &xT = tipInfo.mGlobalCoord;
107 const FloatArray &t = tipInfo.mTangDir;
108// const FloatArray &n = tipInfo.mNormalDir;
109
110 // It is meaningless to propagate a tip that is not inside any element
111 Element *el = localizer->giveElementContainingPoint(tipInfo.mGlobalCoord);
112 if ( el != nullptr ) {
113
114
115
116 FloatArray x(xT);
117 x.add(mRadius, t);
118// circPoints.push_back(x);
119
120
121 std :: vector< double >sigTTArray, sigRTArray;
122
123 FloatArray strainVec;
124
125 if ( mUseRadialBasisFunc ) {
126 // Interpolate strain with radial basis functions
127
128 // Choose a cut-off length l:
129 // take the distance between two nodes in the element containing the
130 // crack tip multiplied by a constant factor.
131 // ( This choice implies that we hope that the element has reasonable
132 // aspect ratio.)
133 const auto &x1 = el->giveDofManager(1)->giveCoordinates();
134 const auto &x2 = el->giveDofManager(2)->giveCoordinates();
135 const double l = 1.0 * distance(x1, x2);
136
137 // Use the octree to get all elements that have
138 // at least one Gauss point in a certain region around the tip.
139 const double searchRadius = 3.0 * l;
140 IntArray elIndices;
141 localizer->giveAllElementsWithIpWithinBox(elIndices, x, searchRadius);
142
143
144 // Loop over the elements and Gauss points obtained.
145 // Evaluate the interpolation.
146 FloatArray sumQiWiVi;
147 double sumWiVi = 0.0;
148 for ( int elIndex: elIndices ) {
149 Element *gpEl = iDomain.giveElement(elIndex);
150
151 for ( auto &gp_i: *gpEl->giveDefaultIntegrationRulePtr() ) {
153 // Compute global gp coordinates
155 FEInterpolation *interp = gpEl->giveInterpolation();
156 interp->evalN( N, gp_i->giveNaturalCoordinates(), FEIElementGeometryWrapper(gpEl) );
157
158
159 // Compute global coordinates of Gauss point
160 FloatArray globalCoord(2);
161 globalCoord.zero();
162
163 for ( int i = 1; i <= gpEl->giveNumberOfDofManagers(); i++ ) {
164 DofManager *dMan = gpEl->giveDofManager(i);
165 globalCoord.at(1) += N.at(i) * dMan->giveCoordinate(1);
166 globalCoord.at(2) += N.at(i) * dMan->giveCoordinate(2);
167 }
168
169
171 // Compute weight of kernel function
172
173 FloatArray tipToGP;
174 tipToGP.beDifferenceOf(globalCoord, xT);
175 bool inFrontOfCrack = true;
176 if ( tipToGP.dotProduct(t) < 0.0 ) {
177 inFrontOfCrack = false;
178 }
179
180 double r = distance(x, globalCoord);
181
182 if ( r < l && inFrontOfCrack ) {
183 double w = ( ( l - r ) / ( pow(2.0 * M_PI, 1.5) * pow(l, 3) ) ) * exp( -0.5 * pow(r, 2) / pow(l, 2) );
184
185 // Compute gp volume
186 double V = gpEl->computeVolumeAround(gp_i);
187
188 // Get stress
189 StructuralMaterialStatus *ms = dynamic_cast< StructuralMaterialStatus * >( gp_i->giveMaterialStatus() );
190 if ( ms == nullptr ) {
191 OOFEM_ERROR("failed to fetch MaterialStatus.");
192 }
193
194 FloatArray strainVecGP = ms->giveStrainVector();
195
196 if ( sumQiWiVi.giveSize() != strainVecGP.giveSize() ) {
197 sumQiWiVi.resize( strainVecGP.giveSize() );
198 sumQiWiVi.zero();
199 }
200
201 // Add to numerator
202 sumQiWiVi.add(w * V, strainVecGP);
203
204 // Add to denominator
205 sumWiVi += w * V;
206 }
207 }
208 }
209
210
211 if ( fabs(sumWiVi) > 1.0e-12 ) {
212 strainVec.beScaled(1.0 / sumWiVi, sumQiWiVi);
213 } else {
214 // Take strain from closest Gauss point
215 int region = 1;
216 bool useCZGP = false;
217 GaussPoint &gp = * ( localizer->giveClosestIP(x, region, useCZGP) );
218
219
220 // Compute strain
222 if ( ms == nullptr ) {
223 OOFEM_ERROR("failed to fetch MaterialStatus.");
224 }
225
226 strainVec = ms->giveStrainVector();
227 }
228 } else {
229 // Take stress from closest Gauss point
230 int region = 1;
231 bool useCZGP = false;
232 GaussPoint &gp = * ( localizer->giveClosestIP(x, region, useCZGP) );
233
234
235 // Compute stresses
237 if ( ms == nullptr ) {
238 OOFEM_ERROR("failed to fetch MaterialStatus.");
239 }
240
241 strainVec = ms->giveStrainVector();
242 }
243
244 // Compute principal strain
245 FloatArray principalVals;
246 FloatMatrix principalDirs;
247 StructuralMaterial::computePrincipalValDir(principalVals, principalDirs, strainVec, principal_strain);
248
249
250
251 // Compare with threshold
252 printf("Max principal strain: %e\n", principalVals[0]);
253 if ( principalVals[0] > mStrainThreshold ) {
254
255 FloatArray propNormal;
256 propNormal.beColumnOf(principalDirs, 1);
257
258 FloatArray propTangent = Vec2(-propNormal(1), propNormal(0));
259
260 if( propTangent.dotProduct(t) < 0.0 ) {
261 propTangent.times(-1.0);
262 }
263
264 // Fill up struct
265 oTipProp.mTipIndex = tipInfo.mTipIndex;
266 oTipProp.mPropagationDir = propTangent;
268
269 return true;
270 }
271
272 } // Tip is inside an element.
273
274
275 return false;
276}
277
278} // end namespace oofem
279
#define N(a, b)
#define REGISTER_PropagationLaw(class)
double giveCoordinate(int i) const
Definition dofmanager.h:383
const FloatArray & giveCoordinates() const
Definition dofmanager.h:390
SpatialLocalizer * giveSpatialLocalizer()
Definition domain.C:1255
Element * giveElement(int n)
Definition domain.C:165
void setRecordKeywordField(std ::string keyword, int number)
void setField(int item, InputFieldType id)
virtual FEInterpolation * giveInterpolation() const
Definition element.h:648
virtual int giveNumberOfDofManagers() const
Definition element.h:695
DofManager * giveDofManager(int i) const
Definition element.C:553
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
Definition element.h:886
virtual double computeVolumeAround(GaussPoint *gp)
Definition element.h:530
const TipInfo & giveTipInfo() const
virtual bool propagationIsAllowed() const
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
double dotProduct(const FloatArray &x) const
Definition floatarray.C:524
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void beColumnOf(const FloatMatrix &mat, int col)
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Definition floatarray.C:403
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void beScaled(double s, const FloatArray &b)
Definition floatarray.C:208
void add(const FloatArray &src)
Definition floatarray.C:218
void times(double s)
Definition floatarray.C:834
IntegrationPointStatus * giveMaterialStatus(IntegrationPointStatusIDType key=IPSID_Default)
Definition gausspoint.h:204
const char * giveInputRecordName() const override
virtual GaussPoint * giveClosestIP(const FloatArray &coords, int region, bool iCohesiveZoneGP=false)=0
virtual Element * giveElementContainingPoint(const FloatArray &coords, const IntArray *regionList=nullptr)=0
virtual void giveAllElementsWithIpWithinBox(elementContainerType &elemSet, const FloatArray &coords, const double radius)=0
const FloatArray & giveStrainVector() const
Returns the const pointer to receiver's strain vector.
static void computePrincipalValDir(FloatArray &answer, FloatMatrix &dir, const FloatArray &s, stressStrainPrincMode mode)
FloatArray mTangDir
Definition tipinfo.h:32
FloatArray mGlobalCoord
Definition tipinfo.h:30
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define M_PI
Definition mathfem.h:52
static FloatArray Vec2(const double &a, const double &b)
Definition floatarray.h:606
@ principal_strain
For computing principal strains from engineering strains.
double distance(const FloatArray &x, const FloatArray &y)
#define _IFT_PLPrincipalStrain_IncLength
Increment length per time step.
#define _IFT_PLPrincipalStrain_RadialBasisFunc
If radial basis functions should be used for strain interpolation.
#define _IFT_PLPrincipalStrain_StrainThreshold
Threshold for crack propagation.
#define _IFT_PLPrincipalStrain_Radius
Radius away from tip used when picking sampling point.
double mPropagationLength
Definition tipinfo.h:45
FloatArray mPropagationDir
Definition tipinfo.h:44

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