OGS
BHEParameterValidation.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
6#include <spdlog/fmt/fmt.h>
7
8#include <algorithm>
9#include <cmath>
10
11#include "BaseLib/Error.h"
12#include "BaseLib/Logging.h"
16#include "Pipe.h"
17
18namespace ProcessLib
19{
20namespace HeatTransportBHE
21{
22namespace BHE
23{
25 double const t,
27 std::string_view const param_role)
28{
29 double const v = param(t, pos)[0];
30 if (!std::isfinite(v) || v <= 0.0)
31 {
33 "BHE {:s} ('{}') is non-finite or non-positive (value={:g}) at "
34 "{}.",
35 param_role, param.name, v, pos);
36 }
37 return v;
38}
39
41 double const D,
42 double const d0,
43 double const distance,
44 std::string_view const equation,
45 std::string_view const cause)
46{
47 return fmt::format(
48 "BHE geometry invalid at {} ({:s}): D={:g}, d0={:g}, distance={:g}. "
49 "{:s}",
50 pos, equation, D, d0, distance, cause);
51}
52
53void checkAcoshArg(double const arg, std::string_view const context)
54{
55 if (!std::isfinite(arg) || arg <= 1.0)
56 {
57 OGS_FATAL("{:s} -> acosh argument = {:g} (must be finite and > 1).",
58 context, arg);
59 }
60}
61
62void checkBoreholeVsPipeDiameter(double const D,
63 double const min_diameter,
65 std::string_view const context)
66{
67 if (!(D > min_diameter) || !std::isfinite(D / min_diameter))
68 {
70 "BHE geometry invalid at {} ({:s}): borehole diameter "
71 "D={:g} must strictly exceed the minimum diameter {:g} required by "
72 "this formula.",
73 pos, context, D, min_diameter);
74 }
75}
76
77double checkedGroutArea(double const borehole_area_fraction,
78 double const pipe_outside_area,
80{
81 double const grout_area = borehole_area_fraction - pipe_outside_area;
82 if (grout_area <= 0)
83 {
85 "Non-positive grout cross-sectional area at {}. "
86 "Borehole diameter is too small for the pipe dimensions.",
87 pos);
88 }
89 return grout_area;
90}
91
92void checkEqualPipeOutsideDiameters(Pipe const& inlet, Pipe const& outlet,
93 std::string_view const context)
94{
95 double const d_inlet = inlet.outsideDiameter();
96 double const d_outlet = outlet.outsideDiameter();
97 // The diameters are user-supplied constants, so allow for round-off but
98 // reject genuinely different pipes.
99 if (std::abs(d_inlet - d_outlet) >
100 1e-12 * std::max(std::abs(d_inlet), std::abs(d_outlet)))
101 {
102 OGS_FATAL(
103 "{:s}: inlet and outlet pipe outside diameters differ "
104 "(inlet={:g}, outlet={:g}). U-type BHE thermal resistance formulas "
105 "assume a single pipe diameter; inlet and outlet may differ only "
106 "in wall thermal conductivity.",
107 context, d_inlet, d_outlet);
108 }
109}
110
112 ParameterLib::Parameter<double> const& param, std::string_view const role)
113{
114 // Borehole geometry properties are sampled once at t=0 and are physically
115 // time-invariant, so reject parameter types that genuinely vary in time.
116 // Parameter::isTimeDependent() is too conservative to use as the sole
117 // criterion here: a FunctionParameter reports true even for a purely
118 // spatial expression. We therefore deny-list only the parameter types that
119 // are always genuinely time-varying, and merely warn (below) for anything
120 // else that reports time-dependence.
121 if (dynamic_cast<ParameterLib::CurveScaledParameter<double> const*>(
122 &param) != nullptr ||
124 &param) != nullptr)
125 {
126 OGS_FATAL(
127 "BHE {:s} '{}' uses a time-varying parameter type, but borehole "
128 "geometry properties are sampled once at t=0 and are physically "
129 "time-invariant. Use ConstantParameter, MeshElementParameter, or "
130 "a spatial-only FunctionParameter.",
131 role, param.name);
132 }
133 if (param.isTimeDependent())
134 {
135 WARN(
136 "BHE {:s} '{}' reports time-dependence. This is expected for a "
137 "FunctionParameter, whose time-dependence flag is set even for a "
138 "purely spatial expression, so a spatial-only expression is fine. "
139 "Only the value at t=0 is used; ensure the expression does not "
140 "actually depend on time.",
141 role, param.name);
142 }
143
144 if (dynamic_cast<ParameterLib::MeshNodeParameter<double> const*>(&param))
145 {
146 OGS_FATAL(
147 "BHE parameter '{}' must not be a MeshNodeParameter. "
148 "Use MeshElementParameter for spatially varying BHE properties.",
149 param.name);
150 }
151
152 if (param.getNumberOfGlobalComponents() != 1)
153 {
154 OGS_FATAL(
155 "BHE {:s} '{}' must be scalar (1 component), got {:d} components.",
156 role, param.name, param.getNumberOfGlobalComponents());
157 }
158}
159} // namespace BHE
160} // namespace HeatTransportBHE
161} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:10
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
void checkAcoshArg(double const arg, std::string_view const context)
double sampleStrictPositive(ParameterLib::Parameter< double > const &param, double const t, ParameterLib::SpatialPosition const &pos, std::string_view const param_role)
void validateScalarTimeInvariantBHEParameter(ParameterLib::Parameter< double > const &param, std::string_view const role)
void checkBoreholeVsPipeDiameter(double const D, double const min_diameter, ParameterLib::SpatialPosition const &pos, std::string_view const context)
std::string uTypeGeometryContext(ParameterLib::SpatialPosition const &pos, double const D, double const d0, double const distance, std::string_view const equation, std::string_view const cause)
double checkedGroutArea(double const borehole_area_fraction, double const pipe_outside_area, ParameterLib::SpatialPosition const &pos)
void checkEqualPipeOutsideDiameters(Pipe const &inlet, Pipe const &outlet, std::string_view const context)
A parameter represented by a mesh property vector.
virtual bool isTimeDependent() const =0
virtual int getNumberOfGlobalComponents() const =0