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 "MooseTypes.h" 11 : #include "IntegratedBCBase.h" 12 : 13 : #ifdef NEML2_ENABLED 14 : 15 : // MOOSE includes 16 : #include "NEML2CentralDifference.h" 17 : 18 : registerMooseObject("SolidMechanicsApp", NEML2CentralDifference); 19 : 20 : InputParameters 21 0 : NEML2CentralDifference::validParams() 22 : { 23 0 : InputParameters params = ExplicitMixedOrder::validParams(); 24 0 : params.addClassDescription( 25 : "Central difference time integrator using NEML2 material models and kernels."); 26 0 : params.addRequiredParam<UserObjectName>( 27 : "assembly", "The NEML2Assembly object to use to provide assembly information"); 28 0 : params.addRequiredParam<UserObjectName>( 29 : "fe", "The NEML2FEInterpolation object to use to couple variables"); 30 0 : return params; 31 0 : } 32 : 33 0 : NEML2CentralDifference::NEML2CentralDifference(const InputParameters & parameters) 34 0 : : ExplicitMixedOrder(parameters) 35 : { 36 0 : } 37 : 38 : void 39 0 : NEML2CentralDifference::rebuildBoundaryElementList() 40 : { 41 0 : if (!_nl) 42 0 : return; 43 : 44 0 : _boundary_elems.clear(); 45 : 46 : // build boundary element list by iterating over all integrated BCs 47 0 : const auto & ibcs = _nl->getIntegratedBCWarehouse(); 48 : std::unordered_set<BoundaryID> bnds; 49 0 : for (const auto & ibc : ibcs.getObjects()) 50 0 : bnds.insert(ibc->boundaryIDs().begin(), ibc->boundaryIDs().end()); 51 : 52 0 : if (!bnds.empty()) 53 : { 54 0 : mooseInfo("Dectected BCs on ", bnds.size(), " boundaries."); 55 : 56 : // deduplicate elements that have multiple boundaries 57 : std::unordered_set<const Elem *> unique_elems; 58 0 : const auto end = _fe_problem.mesh().bndElemsEnd(); 59 0 : for (auto it = _fe_problem.mesh().bndElemsBegin(); it != end; ++it) 60 0 : if (bnds.find((*it)->_bnd_id) != bnds.end()) 61 0 : unique_elems.insert((*it)->_elem); 62 : 63 0 : _boundary_elems.assign(unique_elems.begin(), unique_elems.end()); 64 0 : mooseInfo("Adding ", _boundary_elems.size(), " elements to the algebraic range."); 65 : } 66 : 67 0 : _boundary_elems_dirty = false; 68 : } 69 : 70 : void 71 0 : NEML2CentralDifference::initialSetup() 72 : { 73 0 : ExplicitMixedOrder::initialSetup(); 74 0 : _neml2_assembly = &_fe_problem.getUserObject<NEML2Assembly>("assembly", /*tid=*/0); 75 0 : _fe = &_fe_problem.getUserObject<NEML2FEInterpolation>("fe", /*tid=*/0); 76 0 : rebuildBoundaryElementList(); 77 0 : } 78 : 79 : void 80 0 : NEML2CentralDifference::meshChanged() 81 : { 82 0 : ExplicitMixedOrder::meshChanged(); 83 0 : _boundary_elems_dirty = true; 84 0 : } 85 : 86 : void 87 0 : NEML2CentralDifference::postSolve() 88 : { 89 : ExplicitMixedOrder::postSolve(); 90 0 : _fe->invalidateInterpolations(); 91 0 : } 92 : 93 : void 94 0 : NEML2CentralDifference::evaluateRHSResidual() 95 : { 96 0 : if (_boundary_elems_dirty) 97 0 : rebuildBoundaryElementList(); 98 : 99 0 : if (_fe->contextUpToDate() && _neml2_assembly->upToDate()) 100 : { 101 0 : libMesh::ConstElemRange boundary_elem_range(&_boundary_elems); 102 0 : _fe_problem.setCurrentAlgebraicElementRange(&boundary_elem_range); 103 : 104 0 : libMesh::ConstNodeRange null_node_range(&_no_node); 105 0 : _fe_problem.setCurrentAlgebraicNodeRange(&null_node_range); 106 : } 107 : 108 0 : ExplicitMixedOrder::evaluateRHSResidual(); 109 : 110 : // Reset the algebraic ranges 111 0 : _fe_problem.setCurrentAlgebraicElementRange(nullptr); 112 0 : _fe_problem.setCurrentAlgebraicNodeRange(nullptr); 113 0 : } 114 : 115 : #endif // NEML2_ENABLED