https://mooseframework.inl.gov
MeshCut2DNucleationBase.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 #include "XFEMAppTypes.h"
12 #include "XFEM.h"
13 
14 #include "MooseMesh.h"
15 
16 #include "libmesh/parallel_algebra.h"
17 #include "libmesh/parallel.h"
18 
21 {
23  params.addParam<std::vector<BoundaryName>>(
24  "initiate_on_boundary",
25  "Cracks can only initiate on elements adjacent to specified boundaries.");
26  params.addParam<Real>("nucleation_radius",
27  0,
28  "Cracks will only nucleate if they are outside the nucleation_radius of an "
29  "existing crack.");
30  // Make this userobject execute before every other standard UO including meshCutterUO
31  params.setDocString(
32  "execution_order_group",
33  "Nucleation UO needs to be completely executed before GeometricCutUserObject.");
34  params.set<int>("execution_order_group") = -1;
35 
36  ExecFlagEnum & exec = params.set<ExecFlagEnum>("execute_on");
38  params.setDocString("execute_on", exec.getDocString());
39  params.set<ExecFlagEnum>("execute_on") = EXEC_XFEM_MARK;
40  return params;
41 }
42 
44  : ElementUserObject(parameters),
45  _mesh(_subproblem.mesh()),
46  _nucleation_radius(getParam<Real>("nucleation_radius"))
47 {
48  FEProblemBase * fe_problem = dynamic_cast<FEProblemBase *>(&_subproblem);
49  if (fe_problem == NULL)
50  paramError("Problem casting _subproblem to FEProblemBase in MeshCut2DNucleationBase");
51  _xfem = MooseSharedNamespace::dynamic_pointer_cast<XFEM>(fe_problem->getXFEM());
52  if (_xfem == nullptr)
53  paramError("Problem casting to XFEM in MeshCut2DNucleationBase");
54 
55  if (isParamValid("initiate_on_boundary"))
56  {
57  std::vector<BoundaryName> initiation_boundary_names =
58  getParam<std::vector<BoundaryName>>("initiate_on_boundary");
59  _initiation_boundary_ids = _mesh.getBoundaryIDs(initiation_boundary_names);
60  }
61 }
62 
63 void
65 {
66  _nucleated_elems.clear();
67 }
68 
69 void
71 {
72  std::pair<RealVectorValue, RealVectorValue> cutterElemNodes;
73  bool is_cut = _xfem->isElemCut(_current_elem);
74  if (_current_elem->processor_id() != processor_id())
75  return;
76 
77  unsigned int current_eid = _current_elem->id();
78  std::map<unsigned int, std::pair<RealVectorValue, RealVectorValue>>::iterator mit;
79  mit = _nucleated_elems.find(current_eid);
80 
81  bool cut_element = false;
82  if (_initiation_boundary_ids.empty())
83  {
84  // nucleating crack in bulk
85  // This does not currently allow for nucleation in an element that is already cut
86  cut_element = (!is_cut && doesElementCrack(cutterElemNodes));
87  }
88  else
89  {
90  // nucleating crack on specified boundary
91  bool isOnBoundary = false;
92  for (unsigned int i = 0; i < _initiation_boundary_ids.size(); ++i)
93  if (_mesh.isBoundaryElem(current_eid, _initiation_boundary_ids[i]))
94  {
95  isOnBoundary = true;
96  break;
97  }
98  // This does not currently allow for nucleation in an element that is already cut
99  cut_element = (!is_cut && isOnBoundary && doesElementCrack(cutterElemNodes));
100  }
101 
102  if (cut_element)
103  {
104  if (mit != _nucleated_elems.end())
105  mooseError("ERROR: element ", current_eid, " already marked for crack nucleation.");
106 
107  _nucleated_elems[current_eid] = cutterElemNodes;
108  }
109 }
110 
111 void
113 {
114  const auto & xmuo = static_cast<const MeshCut2DNucleationBase &>(y);
115  for (std::map<unsigned int, std::pair<RealVectorValue, RealVectorValue>>::const_iterator mit =
116  xmuo._nucleated_elems.begin();
117  mit != xmuo._nucleated_elems.end();
118  ++mit)
119  {
120  _nucleated_elems[mit->first] = mit->second; // TODO do error checking for duplicates here too
121  }
122 }
123 
124 void
126 {
128  // _nucleated_elems is not cleared here because it needs to be available to the mesh cutter
129 }
virtual void threadJoin(const UserObject &y) override
MeshCut2DNucleationBase(const InputParameters &parameters)
virtual bool doesElementCrack(std::pair< RealVectorValue, RealVectorValue > &cutterElemNodes)=0
Determine whether the current element should be cut by a new crack.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void setDocString(const std::string &name, const std::string &doc)
static InputParameters validParams()
MooseMesh & _mesh
The FE solution mesh.
T & set(const std::string &name, bool quiet_mode=false)
MeshBase & mesh
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
const std::vector< double > y
const Parallel::Communicator & _communicator
This is the XFEM class.
Definition: XFEM.h:107
std::shared_ptr< XFEM > _xfem
shared pointer to XFEM
SubProblem & _subproblem
bool isParamValid(const std::string &name) const
virtual void initialize() override
void paramError(const std::string &param, Args... args) const
std::map< unsigned int, std::pair< RealVectorValue, RealVectorValue > > _nucleated_elems
const ExecFlagType EXEC_XFEM_MARK
Exec flag used to execute MooseObjects while elements are being marked for cutting by XFEM...
Definition: XFEMAppTypes.C:13
virtual void finalize() override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Elem *const & _current_elem
std::shared_ptr< XFEMInterface > getXFEM()
virtual void execute() override
void mooseError(Args &&... args) const
std::vector< BoundaryID > getBoundaryIDs(const Elem *const elem, const unsigned short int side) const
static InputParameters validParams()
bool isBoundaryElem(dof_id_type elem_id) const
processor_id_type processor_id() const
std::vector< BoundaryID > _initiation_boundary_ids
void set_union(T &data, const unsigned int root_id) const