// Copyright 2020, the Aether Development Team (see doc/dev_team.md for members) // Full license can be found in License.md #ifndef INCLUDE_SOLVERS_H_ #define INCLUDE_SOLVERS_H_ // The armadillo library is to allow the use of 3d cubes and other // array types, with array math built in. This eliminates loops! #include using namespace arma; struct projection_struct { arma_mat gradLR; arma_mat gradDU; arma_mat R; arma_mat L; arma_mat U; arma_mat D; arma_mat grad_edge_LR; arma_mat grad_edge_DU; }; arma_vec limiter_mc(arma_vec &left, arma_vec &right, int64_t nPts, int64_t nGCs); arma_vec calc_grad_1d(arma_vec &values, arma_vec &x, int64_t nPts, int64_t nGCs); arma_mat calc_grad(arma_mat values, arma_mat x, int64_t nGCs, bool DoX); projection_struct project_to_edges(arma_mat &values, arma_mat &x_centers, arma_mat &x_edges, arma_mat &y_centers, arma_mat &y_edges, int64_t nGCs); namespace Cubesphere_tools { /* struct projection_struct { arma_mat gradLR; arma_mat gradDU; arma_mat R; arma_mat L; arma_mat U; arma_mat D; }; */ arma_vec limiter_mc(arma_vec &left, arma_vec &right, int64_t nPts, int64_t nGCs); void print(arma_vec values); arma_vec calc_grad_1d(arma_vec &values, arma_vec &x, int64_t nPts, int64_t nGCs); arma_mat calc_grad(arma_mat values, arma_mat x, int64_t nGCs, bool DoX); arma_mat project_from_left(arma_mat values, arma_mat gradients, arma_mat x_centers, arma_mat x_edges, int64_t nGCs); arma_mat project_from_right(arma_mat values, arma_mat gradients, arma_mat x_centers, arma_mat x_edges, int64_t nGCs); arma_vec limiter_value(arma_vec projected, arma_vec values, int64_t nPts, int64_t nGCs); //projection_struct project_to_edges(arma_mat &values, arma_mat &x_centers, // arma_mat &x_edges, arma_mat &y_centers, arma_mat &y_edges, int64_t nGCs); } arma_vec solver_conduction( arma_vec value, arma_vec lambda, arma_vec front, arma_vec source, arma_vec dx, precision_t dt, int64_t nGCs, bool return_diff = false, arma_vec source2 = arma_vec()); arma_cube solver_chemistry(arma_cube density, arma_cube source, arma_cube loss, precision_t dt); arma_mat solver_chemistry(arma_mat density, arma_mat source, arma_mat loss, precision_t dt); std::vector coriolis(std::vector velocity, precision_t rotation_rate, arma_cube lat_scgc); /// Set flag values that indicate whether the previous, next, closest, /// or an interpolated value should be used. const int iPrevious_ = 1; const int iNext_ = 2; const int iClosest_ = 3; const int iInterp_ = 4; double interpolate_1d(double outX, std::vector inXs, std::vector inValues); double interpolate_1d_get_index_doubles(double intime, std::vector times); // Overloading the interpolation function: double interpolate_1d_w_index(std::vector values, double interpolation_index, int interpolation_type); double interpolate_1d_w_index(std::vector values, double interpolation_index, int interpolation_type); double interpolate_1d_w_index(std::vector values, float interpolation_index, int interpolation_type); double interpolate_1d_w_index(arma_vec values, double interpolation_index, int interpolation_type); fmat interpolate_1d_w_index(std::vector values, double interpolation_index, int interpolation_type); arma_cube calc_gradient_lon(arma_cube value, Grid &grid); arma_cube calc_gradient_lat(arma_cube value, Grid &grid); arma_cube calc_gradient_alt(arma_cube value, Grid &grid); std::vector calc_gradient_vector(arma_cube value_scgc, Grid &grid); std::vector calc_gradient_cubesphere(arma_cube value, Grid &grid); std::vector calc_gradient_dipole(arma_cube value, Grid grid); arma_cube calc_gradient_alt_4th(arma_cube value, Grid &grid); arma_mat project_onesided_alt_3rd(arma_cube value, Grid &grid, int64_t iAlt); // Calculate 4th-order gradients in the native coordinate system: arma_cube calc_gradient4o_i(arma_cube value, Grid &grid); arma_cube calc_gradient4o_j(arma_cube value, Grid &grid); arma_cube calc_gradient4o_k(arma_cube value, Grid &grid); // Calculate 2nd-order gradients in the native coordinate system: arma_cube calc_gradient2o_i(arma_cube value, Grid &grid); arma_cube calc_gradient2o_j(arma_cube value, Grid &grid); arma_cube calc_gradient2o_k(arma_cube value, Grid &grid); // interpolation in 1D precision_t linear_interpolation(const precision_t y0, const precision_t y1, const precision_t ratio); // interpolation in 3D, data should be a cube of size 2-2-2 precision_t interpolate_unit_cube(const arma_cube &data, const precision_t xRatio, const precision_t yRatio, const precision_t zRatio); precision_t limiter_mc(precision_t dUp, precision_t dDown, precision_t beta); /********************************************************************** \brief Calculate dt (cell size / cMax) in each direction, and take min \param dt returns the neutral time-step \param grid The grid to define the neutrals on **/ precision_t calc_dt(Grid &grid, std::vector cMax_vcgc); precision_t calc_dt_sphere(Grid &grid, std::vector cMax_vcgc); precision_t calc_dt_cubesphere(Grid &grid, std::vector cMax_vcgc); precision_t calc_dt_vertical(Grid &grid, std::vector cMax_vcgc); #endif // INCLUDE_SOLVERS_H_