Program Listing for File math.h
↰ Return to documentation for file (framework/math/math.h)
// SPDX-FileCopyrightText: 2024 The OpenSn Authors <https://open-sn.github.io/opensn/>
// SPDX-License-Identifier: MIT
#pragma once
#include "framework/math/quadratures/spatial/spatial_quadrature.h"
#include "framework/math/quadratures/angular/angular_quadrature.h"
#include "framework/math/unknown_manager/unknown_manager.h"
#include "framework/data_types/vector.h"
#include "framework/data_types/dense_matrix.h"
#include "framework/data_types/ndarray.h"
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <fstream>
#include <memory>
namespace opensn
{
class SparseMatrix;
class UnknownManager;
class SpatialDiscretization_FV;
class SpatialDiscretization_PWLD;
class SpatialDiscretization_PWLC;
using MatVec3 = std::vector<std::vector<Vector3>>;
/// Spatial discretization type.
enum class SpatialDiscretizationType
{
UNDEFINED = 0,
FINITE_VOLUME = 1,
PIECEWISE_LINEAR_CONTINUOUS = 2,
PIECEWISE_LINEAR_DISCONTINUOUS = 3,
LAGRANGE_CONTINUOUS = 4,
LAGRANGE_DISCONTINUOUS = 5
};
enum class NormType : int
{
L1_NORM = 1,
L2_NORM = 2,
LINF_NORM = 3
};
/**Sample a Cumulative Distribution Function (CDF) given a probability.
*
* The supplied vector should contain the upper bin boundary for each bin and will return
* the bin associated with the bin that brackets the supplied probability.
*/
int SampleCDF(double x, std::vector<double> cdf_bin);
/** Return the transpose of a matrix.
*
* For an m x n input A, returns an n x m matrix T where T[j][i] = A[i][j].
* \throws std::runtime_error if the matrix is empty or has inconsistent row sizes.
*/
std::vector<std::vector<double>> Transpose(const std::vector<std::vector<double>>& matrix);
NDArray<double, 2> Transpose(const NDArray<double, 2>& matrix);
/** Invert a square matrix using SVD-based pseudo-inversion (LAPACK dgesvd).
*
* Singular values below machine-epsilon * n * sigma_max are treated as zero.
* Emits a warning if the condition number exceeds 1e10.
* \throws std::runtime_error if the matrix is empty, non-square, or SVD fails.
*/
std::vector<std::vector<double>> InvertMatrix(const std::vector<std::vector<double>>& matrix);
NDArray<double, 2> InvertMatrix(const NDArray<double, 2>& matrix);
/** Orthogonalize the columns of a matrix under a weighted inner product.
*
* Applies double-pass modified Gram-Schmidt and normalizes each column so that
* \f$\langle q_i, q_j \rangle_w = \delta_{ij}\f$. Columns whose weighted norm
* falls below 1e-14 are left as zero vectors (linearly dependent directions).
* \throws std::runtime_error if the matrix is empty or has inconsistent row sizes.
*/
std::vector<std::vector<double>>
OrthogonalizeMatrixSpan(const std::vector<std::vector<double>>& matrix,
const std::vector<double>& weights);
NDArray<double, 2> OrthogonalizeMatrixSpan(const NDArray<double, 2>& matrix,
const std::vector<double>& weights);
/// Computes the factorial of an integer.
double Factorial(int x);
/** Return the azimuthal and polar angles for the given direction vector as a pair
* [azimuthal-angle, polar-angle].
*/
std::pair<double, double> OmegaToPhiThetaSafe(const Vector3& omega);
/// Prints the Vector.
void PrintVector(const std::vector<double>& x);
/// Scales a vector in place by constant.
void Scale(std::vector<double>& x, const double& val);
/// Sets a constant value to a vector.
void Set(std::vector<double>& x, const double& val);
/// Multiplies the vector with a constant and returns result.
std::vector<double> Mult(const std::vector<double>& x, const double& val);
/** Return the 1-norm (Taxicab / Manhattan norm):
* \f$\|\boldsymbol{x}\|_{1}=\sum_{i=1}^{n}\left|x_{i}\right|\f$
*/
double L1Norm(const std::vector<double>& x);
/** Return the 2-norm (Euclidean / Frobenius norm):
* \f$\|\boldsymbol{x}\|_{2}=\sqrt{x_{1}^{2}+\cdots+x_{n}^{2}}\f$
*/
double L2Norm(const std::vector<double>& x);
/** Return the infinity-norm:
* \f$\|\mathbf{x}\|_{\infty}=\max\left(\left|x_{1}\right|,\ldots,\left|x_{n}\right|\right)\f$
*/
double LInfNorm(const std::vector<double>& x);
/** Return the p-norm:
* \f$\|\mathbf{x}\|_{p}=\left(\sum_{i=1}^{n}\left|x_{i}\right|^{p}\right)^{1/p}\f$
*/
double LpNorm(const std::vector<double>& x, const double& p);
/** Compute the dot product of two vectors:
* \f$a \cdot b=\sum_{i=1}^{n} a_{i} b_{i}\f$
*/
double Dot(const std::vector<double>& x, const std::vector<double>& y);
/// Adds two vectors component-wise.
std::vector<double> operator+(const std::vector<double>& a, const std::vector<double>& b);
/// Subtracts two vectors component-wise.
std::vector<double> operator-(const std::vector<double>& a, const std::vector<double>& b);
double ComputePointwiseChange(std::vector<double>& x, std::vector<double>& y);
double ComputeL2Change(std::vector<double>& x, std::vector<double>& y);
} // namespace opensn