LCOV - code coverage report
Current view: top level - src/actions - CreateDisplacedProblemAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 67 74 90.5 %
Date: 2025-07-17 01:28:37 Functions: 6 6 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 "CreateDisplacedProblemAction.h"
      11             : #include "MooseApp.h"
      12             : #include "FEProblem.h"
      13             : #include "DisplacedProblem.h"
      14             : #include "NonlinearSystem.h"
      15             : #include "AuxiliarySystem.h"
      16             : #include "RelationshipManager.h"
      17             : 
      18             : registerMooseAction("MooseApp", CreateDisplacedProblemAction, "init_displaced_problem");
      19             : registerMooseAction("MooseApp", CreateDisplacedProblemAction, "add_geometric_rm");
      20             : registerMooseAction("MooseApp", CreateDisplacedProblemAction, "add_algebraic_rm");
      21             : registerMooseAction("MooseApp", CreateDisplacedProblemAction, "add_coupling_rm");
      22             : 
      23             : InputParameters
      24       62387 : CreateDisplacedProblemAction::validParams()
      25             : {
      26       62387 :   InputParameters params = Action::validParams();
      27       62387 :   params.addClassDescription("Create a Problem object that utilizes displacements.");
      28       62387 :   params.addParam<std::vector<std::string>>(
      29             :       "displacements",
      30             :       "The variables corresponding to the x y z displacements of the mesh.  If "
      31             :       "this is provided then the displacements will be taken into account during "
      32             :       "the computation. Creation of the displaced mesh can be suppressed even if "
      33             :       "this is set by setting 'use_displaced_mesh = false'.");
      34      187161 :   params.addParam<bool>(
      35             :       "use_displaced_mesh",
      36      124774 :       true,
      37             :       "Create the displaced mesh if the 'displacements' "
      38             :       "parameter is set. If this is 'false', a displaced mesh will not be created, "
      39             :       "regardless of whether 'displacements' is set.");
      40             : 
      41       62387 :   return params;
      42           0 : }
      43             : 
      44       62149 : CreateDisplacedProblemAction::CreateDisplacedProblemAction(const InputParameters & parameters)
      45       62149 :   : Action(parameters)
      46             : {
      47       62149 : }
      48             : 
      49             : void
      50       12378 : CreateDisplacedProblemAction::addProxyRelationshipManagers(SystemBase & to,
      51             :                                                            SystemBase & from,
      52             :                                                            Moose::RelationshipManagerType rm_type,
      53             :                                                            std::string type)
      54             : {
      55             :   // We do not need to create a geometric proxy RM. There are two reasons:
      56             :   // 1. Based on the old logic, a 'attach_geometric_early=false' geometric RM
      57             :   // never be attached to libMesh side
      58             :   // 2. There is always an algebraic version of this RM.
      59       12378 :   if (rm_type == Moose::RelationshipManagerType::GEOMETRIC)
      60        4126 :     return;
      61             : 
      62        8252 :   auto rm_params = _factory.getValidParams("ProxyRelationshipManager");
      63             : 
      64        8252 :   rm_params.set<bool>("attach_geometric_early") = false;
      65        8252 :   rm_params.set<MooseMesh *>("mesh") = &to.mesh();
      66        8252 :   rm_params.set<System *>("other_system") = &from.system();
      67        8252 :   rm_params.set<std::string>("for_whom") = "DisplacedMesh";
      68        8252 :   rm_params.set<Moose::RelationshipManagerType>("rm_type") = rm_type;
      69             : 
      70        8252 :   rm_params.set<bool>("use_displaced_mesh") = to.subproblem().name() == "DisplacedProblem";
      71             : 
      72        8252 :   if (rm_params.areAllRequiredParamsValid())
      73             :   {
      74        8252 :     auto rm_obj = _factory.create<RelationshipManager>(
      75             :         "ProxyRelationshipManager",
      76       16504 :         to.subproblem().name() + "<-" + from.subproblem().name() + "_" + from.system().name() +
      77       16504 :             "_" + type + "_proxy",
      78        8252 :         rm_params);
      79             : 
      80        8252 :     if (!_app.addRelationshipManager(rm_obj))
      81           0 :       _factory.releaseSharedObjects(*rm_obj);
      82        8252 :   }
      83             :   else
      84           0 :     mooseError("Invalid initialization of ProxyRelationshipManager");
      85        8252 : }
      86             : 
      87             : void
      88        8252 : CreateDisplacedProblemAction::addProxyAlgebraicRelationshipManagers(SystemBase & to,
      89             :                                                                     SystemBase & from)
      90             : {
      91        8252 :   addProxyRelationshipManagers(to, from, Moose::RelationshipManagerType::ALGEBRAIC, "algebraic");
      92        8252 : }
      93             : 
      94             : void
      95        4126 : CreateDisplacedProblemAction::addProxyGeometricRelationshipManagers(SystemBase & to,
      96             :                                                                     SystemBase & from)
      97             : {
      98        4126 :   addProxyRelationshipManagers(to, from, Moose::RelationshipManagerType::GEOMETRIC, "geometric");
      99        4126 : }
     100             : 
     101             : void
     102      231790 : CreateDisplacedProblemAction::act()
     103             : {
     104      231790 :   if (isParamValid("displacements") && getParam<bool>("use_displaced_mesh"))
     105             :   {
     106        8262 :     if (_current_task == "init_displaced_problem")
     107             :     {
     108        2063 :       if (!_displaced_mesh)
     109           0 :         mooseError("displacements were set but a displaced mesh wasn't created!");
     110             : 
     111             :       // Define the parameters
     112        2063 :       InputParameters object_params = _factory.getValidParams("DisplacedProblem");
     113        4126 :       object_params.set<std::vector<std::string>>("displacements") =
     114        6189 :           getParam<std::vector<std::string>>("displacements");
     115        2063 :       object_params.set<MooseMesh *>("mesh") = _displaced_mesh.get();
     116        2063 :       object_params.set<FEProblemBase *>("_fe_problem_base") = _problem.get();
     117        2063 :       object_params.set<bool>("default_ghosting") = _problem->defaultGhosting();
     118             : 
     119             :       // Create the object
     120             :       std::shared_ptr<DisplacedProblem> disp_problem =
     121        2063 :           _factory.create<DisplacedProblem>("DisplacedProblem", "DisplacedProblem", object_params);
     122             : 
     123             :       // Add the Displaced Problem to FEProblemBase
     124        2063 :       _problem->addDisplacedProblem(disp_problem);
     125        2063 :     }
     126             : 
     127        8262 :     if (_current_task == "add_geometric_rm")
     128             :     {
     129        2073 :       if (_mesh->getMeshPtr())
     130           0 :         mooseError(
     131             :             "We should be adding geometric rms so early that we haven't set our MeshBase yet");
     132             : 
     133        2073 :       _mesh->allowRemoteElementRemoval(false);
     134             :       mooseAssert(!_displaced_mesh, "Displaced mesh should not exist yet");
     135             :     }
     136             : 
     137        8262 :     if (_current_task == "add_algebraic_rm")
     138             :     {
     139        2063 :       if (!_displaced_mesh)
     140           0 :         mooseError("We should have created a displaced mesh by now");
     141             : 
     142        2063 :       auto displaced_problem_ptr = _problem->getDisplacedProblem();
     143             : 
     144        4126 :       for (const auto i : make_range(_problem->numNonlinearSystems()))
     145             :       {
     146        2063 :         auto & undisplaced_nl = _problem->getNonlinearSystemBase(i);
     147        2063 :         auto & displaced_nl = displaced_problem_ptr->solverSys(i);
     148             :         // Note the "to" system doesn't actually matter much - the GF will
     149             :         // get added to both systems on the receiving side
     150        2063 :         addProxyAlgebraicRelationshipManagers(undisplaced_nl, displaced_nl);
     151        2063 :         addProxyAlgebraicRelationshipManagers(displaced_nl, undisplaced_nl);
     152             :       }
     153             : 
     154        2063 :       auto & undisplaced_aux = _problem->getAuxiliarySystem();
     155        2063 :       auto & displaced_aux = displaced_problem_ptr->auxSys();
     156             : 
     157             :       // Note that there is no reason to copy coupling factors back and forth because the displaced
     158             :       // systems do not have their own matrices (they are constructed with their libMesh::System of
     159             :       // type TransientExplicitSystem)
     160             : 
     161             :       // Note the "to" system doesn't actually matter much - the GF will
     162             :       // get added to both systems on the receiving side
     163        2063 :       addProxyAlgebraicRelationshipManagers(undisplaced_aux, displaced_aux);
     164        2063 :       addProxyAlgebraicRelationshipManagers(displaced_aux, undisplaced_aux);
     165             : 
     166             :       // Add geometric ghosting (which only acts through the mesh) through the single auxiliary
     167             :       // system as opposed to duplicating the effort through potentially multiple nonlinear systems
     168        2063 :       addProxyGeometricRelationshipManagers(undisplaced_aux, displaced_aux);
     169        2063 :       addProxyGeometricRelationshipManagers(displaced_aux, undisplaced_aux);
     170             : 
     171             :       // When adding the geometric relationship mangers we told the mesh not to allow remote element
     172             :       // removal during the initial MeshBase::prepare_for_use call. Verify that we did indeed tell
     173             :       // the mesh that
     174        2063 :       if (_mesh->allowRemoteElementRemoval() || _displaced_mesh->allowRemoteElementRemoval())
     175           0 :         mooseError("We should not have been allowing remote element deletion prior to the addition "
     176             :                    "of late geometric ghosting functors");
     177        2063 :     }
     178             :   }
     179      231790 : }

Generated by: LCOV version 1.14