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

Generated by: LCOV version 1.14