1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// SPDX-License-Identifier: GPL-3.0-only
// Copyright (C) 2026 OUTRAM PARK contributors
// Derived from OpenFOAM (www.openfoam.com)
// applications/solvers/basic/laplacianFoam/laplacianFoam.C
// Copyright (C) 2011-2017 OpenFOAM Foundation
// Copyright (C) 2019 OpenCFD Ltd.
// src/thermoTools/derivedFvPatchFields/externalWallHeatFluxTemperature/
// externalWallHeatFluxTemperatureFvPatchScalarField.C (convective arm,
// lines 424-447 of the vendored copy: valueFraction = hp/(hp + kappa
// deltaCoeffs), refValue = Ta)
// src/finiteVolume/interpolation/surfaceInterpolation/schemes/harmonic/
// harmonic.H (face conductivity 1/reverseLinear(1/k))
// Upstream licence: GPL-3.0-or-later.
//
// This file is part of OUTRAM PARK.
//
// OUTRAM PARK is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// OUTRAM PARK is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with OUTRAM PARK. If not, see <https://www.gnu.org/licenses/>.
//! # Steady heat conduction with a volumetric source (gh:#949)
//!
//! A small steady conduction solver: the steady form of OpenFOAM's
//! `laplacianFoam`,
//!
//! ```text
//! -div( k(T) grad T ) = q''' in the solid
//! ```
//!
//! with a per-zone uniform heat source `q'''` (W/m^3), a per-zone
//! conductivity `k(T)` (W/(m K)) supplied by the caller, and one thermal
//! condition per boundary patch: adiabatic, fixed temperature, or convective
//! (`-k dT/dn = h (T - T_ambient)`).
//!
//! It exists for the **beginner thermal profile** of `outram-mc-libs`
//! (gh:#949, under #945): a coarse temperature field for any shape, with an
//! **energy balance** (heat generated against heat leaving through the
//! boundary) reported beside it. Serious thermal-hydraulics is `nee_soon`'s.
//!
//! ## What is ported, and what is new
//!
//! | piece | source |
//! |---|---|
//! | the equation, `fvm::laplacian(k, T) == source` | `laplacianFoam.C` (`TEqn`), run steady (`ddt` dropped, as with `ddtSchemes steadyState`) |
//! | the convective boundary as a mixed (Robin) condition, `valueFraction = h/(h + k/d)`, `refValue = T_a` | `externalWallHeatFluxTemperatureFvPatchScalarField.C` (`hp` without radiation or solid layers) |
//! | `k(T)` re-evaluated between outer passes (Picard) | the outer `simple.loop()` of `laplacianFoam`, here with `k` updated each pass (upstream's `DT` is constant) |
//! | **face conductivity as series resistance**, `A / (d_P/k_P + d_N/k_N)` | OpenFOAM's `harmonic` interpolation (`schemes/harmonic/harmonic.H`: `1/reverseLinear(1/k)`), chosen over the default `Gauss linear`, which averages `k` linearly and is wrong at a material interface |
//! | **energy balance** from the boundary condition definitions, not from the matrix | new here |
//! | radial (slab / cylinder / sphere) and voxel meshers | new here ([`mesh`]) |
//!
//! ## The energy balance, and what it can catch
//!
//! The heat leaving each boundary face is recomputed from that face's own
//! condition (`h`, `T_a`, `k` of its cell, the face distance) and the solved
//! cell temperature, independently of the assembled matrix. In a correct
//! finite-volume solve the interior fluxes cancel pairwise, so generated minus
//! removed equals the sum of the linear-solver residuals: it is small by
//! construction. Its job is to catch an assembly that drops or doubles a
//! boundary contribution (a zero boundary conductivity was such a defect
//! elsewhere in this workspace; see `outram-foam-appbuilder-lib`'s
//! `thermo_mechanics::mesh_solve`) and an unconverged solve. It does **not**
//! measure discretisation error; the closed-form tests in this module do.
//!
//! ## Verification
//!
//! [`closed_form`] is the exact solution for uniform `q'''` in nested slab,
//! cylinder and sphere shells with a fixed-temperature or convective surface.
//! The tests in `tests.rs` compare the solve against it and measure the
//! convergence order; the methodology and results are in their doc comments.
//!
//! Status: untrusted AI-generated draft (2026-10-17) per `RESPONSIBLE_USE.md`.
//! For research, education and V&V only.
pub use ;
pub use ;
pub use ;
use Error;
/// What can go wrong setting up or solving a steady conduction problem.