Antkeeper  0.0.1
atmosphere.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ANTKEEPER_PHYSICS_GAS_ATMOSPHERE_HPP
21 #define ANTKEEPER_PHYSICS_GAS_ATMOSPHERE_HPP
22 
24 #include <engine/math/numbers.hpp>
25 #include <algorithm>
26 #include <cmath>
27 
28 namespace physics {
29 namespace gas {
30 
32 namespace atmosphere {
33 
44 template <class T>
45 T polarization(T ior, T density)
46 {
47  constexpr T k = T(2) * math::pi<T> * math::pi<T>;
48  const T ior2m1 = ior * ior - T(1);
49  const T num = k * ior2m1 * ior2m1;
50  const T den = T(3) * density * density;
51  return num / den;
52 }
53 
68 template <class T>
70 {
71  const T wavelength2 = wavelength * wavelength;
72  return math::four_pi<T> * (density / (wavelength2 * wavelength2)) * polarization;
73 }
74 
88 template <class T>
89 T scattering(T density, T polarization)
90 {
91  return math::four_pi<T> * density * polarization;
92 }
93 
104 template <class T>
105 T absorption(T scattering, T albedo)
106 {
107  return scattering * (T(1) / albedo - T(1));
108 }
109 
120 template <class T>
121 T extinction(T scattering, T albedo)
122 {
123  return scattering / albedo;
124 }
125 
136 template <class T>
137 T optical_depth_exp(const math::vec3<T>& a, const math::vec3<T>& b, T r, T sh, std::size_t n)
138 {
139  sh = T(-1) / sh;
140 
141  const T h = math::length(b - a) / T(n);
142 
143  math::vec3<T> dy = (b - a) / T(n);
144  math::vec3<T> y = a + dy;
145 
146  T f_x = std::exp((math::length(a) - r) * sh);
147  T f_y = std::exp((math::length(y) - r) * sh);
148  T sum = (f_x + f_y);
149 
150  for (std::size_t i = 1; i < n; ++i)
151  {
152  f_x = f_y;
153  y += dy;
154  f_y = std::exp((math::length(y) - r) * sh);
155  sum += (f_x + f_y);
156  }
157 
158  return sum / T(2) * h;
159 }
160 
173 template <class T>
174 T optical_depth_tri(const math::vec3<T>& p0, const math::vec3<T>& p1, T r, T a, T b, T c, std::size_t n)
175 {
176  a = T(1) / (a - c);
177  b = T(1) / (b - c);
178 
179  const T h = math::length(p1 - p0) / T(n);
180 
181  math::vec3<T> dy = (p1 - p0) / T(n);
182  math::vec3<T> y = p0 + dy;
183 
184  T z = math::length(p0) - r;
185  T f_x = std::max(T(0), std::max(T(0), c - z) * a - std::max(T(0), z - c) * b + T(1));
186 
187  z = math::length(y) - r;
188  T f_y = std::max(T(0), std::max(T(0), c - z) * a - std::max(T(0), z - c) * b + T(1));
189  T sum = (f_x + f_y);
190 
191  for (std::size_t i = 1; i < n; ++i)
192  {
193  f_x = f_y;
194  y += dy;
195 
196  z = math::length(y) - r;
197  f_y = std::max(T(0), std::max(T(0), c - z) * a - std::max(T(0), z - c) * b + T(1));
198 
199  sum += (f_x + f_y);
200  }
201 
202  return sum / T(2) * h;
203 }
204 
206 namespace density {
207 
220  template <class T>
221  T exponential(T d0, T z, T sh)
222  {
223  return d0 * std::exp(-z / sh);
224  }
225 
239  template <class T>
240  T triangular(T d0, T z, T a, T b, T c)
241  {
242  return d0 * std::max(T(0), std::max(T(0), c - z) / (a - c) - std::max(T(0), z - c) / (b - c) + T(1));
243  }
244 
245 } // namespace density
246 
247 } // namespace atmosphere
248 
249 } // namespace gas
250 } // namespace physics
251 
252 #endif // ANTKEEPER_PHYSICS_GAS_ATMOSPHERE_HPP
constexpr vector< T, N > max(const vector< T, N > &x, const vector< T, N > &y)
Returns a vector containing the maximum elements of two vectors.
Definition: vector.hpp:1328
T length(const quaternion< T > &q)
Calculates the length of a quaternion.
Definition: quaternion.hpp:602
constexpr T sum(const vector< T, N > &x) noexcept
Calculates the sum of all elements in a vector.
Definition: vector.hpp:1585
constexpr T gas
Molar gas constant (R), in joule per kelvin per mole.
Definition: constants.hpp:50
T exponential(T d0, T z, T sh)
Calculates the density of exponentially-distributed atmospheric particles at a given elevation.
Definition: atmosphere.hpp:221
T triangular(T d0, T z, T a, T b, T c)
Calculates the density of triangularly-distributed atmospheric particles at a given elevation.
Definition: atmosphere.hpp:240
T extinction(T scattering, T albedo)
Calculates an extinction coefficient.
Definition: atmosphere.hpp:121
T absorption(T scattering, T albedo)
Calculates an absorption coefficient.
Definition: atmosphere.hpp:105
T scattering(T density, T polarization, T wavelength)
Calculates a wavelength-dependent scattering coefficient.
Definition: atmosphere.hpp:69
T polarization(T ior, T density)
Calculates a particle polarizability factor.
Definition: atmosphere.hpp:45
T optical_depth_exp(const math::vec3< T > &a, const math::vec3< T > &b, T r, T sh, std::size_t n)
Approximates the optical depth of exponentially-distributed atmospheric particles between two points ...
Definition: atmosphere.hpp:137
T optical_depth_tri(const math::vec3< T > &p0, const math::vec3< T > &p1, T r, T a, T b, T c, std::size_t n)
Approximates the optical depth of triangularly-distributed atmospheric particles between two points u...
Definition: atmosphere.hpp:174
T wavelength(T t, T lambda, T c=constants::speed_of_light< T >)
Wavelength variant of Planck's law.
Definition: planck.hpp:43
Physics.
Definition: constants.hpp:23
n-dimensional vector.
Definition: vector.hpp:44