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