https://mooseframework.inl.gov
SCMSolutionTransfer.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 
10 #include "SCMSolutionTransfer.h"
11 #include "MultiApp.h"
12 #include "FEProblemBase.h"
13 #include "DisplacedProblem.h"
14 #include "SubChannelMesh.h"
15 
17 registerMooseObjectRenamed("SubChannelApp",
18  SolutionTransfer,
19  "06/30/2027 24:00",
21 registerMooseObjectRenamed("SubChannelApp",
22  SCMPinSolutionTransfer,
23  "06/30/2027 24:00",
25 registerMooseObjectRenamed("SubChannelApp",
26  PinSolutionTransfer,
27  "06/30/2027 24:00",
29 
32 {
34  params.addRequiredParam<std::vector<AuxVariableName>>("variable",
35  "The auxiliary variables to transfer.");
36  MooseEnum transfer_type("subchannel pin", "subchannel");
37  params.addParam<MooseEnum>("transfer_type",
38  transfer_type,
39  "Whether to transfer subchannel-centered or pin-centered fields.");
40  params.addClassDescription(
41  "Transfers subchannel or pin solutions from a SubChannel mesh onto a visualization mesh.");
42  return params;
43 }
44 
46  : MultiAppTransfer(parameters),
47  _var_names(getParam<std::vector<AuxVariableName>>("variable")),
48  _pin_transfer(getParam<MooseEnum>("transfer_type") == "pin")
49 {
51  paramError("from_multiapp", "This transfer works only into multi-app.");
52 }
53 
54 void
56 {
58  for (std::size_t var_index = 0; var_index < _var_names.size(); ++var_index)
59  {
60  if (_to_problems.empty())
61  continue;
62 
64  0, _var_names[var_index], Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_ANY);
65  const auto & fe_type = from_var.feType();
66 
67  if (fe_type.family != LAGRANGE || fe_type.order != FIRST)
68  paramError("variable",
69  "This transfer requires a first order Lagrange variable for the source variable");
70 
71  MooseVariableFieldBase & to_var = _to_problems[0]->getVariable(
72  0, _var_names[var_index], Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_ANY);
73  const auto & fe_type_target = to_var.feType();
74 
75  if (fe_type_target.family != LAGRANGE || fe_type_target.order != FIRST)
76  paramError("variable",
77  "This transfer requires a first order Lagrange variable for the source variable");
78  }
79 }
80 
81 void
83 {
84  TIME_SECTION(
85  "MultiAppDetailedSolutionBaseTransfer::execute()", 5, "Transferring subchannel solutions");
86  getAppInfo();
87 
88  switch (_current_direction)
89  {
90  case TO_MULTIAPP:
91  case BETWEEN_MULTIAPP:
93  break;
94 
95  default:
96  break;
97  }
98 }
99 
100 void
102 {
103  mooseAssert(_from_meshes.size() == 1, "Only one source mesh can be active in this transfer.");
104  auto * from_mesh = dynamic_cast<SubChannelMesh *>(_from_meshes[0]);
105  if (from_mesh == nullptr)
106  mooseError("This transfer works only with SubChannelMesh classes.");
107  if (_pin_transfer && !from_mesh->pinMeshExist())
108  mooseError(
109  "This transfer was configured for pin variables, but the source mesh has no pin mesh.");
110 
111  for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++)
112  if (getToMultiApp()->hasLocalApp(i))
114 }
115 
116 void
118 {
119  transferNodalVars(app_idx);
120 }
121 
122 void
124 {
126 
127  FEProblemBase & to_problem = getToMultiApp()->appProblemBase(app_idx);
128  MooseMesh * mesh = NULL;
129  if (_displaced_target_mesh && to_problem.getDisplacedProblem())
130  mesh = &to_problem.getDisplacedProblem()->mesh();
131  else
132  mesh = &to_problem.mesh();
133 
134  const SubChannelMesh & from_mesh = dynamic_cast<SubChannelMesh &>(*_from_meshes[0]);
135  FEProblemBase & from_problem = *_from_problems[0];
136 
137  for (auto & node : mesh->getMesh().local_node_ptr_range())
138  {
139  if (processor_id() != 0)
140  continue;
141  Node * from_node = getFromNode(from_mesh, *node);
142 
143  for (auto & var_name : _var_names)
144  {
145  System * to_sys = find_sys(to_problem.es(), var_name);
146  unsigned int to_sys_num = to_sys->number();
147  unsigned int to_var_num = to_sys->variable_number(var_name);
148 
149  if (node->n_dofs(to_sys_num, to_var_num) > 0)
150  {
151  System * from_sys = find_sys(from_problem.es(), var_name);
152  unsigned int from_sys_num = from_sys->number();
153  unsigned int from_var_num = from_sys->variable_number(var_name);
154 
155  // Return to parent app MPI communicator to get solution dof
156  swapper.forceSwap();
157  NumericVector<Real> * from_solution = from_sys->solution.get();
158  dof_id_type from_dof = from_node->dof_number(from_sys_num, from_var_num, 0);
159  Real from_value = (*from_solution)(from_dof);
160  swapper.forceSwap();
161 
162  NumericVector<Real> & to_solution = getToMultiApp()->appTransferVector(app_idx, var_name);
163  dof_id_type to_dof = node->dof_number(to_sys_num, to_var_num, 0);
164  to_solution.set(to_dof, from_value);
165  }
166  }
167  }
168 
169  for (auto & var_name : _var_names)
170  {
171  getToMultiApp()->appTransferVector(app_idx, var_name).close();
172  find_sys(to_problem.es(), var_name)->update();
173  }
174 }
175 
176 Node *
177 SCMSolutionTransfer::getFromNode(const SubChannelMesh & from_mesh, const Point & src_node)
178 {
179  unsigned int sch_idx =
180  _pin_transfer ? from_mesh.pinIndex(src_node) : from_mesh.channelIndex(src_node);
181  unsigned iz = from_mesh.getZIndex(src_node);
182  return _pin_transfer ? from_mesh.getPinNode(sch_idx, iz) : from_mesh.getChannelNode(sch_idx, iz);
183 }
LAGRANGE
virtual void execute() override
virtual unsigned int pinIndex(const Point &p) const =0
const libMesh::FEType & feType() const
void paramError(const std::string &param, Args... args) const
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
MooseEnum _current_direction
void transferVarsToApp(unsigned int app_idx)
FIRST
static InputParameters validParams()
virtual Node * getPinNode(unsigned int i_pin, unsigned int iz) const =0
Get the pin mesh node for a given pin index and elevation index.
const std::vector< AuxVariableName > & _var_names
Variable names to transfer.
MeshBase & mesh
void initialSetup() override
std::vector< FEProblemBase *> _to_problems
const Parallel::Communicator & comm() const
const std::shared_ptr< MultiApp > getToMultiApp() const
void addRequiredParam(const std::string &name, const std::string &doc_string)
bool _displaced_target_mesh
bool contains(const std::string &value) const
unsigned int number() const
std::vector< MooseMesh *> _from_meshes
SCMSolutionTransfer(const InputParameters &parameters)
Transfers subchannel and pin solutions from a SubChannel mesh onto a visualization mesh...
void initialSetup() override
Node * getFromNode(const SubChannelMesh &from_mesh, const Point &src_node)
virtual libMesh::EquationSystems & es() override
static libMesh::System * find_sys(libMesh::EquationSystems &es, const std::string &var_name)
registerMooseObjectRenamed("SubChannelApp", SolutionTransfer, "06/30/2027 24:00", SCMSolutionTransfer)
void transferNodalVars(unsigned int app_idx)
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const=0
static InputParameters validParams()
const bool _pin_transfer
Whether pin fields should be transferred instead of subchannel fields.
SubProblem & _subproblem
virtual unsigned int channelIndex(const Point &point) const =0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
MultiMooseEnum _directions
registerMooseObject("SubChannelApp", SCMSolutionTransfer)
virtual MooseMesh & mesh() override
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
Base class for subchannel meshes.
processor_id_type processor_id() const
virtual void getAppInfo()
virtual unsigned int getZIndex(const Point &point) const
Get axial index of point.
std::vector< FEProblemBase *> _from_problems
uint8_t dof_id_type