NeoN
A framework for CFD software
Loading...
Searching...
No Matches
geometryScheme.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2023 - 2026 NeoN authors
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7
8#include <optional>
9
15
17{
18
20{
21
22public:
23
25
26 virtual ~GeometrySchemeFactory() = default;
27
28 virtual void updateWeights(const Executor& exec, SurfaceField<scalar>& weights) = 0;
29
30 virtual void
31 updateNonOrthDeltaCoeffs(const Executor& exec, SurfaceField<scalar>& nonOrthDeltaCoeffs) = 0;
32
33 // nonOrthDeltaCoeffs is the precomputed 1/(n.d) field (must be updated first); the
34 // correction vectors read it rather than re-deriving the formula, keeping a single
35 // source of truth for the coefficient.
37 const Executor& exec,
38 const SurfaceField<scalar>& nonOrthDeltaCoeffs,
39 SurfaceField<Vec3>& nonOrthCorrectionVec3s
40 ) = 0;
41};
42
43/* @class GeometryScheme
44 * @brief Implements access to compute weights and nonOrthDeltaCoeffs
45 *
46 * Where:
47 * - weight: the distance of the cell centre to face normalized by the distance to the neighbour
48 * cell
49 * - nonOrthDeltaCoeff: 1 / (faceNormal . cellToCellDist), the over-relaxed (non-orthogonal)
50 * inverse distance, floored at 1 / (0.05 * |cellToCellDist|)
51 */
53{
54public:
55
57 const Executor& exec,
58 std::unique_ptr<GeometrySchemeFactory> kernel,
62 );
63
65 const Executor& exec,
66 const UnstructuredMesh& mesh,
67 std::unique_ptr<GeometrySchemeFactory> kernel
68 );
69
70 GeometryScheme(const UnstructuredMesh& mesh // will lookup the kernel
71 );
72
73 virtual ~GeometryScheme() = default;
74
76
78
80
81 // Vector from the owner cell centre to the face centre (Cf - C_own), one per internal face.
82 // Eagerly computed and cached by update() while the mesh centres are still alive; schemes that
83 // need a cell-to-face offset (e.g. linearUpwind's gradient correction) read it from here.
85
86 // Vector from the neighbour cell centre to the face centre (Cf - C_nei), one per internal face.
88
89 // Safety-net trigger for the faceDelta* fields: builds them from the still-live mesh centres if
90 // update() has not already (it normally has, since update() computes them eagerly), then
91 // releases the source geometry via reset(). Errors out if the centres were already freed.
92 // Idempotent; const so it is reachable through the shared (read-only) GeometryScheme handle.
93 // No-op cost once the deltas exist is a single bool check.
94 void ensureFaceDeltas() const;
95
96 void update();
97
98 // Frees the mesh's per-cell/face centre arrays once the geometry-scheme fields are cached, to
99 // save device memory. Deferred (lazy + idempotent): triggered on the first read of any cached
100 // geometry field, or by ensureFaceDeltas() right after the faceDelta* fields are built — not in
101 // update(), so that a late faceDelta* opt-in can still read the centres.
102 // TODO: check if we can remove the temporary fields from the unstructured mesh
103 // altogether: compute the geometry-scheme data explicitly first and pass it as an
104 // argument, instead of freeing mesh members after the fact.
105 void reset() const;
106
107 std::string name() const;
108
109 // add selection mechanism via dictionary later
110 static const std::shared_ptr<GeometryScheme> readOrCreate(const UnstructuredMesh& mesh);
111
112private:
113
114 const Executor exec_;
115 const UnstructuredMesh& mesh_;
116 std::unique_ptr<GeometrySchemeFactory> kernel_;
117
118 SurfaceField<scalar> weights_;
119 SurfaceField<scalar> nonOrthDeltaCoeffs_;
120 SurfaceField<Vec3> nonOrthCorrectionVec3s_;
121
122 // Populated (from the mesh centres) eagerly by update(); ensureFaceDeltas() is a fallback that
123 // fills them if update() somehow hasn't. std::optional so they can be released with reset(),
124 // and mutable so the const accessors / ensureFaceDeltas() can populate them through the shared
125 // handle. Each holds nInternalFaces * sizeof(Vec3) of device memory.
126 mutable std::optional<SurfaceField<Vec3>> faceDeltaOwner_;
127 mutable std::optional<SurfaceField<Vec3>> faceDeltaNeighbour_;
128 mutable bool faceDeltasComputed_ = false;
129 // Guards the one-shot, deferred release of the mesh centre arrays (see reset()).
130 mutable bool sourceGeometryReleased_ = false;
131};
132
133} // namespace NeoN
Represents an unstructured mesh in NeoN.
virtual void updateWeights(const Executor &exec, SurfaceField< scalar > &weights)=0
virtual void updateNonOrthDeltaCoeffs(const Executor &exec, SurfaceField< scalar > &nonOrthDeltaCoeffs)=0
virtual void updateNonOrthCorrectionVec3s(const Executor &exec, const SurfaceField< scalar > &nonOrthDeltaCoeffs, SurfaceField< Vec3 > &nonOrthCorrectionVec3s)=0
const SurfaceField< Vec3 > & nonOrthCorrectionVec3s() const
GeometryScheme(const UnstructuredMesh &mesh)
const SurfaceField< Vec3 > & faceDeltaOwner() const
const SurfaceField< scalar > & weights() const
static const std::shared_ptr< GeometryScheme > readOrCreate(const UnstructuredMesh &mesh)
const SurfaceField< scalar > & nonOrthDeltaCoeffs() const
GeometryScheme(const Executor &exec, std::unique_ptr< GeometrySchemeFactory > kernel, const SurfaceField< scalar > &weights, const SurfaceField< scalar > &nonOrthDeltaCoeffs, const SurfaceField< Vec3 > &nonOrthCorrectionVec3s)
const SurfaceField< Vec3 > & faceDeltaNeighbour() const
GeometryScheme(const Executor &exec, const UnstructuredMesh &mesh, std::unique_ptr< GeometrySchemeFactory > kernel)
Represents a surface field in a finite volume method.
std::variant< SerialExecutor, CPUExecutor, GPUExecutor > Executor
Definition executor.hpp:20