LCOV - code coverage report
Current view: top level - src/actions - XFEMAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose xfem: #31405 (292dce) with base fef103 Lines: 148 157 94.3 %
Date: 2025-09-04 07:58:55 Functions: 3 3 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 "XFEMAction.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "FEProblem.h"
      14             : #include "NonlinearSystem.h"
      15             : #include "Executioner.h"
      16             : #include "MooseEnum.h"
      17             : #include "Parser.h"
      18             : #include "Factory.h"
      19             : #include "AddVariableAction.h"
      20             : #include "MooseApp.h"
      21             : #include "InputParameterWarehouse.h"
      22             : 
      23             : #include "GeometricCutUserObject.h"
      24             : #include "CrackFrontDefinition.h"
      25             : 
      26             : #include "libmesh/transient_system.h"
      27             : #include "libmesh/string_to_enum.h"
      28             : 
      29             : // XFEM includes
      30             : #include "XFEM.h"
      31             : 
      32             : registerMooseAction("XFEMApp", XFEMAction, "setup_xfem");
      33             : 
      34             : registerMooseAction("XFEMApp", XFEMAction, "add_aux_variable");
      35             : 
      36             : registerMooseAction("XFEMApp", XFEMAction, "add_aux_kernel");
      37             : 
      38             : registerMooseAction("XFEMApp", XFEMAction, "add_variable");
      39             : 
      40             : registerMooseAction("XFEMApp", XFEMAction, "add_kernel");
      41             : 
      42             : registerMooseAction("XFEMApp", XFEMAction, "add_bc");
      43             : 
      44             : InputParameters
      45         421 : XFEMAction::validParams()
      46             : {
      47         421 :   InputParameters params = Action::validParams();
      48             : 
      49         842 :   params.addParam<std::vector<UserObjectName>>(
      50             :       "geometric_cut_userobjects",
      51             :       {},
      52             :       "List of names of GeometricCutUserObjects with cut info and methods");
      53         842 :   params.addParam<std::string>("qrule", "volfrac", "XFEM quadrature rule to use");
      54        1263 :   params.addRangeCheckedParam<unsigned int>(
      55             :       "debug_output_level",
      56         842 :       1,
      57             :       "debug_output_level <= 3",
      58             :       "Controls the amount of debug output from XFEM.  0: None, 1: Summary, 2: Details on "
      59             :       "modifications to mesh, 3: Full dump of element fragment algorithm mesh");
      60         842 :   params.addParam<bool>("output_cut_plane", false, "Output the XFEM cut plane and volume fraction");
      61         842 :   params.addParam<bool>("use_crack_growth_increment", false, "Use fixed crack growth increment");
      62         842 :   params.addParam<Real>("crack_growth_increment", 0.1, "Crack growth increment");
      63         842 :   params.addParam<bool>("use_crack_tip_enrichment", false, "Use crack tip enrichment functions");
      64         842 :   params.addParam<UserObjectName>("crack_front_definition",
      65             :                                   "The CrackFrontDefinition user object name (only "
      66             :                                   "needed if 'use_crack_tip_enrichment=true')");
      67         842 :   params.addParam<std::vector<VariableName>>("displacements",
      68             :                                              "Names of displacement variables (only "
      69             :                                              "needed if 'use_crack_tip_enrichment=true')");
      70         842 :   params.addParam<std::vector<VariableName>>("enrichment_displacements",
      71             :                                              "Names of enrichment displacement variables (only "
      72             :                                              "needed if 'use_crack_tip_enrichment=true')");
      73         842 :   params.addParam<std::vector<BoundaryName>>("cut_off_boundary",
      74             :                                              "Boundary that contains all nodes for which "
      75             :                                              "enrichment DOFs should be fixed away from crack tip "
      76             :                                              "(only needed if 'use_crack_tip_enrichment=true')");
      77         842 :   params.addParam<Real>("cut_off_radius",
      78             :                         "The cut off radius of crack tip enrichment functions (only needed if "
      79             :                         "'use_crack_tip_enrichment=true')");
      80         421 :   params.addClassDescription("Action to input general parameters and simulation options for use "
      81             :                              "in XFEM.");
      82         421 :   return params;
      83           0 : }
      84             : 
      85         421 : XFEMAction::XFEMAction(const InputParameters & params)
      86             :   : Action(params),
      87         421 :     _geom_cut_userobjects(getParam<std::vector<UserObjectName>>("geometric_cut_userobjects")),
      88        1263 :     _xfem_qrule(getParam<std::string>("qrule")),
      89         421 :     _xfem_cut_plane(false),
      90         842 :     _xfem_use_crack_growth_increment(getParam<bool>("use_crack_growth_increment")),
      91         842 :     _xfem_crack_growth_increment(getParam<Real>("crack_growth_increment")),
      92        1263 :     _use_crack_tip_enrichment(getParam<bool>("use_crack_tip_enrichment"))
      93             : {
      94         421 :   _order = "CONSTANT";
      95         421 :   _family = "MONOMIAL";
      96         842 :   if (isParamValid("output_cut_plane"))
      97         842 :     _xfem_cut_plane = getParam<bool>("output_cut_plane");
      98             : 
      99         421 :   if (_use_crack_tip_enrichment)
     100             :   {
     101           8 :     if (isParamValid("crack_front_definition"))
     102           4 :       _crack_front_definition = getParam<UserObjectName>("crack_front_definition");
     103             :     else
     104           0 :       mooseError("To add crack tip enrichment, crack_front_definition must be provided.");
     105             : 
     106           8 :     if (isParamValid("displacements"))
     107           8 :       _displacements = getParam<std::vector<VariableName>>("displacements");
     108             :     else
     109           0 :       mooseError("To add crack tip enrichment, displacements must be provided.");
     110             : 
     111           8 :     if (isParamValid("enrichment_displacements"))
     112             :     {
     113          12 :       _enrich_displacements = getParam<std::vector<VariableName>>("enrichment_displacements");
     114           4 :       if (_enrich_displacements.size() != 8 && _displacements.size() == 2)
     115           0 :         mooseError("The number of enrichment displacements should be total 8 for 2D.");
     116           4 :       else if (_enrich_displacements.size() != 12 && _displacements.size() == 3)
     117           0 :         mooseError("The number of enrichment displacements should be total 12 for 3D.");
     118             :     }
     119             :     else
     120           0 :       mooseError("To add crack tip enrichment, enrichment_displacements must be provided.");
     121             : 
     122           8 :     if (isParamValid("cut_off_boundary"))
     123           8 :       _cut_off_bc = getParam<std::vector<BoundaryName>>("cut_off_boundary");
     124             :     else
     125           0 :       mooseError("To add crack tip enrichment, cut_off_boundary must be provided.");
     126             : 
     127           8 :     if (isParamValid("cut_off_radius"))
     128           8 :       _cut_off_radius = getParam<Real>("cut_off_radius");
     129             :     else
     130           0 :       mooseError("To add crack tip enrichment, cut_off_radius must be provided.");
     131             :   }
     132         421 : }
     133             : 
     134             : void
     135        2522 : XFEMAction::act()
     136             : {
     137             : 
     138        2522 :   std::shared_ptr<XFEMInterface> xfem_interface = _problem->getXFEM();
     139        2522 :   if (xfem_interface == nullptr)
     140             :   {
     141         421 :     const auto & params = _app.getInputParameterWarehouse().getInputParameters();
     142         421 :     InputParameters & pars(*(params.find(uniqueActionName())->second.get()));
     143         421 :     pars.set<FEProblemBase *>("_fe_problem_base") = &*_problem;
     144         421 :     std::shared_ptr<XFEM> new_xfem(new XFEM(_pars));
     145         842 :     _problem->initXFEM(new_xfem);
     146         842 :     xfem_interface = _problem->getXFEM();
     147             :   }
     148             : 
     149        2522 :   std::shared_ptr<XFEM> xfem = MooseSharedNamespace::dynamic_pointer_cast<XFEM>(xfem_interface);
     150        2522 :   if (xfem == nullptr)
     151           0 :     mooseError("dynamic cast of xfem object failed");
     152             : 
     153        2522 :   if (_current_task == "setup_xfem")
     154             :   {
     155         420 :     xfem->setXFEMQRule(_xfem_qrule);
     156             : 
     157         420 :     xfem->setCrackGrowthMethod(_xfem_use_crack_growth_increment, _xfem_crack_growth_increment);
     158        1260 :     xfem->setDebugOutputLevel(getParam<unsigned int>("debug_output_level"));
     159             :   }
     160        2102 :   else if (_current_task == "add_variable" && _use_crack_tip_enrichment)
     161             :   {
     162           4 :     auto var_params = _factory.getValidParams("MooseVariable");
     163           8 :     var_params.set<MooseEnum>("family") = "LAGRANGE";
     164           8 :     var_params.set<MooseEnum>("order") = "FIRST";
     165             : 
     166          36 :     for (const auto & enrich_disp : _enrich_displacements)
     167          64 :       _problem->addVariable("MooseVariable", enrich_disp, var_params);
     168           4 :   }
     169        2098 :   else if (_current_task == "add_kernel" && _use_crack_tip_enrichment)
     170             :   {
     171          36 :     for (unsigned int i = 0; i < _enrich_displacements.size(); ++i)
     172             :     {
     173          64 :       InputParameters params = _factory.getValidParams("CrackTipEnrichmentStressDivergenceTensors");
     174          64 :       params.set<NonlinearVariableName>("variable") = _enrich_displacements[i];
     175          32 :       params.set<unsigned int>("component") = i / 4;
     176          32 :       params.set<unsigned int>("enrichment_component") = i % 4;
     177          32 :       params.set<UserObjectName>("crack_front_definition") = _crack_front_definition;
     178          32 :       params.set<std::vector<VariableName>>("enrichment_displacements") = _enrich_displacements;
     179          32 :       params.set<std::vector<VariableName>>("displacements") = _displacements;
     180          32 :       _problem->addKernel(
     181             :           "CrackTipEnrichmentStressDivergenceTensors", _enrich_displacements[i], params);
     182          32 :     }
     183             :   }
     184        2094 :   else if (_current_task == "add_bc" && _use_crack_tip_enrichment)
     185             :   {
     186          36 :     for (unsigned int i = 0; i < _enrich_displacements.size(); ++i)
     187             :     {
     188          64 :       InputParameters params = _factory.getValidParams("CrackTipEnrichmentCutOffBC");
     189          64 :       params.set<NonlinearVariableName>("variable") = _enrich_displacements[i];
     190          32 :       params.set<Real>("value") = 0;
     191          32 :       params.set<std::vector<BoundaryName>>("boundary") = _cut_off_bc;
     192          32 :       params.set<Real>("cut_off_radius") = _cut_off_radius;
     193          32 :       params.set<UserObjectName>("crack_front_definition") = _crack_front_definition;
     194          32 :       _problem->addBoundaryCondition(
     195             :           "CrackTipEnrichmentCutOffBC", _enrich_displacements[i], params);
     196          32 :     }
     197             :   }
     198        2090 :   else if (_current_task == "add_aux_variable" && _xfem_cut_plane)
     199             :   {
     200         421 :     auto var_params = _factory.getValidParams("MooseVariableConstMonomial");
     201             : 
     202         842 :     _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_origin_x", var_params);
     203         842 :     _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_origin_y", var_params);
     204         842 :     _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_origin_z", var_params);
     205         842 :     _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_normal_x", var_params);
     206         842 :     _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_normal_y", var_params);
     207         842 :     _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_normal_z", var_params);
     208         842 :     _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_origin_x", var_params);
     209         842 :     _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_origin_y", var_params);
     210         842 :     _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_origin_z", var_params);
     211         842 :     _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_normal_x", var_params);
     212         842 :     _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_normal_y", var_params);
     213         842 :     _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_normal_z", var_params);
     214         842 :     _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_volfrac", var_params);
     215         421 :   }
     216        1669 :   else if (_current_task == "add_aux_kernel" && _xfem_cut_plane)
     217             :   {
     218         420 :     InputParameters params = _factory.getValidParams("XFEMVolFracAux");
     219         840 :     params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_BEGIN;
     220         840 :     params.set<AuxVariableName>("variable") = "xfem_volfrac";
     221         840 :     _problem->addAuxKernel("XFEMVolFracAux", "xfem_volfrac", params);
     222             : 
     223         420 :     params = _factory.getValidParams("XFEMCutPlaneAux");
     224         420 :     params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
     225             : 
     226             :     // first cut plane
     227         420 :     params.set<unsigned int>("plane_id") = 0;
     228             : 
     229         840 :     params.set<AuxVariableName>("variable") = "xfem_cut_origin_x";
     230         840 :     params.set<MooseEnum>("quantity") = "origin_x";
     231         840 :     _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_origin_x", params);
     232             : 
     233         840 :     params.set<AuxVariableName>("variable") = "xfem_cut_origin_y";
     234         840 :     params.set<MooseEnum>("quantity") = "origin_y";
     235         840 :     _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_origin_y", params);
     236             : 
     237         840 :     params.set<AuxVariableName>("variable") = "xfem_cut_origin_z";
     238         840 :     params.set<MooseEnum>("quantity") = "origin_z";
     239         840 :     _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_origin_z", params);
     240             : 
     241         840 :     params.set<AuxVariableName>("variable") = "xfem_cut_normal_x";
     242         840 :     params.set<MooseEnum>("quantity") = "normal_x";
     243         840 :     _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_normal_x", params);
     244             : 
     245         840 :     params.set<AuxVariableName>("variable") = "xfem_cut_normal_y";
     246         840 :     params.set<MooseEnum>("quantity") = "normal_y";
     247         840 :     _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_normal_y", params);
     248             : 
     249         840 :     params.set<AuxVariableName>("variable") = "xfem_cut_normal_z";
     250         840 :     params.set<MooseEnum>("quantity") = "normal_z";
     251         840 :     _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_normal_z", params);
     252             : 
     253             :     // second cut plane
     254         420 :     params.set<unsigned int>("plane_id") = 1;
     255             : 
     256         840 :     params.set<AuxVariableName>("variable") = "xfem_cut2_origin_x";
     257         840 :     params.set<MooseEnum>("quantity") = "origin_x";
     258         840 :     _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_origin_x", params);
     259             : 
     260         840 :     params.set<AuxVariableName>("variable") = "xfem_cut2_origin_y";
     261         840 :     params.set<MooseEnum>("quantity") = "origin_y";
     262         840 :     _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_origin_y", params);
     263             : 
     264         840 :     params.set<AuxVariableName>("variable") = "xfem_cut2_origin_z";
     265         840 :     params.set<MooseEnum>("quantity") = "origin_z";
     266         840 :     _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_origin_z", params);
     267             : 
     268         840 :     params.set<AuxVariableName>("variable") = "xfem_cut2_normal_x";
     269         840 :     params.set<MooseEnum>("quantity") = "normal_x";
     270         840 :     _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_normal_x", params);
     271             : 
     272         840 :     params.set<AuxVariableName>("variable") = "xfem_cut2_normal_y";
     273         840 :     params.set<MooseEnum>("quantity") = "normal_y";
     274         840 :     _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_normal_y", params);
     275             : 
     276         840 :     params.set<AuxVariableName>("variable") = "xfem_cut2_normal_z";
     277         840 :     params.set<MooseEnum>("quantity") = "normal_z";
     278         840 :     _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_normal_z", params);
     279         420 :   }
     280        2522 : }

Generated by: LCOV version 1.14