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 "MortarNodalAuxKernel.h" 11 : #include "MooseVariableField.h" 12 : #include "MortarUtils.h" 13 : #include "MooseUtils.h" 14 : #include "AutomaticMortarGeneration.h" 15 : #include "libmesh/quadrature.h" 16 : 17 : namespace 18 : { 19 : const InputParameters & 20 84 : setBoundaryParam(const InputParameters & params_in) 21 : { 22 84 : InputParameters & ret = const_cast<InputParameters &>(params_in); 23 168 : ret.set<std::vector<BoundaryName>>("boundary") = { 24 252 : params_in.get<BoundaryName>("secondary_boundary")}; 25 84 : return ret; 26 168 : } 27 : } 28 : 29 : template <typename ComputeValueType> 30 : InputParameters 31 15029 : MortarNodalAuxKernelTempl<ComputeValueType>::validParams() 32 : { 33 15029 : InputParameters params = AuxKernelTempl<ComputeValueType>::validParams(); 34 15029 : params += MortarConsumerInterface::validParams(); 35 30058 : params.set<bool>("ghost_point_neighbors") = true; 36 30058 : params.suppressParameter<std::vector<BoundaryName>>("boundary"); 37 30058 : params.suppressParameter<std::vector<SubdomainName>>("block"); 38 30058 : params.addParam<bool>( 39 30058 : "incremental", false, "Whether to accumulate mortar auxiliary kernel value"); 40 : 41 : // We should probably default use_displaced_mesh to true. If no displaced mesh exists 42 : // FEProblemBase::addKernel will automatically correct it to false. However, 43 : // this will still prompt a call from AugmentSparsityOnInterface to get a displaced 44 : // mortar interface since object._use_displaced_mesh = true. 45 : 46 15029 : return params; 47 0 : } 48 : 49 : template <typename ComputeValueType> 50 84 : MortarNodalAuxKernelTempl<ComputeValueType>::MortarNodalAuxKernelTempl( 51 : const InputParameters & parameters) 52 : : AuxKernelTempl<ComputeValueType>(setBoundaryParam(parameters)), 53 : MortarConsumerInterface(this), 54 84 : _displaced(this->template getParam<bool>("use_displaced_mesh")), 55 336 : _fe_problem(*this->template getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")), 56 84 : _msm_volume(0), 57 168 : _incremental(this->template getParam<bool>("incremental")), 58 84 : _u_old(uOld()), 59 84 : _test_lower(_var.phiLower()), 60 168 : _coord_msm(_assembly.mortarCoordTransformation()) 61 : { 62 84 : if (!isNodal()) 63 0 : paramError("variable", 64 : "MortarNodalAuxKernel derived classes populate nodal aux variables only."); 65 84 : } 66 : 67 : template <typename ComputeValueType> 68 : void 69 84 : MortarNodalAuxKernelTempl<ComputeValueType>::initialSetup() 70 : { 71 84 : std::array<const MortarNodalAuxKernelTempl<ComputeValueType> *, 1> consumers = {{this}}; 72 : 73 84 : Moose::Mortar::setupMortarMaterials(consumers, 74 : _fe_problem, 75 : amg(), 76 84 : _tid, 77 84 : _secondary_ip_sub_to_mats, 78 84 : _primary_ip_sub_to_mats, 79 84 : _secondary_boundary_mats); 80 84 : } 81 : 82 : template <typename ComputeValueType> 83 : void 84 774 : MortarNodalAuxKernelTempl<ComputeValueType>::compute() 85 : { 86 774 : if (!_var.isNodalDefined()) 87 99 : return; 88 : 89 675 : ComputeValueType value(0); 90 675 : Real total_volume = 0; 91 : 92 675 : const auto & its = amg().secondariesToMortarSegments(*_current_node); 93 : 94 3243 : auto act_functor = [&value, &total_volume, this]() 95 : { 96 1284 : _msm_volume = 0; 97 1284 : setNormals(); 98 1284 : value += computeValue(); 99 0 : total_volume += _msm_volume; 100 : }; 101 : 102 675 : std::array<MortarNodalAuxKernelTempl<ComputeValueType> *, 1> consumers = {{this}}; 103 : 104 675 : Moose::Mortar::loopOverMortarSegments(its, 105 : _assembly, 106 : _subproblem, 107 : _fe_problem, 108 : amg(), 109 675 : _displaced, 110 : consumers, 111 675 : _tid, 112 675 : _secondary_ip_sub_to_mats, 113 675 : _primary_ip_sub_to_mats, 114 675 : _secondary_boundary_mats, 115 : act_functor, 116 : /*reinit_mortar_user_objects=*/false); 117 : 118 : // We have to reinit the node for this variable in order to get the dof index set for the node 119 675 : _var.reinitNode(); 120 : 121 : // If the node doesn't have corresponding mortar segments, force the value assigned in this step 122 : // to be zero. This can be useful when nodes initially do not project but will project at a 123 : // different stage of the simulation 124 : 125 675 : if (MooseUtils::relativeFuzzyEqual(total_volume, 0.0)) 126 0 : value = 0; 127 : else 128 675 : value /= total_volume; 129 : 130 : // Allow mortar auxiliary kernels to compute quantities incrementally 131 675 : if (!_incremental) 132 675 : _var.setNodalValue(value); 133 : else 134 : { 135 : mooseAssert(_u_old.size() == 1, 136 : "Expected 1 value in MortarNodalAuxKernel, but got " << _u_old.size()); 137 0 : _var.setNodalValue(value + _u_old[0]); 138 : } 139 675 : } 140 : 141 : template <typename ComputeValueType> 142 : void 143 0 : MortarNodalAuxKernelTempl<ComputeValueType>::precalculateValue() 144 : { 145 0 : mooseError( 146 : "not clear where this should be implemented in the compute loop. If you want to implement " 147 : "this function, please contact a MOOSE developer and tell them your use case"); 148 : } 149 : 150 : // Explicitly instantiates the two versions of the MortarNodalAuxKernelTempl class 151 : template class MortarNodalAuxKernelTempl<Real>; 152 : template class MortarNodalAuxKernelTempl<RealVectorValue>;