numerics 0.1.0
Loading...
Searching...
No Matches
fields.hpp
Go to the documentation of this file.
1/// @file pde/fields.hpp
2/// @brief 3D scalar and vector fields on Cartesian grids, with PDE field
3/// solvers.
4///
5/// ScalarField3D -- potential phi(x,y,z) on a uniform grid with trilinear
6/// sampling. VectorField3D -- three ScalarField3D components; sample() returns
7/// trilinear (fx,fy,fz). FieldSolver -- static PDE utilities (Poisson solve,
8/// gradient, divergence, curl). MagneticSolver -- static utilities for J =
9/// -sigma*grad(phi) and B = curl(A) via vector Poisson.
10#pragma once
11
13#include "spatial/grid3d.hpp"
14#include <array>
15#include <utility>
16#include <vector>
17
18namespace num {
19
20// ScalarField3D
21
23 public:
24 /// @param nx,ny,nz Grid resolution
25 /// @param dx Cell size [m]
26 /// @param ox,oy,oz World-space origin
27 ScalarField3D(int nx,
28 int ny,
29 int nz,
30 float dx,
31 float ox = 0.0f,
32 float oy = 0.0f,
33 float oz = 0.0f);
34
35 Grid3D& grid() { return grid_; }
36 const Grid3D& grid() const { return grid_; }
37
38 int nx() const { return grid_.nx(); }
39 int ny() const { return grid_.ny(); }
40 int nz() const { return grid_.nz(); }
41 float dx() const { return static_cast<float>(grid_.dx()); }
42 float ox() const { return ox_; }
43 float oy() const { return oy_; }
44 float oz() const { return oz_; }
45
46 void set(int i, int j, int k, double v) { grid_.set(i, j, k, v); }
47 void fill(double v) { grid_.fill(v); }
48 /// Fill every cell with f(i, j, k).
49 template<typename F>
50 void fill(F&& f) {
51 grid_.fill(std::forward<F>(f));
52 }
53
54 /// Construct and fill from callable f(i, j, k) -> double.
55 template<typename F>
57 int ny,
58 int nz,
59 float dx,
60 F&& f,
61 float ox = 0.0f,
62 float oy = 0.0f,
63 float oz = 0.0f)
64 : ScalarField3D(nx, ny, nz, dx, ox, oy, oz) {
65 fill(std::forward<F>(f));
66 }
67
68 /// Trilinear interpolation at world position (x,y,z).
69 /// Returns 0 outside the grid domain.
70 float sample(float x, float y, float z) const;
71
72 private:
73 Grid3D grid_;
74 float ox_, oy_, oz_;
75};
76
77// VectorField3D
78
80 ScalarField3D x, y, z; ///< x, y, z components on the same grid layout
81
82 VectorField3D(int nx,
83 int ny,
84 int nz,
85 float dx,
86 float ox = 0.0f,
87 float oy = 0.0f,
88 float oz = 0.0f);
89
90 /// Trilinear-interpolated field vector at world position.
91 std::array<float, 3> sample(float px, float py, float pz) const;
92
93 /// Multiply all components by scalar s.
94 void scale(float s);
95};
96
97// FieldSolver
98
100 public:
101 /// Dirichlet boundary condition: fix phi = value at grid node flat_idx.
102 struct DirichletBC {
103 int flat_idx; ///< k*ny*nx + j*nx + i
104 double value;
105 };
106
107 /// @brief Solve \f$\Delta\phi=s\f$ with zero Dirichlet boundaries.
109 const ScalarField3D& source,
110 double tol = 1e-6,
111 int max_iter = 500);
112
113 /// @brief Solve \f$\nabla\cdot(c\nabla\phi)=0\f$ with Dirichlet data.
115 const ScalarField3D& coeff,
116 const std::vector<DirichletBC>& bcs,
117 double tol = 1e-6,
118 int max_iter = 500);
119
120 /// @brief Compute \f$\nabla\phi\f$.
122
123 /// @brief Compute \f$\nabla\cdot f\f$.
124 static ScalarField3D divergence(const VectorField3D& f);
125
126 /// Compute curl(A) via central finite differences (one-sided at
127 /// boundaries).
128 static VectorField3D curl(const VectorField3D& A);
129};
130
131// MagneticSolver
132
134 public:
135 static constexpr double MU0 = 1.2566370614e-6; ///< mu_0 [H/m]
136
137 /// Compute current density J = -sigma*grad(phi) [A/m^2].
138 static VectorField3D current_density(const ScalarField3D& sigma,
139 const ScalarField3D& phi);
140
141 /// Solve for static magnetic field B given current density J.
142 /// Solves Laplacian(A) = -mu0*J (Coulomb gauge, Dirichlet A=0) via three CG
143 /// solves, then returns B = curl(A).
145 double tol = 1e-6,
146 int max_iter = 500);
147};
148
149} // namespace num
static VectorField3D gradient(const ScalarField3D &phi)
Compute .
Definition fields.cpp:186
static SolverResult solve_var_poisson(ScalarField3D &phi, const ScalarField3D &coeff, const std::vector< DirichletBC > &bcs, double tol=1e-6, int max_iter=500)
Solve with Dirichlet data.
Definition fields.cpp:111
static SolverResult solve_poisson(ScalarField3D &phi, const ScalarField3D &source, double tol=1e-6, int max_iter=500)
Solve with zero Dirichlet boundaries.
Definition fields.cpp:82
static VectorField3D curl(const VectorField3D &A)
Definition fields.cpp:200
static ScalarField3D divergence(const VectorField3D &f)
Compute .
Definition fields.cpp:193
double dx() const
Definition grid3d.hpp:24
int ny() const
Definition grid3d.hpp:22
int nz() const
Definition grid3d.hpp:23
int nx() const
Definition grid3d.hpp:21
void fill(real v)
Definition grid3d.cpp:15
void set(int i, int j, int k, real v)
Definition grid3d.hpp:30
static VectorField3D solve_magnetic_field(const VectorField3D &J, double tol=1e-6, int max_iter=500)
Definition fields.cpp:224
static VectorField3D current_density(const ScalarField3D &sigma, const ScalarField3D &phi)
Compute current density J = -sigma*grad(phi) [A/m^2].
Definition fields.cpp:208
static constexpr double MU0
mu_0 [H/m]
Definition fields.hpp:135
void set(int i, int j, int k, double v)
Definition fields.hpp:46
float oy() const
Definition fields.hpp:43
float ox() const
Definition fields.hpp:42
void fill(F &&f)
Fill every cell with f(i, j, k).
Definition fields.hpp:50
int nx() const
Definition fields.hpp:38
ScalarField3D(int nx, int ny, int nz, float dx, F &&f, float ox=0.0f, float oy=0.0f, float oz=0.0f)
Construct and fill from callable f(i, j, k) -> double.
Definition fields.hpp:56
float dx() const
Definition fields.hpp:41
float sample(float x, float y, float z) const
Definition fields.cpp:27
int ny() const
Definition fields.hpp:39
const Grid3D & grid() const
Definition fields.hpp:36
Grid3D & grid()
Definition fields.hpp:35
float oz() const
Definition fields.hpp:44
int nz() const
Definition fields.hpp:40
void fill(double v)
Definition fields.hpp:47
3D Cartesian scalar grid backed by num::Vector storage.
constexpr real phi
Golden ratio.
Definition math.hpp:45
constexpr real e
Definition math.hpp:44
Umbrella include for all linear solvers.
Dirichlet boundary condition: fix phi = value at grid node flat_idx.
Definition fields.hpp:102
int flat_idx
k*ny*nx + j*nx + i
Definition fields.hpp:103
std::array< float, 3 > sample(float px, float py, float pz) const
Trilinear-interpolated field vector at world position.
Definition fields.cpp:65
ScalarField3D z
x, y, z components on the same grid layout
Definition fields.hpp:80
ScalarField3D x
Definition fields.hpp:80
void scale(float s)
Multiply all components by scalar s.
Definition fields.cpp:69
ScalarField3D y
Definition fields.hpp:80