OOFEM 3.0
Loading...
Searching...
No Matches
ncprincipalstress.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 "ncprincipalstress.h"
36#include "error.h"
37#include "xfem/enrichmentitem.h"
38#include "domain.h"
39#include "element.h"
40#include "gausspoint.h"
41
44
46#include "xfem/xfemmanager.h"
52#include "dynamicdatareader.h"
53#include "dynamicinputrecord.h"
54#include "geometry.h"
55#include "classfactory.h"
56#include "spatiallocalizer.h"
57#include "crosssection.h"
58
59#include <memory>
60
61namespace oofem {
63
65 NucleationCriterion(ipDomain),
66 mStressThreshold(0.0),
67 mInitialCrackLength(0.0),
68 mMatForceRadius(0.0),
69 mIncrementLength(0.0),
70 mCrackPropThreshold(0.0),
71 mCutOneEl(false),
72 mCrossSectionInd(2)
73{ }
74
76
77std::vector<std::unique_ptr<EnrichmentItem>> NCPrincipalStress::nucleateEnrichmentItems()
78{
79 SpatialLocalizer *octree = this->mpDomain->giveSpatialLocalizer();
80 XfemManager *xMan = mpDomain->giveXfemManager();
81
82 std::vector<std::unique_ptr<EnrichmentItem>> eiList;
83
84 // Center coordinates of newly inserted cracks
85 std::vector<FloatArray> center_coord_inserted_cracks;
86
87 // Loop over all elements and all bulk GP.
88 for(auto &el : mpDomain->giveElements() ) {
89 int numIR = el->giveNumberOfIntegrationRules();
90 int csNum = el->giveCrossSection()->giveNumber();
91
92 if(csNum == mCrossSectionInd || true) {
93
94 for(int irInd = 0; irInd < numIR; irInd++) {
95 IntegrationRule *ir = el->giveIntegrationRule(irInd);
96
97 int numGP = ir->giveNumberOfIntegrationPoints();
98
99 for(int gpInd = 0; gpInd < numGP; gpInd++) {
100 GaussPoint *gp = ir->getIntegrationPoint(gpInd);
101
102 // int csNum = gp->giveCrossSection()->giveNumber();
103 // printf("csNum: %d\n", csNum);
104
105
107
108 if ( ms ) {
109
110 const FloatArray &stress = ms->giveTempStressVector();
111
112 FloatArray principalVals;
113 FloatMatrix principalDirs;
114 StructuralMaterial::computePrincipalValDir(principalVals, principalDirs, stress, principal_stress);
115
116 if ( principalVals[0] > mStressThreshold ) {
117
118
119
120 // printf("\nFound GP with stress above threshold.\n");
121 // printf("principalVals: "); principalVals.printYourself();
122
123 FloatArray crackNormal;
124 crackNormal.beColumnOf(principalDirs, 1);
125 // printf("crackNormal: "); crackNormal.printYourself();
126
127 FloatArray crackTangent = Vec2(-crackNormal(1), crackNormal(0));
128 crackTangent.normalize();
129 // printf("crackTangent: "); crackTangent.printYourself();
130
131
132
133 // Create geometry
135 // printf("Global coord: "); pc.printYourself();
136
137
138 FloatArray ps = pc;
139 ps.add(-0.5*mInitialCrackLength, crackTangent);
140
141 FloatArray pe = pc;
142 pe.add(0.5*mInitialCrackLength, crackTangent);
143
144 if ( mCutOneEl ) {
145 // If desired, ensure that the crack cuts exactly one element.
146 Line line(ps, pe);
147 std::vector<FloatArray> intersecPoints;
148 // line.computeIntersectionPoints(el.get(), intersecPoints);
149
150 for ( int i = 1; i <= el->giveNumberOfDofManagers(); i++ ) {
151// int n1 = i;
152// int n2 = 0;
153// if ( i < el->giveNumberOfDofManagers() ) {
154// n2 = i + 1;
155// } else {
156// n2 = 1;
157// }
158
159 // const FloatArray &p1 = *(el->giveDofManager(n1)->giveCoordinates());
160 // const FloatArray &p2 = *(el->giveDofManager(n2)->giveCoordinates());
161
162
163 }
164
165 // printf("intersecPoints.size(): %lu\n", intersecPoints.size());
166
167 if ( intersecPoints.size() == 2 ) {
168 ps = std::move(intersecPoints[0]);
169 pe = std::move(intersecPoints[1]);
170 } else {
171 OOFEM_ERROR("intersecPoints.size() != 2")
172 }
173 }
174
175 FloatArray points = Vec6(ps(0), ps(1), pc(0), pc(1), pe(0), pe(1));
176
177 // double diffX = 0.5*(ps(0) + pe(0)) - pc(0);
178 // printf("diffX: %e\n", diffX);
179
180 // double diffY = 0.5*(ps(1) + pe(1)) - pc(1);
181 // printf("diffY: %e\n", diffY);
182
183
184 // TODO: Check if nucleation is allowed, by checking for already existing cracks close to the GP.
185 // Idea: Nucleation is not allowed if we are within an enriched element. In this way, branching is not
186 // completely prohibited, but we avoid initiating multiple similar cracks.
187 bool insertionAllowed = true;
188
189 Element *el_s = octree->giveElementContainingPoint(ps);
190 if ( el_s ) {
191 if ( xMan->isElementEnriched(el_s) ) {
192 insertionAllowed = false;
193 }
194 }
195
196 Element *el_c = octree->giveElementContainingPoint(pc);
197 if ( el_c ) {
198 if ( xMan->isElementEnriched(el_c) ) {
199 insertionAllowed = false;
200 }
201 }
202
203 Element *el_e = octree->giveElementContainingPoint(pe);
204 if ( el_e ) {
205 if ( xMan->isElementEnriched(el_e) ) {
206 insertionAllowed = false;
207 }
208 }
209
210 for ( const auto &x: center_coord_inserted_cracks ) {
211 if ( distance(x, pc) < 2.0*mInitialCrackLength ) {
212 insertionAllowed = false;
213 printf("Preventing insertion.\n");
214 break;
215 }
216 }
217
218 if ( insertionAllowed ) {
219 int n = xMan->giveNumberOfEnrichmentItems() + 1;
220 std::unique_ptr<Crack> crack = std::make_unique<Crack>(n, xMan, mpDomain);
221
222
223 // Geometry
224 std::unique_ptr<BasicGeometry> geom = std::make_unique<PolygonLine>();
225 geom->insertVertexBack(ps);
226 geom->insertVertexBack(pc);
227 geom->insertVertexBack(pe);
228 crack->setGeometry(std::move(geom));
229
230 // Enrichment function
231 crack->setEnrichmentFunction(std::make_unique<HeavisideFunction>(1, mpDomain));
232
233 // Enrichment fronts
234 crack->setEnrichmentFrontStart(std::make_unique<EnrFrontCohesiveBranchFuncOneEl>());
235
236 crack->setEnrichmentFrontEnd(std::make_unique<EnrFrontCohesiveBranchFuncOneEl>());
237
238
239
240
242 // Propagation law
243
244 // Options
245 // double radius = 0.5*mInitialCrackLength, angleInc = 10.0, incrementLength = 0.5*mInitialCrackLength, hoopStressThreshold = 0.0;
246 // bool useRadialBasisFunc = true;
247
248 // PLHoopStressCirc *pl = new PLHoopStressCirc();
249 // pl->setRadius(radius);
250 // pl->setAngleInc(angleInc);
251 // pl->setIncrementLength(incrementLength);
252 // pl->setHoopStressThreshold(hoopStressThreshold);
253 // pl->setUseRadialBasisFunc(useRadialBasisFunc);
254
255 // PLDoNothing *pl = new PLDoNothing();
256
257 auto pl = std::make_unique<PLMaterialForce>();
258 pl->setRadius(mMatForceRadius);
259 pl->setIncrementLength(mIncrementLength);
260// pl->setIncrementLength(0.25);
261// pl->setCrackPropThreshold(0.25);
262 pl->setCrackPropThreshold(mCrackPropThreshold);
263
264 crack->setPropagationLaw(std::move(pl));
265
266 crack->updateDofIdPool();
267
268 center_coord_inserted_cracks.push_back(pc);
269 eiList.push_back( std::unique_ptr<EnrichmentItem>(std::move(crack)) );
270
271// printf("Nucleating a crack in NCPrincipalStress::nucleateEnrichmentItems.\n");
272// printf("el->giveGlobalNumber(): %d\n", el->giveGlobalNumber() );
273
274 // We only introduce one crack per element in a single time step.
275 break;
276 }
277 }
278 }
279
280 }
281 }
282 } // If correct csNum
283 }
284
285
286 return eiList;
287}
288
289
291{
293
295// printf("mStressThreshold: %e\n", mStressThreshold);
296
298// printf("mInitialCrackLength: %e\n", mInitialCrackLength);
299
301// printf("mMatForceRadius: %e\n", mMatForceRadius);
302
304// printf("mIncrementLength: %e\n", mIncrementLength);
305
307// printf("mCrackPropThreshold: %e\n", mCrackPropThreshold);
308
309
310}
311
312void NCPrincipalStress :: appendInputRecords(DynamicDataReader &oDR)
313{
314 auto ir = std::make_unique<DynamicInputRecord>();
315
316 ir->setRecordKeywordField( this->giveInputRecordName(), 1 );
317
323
324 oDR.insertInputRecord(DataReader :: IR_crackNucleationRec, std::move(ir));
325
326 // Enrichment function
327 auto efRec = std::make_unique<DynamicInputRecord>();
328 mpEnrichmentFunc->giveInputRecord(* efRec);
329 oDR.insertInputRecord(DataReader :: IR_enrichFuncRec, std::move(efRec));
330}
331
332} /* namespace oofem */
#define REGISTER_NucleationCriterion(class)
void insertInputRecord(InputRecordType type, std::unique_ptr< InputRecord > record)
void beColumnOf(const FloatMatrix &mat, int col)
void add(const FloatArray &src)
Definition floatarray.C:218
const FloatArray & giveGlobalCoordinates()
Definition gausspoint.h:159
IntegrationPointStatus * giveMaterialStatus(IntegrationPointStatusIDType key=IPSID_Default)
Definition gausspoint.h:204
int giveNumberOfIntegrationPoints() const
GaussPoint * getIntegrationPoint(int n)
int mCrossSectionInd
Index of the cross section that the nucleation criterion applies to.
const char * giveInputRecordName() const override
void initializeFrom(InputRecord &ir) override
bool mCutOneEl
If the initiated crack should cut exactly one element.
NCPrincipalStress(Domain *ipDomain)
std::vector< std::unique_ptr< EnrichmentItem > > nucleateEnrichmentItems() override
virtual void initializeFrom(InputRecord &ir)
std::unique_ptr< EnrichmentFunction > mpEnrichmentFunc
virtual Element * giveElementContainingPoint(const FloatArray &coords, const IntArray *regionList=nullptr)=0
const FloatArray & giveTempStressVector() const
Returns the const pointer to receiver's temporary stress vector.
static void computePrincipalValDir(FloatArray &answer, FloatMatrix &dir, const FloatArray &s, stressStrainPrincMode mode)
bool isElementEnriched(const Element *elem)
int giveNumberOfEnrichmentItems() const
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
static FloatArray Vec2(const double &a, const double &b)
Definition floatarray.h:606
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
@ principal_stress
For computing principal stresses.
double distance(const FloatArray &x, const FloatArray &y)
#define _IFT_NCPrincipalStress_IncrementLength
#define _IFT_NCPrincipalStress_InitialCrackLength
#define _IFT_NCPrincipalStress_MatForceRadius
#define _IFT_NCPrincipalStress_CrackPropThreshold
#define _IFT_NCPrincipalStress_StressThreshold

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