https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
45void
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
63void
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 {
112 _grad_values_positive_level_set_side[i] = RealVectorValue(0);
113 _grad_values_negative_level_set_side[i] = RealVectorValue(0);
114 }
115 }
116}
117
118void
126
127const Elem *
128NodeValueAtXFEMInterface::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}
const Real p
registerMooseObject("XFEMApp", NodeValueAtXFEMInterface)
std::shared_ptr< XFEMInterface > getXFEM()
const UserObject & getUserObjectBase(const std::string &name, const THREAD_ID tid=0) const
static InputParameters validParams()
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)
void addClassDescription(const std::string &doc_string)
std::shared_ptr< MeshBase > getCutterMesh() const
Get the cutter mesh pointer.
void mooseError(Args &&... args) const
virtual std::unique_ptr< libMesh::PointLocatorBase > getPointLocator() const
virtual void finalize() override
std::shared_ptr< XFEM > _xfem
Pointer to the XFEM controller object.
MooseVariableFEBase * _var
Pointer to MooseVariableFEBase 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.
MooseMesh & _mesh
The computation mesh.
virtual void execute() override
std::unique_ptr< libMesh::PointLocatorBase > _pl
Pointer to PointLocatorBase object.
const unsigned int _level_set_var_number
The variable number of the level set variable we are operating on.
std::map< unsigned int, Real > _values_negative_level_set_side
Mapping from point index and its values at the negative level set side.
static InputParameters validParams()
NodeValueAtXFEMInterface(const InputParameters &parameters)
virtual void initialize() override
const InterfaceMeshCutUserObjectBase * _mesh_cut
Pointer to LineSegmentCutSetUserObject object.
const ElementPairLocator::ElementPairList * _elem_pairs
Pointer to ElementPairList object.
const NumericVector< Number > & _solution
The subproblem solution vector.
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.
std::map< unsigned int, Real > _values_positive_level_set_side
Mapping from point index and its values at the positive level set side.
std::map< unsigned int, RealVectorValue > _grad_values_negative_level_set_side
Mapping from point index and its gradient at the negative level set side.
std::vector< Point > _nodes
The nodes to evaluate at.
const libMesh::System & _system
System reference.
virtual void reinitElemPhys(const Elem *elem, const std::vector< Point > &phys_points_in_elem, const THREAD_ID tid)=0
virtual void setCurrentSubdomainID(const Elem *elem, const THREAD_ID tid)=0
void set_union(T &data, const unsigned int root_id) const
SubProblem & _subproblem
FEProblemBase & _fe_problem
const Parallel::Communicator & _communicator
processor_id_type processor_id() const
unsigned int number() const
MeshBase & mesh