LCOV - code coverage report
Current view: top level - src/transfers - MultiAppVariableValueSampleTransfer.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 60 67 89.6 %
Date: 2025-07-17 01:28:37 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "MultiAppVariableValueSampleTransfer.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "FEProblem.h"
      14             : #include "MooseMesh.h"
      15             : #include "MooseTypes.h"
      16             : #include "MooseVariableFE.h"
      17             : #include "MultiApp.h"
      18             : #include "SystemBase.h"
      19             : 
      20             : #include "libmesh/meshfree_interpolation.h"
      21             : #include "libmesh/numeric_vector.h"
      22             : #include "libmesh/system.h"
      23             : 
      24             : using namespace libMesh;
      25             : 
      26             : registerMooseObject("MooseApp", MultiAppVariableValueSampleTransfer);
      27             : 
      28             : InputParameters
      29       14333 : MultiAppVariableValueSampleTransfer::validParams()
      30             : {
      31       14333 :   InputParameters params = MultiAppTransfer::validParams();
      32       14333 :   params.addClassDescription(
      33             :       "Transfers the value of a variable within the master application at each sub-application "
      34             :       "position and transfers the value to a field variable on the sub-application(s).");
      35       14333 :   params.addRequiredParam<AuxVariableName>(
      36             :       "variable", "The auxiliary variable to store the transferred values in.");
      37       14333 :   params.addRequiredParam<VariableName>("source_variable", "The variable to transfer from.");
      38       14333 :   return params;
      39           0 : }
      40             : 
      41          34 : MultiAppVariableValueSampleTransfer::MultiAppVariableValueSampleTransfer(
      42          34 :     const InputParameters & parameters)
      43             :   : MultiAppTransfer(parameters),
      44          34 :     _to_var_name(getParam<AuxVariableName>("variable")),
      45          68 :     _from_var_name(getParam<VariableName>("source_variable"))
      46             : {
      47          34 :   if (_directions.size() != 1 || (isParamValid("from_multi_app") && isParamValid("to_multi_app")))
      48           0 :     paramError("direction", "This transfer is only unidirectional");
      49             : 
      50          34 :   if (hasFromMultiApp())
      51           0 :     paramError("from_multi_app", "This transfer direction has not been implemented");
      52          34 : }
      53             : 
      54             : void
      55          34 : MultiAppVariableValueSampleTransfer::initialSetup()
      56             : {
      57          34 :   MultiAppTransfer::initialSetup();
      58             : 
      59          34 :   variableIntegrityCheck(_to_var_name, false);
      60             : 
      61          34 :   if (isParamValid("from_multi_app"))
      62           0 :     getFromMultiApp()->problemBase().mesh().errorIfDistributedMesh(
      63             :         "MultiAppVariableValueSampleTransfer");
      64          34 :   if (isParamValid("to_multi_app"))
      65          34 :     getToMultiApp()->problemBase().mesh().errorIfDistributedMesh(
      66             :         "MultiAppVariableValueSampleTransfer");
      67          34 : }
      68             : 
      69             : void
      70          32 : MultiAppVariableValueSampleTransfer::execute()
      71             : {
      72          32 :   TIME_SECTION(
      73             :       "MultiAppVariableValueSampleTransfer::execute()", 5, "Sampling a variable for transfer");
      74             : 
      75          32 :   switch (_current_direction)
      76             :   {
      77          32 :     case TO_MULTIAPP:
      78             :     {
      79          32 :       FEProblemBase & from_problem = getToMultiApp()->problemBase();
      80             :       MooseVariableField<Real> & from_var = static_cast<MooseVariableField<Real> &>(
      81          32 :           from_problem.getActualFieldVariable(0, _from_var_name));
      82          32 :       SystemBase & from_system_base = from_var.sys();
      83          32 :       SubProblem & from_sub_problem = from_system_base.subproblem();
      84             : 
      85          32 :       MooseMesh & from_mesh = from_problem.mesh();
      86             : 
      87          32 :       std::unique_ptr<PointLocatorBase> pl = from_mesh.getPointLocator();
      88             : 
      89          96 :       for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++)
      90             :       {
      91          64 :         Real value = -std::numeric_limits<Real>::max();
      92             : 
      93             :         { // Get the value of the variable at the point where this multiapp is in the master domain
      94             : 
      95          64 :           Point multi_app_position = getToMultiApp()->position(i);
      96             : 
      97          64 :           std::vector<Point> point_vec(1, multi_app_position);
      98             : 
      99             :           // First find the element the hit lands in
     100          64 :           const Elem * elem = (*pl)(multi_app_position);
     101             : 
     102          64 :           if (elem && elem->processor_id() == from_mesh.processor_id())
     103             :           {
     104          46 :             from_sub_problem.setCurrentSubdomainID(elem, 0);
     105          46 :             from_sub_problem.reinitElemPhys(elem, point_vec, 0);
     106             : 
     107             :             mooseAssert(from_var.sln().size() == 1, "No values in u!");
     108          46 :             value = from_var.sln()[0];
     109             :           }
     110             : 
     111          64 :           _communicator.max(value);
     112             : 
     113          64 :           if (value == -std::numeric_limits<Real>::max())
     114           0 :             mooseError("Transfer failed to sample point value at point: ", multi_app_position);
     115          64 :         }
     116             : 
     117          64 :         if (getToMultiApp()->hasLocalApp(i))
     118             :         {
     119          46 :           Moose::ScopedCommSwapper swapper(getToMultiApp()->comm());
     120             : 
     121             :           // Loop over the master nodes and set the value of the variable
     122          46 :           System * to_sys = find_sys(getToMultiApp()->appProblemBase(i).es(), _to_var_name);
     123             : 
     124          46 :           unsigned int sys_num = to_sys->number();
     125          46 :           unsigned int var_num = to_sys->variable_number(_to_var_name);
     126             : 
     127          46 :           NumericVector<Real> & solution = getToMultiApp()->appTransferVector(i, _to_var_name);
     128             : 
     129          46 :           MooseMesh & mesh = getToMultiApp()->appProblemBase(i).mesh();
     130             : 
     131       11178 :           for (const auto & node : as_range(mesh.localNodesBegin(), mesh.localNodesEnd()))
     132             :           {
     133        5566 :             if (node->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this node
     134             :             {
     135             :               // The zero only works for LAGRANGE!
     136        5566 :               dof_id_type dof = node->dof_number(sys_num, var_num, 0);
     137             : 
     138        5566 :               solution.set(dof, value);
     139             :             }
     140          46 :           }
     141          46 :           solution.close();
     142          46 :           getToMultiApp()->appProblemBase(i).es().update();
     143          46 :         }
     144             :       }
     145             : 
     146          32 :       break;
     147          32 :     }
     148           0 :     case FROM_MULTIAPP:
     149             :     {
     150           0 :       mooseError("Doesn't make sense to transfer a sampled variable's value from a MultiApp!!");
     151             :       break;
     152             :     }
     153             :   }
     154          32 : }

Generated by: LCOV version 1.14