https://mooseframework.inl.gov
NodeValueAtXFEMInterface.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 "MooseVariableFE.h"
12 #include "XFEM.h"
14 #include "libmesh/parallel_algebra.h"
15 #include "libmesh/parallel.h"
16 
18 
21 {
23  params.addRequiredParam<VariableName>(
24  "variable", "The name of the variable that this UserObject operates on");
25  params.addParam<UserObjectName>(
26  "interface_mesh_cut_userobject",
27  "Name of InterfaceMeshCutUserObject that provides cut locations to this UserObject.");
28  params.addRequiredParam<VariableName>(
29  "level_set_var", "The name of level set variable used to represent the interface");
30  params.addClassDescription("Obtain field values and gradients on the interface.");
31  return params;
32 }
33 
35  : GeneralUserObject(parameters),
36  _mesh(_subproblem.mesh()),
37  _var(&_subproblem.getVariable(_tid, parameters.get<VariableName>("variable"))),
38  _level_set_var_number(
39  _subproblem.getVariable(_tid, parameters.get<VariableName>("level_set_var")).number()),
40  _system(_subproblem.getSystem(getParam<VariableName>("level_set_var"))),
41  _solution(*_system.current_local_solution.get())
42 {
43 }
44 
45 void
47 {
49  _xfem = MooseSharedNamespace::dynamic_pointer_cast<XFEM>(_fe_problem.getXFEM());
50  if (_xfem == nullptr)
51  mooseError("Problem casting to XFEM in NodeValueAtXFEMInterface");
52 
53  const UserObject * uo =
54  &(_fe_problem.getUserObjectBase(getParam<UserObjectName>("interface_mesh_cut_userobject")));
55 
56  if (dynamic_cast<const InterfaceMeshCutUserObjectBase *>(uo) == nullptr)
57  mooseError("UserObject casting to InterfaceMeshCutUserObjectBase in NodeValueAtXFEMInterface");
58 
59  _mesh_cut = dynamic_cast<const InterfaceMeshCutUserObjectBase *>(uo);
60  _elem_pairs = _xfem->getXFEMCutElemPairs(_xfem->getGeometricCutID(_mesh_cut));
61 }
62 
63 void
65 {
70  _nodes.clear();
71 
72  std::shared_ptr<MeshBase> cutter_mesh = _mesh_cut->getCutterMesh();
73 
74  for (const auto & node : cutter_mesh->node_ptr_range())
75  _nodes.push_back(*node);
76 
77  _pl->enable_out_of_mesh_mode();
78 
79  for (const auto & node : cutter_mesh->node_ptr_range())
80  {
81  unsigned int i = node->id();
82 
83  if ((*_pl)(*node) != nullptr)
84  {
85  const Elem * elem = getElemContainingPoint(*node, /*positive_level_set = */ true);
86 
87  if (elem != nullptr)
88  {
89  _subproblem.setCurrentSubdomainID(elem, /*_tid */ 0);
90  _subproblem.reinitElemPhys(elem, {*node}, 0);
91 
92  _values_positive_level_set_side[i] = (dynamic_cast<MooseVariable *>(_var))->sln()[0];
94  ((dynamic_cast<MooseVariable *>(_var))->gradSln())[0];
95  }
96 
97  const Elem * elem2 = getElemContainingPoint(*node, false);
98  if (elem2 != nullptr)
99  {
100  _subproblem.setCurrentSubdomainID(elem2, /*_tid */ 0);
101  _subproblem.reinitElemPhys(elem2, {*node}, 0);
102 
103  _values_negative_level_set_side[i] = (dynamic_cast<MooseVariable *>(_var))->sln()[0];
105  ((dynamic_cast<MooseVariable *>(_var))->gradSln())[0];
106  }
107  }
108  else // When node is outside of computation domain
109  {
114  }
115  }
116 }
117 
118 void
120 {
125 }
126 
127 const Elem *
128 NodeValueAtXFEMInterface::getElemContainingPoint(const Node & p, bool positive_level_set)
129 {
130  const Elem * elem1 = (*_pl)(p);
131 
132  if (elem1->processor_id() != processor_id())
133  return nullptr;
134 
135  const Node * node = elem1->node_ptr(0);
136 
137  dof_id_type ls_dof_id = node->dof_number(_system.number(), _level_set_var_number, 0);
138 
139  Number ls_node_value = _solution(ls_dof_id);
140 
141  bool positive = false;
142 
143  if (_xfem->isPointInsidePhysicalDomain(elem1, *node))
144  {
145  if (ls_node_value > 0.0)
146  positive = true;
147  }
148  else
149  {
150  if (ls_node_value < 0.0)
151  positive = false;
152  }
153 
154  const Elem * elem2 = nullptr;
155  bool found = false;
156  for (auto & pair : *_elem_pairs)
157  {
158  if (pair.first == elem1)
159  {
160  elem2 = pair.second;
161  found = true;
162  }
163  else if (pair.second == elem1)
164  {
165  elem2 = pair.first;
166  found = true;
167  }
168  }
169 
170  if (!found)
171  mooseError("NodeValueAtXFEMInterface: The interface node ",
172  p,
173  " are not found by element pair locator.");
174 
175  if ((positive && positive_level_set) || (!positive && !positive_level_set))
176  return elem1;
177  else if ((!positive && positive_level_set) || (positive && !positive_level_set))
178  return elem2;
179  else
180  return nullptr;
181 }
registerMooseObject("XFEMApp", NodeValueAtXFEMInterface)
std::map< unsigned int, Real > _values_positive_level_set_side
Mapping from point index and its values at the positive level set side.
static InputParameters validParams()
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const NumericVector< Number > & _solution
The subproblem solution vector.
MooseMesh & _mesh
The computation mesh.
const unsigned int _level_set_var_number
The variable number of the level set variable we are operating on.
MeshBase & mesh
virtual void setCurrentSubdomainID(const Elem *elem, const THREAD_ID tid)=0
std::shared_ptr< MeshBase > getCutterMesh() const
Get the cutter mesh pointer.
const Parallel::Communicator & _communicator
This is the XFEM class.
Definition: XFEM.h:107
void addRequiredParam(const std::string &name, const std::string &doc_string)
std::unique_ptr< libMesh::PointLocatorBase > _pl
Pointer to PointLocatorBase object.
const Elem * getElemContainingPoint(const Node &p, bool positive_level_set)
Find the element in the element pairs that contains the point in its physical domain.
SubProblem & _subproblem
MooseVariableFEBase * _var
Pointer to MooseVariableFEBase object.
std::shared_ptr< XFEM > _xfem
Pointer to the XFEM controller object.
unsigned int number() const
std::map< unsigned int, Real > _values_negative_level_set_side
Mapping from point index and its values at the negative level set side.
const ElementPairLocator::ElementPairList * _elem_pairs
Pointer to ElementPairList object.
std::map< unsigned int, RealVectorValue > _grad_values_positive_level_set_side
Mapping from point index and its gradient at the positive level set side.
virtual void finalize() override
virtual void reinitElemPhys(const Elem *elem, const std::vector< Point > &phys_points_in_elem, const THREAD_ID tid)=0
const libMesh::System & _system
System reference.
static InputParameters validParams()
FEProblemBase & _fe_problem
std::shared_ptr< XFEMInterface > getXFEM()
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
std::vector< Point > _nodes
The nodes to evaluate at.
virtual std::unique_ptr< libMesh::PointLocatorBase > getPointLocator() const
NodeValueAtXFEMInterface(const InputParameters &parameters)
const UserObject & getUserObjectBase(const std::string &name, const THREAD_ID tid=0) const
Real Number
const InterfaceMeshCutUserObjectBase * _mesh_cut
Pointer to LineSegmentCutSetUserObject object.
virtual void execute() override
virtual void initialize() override
processor_id_type processor_id() const
const Elem & get(const ElemType type_in)
std::map< unsigned int, RealVectorValue > _grad_values_negative_level_set_side
Mapping from point index and its gradient at the negative level set side.
uint8_t dof_id_type
void set_union(T &data, const unsigned int root_id) const