LCOV - code coverage report
Current view: top level - src/transfers - MultiAppPostprocessorToAuxScalarTransfer.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 909fe5 Lines: 68 72 94.4 %
Date: 2025-08-29 20:01:24 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 "MultiAppPostprocessorToAuxScalarTransfer.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "FEProblem.h"
      14             : #include "MooseTypes.h"
      15             : #include "MooseVariableScalar.h"
      16             : #include "MultiApp.h"
      17             : #include "SystemBase.h"
      18             : 
      19             : #include "libmesh/meshfree_interpolation.h"
      20             : #include "libmesh/system.h"
      21             : 
      22             : // Define the input parameters
      23             : registerMooseObject("MooseApp", MultiAppPostprocessorToAuxScalarTransfer);
      24             : 
      25             : InputParameters
      26       14463 : MultiAppPostprocessorToAuxScalarTransfer::validParams()
      27             : {
      28       14463 :   InputParameters params = MultiAppTransfer::validParams();
      29       28926 :   params.addClassDescription("Transfers from a postprocessor to a scalar auxiliary variable.");
      30       57852 :   params.addRequiredParam<PostprocessorName>(
      31             :       "from_postprocessor", "The name of the Postprocessor to transfer the value from.");
      32       43389 :   params.addRequiredParam<VariableName>(
      33             :       "to_aux_scalar", "The name of the scalar AuxVariable to transfer the value to.");
      34       14463 :   MultiAppTransfer::addUserObjectExecutionCheckParam(params);
      35             : 
      36       14463 :   return params;
      37           0 : }
      38             : 
      39          99 : MultiAppPostprocessorToAuxScalarTransfer::MultiAppPostprocessorToAuxScalarTransfer(
      40          99 :     const InputParameters & parameters)
      41             :   : MultiAppTransfer(parameters),
      42          99 :     _from_pp_name(getParam<PostprocessorName>("from_postprocessor")),
      43         297 :     _to_aux_name(getParam<VariableName>("to_aux_scalar"))
      44             : {
      45          99 :   if (_directions.size() != 1)
      46           0 :     paramError("direction", "This transfer is only unidirectional");
      47          99 : }
      48             : 
      49             : void
      50         255 : MultiAppPostprocessorToAuxScalarTransfer::execute()
      51             : {
      52        1275 :   TIME_SECTION("MultiAppPostprocessorToAuxScalarTransfer::execute()",
      53             :                5,
      54             :                "Performing transfer between a scalar variable and a postprocessor");
      55             : 
      56             :   // Execute the postprocessor if it was specified to execute on TRANSFER
      57         255 :   switch (_current_direction)
      58             :   {
      59         110 :     case TO_MULTIAPP:
      60             :     {
      61         110 :       checkParentAppUserObjectExecuteOn(_from_pp_name);
      62         110 :       _fe_problem.computeUserObjectByName(EXEC_TRANSFER, Moose::PRE_AUX, _from_pp_name);
      63         110 :       _fe_problem.computeUserObjectByName(EXEC_TRANSFER, Moose::POST_AUX, _from_pp_name);
      64         110 :       break;
      65             :     }
      66          95 :     case FROM_MULTIAPP:
      67          95 :       errorIfObjectExecutesOnTransferInSourceApp(_from_pp_name);
      68             :   }
      69             : 
      70             :   // Perform action based on the transfer direction
      71         255 :   switch (_current_direction)
      72             :   {
      73             :     // MultiApp -> MultiApp
      74          50 :     case BETWEEN_MULTIAPP:
      75             :     {
      76         150 :       for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++)
      77             :       {
      78         100 :         if (getFromMultiApp()->hasLocalApp(i))
      79             :         {
      80             :           // Extract the postprocessor that is being transferred
      81          76 :           FEProblemBase & from_problem = getFromMultiApp()->appProblemBase(i);
      82          76 :           Real pp_value = from_problem.getPostprocessorValueByName(_from_pp_name);
      83             : 
      84          76 :           if (getToMultiApp()->hasLocalApp(i))
      85             :           {
      86             :             // Get reference to the AuxVariable where the postprocessor will be passed
      87             :             MooseVariableScalar & scalar =
      88          76 :                 getToMultiApp()->appProblemBase(i).getScalarVariable(_tid, _to_aux_name);
      89             : 
      90          76 :             scalar.reinit();
      91             : 
      92             :             // Set all values of the AuxVariable to the value of the postprocessor
      93          76 :             scalar.setValues(pp_value);
      94             : 
      95             :             // Update the solution
      96          76 :             scalar.insert(scalar.sys().solution());
      97          76 :             scalar.sys().solution().close();
      98             :           }
      99             :         }
     100             :       }
     101          50 :       break;
     102             :     }
     103             : 
     104             :     // main app -> MultiApp
     105         110 :     case TO_MULTIAPP:
     106             :     {
     107             :       // Extract the postprocessor that is being transferred
     108         110 :       FEProblemBase & from_problem = getToMultiApp()->problemBase();
     109         110 :       Real pp_value = from_problem.getPostprocessorValueByName(_from_pp_name);
     110             : 
     111             :       // Loop through each of the sub apps
     112         330 :       for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++)
     113         220 :         if (getToMultiApp()->hasLocalApp(i))
     114             :         {
     115             :           // Get reference to the AuxVariable where the postprocessor will be passed
     116             :           MooseVariableScalar & scalar =
     117         166 :               getToMultiApp()->appProblemBase(i).getScalarVariable(_tid, _to_aux_name);
     118             : 
     119         166 :           scalar.reinit();
     120             : 
     121             :           // Set all values of the AuxVariable to the value of the postprocessor
     122         166 :           scalar.setValues(pp_value);
     123             : 
     124             :           // Update the solution
     125         166 :           scalar.insert(scalar.sys().solution());
     126         166 :           scalar.sys().solution().close();
     127             :         }
     128         110 :       break;
     129             :     }
     130             : 
     131             :     // MultiApp -> main app
     132          95 :     case FROM_MULTIAPP:
     133             :     {
     134             :       // The number of sub applications
     135          95 :       unsigned int num_apps = getFromMultiApp()->numGlobalApps();
     136             : 
     137             :       // The AuxVariable for storing the postprocessor values from the sub app
     138             :       MooseVariableScalar & scalar =
     139          95 :           getFromMultiApp()->problemBase().getScalarVariable(_tid, _to_aux_name);
     140             : 
     141             :       // Ensure that the variable is up to date
     142          95 :       scalar.reinit();
     143             : 
     144             :       // The dof indices for the scalar variable of interest
     145          95 :       auto && dof = scalar.dofIndices();
     146             : 
     147             :       // Error if there is a size mismatch between the scalar AuxVariable and the number of sub apps
     148          95 :       if (num_apps != scalar.sln().size())
     149          16 :         mooseError("The number of sub apps (",
     150             :                    num_apps,
     151             :                    ") must be equal to the order of the scalar AuxVariable (",
     152           8 :                    scalar.order(),
     153             :                    ")");
     154             : 
     155             :       // Loop over each sub-app and populate the AuxVariable values from the postprocessors
     156         296 :       for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++)
     157         209 :         if (getFromMultiApp()->hasLocalApp(i) && getFromMultiApp()->isRootProcessor())
     158             :           // Note: This can't be done using MooseScalarVariable::insert() because different
     159             :           // processors will be setting dofs separately.
     160         316 :           scalar.sys().solution().set(
     161         158 :               dof[i],
     162         316 :               getFromMultiApp()->appProblemBase(i).getPostprocessorValueByName(_from_pp_name));
     163             : 
     164          87 :       scalar.sys().solution().close();
     165             : 
     166          87 :       break;
     167             :     }
     168             :   }
     169         247 : }
     170             : 
     171             : void
     172          26 : MultiAppPostprocessorToAuxScalarTransfer::checkSiblingsTransferSupported() const
     173             : {
     174             :   // Check that we are in the supported configuration: same number of source and target apps
     175             :   // The allocation of the child apps on the processors must be the same
     176          26 :   if (getFromMultiApp()->numGlobalApps() == getToMultiApp()->numGlobalApps())
     177             :   {
     178          78 :     for (const auto i : make_range(getToMultiApp()->numGlobalApps()))
     179          52 :       if (getFromMultiApp()->hasLocalApp(i) + getToMultiApp()->hasLocalApp(i) == 1)
     180           0 :         mooseError("Child application allocation on parallel processes must be the same to support "
     181             :                    "siblings postprocessor to scalar variable transfer");
     182             :   }
     183             :   else
     184           0 :     mooseError("Number of source and target child apps must match for siblings transfer");
     185          26 : }

Generated by: LCOV version 1.14