www.mooseframework.org
UpdateDisplacedMeshThread.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
12 #include "AllNodesSendListThread.h"
13 #include "DisplacedProblem.h"
14 #include "MooseMesh.h"
15 
16 #include "libmesh/mesh_base.h"
17 #include "libmesh/numeric_vector.h"
18 #include "libmesh/transient_system.h"
19 #include "libmesh/explicit_system.h"
20 
22  DisplacedProblem & displaced_problem)
23  : ThreadedNodeLoop<NodeRange, NodeRange::const_iterator>(fe_problem),
24  _displaced_problem(displaced_problem),
25  _ref_mesh(_displaced_problem.refMesh()),
26  _nl_soln(_displaced_problem._nl_solution),
27  _aux_soln(*_displaced_problem._aux_solution)
28 {
29  this->init();
30 }
31 
33  Threads::split split)
34  : ThreadedNodeLoop<NodeRange, NodeRange::const_iterator>(x, split),
35  _displaced_problem(x._displaced_problem),
36  _ref_mesh(x._ref_mesh),
37  _nl_soln(x._nl_soln),
38  _aux_soln(x._aux_soln),
39  _sys_to_nonghost_and_ghost_soln(x._sys_to_nonghost_and_ghost_soln),
40  _sys_to_var_num_and_direction(x._sys_to_var_num_and_direction)
41 {
42 }
43 
44 void
46 {
47  std::vector<std::string> & displacement_variables = _displaced_problem._displacements;
48  unsigned int num_displacements = displacement_variables.size();
49  auto & es = _displaced_problem.es();
50 
53 
54  for (unsigned int i = 0; i < num_displacements; i++)
55  {
56  std::string displacement_name = displacement_variables[i];
57 
58  for (const auto sys_num : make_range(es.n_systems()))
59  {
60  auto & sys = es.get_system(sys_num);
61  if (sys.has_variable(displacement_name))
62  {
63  auto & val = _sys_to_var_num_and_direction[sys.number()];
64  val.first.push_back(sys.variable_number(displacement_name));
65  val.second.push_back(i);
66  break;
67  }
68  }
69  }
70 
71  for (const auto & pr : _sys_to_var_num_and_direction)
72  {
73  auto & sys = es.get_system(pr.first);
74  mooseAssert(sys.number() <= _nl_soln.size(),
75  "The system number should always be less than or equal to the number of nonlinear "
76  "systems. If it is equal, then this system is the auxiliary system");
77  const NumericVector<Number> * const nonghost_soln =
78  sys.number() < _nl_soln.size() ? _nl_soln[sys.number()] : &_aux_soln;
80  sys.number(),
81  std::make_pair(nonghost_soln,
82  NumericVector<Number>::build(nonghost_soln->comm()).release()));
83  }
84 
85  ConstNodeRange node_range(_ref_mesh.getMesh().nodes_begin(), _ref_mesh.getMesh().nodes_end());
86 
87  for (auto & [sys_num, var_num_and_direction] : _sys_to_var_num_and_direction)
88  {
89  auto & sys = es.get_system(sys_num);
90  AllNodesSendListThread send_list(
91  this->_fe_problem, _ref_mesh, var_num_and_direction.first, sys);
92  Threads::parallel_reduce(node_range, send_list);
93  send_list.unique();
94  auto & [soln, ghost_soln] = libmesh_map_find(_sys_to_nonghost_and_ghost_soln, sys_num);
95  ghost_soln->init(soln->size(), soln->local_size(), send_list.send_list(), true, GHOSTED);
96  soln->localize(*ghost_soln, send_list.send_list());
97  }
98 }
99 
100 void
101 UpdateDisplacedMeshThread::onNode(NodeRange::const_iterator & nd)
102 {
103  Node & displaced_node = *(*nd);
104 
105  Node & reference_node = _ref_mesh.nodeRef(displaced_node.id());
106 
107  for (auto & [sys_num, var_num_and_direction] : _sys_to_var_num_and_direction)
108  {
109  auto & var_numbers = var_num_and_direction.first;
110  auto & directions = var_num_and_direction.second;
111  for (const auto i : index_range(var_numbers))
112  {
113  const auto direction = directions[i];
114  if (reference_node.n_dofs(sys_num, var_numbers[i]) > 0)
115  displaced_node(direction) =
116  reference_node(direction) +
117  (*libmesh_map_find(_sys_to_nonghost_and_ghost_soln, sys_num).second)(
118  reference_node.dof_number(sys_num, var_numbers[i], 0));
119  }
120  }
121 }
122 
123 void
125 {
126 }
std::map< unsigned int, std::pair< std::vector< unsigned int >, std::vector< unsigned int > > > _sys_to_var_num_and_direction
const std::vector< const NumericVector< Number > * > & _nl_soln
void join(const UpdateDisplacedMeshThread &)
virtual EquationSystems & es() override
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual const Node & nodeRef(const dof_id_type i) const
Definition: MooseMesh.C:637
const NumericVector< Number > & _aux_soln
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:3199
GHOSTED
StoredRange< MeshBase::const_node_iterator, const Node *> ConstNodeRange
std::vector< std::string > _displacements
UpdateDisplacedMeshThread(FEProblemBase &fe_problem, DisplacedProblem &displaced_problem)
static std::unique_ptr< NumericVector< Number > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
tbb::split split
const std::vector< dof_id_type > & send_list() const
IntRange< T > make_range(T beg, T end)
virtual void onNode(NodeRange::const_iterator &nd) override
Called for each node.
std::map< unsigned int, std::pair< const NumericVector< Number > *, std::shared_ptr< NumericVector< Number > > > > _sys_to_nonghost_and_ghost_soln
StoredRange< MeshBase::node_iterator, Node *> NodeRange
auto index_range(const T &sizable)