https://mooseframework.inl.gov
XFEMMaterialStateMarkerBase.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
11 
12 #include "XFEM.h"
13 #include "MooseMesh.h"
14 
15 #include "libmesh/parallel_algebra.h"
16 #include "libmesh/parallel.h"
17 
20 {
22  params.addParam<std::vector<BoundaryName>>(
23  "initiate_on_boundary",
24  "Permit cracks to initiate in elements adjacent to specified boundaries");
25  params.addParam<bool>("secondary_cracks", false, "should secondary cracks be allowed");
26  return params;
27 }
28 
30  : ElementUserObject(parameters),
31  _mesh(_subproblem.mesh()),
32  _secondary_cracks(getParam<bool>("secondary_cracks"))
33 {
34  FEProblemBase * fe_problem = dynamic_cast<FEProblemBase *>(&_subproblem);
35  if (fe_problem == nullptr)
36  mooseError("Problem casting _subproblem to FEProblemBase in XFEMMaterialStateMarkerBase");
37  _xfem = MooseSharedNamespace::dynamic_pointer_cast<XFEM>(fe_problem->getXFEM());
38  if (_xfem == nullptr)
39  mooseError("Problem casting to XFEM in XFEMMaterialStateMarkerBase");
40  if (isNodal())
41  mooseError("XFEMMaterialStateMarkerBase can only be run on an element variable");
42 
43  if (isParamValid("initiate_on_boundary"))
44  {
45  std::vector<BoundaryName> initiation_boundary_names =
46  getParam<std::vector<BoundaryName>>("initiate_on_boundary");
47  _initiation_boundary_ids = _mesh.getBoundaryIDs(initiation_boundary_names, true);
48  }
49 }
50 
51 void
53 {
54  _marked_elems.clear();
56  .clear(); // mark the fragment which has secondary crack growing from the primary crack
57  _marked_elem_sides.clear();
58 }
59 
60 void
62 {
63  RealVectorValue direction;
64  bool isCut = _xfem->isElemCut(_current_elem);
65  bool isCTE = _xfem->isElemAtCrackTip(_current_elem);
66  bool isOnBoundary = false;
67  unsigned int boundarySide = 99999;
68  unsigned int _current_eid = _current_elem->id();
69  std::map<unsigned int, RealVectorValue>::iterator mit;
70  mit = _marked_elems.find(_current_eid);
71 
72  for (unsigned int i = 0; i < _initiation_boundary_ids.size(); ++i)
73  {
74  if (_mesh.isBoundaryElem(_current_eid, _initiation_boundary_ids[i]))
75  {
76  isOnBoundary = true;
78  }
79  }
80 
81  if (isCTE && doesElementCrack(direction))
82  {
83  if (mit != _marked_elems.end())
84  {
85  mooseError("ERROR: element ", _current_eid, " already marked for crack growth.");
86  }
87  _marked_elems[_current_eid] = direction;
88  }
89  else if (isOnBoundary && doesElementCrack(direction))
90  {
91  if (mit != _marked_elems.end())
92  {
93  mooseError("ERROR: element ", _current_eid, " already marked for crack growth.");
94  }
95  _marked_elems[_current_eid] = direction;
96  _marked_elem_sides[_current_eid] = boundarySide;
97  }
98  else if (isCut && _secondary_cracks && doesElementCrack(direction))
99  {
100  if (mit != _marked_elems.end())
101  {
102  mooseError("ERROR: element ", _current_eid, " already marked for crack growth.");
103  }
104  _marked_elems[_current_eid] = direction;
105  _marked_frags.insert(_current_eid);
106  }
107 }
108 
109 void
111 {
112  const auto & xmuo = dynamic_cast<const XFEMMaterialStateMarkerBase &>(y);
113 
114  for (std::map<unsigned int, RealVectorValue>::const_iterator mit = xmuo._marked_elems.begin();
115  mit != xmuo._marked_elems.end();
116  ++mit)
117  {
118  _marked_elems[mit->first] = mit->second; // TODO do error checking for duplicates here too
119  }
120 
121  for (std::set<unsigned int>::const_iterator mit = xmuo._marked_frags.begin();
122  mit != xmuo._marked_frags.end();
123  ++mit)
124  {
125  _marked_frags.insert(*mit); // TODO do error checking for duplicates here too
126  }
127 
128  for (std::map<unsigned int, unsigned int>::const_iterator mit = xmuo._marked_elem_sides.begin();
129  mit != xmuo._marked_elem_sides.end();
130  ++mit)
131  {
132  _marked_elem_sides[mit->first] = mit->second; // TODO do error checking for duplicates here too
133  }
134 }
135 
136 void
138 {
142 
143  _xfem->clearStateMarkedElems();
144  std::map<unsigned int, RealVectorValue>::iterator mit;
145  for (mit = _marked_elems.begin(); mit != _marked_elems.end(); ++mit)
146  {
147  if (_marked_elem_sides.find(mit->first) != _marked_elem_sides.end())
148  {
149  _xfem->addStateMarkedElem(mit->first, mit->second, _marked_elem_sides[mit->first]);
150  }
151  else if (_marked_frags.find(mit->first) != _marked_frags.end())
152  {
153  _xfem->addStateMarkedFrag(mit->first, mit->second);
154  }
155  else
156  {
157  _xfem->addStateMarkedElem(mit->first, mit->second);
158  }
159  }
160  _marked_elems.clear();
161  _marked_frags.clear();
162  _marked_elem_sides.clear();
163 }
164 
165 bool
167 {
168  direction(1) = 1.0;
169  return true;
170 }
static InputParameters validParams()
Factory constructor, takes parameters so that all derived classes can be built using the same constru...
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
static InputParameters validParams()
MeshBase & mesh
const std::vector< double > y
const Parallel::Communicator & _communicator
XFEMMaterialStateMarkerBase(const InputParameters &parameters)
This is the XFEM class.
Definition: XFEM.h:107
SubProblem & _subproblem
bool isParamValid(const std::string &name) const
std::map< unsigned int, unsigned int > _marked_elem_sides
std::vector< BoundaryID > _initiation_boundary_ids
unsigned int sideWithBoundaryID(const Elem *const elem, const BoundaryID boundary_id) const
virtual void threadJoin(const UserObject &y) override
std::set< unsigned int > _marked_frags
bool isNodal() const
const Elem *const & _current_elem
std::shared_ptr< XFEMInterface > getXFEM()
void mooseError(Args &&... args) const
std::map< unsigned int, RealVectorValue > _marked_elems
virtual bool doesElementCrack(RealVectorValue &direction)
Determine whether the current element should be cut by a new crack.
std::vector< BoundaryID > getBoundaryIDs(const Elem *const elem, const unsigned short int side) const
bool isBoundaryElem(dof_id_type elem_id) const
void set_union(T &data, const unsigned int root_id) const