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 "FVHarmonicAverage.h" 11 : 12 : #include <algorithm> 13 : #include <cmath> 14 : #include <limits> 15 : 16 : registerMooseObject("MooseApp", FVHarmonicAverage); 17 : 18 : InputParameters 19 3101 : FVHarmonicAverage::validParams() 20 : { 21 3101 : InputParameters params = FVInterpolationMethod::validParams(); 22 3101 : params.addClassDescription( 23 : "Harmonic mean interpolation for finite-volume quantities using FaceInfo geometry weights."); 24 3101 : return params; 25 0 : } 26 : 27 20 : FVHarmonicAverage::FVHarmonicAverage(const InputParameters & params) : FVInterpolationMethod(params) 28 : { 29 20 : } 30 : 31 : Real 32 2 : FVHarmonicAverage::interpolate(const FaceInfo & face, 33 : const Real elem_value, 34 : const Real neighbor_value) const 35 : { 36 : mooseAssert(face.neighborPtr(), 37 : "Harmonic interpolation is intended for internal faces with a neighbor."); 38 : // We will guard for the zeros below 39 : mooseAssert( 40 : (elem_value >= 0 && neighbor_value >= 0) || (elem_value <= 0 && neighbor_value <= 0), 41 : "Harmonic interpolation requires the element and neighbor values to have the same sign."); 42 : 43 2 : const Real gc = face.gC(); 44 2 : const Real one_minus_gc = 1.0 - gc; 45 : 46 : // We guard against those nasty zeros here 47 4 : const auto safe = [](const Real value) 48 : { 49 : // Use the smallest positive normalized value to avoid division by zero while keeping sign. 50 4 : const Real eps = std::numeric_limits<Real>::min(); 51 4 : return std::copysign(std::max(std::abs(value), eps), value); 52 : }; 53 : 54 : // Weighted harmonic mean: 1 / (g/phi_e + (1-g)/phi_n). 55 2 : const Real denom = gc / safe(elem_value) + one_minus_gc / safe(neighbor_value); 56 2 : return 1.0 / denom; 57 : }