https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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.");
24 "negative_id", 0, "The CutSubdomainID corresponding to a non-positive signed distance");
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"))
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
59void
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
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
107void
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
191const std::vector<Point>
192InterfaceMeshCutUserObjectBase::getCrackFrontPoints(unsigned int /*num_crack_front_points*/) const
193{
194 mooseError("getCrackFrontPoints() is not implemented for this object.");
195}
196
197const std::vector<RealVectorValue>
198InterfaceMeshCutUserObjectBase::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}
const Real p
unsigned int count
unsigned int CutSubdomainID
const UserObject & getUserObjectBase(const std::string &name, const THREAD_ID tid=0) const
const Function & getFunction(const std::string &name) const
virtual Real value(Real t, const Point &p) const
static InputParameters validParams()
Factory constructor, takes parameters so that all derived classes can be built using the same constru...
bool isParamSetByUser(const std::string &name) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
std::unique_ptr< EquationSystems > _equation_systems
Local equation system for exodus output.
InterfaceMeshCutUserObjectBase(const InputParameters &parameters)
std::unordered_map< dof_id_type, Point > _initial_nodes_location
initial nodes location
std::unordered_map< dof_id_type, std::vector< dof_id_type > > _node_to_elem_map
node to element map of cut mesh
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
const CutSubdomainID _positive_id
The CutSubdomainID for the positive side of the cut.
MooseMesh & _mesh
The computation domain mesh.
virtual void calculateNormals()=0
calculate the element normal values for all of the elements.
const CutSubdomainID _negative_id
The CutSubdomainID for the negative side of the cut.
const bool _output_exodus
Output exodus file.
virtual Real calculateSignedDistance(Point p) const =0
Calculate the signed distance for a given point relative to the surface.
ExplicitSystem * _explicit_system
Local explicit system for exodus output.
std::shared_ptr< MeshBase > _cutter_mesh
The cutter mesh.
std::unique_ptr< ExodusII_IO > _exodus_io
Exodus for outputing points and values.
const Function * _func
Velocity function.
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_x
Local variable number for displacement x.
virtual CutSubdomainID getCutSubdomainID(const Node *node) const override
unsigned int _var_num_disp_y
Local variable number for displacement y.
const XFEMMovingInterfaceVelocityBase * _interface_velocity
Pointer to XFEMMovingInterfaceVelocityBase object.
unsigned int _var_num_disp_z
Local variable number for displacement z.
virtual Point nodeNormal(const unsigned int &node_id)=0
return the normal at a node in the cutting mesh
std::unique_ptr< PointLocatorBase > _pl
Pointer to PointLocatorBase object.
std::string getOutputFileBase(bool for_non_moose_build_output=false) const
const InputParameters & parameters() const
const std::string & name() const
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
virtual unsigned int dimension() const
virtual std::unique_ptr< libMesh::PointLocatorBase > getPointLocator() const
FEProblemBase & _fe_problem
virtual Real computeMovingInterfaceVelocity(dof_id_type node_id, RealVectorValue normal) const =0
Compute the interface velocity for a node.
const Parallel::Communicator & _communicator
MeshBase & mesh