https://mooseframework.inl.gov
InterfaceMeshCutUserObjectBase.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 
12 
15 {
17  params.addRequiredParam<MeshFileName>("mesh_file", "Mesh file for the XFEM geometric cut.");
18  params.addParam<UserObjectName>("interface_velocity_uo",
19  "The name of userobject that computes the velocity.");
20  params.addParam<FunctionName>("interface_velocity_function",
21  "The name of function that provides interface velocity.");
22  params.addParam<bool>("output_exodus", true, "Whether to output exodus file of cutter mesh.");
23  params.addParam<CutSubdomainID>(
24  "negative_id", 0, "The CutSubdomainID corresponding to a non-positive signed distance");
25  params.addParam<CutSubdomainID>(
26  "positive_id", 1, "The CutSubdomainID corresponding to a positive signed distance");
27  return params;
28 }
29 
31  : GeometricCutUserObject(parameters),
32  _interface_velocity(nullptr),
33  _func(nullptr),
34  _mesh(_subproblem.mesh()),
35  _exodus_io(nullptr),
36  _explicit_system(nullptr),
37  _equation_systems(nullptr),
38  _output_exodus(getParam<bool>("output_exodus")),
39  _negative_id(getParam<CutSubdomainID>("negative_id")),
40  _positive_id(getParam<CutSubdomainID>("positive_id"))
41 {
42  MeshFileName xfem_cutter_mesh_file = getParam<MeshFileName>("mesh_file");
43  _cutter_mesh = std::make_shared<ReplicatedMesh>(_communicator);
44  _cutter_mesh->read(xfem_cutter_mesh_file);
45  _exodus_io = std::make_unique<ExodusII_IO>(*_cutter_mesh);
46 
47  if (!parameters.isParamSetByUser("interface_velocity_uo") &&
48  !parameters.isParamSetByUser("interface_velocity_function"))
49  paramError("Either `interface_velocity_uo` or `interface_velocity_function` must be provided.");
50  else if (parameters.isParamSetByUser("interface_velocity_uo") &&
51  parameters.isParamSetByUser("interface_velocity_function"))
52  paramError(
53  "'interface_velocity_uo` and `interface_velocity_function` cannot be both provided.");
54 
55  if (parameters.isParamSetByUser("interface_velocity_function"))
56  _func = &getFunction("interface_velocity_function");
57 }
58 
59 void
61 {
62  if (_func == nullptr)
63  {
64  const UserObject * uo =
65  &(_fe_problem.getUserObjectBase(getParam<UserObjectName>("interface_velocity_uo")));
66 
67  if (dynamic_cast<const XFEMMovingInterfaceVelocityBase *>(uo) == nullptr)
68  mooseError("UserObject casting to XFEMMovingInterfaceVelocityBase in "
69  "MovingLineSegmentCutSetUserObject");
70 
71  _interface_velocity = dynamic_cast<const XFEMMovingInterfaceVelocityBase *>(uo);
73  }
74 
75  for (const auto & node : _cutter_mesh->node_ptr_range())
76  _initial_nodes_location[node->id()] = *node;
77 
78  for (const auto & elem : _cutter_mesh->element_ptr_range())
79  for (unsigned int n = 0; n < elem->n_nodes(); n++)
80  _node_to_elem_map[elem->node_id(n)].push_back(elem->id());
81 
82  _cutter_mesh->prepare_for_use();
83  _cutter_mesh->set_mesh_dimension(_mesh.dimension() - 1);
84 
85  if (_output_exodus)
86  {
87  _equation_systems = std::make_unique<EquationSystems>(*_cutter_mesh);
88  _explicit_system = &(_equation_systems->add_system<ExplicitSystem>("InterfaceMeshSystem"));
89 
90  _explicit_system->add_variable("disp_x");
91  _explicit_system->add_variable("disp_y");
92 
93  if (_mesh.dimension() == 3)
94  _explicit_system->add_variable("disp_z");
95 
96  _equation_systems->init();
97  _exodus_io->write_equation_systems(_app.getOutputFileBase() + "_" + name() + ".e",
99 
100  _var_num_disp_x = _explicit_system->variable_number("disp_x");
101  _var_num_disp_y = _explicit_system->variable_number("disp_y");
102  if (_mesh.dimension() == 3)
103  _var_num_disp_z = _explicit_system->variable_number("disp_z");
104  }
105 }
106 
107 void
109 {
110  std::vector<Point> new_position(_cutter_mesh->n_nodes());
111 
113  _pl->enable_out_of_mesh_mode();
114 
115  std::map<unsigned int, Real> node_velocity;
116  Real sum = 0.0;
117  unsigned count = 0;
118  // Loop all the nodes to calculate the velocity
119  for (const auto & node : _cutter_mesh->node_ptr_range())
120  {
121  if ((*_pl)(*node) != nullptr)
122  {
123  Real velocity;
124  if (_func == nullptr)
125  velocity =
127  else
128  velocity = _func->value(_t, *node);
129 
130  // only updates when t_step >0
131  if (_t_step <= 0)
132  velocity = 0.0;
133 
134  node_velocity[node->id()] = velocity;
135  sum += velocity;
136  count++;
137  }
138  }
139 
140  if (count == 0)
141  mooseError("No node of the cutter mesh is found inside the computational domain.");
142 
143  Real average_velocity = sum / count;
144 
145  for (const auto & node : _cutter_mesh->node_ptr_range())
146  {
147  if ((*_pl)(*node) == nullptr)
148  node_velocity[node->id()] = average_velocity;
149  }
150 
151  for (const auto & node : _cutter_mesh->node_ptr_range())
152  {
153  Point p = *node;
154  p += _dt * nodeNormal(node->id()) * node_velocity[node->id()];
155  new_position[node->id()] = p;
156  }
157  for (const auto & node : _cutter_mesh->node_ptr_range())
158  _cutter_mesh->node_ref(node->id()) = new_position[node->id()];
159 
160  if (_output_exodus)
161  {
162  std::vector<dof_id_type> di;
163  for (const auto & node : _cutter_mesh->node_ptr_range())
164  {
165  _explicit_system->get_dof_map().dof_indices(node, di, _var_num_disp_x);
166  _explicit_system->solution->set(
167  di[0], new_position[node->id()](0) - _initial_nodes_location[node->id()](0));
168 
169  _explicit_system->get_dof_map().dof_indices(node, di, _var_num_disp_y);
170  _explicit_system->solution->set(
171  di[0], new_position[node->id()](1) - _initial_nodes_location[node->id()](1));
172 
173  if (_mesh.dimension() == 3)
174  {
175  _explicit_system->get_dof_map().dof_indices(node, di, _var_num_disp_z);
176  _explicit_system->solution->set(
177  di[0], new_position[node->id()](2) - _initial_nodes_location[node->id()](2));
178  }
179  }
180 
181  _explicit_system->solution->close();
182 
183  _exodus_io->append(true);
184  _exodus_io->write_timestep(
185  _app.getOutputFileBase() + "_" + name() + ".e", *_equation_systems, _t_step + 1, _t);
186  }
187 
189 }
190 
191 const std::vector<Point>
192 InterfaceMeshCutUserObjectBase::getCrackFrontPoints(unsigned int /*num_crack_front_points*/) const
193 {
194  mooseError("getCrackFrontPoints() is not implemented for this object.");
195 }
196 
197 const std::vector<RealVectorValue>
198 InterfaceMeshCutUserObjectBase::getCrackPlaneNormals(unsigned int /*num_crack_front_points*/) const
199 {
200  mooseError("getCrackPlaneNormals() is not implemented for this object.");
201 }
202 
205 {
206  return calculateSignedDistance(*node) > 0.0 ? _positive_id : _negative_id;
207 }
std::unique_ptr< ExodusII_IO > _exodus_io
Exodus for outputing points and values.
static InputParameters validParams()
Factory constructor, takes parameters so that all derived classes can be built using the same constru...
virtual void calculateNormals()=0
calculate the element normal values for all of the elements.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
InterfaceMeshCutUserObjectBase(const InputParameters &parameters)
const Function & getFunction(const std::string &name) const
std::string getOutputFileBase(bool for_non_moose_build_output=false) const
const XFEMMovingInterfaceVelocityBase * _interface_velocity
Pointer to XFEMMovingInterfaceVelocityBase object.
MeshBase & mesh
std::unordered_map< dof_id_type, Point > _initial_nodes_location
initial nodes location
const CutSubdomainID _negative_id
The CutSubdomainID for the negative side of the cut.
const Parallel::Communicator & _communicator
virtual const std::string & name() const
void addRequiredParam(const std::string &name, const std::string &doc_string)
unsigned int CutSubdomainID
Definition: XFEMAppTypes.h:18
virtual Real computeMovingInterfaceVelocity(dof_id_type node_id, RealVectorValue normal) const =0
Compute the interface velocity for a node.
const Function * _func
Velocity function.
virtual Point nodeNormal(const unsigned int &node_id)=0
return the normal at a node in the cutting mesh
virtual unsigned int dimension() const
unsigned int _var_num_disp_x
Local variable number for displacement x.
virtual const std::vector< RealVectorValue > getCrackPlaneNormals(unsigned int num_crack_front_points) const override
get a set of normal vectors along a crack front from a XFEM GeometricCutUserObject ...
unsigned int _var_num_disp_y
Local variable number for displacement y.
virtual Real calculateSignedDistance(Point p) const =0
Calculate the signed distance for a given point relative to the surface.
void paramError(const std::string &param, Args... args) const
MooseMesh & _mesh
The computation domain mesh.
std::shared_ptr< MeshBase > _cutter_mesh
The cutter mesh.
unsigned int _var_num_disp_z
Local variable number for displacement z.
const bool _output_exodus
Output exodus file.
bool isParamSetByUser(const std::string &name) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::unique_ptr< EquationSystems > _equation_systems
Local equation system for exodus output.
FEProblemBase & _fe_problem
void mooseError(Args &&... args) const
const InputParameters & parameters() const
static const std::string velocity
Definition: NS.h:45
ExplicitSystem * _explicit_system
Local explicit system for exodus output.
virtual const std::vector< Point > getCrackFrontPoints(unsigned int num_crack_front_points) const override
get a set of points along a crack front from a XFEM GeometricCutUserObject
virtual std::unique_ptr< libMesh::PointLocatorBase > getPointLocator() const
const UserObject & getUserObjectBase(const std::string &name, const THREAD_ID tid=0) const
virtual Real value(Real t, const Point &p) const
virtual CutSubdomainID getCutSubdomainID(const Node *node) const override
std::unordered_map< dof_id_type, std::vector< dof_id_type > > _node_to_elem_map
node to element map of cut mesh
std::unique_ptr< PointLocatorBase > _pl
Pointer to PointLocatorBase object.
const CutSubdomainID _positive_id
The CutSubdomainID for the positive side of the cut.