flow
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
test_variable_mu.cpp
Go to the documentation of this file.
1// Variable-viscosity diffusion stencil (ibmBuildDiffusionVar). Verifies the assembled 7-band
2// operator against a host oracle for UniformFaceProps (constant equivalence) and FieldFaceProps
3// with arithmetic and harmonic face means at a viscosity jump.
4#include <cmath>
5#include <cstdio>
6#include <Kokkos_Core.hpp>
7#include <vector>
8
9#include "cut_cell_ibm.hpp"
10#include "face_props.hpp"
11
12namespace {
13int failures = 0;
14#define CHECK(cond) \
15 do { \
16 if (!(cond)) { \
17 std::fprintf(stderr, "CHECK failed: %s\n at %s:%d\n", #cond, __FILE__, __LINE__); \
18 ++failures; \
19 } \
20 } while (0)
21
24using FV = Kokkos::View<float*, peclet::flow::IMem>;
25
26float at(const FV& v, long i) {
27 auto h = Kokkos::create_mirror_view(v);
28 Kokkos::deep_copy(h, v);
29 return h(i);
30}
31
32void run() {
33 const int ex = 8, ey = 6, ez = 6, g = 2;
34 const long n = (long)ex * ey * ez;
35 const long sx = 1, sy = ex, sz = (long)ex * ey;
36 FV AC("AC", n), AW("AW", n), AE("AE", n), AS("AS", n), AN("AN", n), AB("AB", n), AT("AT", n);
37
38 // --- UniformFaceProps == constant operator: A_C = idiag + 6*beta, off = -beta.
39 const double idiag = 0.1, beta = 0.5;
40 peclet::flow::ibmBuildDiffusionVar(AC, AW, AE, AS, AN, AB, AT, ex, ey, ez, g,
42 const long i0 = (long)3 + (long)3 * sy + (long)3 * sz; // an interior cell
43 CHECK(std::fabs(at(AW, i0) - (float)(-beta)) < 1e-6);
44 CHECK(std::fabs(at(AC, i0) - (float)(idiag + beta + beta + beta + beta + beta + beta)) < 1e-6);
45
46 // --- FieldFaceProps with a viscosity jump in x at the face between cell 3 and 4: mu=1 for x<=3,
47 // mu=0.1 for x>=4. Check the -x band of cell 4 (face between 3 and 4) under both means.
48 CCField mu("mu", n);
49 {
50 auto h = Kokkos::create_mirror_view(mu);
51 for (int z = 0; z < ez; ++z)
52 for (int y = 0; y < ey; ++y)
53 for (int x = 0; x < ex; ++x)
54 h((long)x + (long)y * sy + (long)z * sz) = (x <= 3) ? 1.0 : 0.1;
55 Kokkos::deep_copy(mu, h);
56 }
57 const long i4 = (long)4 + (long)3 * sy + (long)3 * sz;
58 // arithmetic: -x face beta = 0.5*(mu(4)+mu(3)) = 0.5*(0.1+1.0) = 0.55
59 peclet::flow::ibmBuildDiffusionVar(AC, AW, AE, AS, AN, AB, AT, ex, ey, ez, g,
60 peclet::flow::FieldFaceProps{CCConst(mu), idiag, false});
61 CHECK(std::fabs(at(AW, i4) - (float)(-0.55)) < 1e-6);
62 // harmonic: 2*mu(4)*mu(3)/(mu(4)+mu(3)) = 2*0.1*1.0/1.1 = 0.181818
63 peclet::flow::ibmBuildDiffusionVar(AC, AW, AE, AS, AN, AB, AT, ex, ey, ez, g,
64 peclet::flow::FieldFaceProps{CCConst(mu), idiag, true});
65 const float harm = (float)(2.0 * 0.1 * 1.0 / 1.1);
66 CHECK(std::fabs(at(AW, i4) - (-harm)) < 1e-6);
67 // +x face of cell 4 is within the mu=0.1 layer: beta = 0.1 (both means agree)
68 CHECK(std::fabs(at(AE, i4) - (float)(-0.1)) < 1e-6);
69 std::printf("variable-mu bands: uniform + arithmetic(-0.55) + harmonic(%.4f) vs oracle OK\n",
70 harm);
71}
72} // namespace
73
74int main(int argc, char** argv) {
75 Kokkos::initialize(argc, argv);
76 run();
77 Kokkos::finalize();
78 if (failures == 0) {
79 std::printf("OK\n");
80 return 0;
81 }
82 std::fprintf(stderr, "%d failure(s)\n", failures);
83 return 1;
84}
flow — portable (Kokkos) Robust-Scaled cut-cell IBM primitives + per-cut-cell overlay build.
flow — face/cell material-property accessors for the variable-coefficient momentum operator.
void ibmBuildDiffusionVar(Kokkos::View< float *, IMem > AC, Kokkos::View< float *, IMem > AW, Kokkos::View< float *, IMem > AE, Kokkos::View< float *, IMem > AS, Kokkos::View< float *, IMem > AN, Kokkos::View< float *, IMem > AB, Kokkos::View< float *, IMem > AT, int ex, int ey, int ez, int g, FaceProps fp)
Kokkos::View< double *, CCMem > CCField
Kokkos::View< const double *, CCMem > CCConst
static constexpr double AC
Kokkos::View< float *, IMem > FV
static int run(int bc)
int main(int argc, char **argv)
#define CHECK(cond)