OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
plhoopstresscirc.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 
36 
37 #include "xfem/propagationlaw.h"
38 #include "xfem/tipinfo.h"
39 #include "classfactory.h"
40 #include "mathfem.h"
41 #include "dynamicinputrecord.h"
42 #include "spatiallocalizer.h"
43 #include "floatmatrix.h"
44 #include "gausspoint.h"
45 #include "../sm/Materials/structuralms.h"
46 #include "xfem/enrichmentitem.h"
47 #include "feinterpol.h"
48 #include "xfem/xfemmanager.h"
49 
50 #include "xfem/XFEMDebugTools.h"
51 
52 namespace oofem {
54 
55 IRResultType PLHoopStressCirc :: initializeFrom(InputRecord *ir)
57 {
58  IRResultType result;
59 
62  IR_GIVE_FIELD(ir, mIncrementLength, _IFT_PLHoopStressCirc_IncLength);
64 
65  int useRadialBasisFunc = 0;
67  if ( useRadialBasisFunc == 1 ) {
68  mUseRadialBasisFunc = true;
69  }
70 
71  return IRRT_OK;
72 }
73 
75 {
76  int number = 1;
77  input.setRecordKeywordField(this->giveInputRecordName(), number);
78 
83 
84  if ( mUseRadialBasisFunc ) {
86  }
87 }
88 
90 {
91  if ( !iEnrFront.propagationIsAllowed() ) {
92  return false;
93  }
94 
95  // Fetch crack tip data
96  const TipInfo &tipInfo = iEnrFront.giveTipInfo();
97 
98  SpatialLocalizer *localizer = iDomain.giveSpatialLocalizer();
99 
100  // Construct circle points on an arc from -90 to 90 degrees
101  double angle = -90.0 + mAngleInc;
102  std :: vector< double >angles;
103  while ( angle <= ( 90.0 - mAngleInc ) ) {
104  angles.push_back(angle * M_PI / 180.0);
105  angle += mAngleInc;
106  }
107 
108  const FloatArray &xT = tipInfo.mGlobalCoord;
109  const FloatArray &t = tipInfo.mTangDir;
110  const FloatArray &n = tipInfo.mNormalDir;
111 
112  // It is meaningless to propagate a tip that is not inside any element
113  Element *el = localizer->giveElementContainingPoint(tipInfo.mGlobalCoord);
114  if ( el != NULL ) {
115  std :: vector< FloatArray >circPoints;
116 
117  for ( size_t i = 0; i < angles.size(); i++ ) {
118  FloatArray tangent(2);
119  tangent.zero();
120  tangent.add(cos(angles [ i ]), t);
121  tangent.add(sin(angles [ i ]), n);
122  tangent.normalize();
123 
124  FloatArray x(xT);
125  x.add(mRadius, tangent);
126  circPoints.push_back(x);
127  }
128 
129 
130 
131  std :: vector< double >sigTTArray, sigRTArray;
132 
133  // Loop over circle points
134  for ( size_t pointIndex = 0; pointIndex < circPoints.size(); pointIndex++ ) {
135  FloatArray stressVec;
136 
137  if ( mUseRadialBasisFunc ) {
138  // Interpolate stress with radial basis functions
139 
140  // Choose a cut-off length l:
141  // take the distance between two nodes in the element containing the
142  // crack tip multiplied by a constant factor.
143  // ( This choice implies that we hope that the element has reasonable
144  // aspect ratio.)
145  const FloatArray &x1 = * ( el->giveDofManager(1)->giveCoordinates() );
146  const FloatArray &x2 = * ( el->giveDofManager(2)->giveCoordinates() );
147  const double l = 1.0 * x1.distance(x2);
148 
149  // Use the octree to get all elements that have
150  // at least one Gauss point in a certain region around the tip.
151  const double searchRadius = 3.0 * l;
152  IntArray elIndices;
153  localizer->giveAllElementsWithIpWithinBox(elIndices, circPoints [ pointIndex ], searchRadius);
154 
155 
156  // Loop over the elements and Gauss points obtained.
157  // Evaluate the interpolation.
158  FloatArray sumQiWiVi;
159  double sumWiVi = 0.0;
160  for ( int elIndex: elIndices ) {
161  Element *gpEl = iDomain.giveElement(elIndex);
162 
163  for ( GaussPoint *gp_i: *gpEl->giveDefaultIntegrationRulePtr() ) {
165  // Compute global gp coordinates
166  FloatArray N;
167  FEInterpolation *interp = gpEl->giveInterpolation();
168  interp->evalN( N, gp_i->giveNaturalCoordinates(), FEIElementGeometryWrapper(gpEl) );
169 
170 
171  // Compute global coordinates of Gauss point
172  FloatArray globalCoord(2);
173  globalCoord.zero();
174 
175  for ( int i = 1; i <= gpEl->giveNumberOfDofManagers(); i++ ) {
176  DofManager *dMan = gpEl->giveDofManager(i);
177  globalCoord.at(1) += N.at(i) * dMan->giveCoordinate(1);
178  globalCoord.at(2) += N.at(i) * dMan->giveCoordinate(2);
179  }
180 
181 
183  // Compute weight of kernel function
184 
185  FloatArray tipToGP;
186  tipToGP.beDifferenceOf(globalCoord, xT);
187  bool inFrontOfCrack = true;
188  if ( tipToGP.dotProduct(t) < 0.0 ) {
189  inFrontOfCrack = false;
190  }
191 
192  double r = circPoints [ pointIndex ].distance(globalCoord);
193 
194  if ( r < l && inFrontOfCrack ) {
195  double w = ( ( l - r ) / ( pow(2.0 * M_PI, 1.5) * pow(l, 3) ) ) * exp( -0.5 * pow(r, 2) / pow(l, 2) );
196 
197  // Compute gp volume
198  double V = gpEl->computeVolumeAround(gp_i);
199 
200  // Get stress
201  StructuralMaterialStatus *ms = dynamic_cast< StructuralMaterialStatus * >( gp_i->giveMaterialStatus() );
202  if ( ms == NULL ) {
203  OOFEM_ERROR("failed to fetch MaterialStatus.");
204  }
205 
206  FloatArray stressVecGP = ms->giveStressVector();
207 
208  if ( sumQiWiVi.giveSize() != stressVecGP.giveSize() ) {
209  sumQiWiVi.resize( stressVecGP.giveSize() );
210  sumQiWiVi.zero();
211  }
212 
213  // Add to numerator
214  sumQiWiVi.add(w * V, stressVecGP);
215 
216  // Add to denominator
217  sumWiVi += w * V;
218  }
219  }
220  }
221 
222 
223  if ( fabs(sumWiVi) > 1.0e-12 ) {
224  stressVec.beScaled(1.0 / sumWiVi, sumQiWiVi);
225  } else {
226  // Take stress from closest Gauss point
227  int region = 1;
228  bool useCZGP = false;
229  GaussPoint &gp = * ( localizer->giveClosestIP(circPoints [ pointIndex ], region, useCZGP) );
230 
231 
232  // Compute stresses
234  if ( ms == NULL ) {
235  OOFEM_ERROR("failed to fetch MaterialStatus.");
236  }
237 
238  stressVec = ms->giveStressVector();
239  }
240  } else {
241  // Take stress from closest Gauss point
242  int region = 1;
243  bool useCZGP = false;
244  GaussPoint &gp = * ( localizer->giveClosestIP(circPoints [ pointIndex ], region, useCZGP) );
245 
246 
247  // Compute stresses
249  if ( ms == NULL ) {
250  OOFEM_ERROR("failed to fetch MaterialStatus.");
251  }
252 
253  stressVec = ms->giveStressVector();
254  }
255 
256  FloatMatrix stress(2, 2);
257 
258  int shearPos = stressVec.giveSize();
259 
260  stress.at(1, 1) = stressVec.at(1);
261  stress.at(1, 2) = stressVec.at(shearPos);
262  stress.at(2, 1) = stressVec.at(shearPos);
263  stress.at(2, 2) = stressVec.at(2);
264 
265 
266  // Rotation matrix
267  FloatMatrix rot(2, 2);
268  rot.at(1, 1) = cos(angles [ pointIndex ]);
269  rot.at(1, 2) = -sin(angles [ pointIndex ]);
270  rot.at(2, 1) = sin(angles [ pointIndex ]);
271  rot.at(2, 2) = cos(angles [ pointIndex ]);
272 
273  FloatArray tRot, nRot;
274  tRot.beProductOf(rot, t);
275  nRot.beProductOf(rot, n);
276 
277  FloatMatrix rotTot(2, 2);
278  rotTot.setColumn(tRot, 1);
279  rotTot.setColumn(nRot, 2);
280 
281 
282  FloatMatrix tmp, stressRot;
283 
284  tmp.beTProductOf(rotTot, stress);
285  stressRot.beProductOf(tmp, rotTot);
286 
287 
288  const double sigThetaTheta = stressRot.at(2, 2);
289  sigTTArray.push_back(sigThetaTheta);
290 
291  const double sigRTheta = stressRot.at(1, 2);
292  sigRTArray.push_back(sigRTheta);
293  }
294 
296  // Compute propagation angle
297 
298  // Find angles that fulfill sigRT = 0
299  const double stressTol = 1.0e-9;
300  double maxSigTT = 0.0, maxAngle = 0.0;
301  bool foundZeroLevel = false;
302  for ( size_t segIndex = 0; segIndex < ( circPoints.size() - 1 ); segIndex++ ) {
303  // If the shear stress sigRT changes sign over the segment
304  if ( sigRTArray [ segIndex ] * sigRTArray [ segIndex + 1 ] < stressTol ) {
305  // Compute location of zero level
306  double xi = EnrichmentItem :: calcXiZeroLevel(sigRTArray [ segIndex ], sigRTArray [ segIndex + 1 ]);
307 
308  double theta = 0.5 * ( 1.0 - xi ) * angles [ segIndex ] + 0.5 * ( 1.0 + xi ) * angles [ segIndex + 1 ];
309  double sigThetaTheta = 0.5 * ( 1.0 - xi ) * sigTTArray [ segIndex ] + 0.5 * ( 1.0 + xi ) * sigTTArray [ segIndex + 1 ];
310 
311  //printf("Found candidate: theta: %e sigThetaTheta: %e\n", theta, sigThetaTheta);
312 
313  if ( sigThetaTheta > maxSigTT ) {
314  foundZeroLevel = true;
315  maxSigTT = sigThetaTheta;
316  maxAngle = theta;
317  }
318  }
319  }
320 
321  if ( !foundZeroLevel ) {
322  return false;
323  }
324 
325  if ( iDomain.giveXfemManager()->giveVtkDebug() ) {
326  XFEMDebugTools :: WriteArrayToMatlab("sigTTvsAngle.m", angles, sigTTArray);
327  XFEMDebugTools :: WriteArrayToMatlab("sigRTvsAngle.m", angles, sigRTArray);
328 
329  XFEMDebugTools :: WriteArrayToGnuplot("sigTTvsAngle.dat", angles, sigTTArray);
330  XFEMDebugTools :: WriteArrayToGnuplot("sigRTvsAngle.dat", angles, sigRTArray);
331  }
332 
333  // Compare with threshold
334  printf("maxSigTT: %e mHoopStressThreshold: %e\n", maxSigTT, mHoopStressThreshold);
335  if ( maxSigTT > mHoopStressThreshold && foundZeroLevel ) {
336  // Rotation matrix
337  FloatMatrix rot(2, 2);
338  rot.at(1, 1) = cos(maxAngle);
339  rot.at(1, 2) = -sin(maxAngle);
340  rot.at(2, 1) = sin(maxAngle);
341  rot.at(2, 2) = cos(maxAngle);
342 
343  FloatArray dir;
344  dir.beProductOf(rot, tipInfo.mTangDir);
345 
346  // Fill up struct
347  oTipProp.mTipIndex = tipInfo.mTipIndex;
348  oTipProp.mPropagationDir = dir;
350 
351  return true;
352  }
353  }
354 
355 
356  return false;
357 }
358 } // end namespace oofem
#define _IFT_PLHoopStressCirc_HoopStressThreshold
Threshold for crack propagation.
The base class for all spatial localizers.
void setField(int item, InputFieldType id)
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
FloatArray mPropagationDir
Definition: tipinfo.h:44
int mTipIndex
Definition: tipinfo.h:34
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
TipInfo gathers useful information about a crack tip, like its position and tangent direction...
Definition: tipinfo.h:24
This class implements a structural material status information.
Definition: structuralms.h:65
virtual FloatArray * giveCoordinates()
Definition: dofmanager.h:382
Abstract base class for all finite elements.
Definition: element.h:145
Base class for dof managers.
Definition: dofmanager.h:113
Class implementing an array of integers.
Definition: intarray.h:61
XfemManager * giveXfemManager()
Definition: domain.C:375
virtual void giveAllElementsWithIpWithinBox(elementContainerType &elemSet, const FloatArray &coords, const double radius)=0
Returns container (set) of all domain elements having integration point within given box...
virtual int giveNumberOfDofManagers() const
Definition: element.h:656
virtual FEInterpolation * giveInterpolation() const
Definition: element.h:629
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Sets receiver to be a - b.
Definition: floatarray.C:341
bool giveVtkDebug() const
Definition: xfemmanager.h:243
double distance(const FloatArray &x) const
Computes the distance between position represented by receiver and position given as parameter...
Definition: floatarray.C:489
Class representing a general abstraction for finite element interpolation class.
Definition: feinterpol.h:132
void beScaled(double s, const FloatArray &b)
Sets receiver to be .
Definition: floatarray.C:146
virtual double computeVolumeAround(GaussPoint *gp)
Returns volume related to given integration point.
Definition: element.h:518
#define _IFT_PLHoopStressCirc_IncLength
Increment length per time step.
virtual bool propagateInterface(Domain &iDomain, EnrichmentFront &iEnrFront, TipPropagation &oTipProp)
Element * giveElement(int n)
Service for accessing particular domain fe element.
Definition: domain.C:160
#define M_PI
Definition: mathfem.h:52
double dotProduct(const FloatArray &x) const
Computes the dot product (or inner product) of receiver and argument.
Definition: floatarray.C:463
Propagation law that propagates the crack in the direction that gives .
#define OOFEM_ERROR(...)
Definition: error.h:61
static void WriteArrayToGnuplot(const std::string &iName, const std::vector< double > &iX, const std::vector< double > &iY)
Class EnrichmentFront: describes the edge or tip of an XFEM enrichment.
SpatialLocalizer * giveSpatialLocalizer()
Returns receiver&#39;s associated spatial localizer.
Definition: domain.C:1184
virtual bool propagationIsAllowed() const
Wrapper around element definition to provide FEICellGeometry interface.
Definition: feinterpol.h:95
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
REGISTER_PropagationLaw(PLDoNothing)
#define N(p, q)
Definition: mdm.C:367
#define _IFT_PLHoopStressCirc_AngleInc
Angle between sampling points on the circle.
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
virtual Element * giveElementContainingPoint(const FloatArray &coords, const IntArray *regionList=NULL)=0
Returns the element, containing given point and belonging to one of the region in region list...
virtual void giveInputRecord(DynamicInputRecord &input)
Class representing vector of real numbers.
Definition: floatarray.h:82
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
virtual const char * giveInputRecordName() const
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
const FloatArray & giveStressVector() const
Returns the const pointer to receiver&#39;s stress vector.
Definition: structuralms.h:107
IntegrationPointStatus * giveMaterialStatus()
Returns reference to associated material status (NULL if not defined).
Definition: gausspoint.h:205
Class representing the general Input Record.
Definition: inputrecord.h:101
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
void beTProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:367
FloatArray mNormalDir
Definition: tipinfo.h:33
void setColumn(const FloatArray &src, int c)
Sets the values of the matrix in specified column.
Definition: floatmatrix.C:648
Class representing the a dynamic Input Record.
FloatArray mTangDir
Definition: tipinfo.h:32
void setRecordKeywordField(std::string keyword, int number)
static double calcXiZeroLevel(const double &iQ1, const double &iQ2)
const TipInfo & giveTipInfo() const
static void WriteArrayToMatlab(const std::string &iName, const std::vector< double > &iX, const std::vector< double > &iY)
double mPropagationLength
Definition: tipinfo.h:45
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:337
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
FloatArray mGlobalCoord
Definition: tipinfo.h:30
virtual double giveCoordinate(int i)
Definition: dofmanager.h:380
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
virtual GaussPoint * giveClosestIP(const FloatArray &coords, int region, bool iCohesiveZoneGP=false)=0
Returns the integration point in associated domain, which is closest to given point.
#define IR_GIVE_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:69
#define _IFT_PLHoopStressCirc_Radius
Radius of circle used for stress sampling points.
double normalize()
Normalizes receiver.
Definition: floatarray.C:828
Class representing integration point in finite element program.
Definition: gausspoint.h:93
void add(const FloatArray &src)
Adds array src to receiver.
Definition: floatarray.C:156
#define _IFT_PLHoopStressCirc_RadialBasisFunc
If radial basis functions should be used for stress interpolation.
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631

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:30 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011