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