OOFEM 3.0
Loading...
Searching...
No Matches
xfemmanager.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 "xfemmanager.h"
36#include "inputrecord.h"
37#include "intarray.h"
38#include "connectivitytable.h"
39#include "floatarray.h"
40#include "domain.h"
41#include "element.h"
42#include "dofmanager.h"
43#include "cltypes.h"
45#include "classfactory.h"
46#include "masterdof.h"
47#include "datareader.h"
48#include "datastream.h"
49#include "contextioerr.h"
50#include "dynamicinputrecord.h"
52#include "XFEMDebugTools.h"
53#include "xfemtolerances.h"
54#include "nucleationcriterion.h"
57
58namespace oofem {
60
61XfemManager :: XfemManager(Domain *domain)
62{
63 this->domain = domain;
64 numberOfEnrichmentItems = -1;
65 numberOfNucleationCriteria = 0;
66 mNumGpPerTri = 12;
67
68 // Default is no refinement of triangles.
69 mNumTriRef = 0;
70
71 // Default is no scaling of enrichment dofs.
72 mEnrDofScaleFac = 1.0;
73
74 doVTKExport = false;
75 mDebugVTK = false;
76 vtkExportFields.clear();
77
78 mNodeEnrichmentItemIndices.resize(0);
79 mElementEnrichmentItemIndices.clear();
80 mMaterialModifyingEnrItemIndices.clear();
81}
82
83XfemManager :: ~XfemManager()
84{}
85
86
88XfemManager :: giveXFEMStateValueType(XFEMStateType type)
89{
90 switch ( type ) {
91 case XFEMST_Enrichment:
92 case XFEMST_LevelSetPhi:
93 case XFEMST_LevelSetGamma:
94 case XFEMST_NumIntersecPoints:
95 case XFEMST_NodeEnrMarker:
96 return ISVT_SCALAR;
97
98 default:
99 return ISVT_UNDEFINED;
100 }
101}
102
103
104bool XfemManager :: isElementEnriched(const Element *elem)
105{
106#if 0
107 // Loop over all EI which asks if el is enriched.
108 for ( int i = 1; i <= this->giveNumberOfEnrichmentItems(); i++ ) {
109 if ( this->giveEnrichmentItem(i)->isElementEnriched(elem) ) {
110 return true;
111 }
112 }
113#else
114 // An element is enriched if one of its nodes is enriched.
115 for ( int n: elem->giveDofManArray() ) {
116 if ( mNodeEnrichmentItemIndices.size() && mNodeEnrichmentItemIndices [ n - 1 ].size() > 0 ) {
117 return true;
118 }
119 }
120
121#endif
122
123 return false;
124}
125
126void
127XfemManager :: createEnrichedDofs()
128{
129 // Creates new dofs due to enrichment and appends them to the dof managers
130 mXFEMPotentialDofIDs.clear();
131
132 for ( auto &ei: enrichmentItemList ) {
133 IntArray dofIdArray;
134 ei->createEnrichedDofs();
135 ei->givePotentialEIDofIdArray(dofIdArray);
136// printf("dofIdArray: "); dofIdArray.printYourself();
137 mXFEMPotentialDofIDs.followedBy(dofIdArray);
138 }
139}
140
141IntArray XfemManager :: giveEnrichedDofIDs(const DofManager &iDMan) const
142{
143 IntArray dofIdArray;
144
145 for(int id : mXFEMPotentialDofIDs) {
146 if(iDMan.hasDofID( DofIDItem(id) )) {
147 dofIdArray.followedBy(id);
148 }
149 }
150
151 return dofIdArray;
152}
153
154void XfemManager :: initializeFrom(InputRecord &ir)
155{
156 thisIr=ir.clone();
157 // read later in instanciateYourself
158 // IR_GIVE_FIELD(ir, numberOfEnrichmentItems, _IFT_XfemManager_numberOfEnrichmentItems);
159 // IR_GIVE_OPTIONAL_FIELD(ir, numberOfNucleationCriteria, _IFT_XfemManager_numberOfNucleationCriteria);
160// printf("numberOfNucleationCriteria: %d\n", numberOfNucleationCriteria);
161
164
166 //printf("mEnrDofScaleFac: %e\n", mEnrDofScaleFac );
167
169 if ( doVTKExport ) {
170 IntArray exportFields;
172 }
173
174 int vtkDebug = 0;
176 if ( vtkDebug == 1 ) {
177 mDebugVTK = true;
178 }
179
180 // TODO: Read as input.
181 XfemTolerances :: setCharacteristicElementLength(0.001);
182}
183
184
206
207int XfemManager :: instanciateYourself(DataReader &dr)
208{
209 std :: string name;
211 numberOfEnrichmentItems=enrichRecs.size();
213 int i=1;
214 for(InputRecord& mir: enrichRecs){
215 mir.giveRecordKeywordField(name);
216
217 std :: unique_ptr< EnrichmentItem >ei( classFactory.createEnrichmentItem( name.c_str(), i, this, this->giveDomain() ) );
218 if ( ei.get() == NULL ) {
219 OOFEM_ERROR( "unknown enrichment item (%s)", name.c_str() );
220 }
221 DataReader::RecordGuard scope(dr,&mir);
222 ei->initializeFrom(mir);
223 ei->instanciateYourself(dr);
224 this->enrichmentItemList [ i - 1 ] = std :: move(ei);
225 i++;
226 }
227
231 i=1;
232 for(auto& mir: nuclRecs){
233 mir.giveRecordKeywordField(name);
234
235 std :: unique_ptr< NucleationCriterion >nc( classFactory.createNucleationCriterion( name.c_str(), this->giveDomain() ) );
236 if ( nc.get() == NULL ) {
237 OOFEM_ERROR( "Unknown nucleation criterion: (%s)", name.c_str() );
238 }
239
240 DataReader::RecordGuard scope(dr,&mir);
241 nc->initializeFrom(mir);
242 nc->instanciateYourself(dr);
243 this->mNucleationCriteria [ i - 1 ] = std :: move(nc);
244 i++;
245 }
246
247
248
249 return 1;
250}
251
252void XfemManager :: postInitialize()
253{
254 for ( int i = 1; i <= numberOfEnrichmentItems; i++ ) {
255 this->giveEnrichmentItem(i)->postInitialize();
256 }
257
258 for ( int i = 1; i <= numberOfNucleationCriteria; i++ ) {
259 giveNucleationCriterion(i)->postInitialize();
260 }
261
263
264}
265
266
267
268void XfemManager :: setDomain(Domain *ipDomain)
269{
270 domain = ipDomain;
271
272 for ( auto &ei : enrichmentItemList ) {
273 ei->setDomain(ipDomain);
274 }
275}
276
277void XfemManager :: saveContext(DataStream &stream, ContextMode mode)
278{
279 if ( mode & CM_Definition ) {
280 if ( !stream.write(this->numberOfEnrichmentItems) ) {
282 }
283 }
284
285 for ( int i = 1; i <= this->numberOfEnrichmentItems; i++ ) {
286 EnrichmentItem *object = this->giveEnrichmentItem(i);
287 if ( ( mode & CM_Definition ) ) {
288 if ( !stream.write( object->giveInputRecordName() ) ) {
290 }
291 }
292
293 object->saveContext(stream, mode);
294 }
295}
296
297
298void XfemManager :: restoreContext(DataStream &stream, ContextMode mode)
299{
300 if ( mode & CM_Definition ) {
301 if ( !stream.read(this->numberOfEnrichmentItems) ) {
303 }
305 }
306
307 for ( int i = 1; i <= this->numberOfEnrichmentItems; i++ ) {
308 EnrichmentItem *obj;
309 if ( mode & CM_Definition ) {
310 std :: string name;
311 if ( !stream.read(name) ) {
313 }
314
315 std :: unique_ptr< EnrichmentItem >ei( classFactory.createEnrichmentItem(name.c_str(), i, this, this->domain) );
316 obj = ei.get();
317 enrichmentItemList.insert( enrichmentItemList.begin() + i - 1, std :: move(ei) );
318 } else {
319 obj = this->giveEnrichmentItem(i);
320 }
321
322 obj->restoreContext(stream, mode);
323 }
324}
325
326void XfemManager :: updateYourself(TimeStep *tStep)
327{
328 // Update level sets
329 for ( auto &ei: enrichmentItemList ) {
330 ei->updateGeometry();
331 }
332
334}
335
336void XfemManager :: propagateFronts(bool &oAnyFronHasPropagated)
337{
338 oAnyFronHasPropagated = false;
339
340 for ( auto &ei: enrichmentItemList ) {
341
342 bool eiHasPropagated = false;
343 ei->propagateFronts(eiHasPropagated);
344
345 if(eiHasPropagated) {
346 oAnyFronHasPropagated = true;
347 }
348#if 0
349 if ( giveVtkDebug() ) {
350 GeometryBasedEI *geoEI = dynamic_cast< GeometryBasedEI * >( ei );
351 if ( geoEI != NULL ) {
352 std :: vector< FloatArray >points;
353 geoEI->giveSubPolygon(points, -0.1, 1.1);
354
355 std :: vector< double >x, y;
356 for ( size_t j = 0; j < points.size(); j++ ) {
357 x.push_back( points [ j ].at(1) );
358 y.push_back( points [ j ].at(2) );
359 }
360
361
362 char fileName [ 200 ];
363 sprintf( fileName, "crack%d.dat", ei->giveNumber() );
364 XFEMDebugTools :: WriteArrayToGnuplot(fileName, x, y);
365 }
366 }
367#endif
368 }
369
371}
372
373void XfemManager :: initiateFronts(bool &oAnyFronHasPropagated, TimeStep *tStep)
374{
375#ifdef __SM_MODULE
376 oAnyFronHasPropagated = false;
377
378 // Loop over EI:s and collect cross sections which have delaminaion EI:s
379 IntArray CSnumbers;
380 std :: vector < FloatArray > initiationFactors; initiationFactors.resize(this->domain->giveNumberOfCrossSectionModels());
381 for ( auto &ei: enrichmentItemList ) {
382 if ( Delamination *dei = dynamic_cast< Delamination * >( ei.get() ) ) {
383 int CSinterfaceNumber = dei->giveDelamInterfaceNum();
384 for (int CSnumber : dei->giveDelamCrossSectionNum()) {
385 CSnumbers.insertSortedOnce(CSnumber);
386 if (initiationFactors[CSnumber-1].giveSize() < CSinterfaceNumber) {
387 initiationFactors[CSnumber-1].resizeWithValues(CSinterfaceNumber);
388 }
389 initiationFactors[CSnumber-1].at(CSinterfaceNumber) = dei->giveInitiationFactor();
390 }
391 }
392 }
393
394 bool failureChecked = false;
395 std :: vector < IntArray > CSinterfaceNumbers; CSinterfaceNumbers.resize(CSnumbers.giveSize());
396 std :: vector < IntArray > CSDofManNumbers; CSDofManNumbers.resize(CSnumbers.giveSize());
397
398 for ( auto &ei: enrichmentItemList ) {
399
400 bool eiHasPropagated = false;
401
402 if ( Delamination *dei = dynamic_cast< Delamination * >( ei.get() ) ) {
403
404 if ( !failureChecked ) {
405 dei->findInitiationFronts(failureChecked, CSnumbers, CSinterfaceNumbers, CSDofManNumbers, initiationFactors, tStep);
406 }
407
408 for (int CSnum : dei->giveDelamCrossSectionNum()) {
409
410 int iCS = CSnumbers.findSorted(CSnum);
411 int iInt = CSinterfaceNumbers[iCS-1].findSorted(dei->giveDelamInterfaceNum());
412 if ( iInt ) {
413 // Check if nodes are viable for enrichment
415 IntArray delamNodes, propNodes;
416 Set *elSet = this->giveDomain()->giveSet(this->giveDomain()->giveCrossSection(CSnum)->giveSetNumber());
417 for (int elID : elSet->giveElementList() ) {
418 delamNodes.followedBy(this->giveDomain()->giveElement(elID)->giveDofManArray());
419 }
420 delamNodes.sort();
421 delamNodes.findCommonValuesSorted(CSDofManNumbers[iCS-1], propNodes);
422 dei->initiateFronts(eiHasPropagated,propNodes);
423 }
424 }
425 } else {
426 OOFEM_ERROR(" XfemManager :: initiateFronts not implemented for other than Delamination.")
427 }
428 if(eiHasPropagated) {
429 oAnyFronHasPropagated = true;
430 }
431 }
433
434#else
435 OOFEM_ERROR(" XfemManager :: initiateFronts not implemented for other than Delamination.")
436#endif
437
438
439}
440
441bool XfemManager :: hasPropagatingFronts()
442{
443 for ( auto &ei: enrichmentItemList ) {
444 if ( ei->hasPropagatingFronts() ) {
445 return true;
446 }
447 }
448
449 return false;
450}
451
452bool XfemManager :: hasInitiationCriteria()
453{
454 for ( auto &ei: enrichmentItemList ) {
455 if ( ei->hasInitiationCriteria() ) {
456 return true;
457 }
458 }
459
460 return false;
461}
462
463void XfemManager :: clearEnrichmentItems()
464{
465 enrichmentItemList.clear();
467}
468
469void XfemManager :: appendEnrichmentItems(std :: vector< std :: unique_ptr< EnrichmentItem > > &iEIlist)
470{
471 for( auto &ei : iEIlist ) {
472 enrichmentItemList.push_back(std::move(ei));
473 }
474
477}
478
479void XfemManager :: nucleateEnrichmentItems(bool &oNewItemsWereNucleated)
480{
481// printf("Entering XfemManager :: nucleateEnrichmentItems\n");
482
483 for(auto &nucCrit : mNucleationCriteria) {
484 //std::vector<std::unique_ptr<EnrichmentItem>> eiList = std::move(nucCrit->nucleateEnrichmentItems());
485 std::vector<std::unique_ptr<EnrichmentItem>> eiList = nucCrit->nucleateEnrichmentItems();
486
487 if(eiList.size() > 0) {
488// printf("eiList.size(): %lu\n", eiList.size() );
489
490// if(giveNumberOfEnrichmentItems() == 0) {
491// printf("giveNumberOfEnrichmentItems() == 0\n");
492
493 for(auto &ei : eiList) {
494 enrichmentItemList.push_back(std::move(ei));
495 }
496
497 // enrichmentItemList.push_back(std::move(ei));
499 oNewItemsWereNucleated = true;
501
502 return;
503// }
504 }
505 }
506
507 oNewItemsWereNucleated = false;
508 return;
509}
510
511bool XfemManager :: hasNucleationCriteria()
512{
513 return ( mNucleationCriteria.size() > 0 );
514}
515
516void XfemManager :: updateNodeEnrichmentItemMap()
517{
519 int nDMan = domain->giveNumberOfDofManagers();
521 mNodeEnrichmentItemIndices.resize(nDMan);
522
523 int nElem = domain->giveNumberOfElements();
525
526 for ( int i = 1; i <= nElem; i++ ) {
527 int elIndex = domain->giveElement(i)->giveGlobalNumber();
528 int elPlaceInArray = domain->giveElementPlaceInArray(elIndex);
529 if ( i != elPlaceInArray ) {
530 printf("i != elPlaceInArray.\n");
531 exit(0);
532 }
533 mElementEnrichmentItemIndices [ elPlaceInArray ].clear();
534 }
535
536 int nEI = giveNumberOfEnrichmentItems();
537
538 for ( int eiIndex = 1; eiIndex <= nEI; eiIndex++ ) {
539 EnrichmentItem *ei = giveEnrichmentItem(eiIndex);
540
541 const std :: unordered_map< int, NodeEnrichmentType > &enrNodeInd = ei->giveEnrNodeMap();
542
543 //for(size_t i = 0; i < enrNodeInd.size(); i++) {
544 for ( auto &nodeEiPair: enrNodeInd ) {
545 mNodeEnrichmentItemIndices [ nodeEiPair.first - 1 ].push_back(eiIndex);
546
547 ConnectivityTable *ct = domain->giveConnectivityTable();
548 //const IntArray *nodeElements = ct->giveDofManConnectivityArray(nodeEiPair.first);
549 IntArray nodeElements;
550 IntArray nodeList = {
551 nodeEiPair.first
552 };
553 ct->giveNodeNeighbourList(nodeElements, nodeList);
554
555 for ( int i = 1; i <= nodeElements.giveSize(); i++ ) {
556 int elInd = nodeElements.at(i);
557
558 bool found = false;
559 for ( size_t j = 0; j < mElementEnrichmentItemIndices [ elInd ].size(); j++ ) {
560 if ( mElementEnrichmentItemIndices [ elInd ] [ j ] == eiIndex ) {
561 found = true;
562 break;
563 }
564 }
565
566 if ( !found ) {
567 mElementEnrichmentItemIndices [ elInd ].push_back(eiIndex);
568 }
569 }
570 }
571 }
572
573
574
575
577 for ( int eiIndex = 1; eiIndex <= nEI; eiIndex++ ) {
578 EnrichmentItem *ei = giveEnrichmentItem(eiIndex);
579
580 if ( ei->canModifyMaterial() ) {
581 mMaterialModifyingEnrItemIndices.push_back(eiIndex);
582 }
583 }
584}
585
586void XfemManager :: giveElementEnrichmentItemIndices(std :: vector< int > &oElemEnrInd, int iElementIndex) const
587{
588 auto res = mElementEnrichmentItemIndices.find(iElementIndex);
589 if ( res != mElementEnrichmentItemIndices.end() ) {
590 oElemEnrInd = res->second;
591 }
592}
593} // end namespace oofem
#define REGISTER_XfemManager(class)
void giveNodeNeighbourList(IntArray &answer, IntArray &nodeList)
Internal range-like class, return type for giveGroupRecords methods.
Definition datareader.h:137
RAII guard for DataReader::enterRecord and DataReader::leaveRecord.
Definition datareader.h:128
GroupRecords giveGroupRecords(const std::shared_ptr< InputRecord > &ir, InputFieldType ift, const std::string &name, InputRecordType irType, bool optional)
Definition datareader.C:46
virtual int read(int *data, std::size_t count)=0
Reads count integer values into array pointed by data.
virtual int write(const int *data, std::size_t count)=0
Writes count integer values from array pointed by data.
bool hasDofID(DofIDItem id) const
Definition dofmanager.C:174
void clear()
Clear receiver.
Definition domain.C:129
void setRecordKeywordField(std ::string keyword, int number)
void setField(int item, InputFieldType id)
const IntArray & giveDofManArray() const
Definition element.h:611
const std ::unordered_map< int, NodeEnrichmentType > & giveEnrNodeMap() const
virtual bool canModifyMaterial() const
virtual const char * giveInputRecordName() const =0
virtual void restoreContext(DataStream &stream, ContextMode mode)
Definition femcmpnn.C:62
void giveSubPolygon(std ::vector< FloatArray > &oPoints, const double &iXiStart, const double &iXiEnd) const
virtual std::shared_ptr< InputRecord > clone() const =0
bool insertSortedOnce(int value, int allocChunk=0)
Definition intarray.C:309
void followedBy(const IntArray &b, int allocChunk=0)
Definition intarray.C:94
int findCommonValuesSorted(const IntArray &iarray, IntArray &common, int allocChunk=0) const
Definition intarray.C:332
void resize(int n)
Definition intarray.C:73
int findSorted(int value) const
Definition intarray.C:293
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
const IntArray & giveElementList()
Definition set.C:158
bool isElementEnriched(const Element *elem)
bool giveVtkDebug() const
std ::vector< int > mMaterialModifyingEnrItemIndices
std ::vector< std ::vector< int > > mNodeEnrichmentItemIndices
IntArray vtkExportFields
std ::vector< std ::unique_ptr< EnrichmentItem > > enrichmentItemList
Enrichment item list.
Domain * giveDomain()
IntArray mXFEMPotentialDofIDs
std ::unordered_map< int, std ::vector< int > > mElementEnrichmentItemIndices
int giveNumberOfNucleationCriteria() const
EnrichmentItem * giveEnrichmentItem(int n)
std::shared_ptr< InputRecord > thisIr
std::vector< std ::unique_ptr< NucleationCriterion > > mNucleationCriteria
NucleationCriterion * giveNucleationCriterion(int n)
virtual const char * giveInputRecordName() const
bool mDebugVTK
If extra debug vtk files should be written.
void updateNodeEnrichmentItemMap()
int giveNumberOfEnrichmentItems() const
#define THROW_CIOERR(e)
#define CM_Definition
Definition contextmode.h:47
#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
long ContextMode
Definition contextmode.h:43
XFEMStateType
Definition xfemmanager.h:92
InternalStateValueType
Determines the type of internal variable.
@ ISVT_SCALAR
Scalar.
@ ISVT_UNDEFINED
Undefined.
ClassFactory & classFactory
@ CIO_IOERR
General IO error.
#define _IFT_XfemManager_numberOfEnrichmentItems
Definition xfemmanager.h:55
#define _IFT_XfemManager_numberOfGpPerTri
Definition xfemmanager.h:57
#define _IFT_XfemManager_debugVTK
Definition xfemmanager.h:64
#define _IFT_XfemManager_numberOfNucleationCriteria
Definition xfemmanager.h:56
#define _IFT_XfemManager_VTKExport
Definition xfemmanager.h:65
#define _IFT_XfemManager_VTKExportFields
Definition xfemmanager.h:66
#define _IFT_XfemManager_enrDofScaleFac
Definition xfemmanager.h:62
#define _IFT_XfemManager_numberOfTriRefs
How many times a subtriangle should be refined.
Definition xfemmanager.h:60

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