OOFEM 3.0
Loading...
Searching...
No Matches
ncprincipalstrain.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 "ncprincipalstrain.h"
36
37#include "error.h"
38#include "xfem/enrichmentitem.h"
39#include "domain.h"
40#include "element.h"
41#include "gausspoint.h"
42
45
47#include "xfem/xfemmanager.h"
53#include "dynamicdatareader.h"
54#include "dynamicinputrecord.h"
55#include "geometry.h"
56#include "classfactory.h"
57#include "spatiallocalizer.h"
58#include "crosssection.h"
59
60#include <memory>
61
62namespace oofem {
64
66NucleationCriterion(ipDomain),
67mStrainThreshold(0.0),
68mInitialCrackLength(0.0),
69mIncrementLength(1.0),
70mPropStrainThreshold(0.0),
71mCutOneEl(false),
72mCrossSectionInd(1)
73{
74
75}
76
80
81std::vector<std::unique_ptr<EnrichmentItem>> NCPrincipalStrain::nucleateEnrichmentItems() {
82
83
84 SpatialLocalizer *octree = this->mpDomain->giveSpatialLocalizer();
85 XfemManager *xMan = mpDomain->giveXfemManager();
86
87 std::vector<std::unique_ptr<EnrichmentItem>> eiList;
88
89 // Center coordinates of newly inserted cracks
90 std::vector<FloatArray> center_coord_inserted_cracks;
91
92 // Loop over all elements and all bulk GP.
93 for(auto &el : mpDomain->giveElements() ) {
94
95 int numIR = el->giveNumberOfIntegrationRules();
96
97 int csNum = el->giveCrossSection()->giveNumber();
98
99 if(csNum == mCrossSectionInd) {
100
101 for(int irInd = 0; irInd < numIR; irInd++) {
102 IntegrationRule *ir = el->giveIntegrationRule(irInd);
103
104
105 int numGP = ir->giveNumberOfIntegrationPoints();
106
107 for(int gpInd = 0; gpInd < numGP; gpInd++) {
108 GaussPoint *gp = ir->getIntegrationPoint(gpInd);
109
110
112
113 if(ms != NULL) {
114
115 const FloatArray &strain = ms->giveTempStrainVector();
116
117 FloatArray principalVals;
118 FloatMatrix principalDirs;
119 StructuralMaterial::computePrincipalValDir(principalVals, principalDirs, strain, principal_strain);
120
121 if(principalVals[0] > mStrainThreshold) {
122
123 FloatArray crackNormal;
124 crackNormal.beColumnOf(principalDirs, 1);
125 // printf("crackNormal: "); crackNormal.printYourself();
126
127 FloatArray crackTangent = {-crackNormal(1), crackNormal(0)};
128 crackTangent.normalize();
129 // printf("crackTangent: "); crackTangent.printYourself();
130
131
132 // Create geometry
134 // printf("Global coord: "); pc.printYourself();
135
136
137 FloatArray ps = pc;
138 ps.add(-0.5*mInitialCrackLength, crackTangent);
139
140 FloatArray pe = pc;
141 pe.add(0.5*mInitialCrackLength, crackTangent);
142
143 if(mCutOneEl) {
144 // If desired, ensure that the crack cuts exactly one element.
145 Line line(ps, pe);
146 std::vector<FloatArray> intersecPoints;
147 // line.computeIntersectionPoints(el.get(), intersecPoints);
148
149
150 if(intersecPoints.size() == 2) {
151 ps = std::move(intersecPoints[0]);
152 pe = std::move(intersecPoints[1]);
153 }
154 else {
155 OOFEM_ERROR("intersecPoints.size() != 2")
156 }
157 }
158
159 FloatArray points = {ps(0), ps(1), pc(0), pc(1), pe(0), pe(1)};
160
161
162 // Check if nucleation is allowed, by checking for already existing cracks close to the GP.
163 // Idea: Nucleation is not allowed if we are within an enriched element. In this way, branching is not
164 // completely prohibited, but we avoid initiating multiple similar cracks.
165 bool insertionAllowed = true;
166
167 Element *el_s = octree->giveElementContainingPoint(ps);
168 if(el_s) {
169 if( xMan->isElementEnriched(el_s) ) {
170 insertionAllowed = false;
171 }
172 }
173
174 Element *el_c = octree->giveElementContainingPoint(pc);
175 if(el_c) {
176 if( xMan->isElementEnriched(el_c) ) {
177 insertionAllowed = false;
178 }
179 }
180
181 Element *el_e = octree->giveElementContainingPoint(pe);
182 if(el_e) {
183 if( xMan->isElementEnriched(el_e) ) {
184 insertionAllowed = false;
185 }
186 }
187
188 for(const auto &x: center_coord_inserted_cracks) {
189 if( distance(x, pc) < 2.0*mInitialCrackLength) {
190 insertionAllowed = false;
191 printf("Preventing insertion.\n");
192 break;
193 }
194 }
195
196 if(insertionAllowed) {
197 int n = xMan->giveNumberOfEnrichmentItems() + 1;
198 std::unique_ptr<Crack> crack = std::make_unique<Crack>(n, xMan, mpDomain);
199
200
201 // Geometry
202 std::unique_ptr<BasicGeometry> geom = std::make_unique<PolygonLine>();
203 geom->insertVertexBack(ps);
204 geom->insertVertexBack(pc);
205 geom->insertVertexBack(pe);
206 crack->setGeometry(std::move(geom));
207
208 // Enrichment function
209 crack->setEnrichmentFunction(std::make_unique<HeavisideFunction>(1, mpDomain));
210
211 // Enrichment fronts
212 crack->setEnrichmentFrontStart(std::make_unique<EnrFrontCohesiveBranchFuncOneEl>());
213
214 crack->setEnrichmentFrontEnd(std::make_unique<EnrFrontCohesiveBranchFuncOneEl>());
215
217 // Propagation law
218
219 // Options
220 auto pl = std::make_unique<PLPrincipalStrain>();
221 pl->setRadius(0.1*mIncrementLength);
222 pl->setIncrementLength(mIncrementLength);
223 pl->setStrainThreshold(mPropStrainThreshold);
224
225 crack->setPropagationLaw(std::move(pl));
226
227 crack->updateDofIdPool();
228
229 center_coord_inserted_cracks.push_back(pc);
230 eiList.push_back( std::unique_ptr<EnrichmentItem>(std::move(crack)) );
231
232 printf("NCPrincipalStrain: Nucleating a crack. principalVals[0]: %e\n", principalVals[0] );
233
234 // We only introduce one crack per element in a single time step.
235 break;
236 }
237 }
238 }
239
240 }
241 }
242 } // If correct csNum
243 }
244
245
246 return eiList;
247}
248
249
266
267void NCPrincipalStrain :: appendInputRecords(DynamicDataReader &oDR)
268{
269 auto ir = std::make_unique<DynamicInputRecord>();
270
271 ir->setRecordKeywordField( this->giveInputRecordName(), 1 );
272
277
278 oDR.insertInputRecord(DataReader :: IR_crackNucleationRec, std::move(ir));
279
280 // Enrichment function
281 auto efRec = std::make_unique<DynamicInputRecord>();
282 mpEnrichmentFunc->giveInputRecord(* efRec);
283 oDR.insertInputRecord(DataReader :: IR_enrichFuncRec, std::move(efRec));
284}
285
286} /* 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)
std::vector< std::unique_ptr< EnrichmentItem > > nucleateEnrichmentItems() override
bool mCutOneEl
If the initiated crack should cut exactly one element.
const char * giveInputRecordName() const override
int mCrossSectionInd
Index of the cross section that the nucleation criterion applies to.
NCPrincipalStrain(Domain *ipDomain)
void initializeFrom(InputRecord &ir) override
virtual void initializeFrom(InputRecord &ir)
std::unique_ptr< EnrichmentFunction > mpEnrichmentFunc
virtual Element * giveElementContainingPoint(const FloatArray &coords, const IntArray *regionList=nullptr)=0
const FloatArray & giveTempStrainVector() const
Returns the const pointer to receiver's temporary strain 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
@ principal_strain
For computing principal strains from engineering strains.
double distance(const FloatArray &x, const FloatArray &y)
#define _IFT_NCPrincipalStrain_StrainThreshold
#define _IFT_NCPrincipalStrain_PropStrainThreshold
#define _IFT_NCPrincipalStrain_IncrementLength
#define _IFT_NCPrincipalStrain_InitialCrackLength

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