Added Astaroth 2.0
This commit is contained in:
737
src/standalone/model/host_memory.cc
Normal file
737
src/standalone/model/host_memory.cc
Normal file
@@ -0,0 +1,737 @@
|
||||
/*
|
||||
Copyright (C) 2014-2018, Johannes Pekkilae, Miikka Vaeisalae.
|
||||
|
||||
This file is part of Astaroth.
|
||||
|
||||
Astaroth is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Astaroth is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Astaroth. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* \brief Brief info.
|
||||
*
|
||||
* Detailed info.
|
||||
*
|
||||
*/
|
||||
#include "host_memory.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "core/errchk.h"
|
||||
|
||||
const char* init_type_names[] = {AC_FOR_INIT_TYPES(AC_GEN_STR)};
|
||||
|
||||
#define XORIG (AcReal(.5) * mesh->info.int_params[AC_nx] * mesh->info.real_params[AC_dsx])
|
||||
#define YORIG (AcReal(.5) * mesh->info.int_params[AC_ny] * mesh->info.real_params[AC_dsy])
|
||||
#define ZORIG (AcReal(.5) * mesh->info.int_params[AC_nz] * mesh->info.real_params[AC_dsz])
|
||||
|
||||
/*
|
||||
#include <stdint.h>
|
||||
static uint64_t ac_rand_next = 1;
|
||||
|
||||
static int32_t
|
||||
ac_rand(void)
|
||||
{
|
||||
ac_rand_next = ac_rand_next * 1103515245 + 12345;
|
||||
return (uint32_t)(ac_rand_next/65536) % 32768;
|
||||
}
|
||||
|
||||
static void
|
||||
ac_srand(const uint32_t seed)
|
||||
{
|
||||
ac_rand_next = seed;
|
||||
}
|
||||
*/
|
||||
|
||||
AcMesh*
|
||||
acmesh_create(const AcMeshInfo& mesh_info)
|
||||
{
|
||||
AcMesh* mesh = (AcMesh*)malloc(sizeof(*mesh));
|
||||
mesh->info = mesh_info;
|
||||
|
||||
const size_t bytes = AC_VTXBUF_SIZE_BYTES(mesh->info);
|
||||
for (int i = 0; i < NUM_VTXBUF_HANDLES; ++i) {
|
||||
mesh->vertex_buffer[VertexBufferHandle(i)] = (AcReal*)malloc(bytes);
|
||||
ERRCHK(mesh->vertex_buffer[VertexBufferHandle(i)] != NULL);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
static void
|
||||
vertex_buffer_set(const VertexBufferHandle& key, const AcReal& val,
|
||||
AcMesh* mesh)
|
||||
{
|
||||
const int n = AC_VTXBUF_SIZE(mesh->info);
|
||||
for (int i = 0; i < n; ++i)
|
||||
mesh->vertex_buffer[key][i] = val;
|
||||
}
|
||||
|
||||
|
||||
/** Inits all fields to 1. Setting the mesh to zero is problematic because some fields are supposed
|
||||
to be > 0 and the results would vary widely, which leads to loss of precision in the
|
||||
computations */
|
||||
void
|
||||
acmesh_clear(AcMesh* mesh)
|
||||
{
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
vertex_buffer_set(VertexBufferHandle(w), 1, mesh); // Init all fields to 1 by default.
|
||||
}
|
||||
|
||||
static AcReal
|
||||
randr(void)
|
||||
{
|
||||
return AcReal(rand()) / AcReal(RAND_MAX);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lnrho_step(AcMesh* mesh)
|
||||
{
|
||||
const int mx = mesh->info.int_params[AC_mx];
|
||||
const int my = mesh->info.int_params[AC_my];
|
||||
const int mz = mesh->info.int_params[AC_mz];
|
||||
|
||||
// const int nx_min = mesh->info.int_params[AC_nx_min];
|
||||
// const int nx_max = mesh->info.int_params[AC_nx_max];
|
||||
// const int ny_min = mesh->info.int_params[AC_ny_min];
|
||||
// const int ny_max = mesh->info.int_params[AC_ny_max];
|
||||
// const int nz_min = mesh->info.int_params[AC_nz_min];
|
||||
// const int nz_max = mesh->info.int_params[AC_nz_max];
|
||||
|
||||
// const AcReal DX = mesh->info.real_params[AC_dsx];
|
||||
// const AcReal DY = mesh->info.real_params[AC_dsy];
|
||||
// const AcReal DZ = mesh->info.real_params[AC_dsz];
|
||||
// const AcReal xmax = DX * (nx_max - nx_min) ;
|
||||
// const AcReal zmax = DZ * (nz_max - nz_min) ;
|
||||
|
||||
// const AcReal lnrho1 = (AcReal) -1.0; // TODO mesh->info.real_params[AC_lnrho1];
|
||||
const AcReal lnrho2 = (AcReal) 0.0; // TODO mesh->info.real_params[AC_lnrho2];
|
||||
// const AcReal rho1 = (AcReal) exp(lnrho1);
|
||||
// const AcReal rho2 = (AcReal) exp(lnrho2);
|
||||
|
||||
// const AcReal k_pert = (AcReal) 1.0; //mesh->info.real_params[AC_k_pert]; //Wamenumber of the perturbation
|
||||
// const AcReal k_pert = 4.0; //mesh->info.real_params[AC_k_pert]; //Wamenumber of the perturbation
|
||||
//const AcReal ampl_pert = xmax/10.0; // xmax/mesh->info.real_params[AC_pert]; //Amplitude of the perturbation
|
||||
// const AcReal ampl_pert = (AcReal) 0.0;//xmax/20.0; // xmax/mesh->info.real_params[AC_pert]; //Amplitude of the perturbation
|
||||
// const AcReal two_pi = (AcReal) 6.28318531;
|
||||
|
||||
// const AcReal xorig = mesh->info.real_params[AC_xorig];
|
||||
// const AcReal zorig = mesh->info.real_params[AC_zorig];
|
||||
// const AcReal trans = mesh->info.real_params[AC_trans];
|
||||
|
||||
|
||||
// AcReal xx, zz, tanhprof, cosz_wave;
|
||||
|
||||
for (int k = 0; k < mz; k++) {
|
||||
for (int j = 0; j < my; j++) {
|
||||
for (int i = 0; i < mx; i++) {
|
||||
int idx = i + j * mx + k * mx * my;
|
||||
// zz = DZ * AcReal(k) - zorig; // Not used
|
||||
// cosz_wave = ampl_pert*AcReal(cos(k_pert*((zz/zmax)*two_pi))); // Not used
|
||||
// xx = DX * AcReal(i) - xorig + cosz_wave; //ADD WAVE TODO // Not used
|
||||
// tanhprof = AcReal(0.5)*((rho2+rho1) + (rho2-rho1)*AcReal(tanh(xx/trans))); // Not used
|
||||
// Commented out the step function initial codition.
|
||||
//mesh->vertex_buffer[VTXBUF_LNRHO][idx] = log(tanhprof);
|
||||
mesh->vertex_buffer[VTXBUF_LNRHO][idx] = lnrho2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// This is the initial condition type for the infalling vedge in the pseudodisk
|
||||
// model.
|
||||
void
|
||||
inflow_vedge(AcMesh* mesh)
|
||||
{
|
||||
const int mx = mesh->info.int_params[AC_mx];
|
||||
const int my = mesh->info.int_params[AC_my];
|
||||
const int mz = mesh->info.int_params[AC_mz];
|
||||
|
||||
// const int nx_min = mesh->info.int_params[AC_nx_min];
|
||||
// const int nx_max = mesh->info.int_params[AC_nx_max];
|
||||
// const int ny_min = mesh->info.int_params[AC_ny_min];
|
||||
// const int ny_max = mesh->info.int_params[AC_ny_max];
|
||||
// const int nz_min = mesh->info.int_params[AC_nz_min];
|
||||
// const int nz_max = mesh->info.int_params[AC_nz_max];
|
||||
|
||||
// const double DX = mesh->info.real_params[AC_dsx];
|
||||
// const double DY = mesh->info.real_params[AC_dsy];
|
||||
const double DZ = mesh->info.real_params[AC_dsz];
|
||||
|
||||
const double AMPL_UU = mesh->info.real_params[AC_ampl_uu];
|
||||
const double ANGL_UU = mesh->info.real_params[AC_angl_uu];
|
||||
|
||||
const double zorig = mesh->info.real_params[AC_zorig];
|
||||
double zz;
|
||||
double trans = mesh->info.real_params[AC_trans];
|
||||
|
||||
// const AcReal range = AcReal(.5);
|
||||
|
||||
// const AcReal zmax = AcReal(DZ * (nz_max - nz_min));
|
||||
// const AcReal gaussr = zmax / AcReal(4.0);
|
||||
|
||||
//for (int k = nz_min; k < nz_max; k++) {
|
||||
// for (int j = ny_min; j < ny_max; j++) {
|
||||
// for (int i = nx_min; i < nx_max; i++) {
|
||||
for (int k = 0; k < mz; k++) {
|
||||
for (int j = 0; j < my; j++) {
|
||||
for (int i = 0; i < mx; i++) {
|
||||
int idx = i + j * mx + k * mx * my;
|
||||
zz = DZ * double(k) - zorig;
|
||||
//mesh->vertex_buffer[VTXBUF_UUX][idx] = -AMPL_UU*cos(ANGL_UU);
|
||||
mesh->vertex_buffer[VTXBUF_UUX][idx] = AcReal(-AMPL_UU*cos(ANGL_UU)*fabs(tanh(zz/trans)));
|
||||
mesh->vertex_buffer[VTXBUF_UUY][idx] = AcReal(0.0);
|
||||
mesh->vertex_buffer[VTXBUF_UUZ][idx] = AcReal(-AMPL_UU*sin(ANGL_UU)*tanh(zz/trans));
|
||||
|
||||
//Variarion to density
|
||||
//AcReal rho = exp(mesh->vertex_buffer[VTXBUF_LNRHO][idx]);
|
||||
//NO GAUSSIAN//rho = rho*exp(-(zz/gaussr)*(zz/gaussr));
|
||||
//mesh->vertex_buffer[VTXBUF_LNRHO][idx] = log(rho + (range*rho) * (randr() - AcReal(-0.5)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is the initial condition type for the infalling vedge in the pseudodisk
|
||||
// model.
|
||||
void
|
||||
inflow_vedge_freefall(AcMesh* mesh)
|
||||
{
|
||||
const int mx = mesh->info.int_params[AC_mx];
|
||||
const int my = mesh->info.int_params[AC_my];
|
||||
const int mz = mesh->info.int_params[AC_mz];
|
||||
|
||||
// const int nx_min = mesh->info.int_params[AC_nx_min];
|
||||
// const int nx_max = mesh->info.int_params[AC_nx_max];
|
||||
// const int ny_min = mesh->info.int_params[AC_ny_min];
|
||||
// const int ny_max = mesh->info.int_params[AC_ny_max];
|
||||
// const int nz_min = mesh->info.int_params[AC_nz_min];
|
||||
// const int nz_max = mesh->info.int_params[AC_nz_max];
|
||||
|
||||
const double DX = mesh->info.real_params[AC_dsx];
|
||||
// const double DY = mesh->info.real_params[AC_dsy];
|
||||
const double DZ = mesh->info.real_params[AC_dsz];
|
||||
|
||||
// const double AMPL_UU = mesh->info.real_params[AC_ampl_uu];
|
||||
const double ANGL_UU = mesh->info.real_params[AC_angl_uu];
|
||||
const double SQ2GM = mesh->info.real_params[AC_sq2GM_star];
|
||||
// const double GM = mesh->info.real_params[AC_GM_star];
|
||||
// const double M_star = mesh->info.real_params[AC_M_star];
|
||||
// const double G_CONST = mesh->info.real_params[AC_G_CONST];
|
||||
|
||||
// const double unit_length = mesh->info.real_params[AC_unit_length];
|
||||
// const double unit_density = mesh->info.real_params[AC_unit_density];
|
||||
// const double unit_velocity = mesh->info.real_params[AC_unit_velocity];
|
||||
|
||||
const double xorig = mesh->info.real_params[AC_xorig];
|
||||
// const double yorig = mesh->info.real_params[AC_yorig];
|
||||
const double zorig = mesh->info.real_params[AC_zorig];
|
||||
// const double trans = mesh->info.real_params[AC_trans];
|
||||
// double xx, yy, zz, RR;
|
||||
double xx, zz, RR;
|
||||
// double delx, dely, delz;
|
||||
double delx, delz;
|
||||
// double u_x, u_y, u_z, veltot, tanhz;
|
||||
double u_x, u_z, veltot, tanhz;
|
||||
|
||||
const double star_pos_x = mesh->info.real_params[AC_star_pos_x];
|
||||
const double star_pos_z = mesh->info.real_params[AC_star_pos_z];
|
||||
|
||||
for (int k = 0; k < mz; k++) {
|
||||
for (int j = 0; j < my; j++) {
|
||||
for (int i = 0; i < mx; i++) {
|
||||
int idx = i + j * mx + k * mx * my;
|
||||
xx = DX * double(i) - xorig;
|
||||
zz = DZ * double(k) - zorig;
|
||||
|
||||
delx = xx - star_pos_x;
|
||||
delz = zz - star_pos_z;
|
||||
//TODO: Figure out isthis needed. Now a placeholder.
|
||||
//tanhz = fabs(tanh(zz/trans));
|
||||
tanhz = 1.0;
|
||||
|
||||
RR = sqrt(delx*delx + delz*delz);
|
||||
veltot = SQ2GM/sqrt(RR); //Free fall velocity
|
||||
|
||||
//Normal velocity components
|
||||
u_x = - veltot*(delx/RR);
|
||||
u_z = - veltot*(delz/RR);
|
||||
|
||||
//printf("star_pos_z %e, zz %e, delz %e, RR %e\n", star_pos_z, zz, delz, RR);
|
||||
|
||||
//printf("unit_length = %e, unit_density = %e, unit_velocity = %e,\n M_star = %e, G_CONST = %e, GM = %e, SQ2GM = %e, \n RR = %e, u_x = %e, u_z %e\n",
|
||||
// unit_length, unit_density,
|
||||
// unit_velocity, M_star, G_CONST, GM, SQ2GM, RR, u_x, u_z);
|
||||
//printf("%e\n", unit_length*unit_length*unit_length);
|
||||
|
||||
|
||||
//Here including an angel tilt due to pseudodisk
|
||||
if (delz >= 0.0) {
|
||||
mesh->vertex_buffer[VTXBUF_UUX][idx] = AcReal((u_x*cos(ANGL_UU) - u_z*sin(ANGL_UU))*tanhz);
|
||||
mesh->vertex_buffer[VTXBUF_UUY][idx] = AcReal(0.0);
|
||||
mesh->vertex_buffer[VTXBUF_UUZ][idx] = AcReal((u_x*sin(ANGL_UU) + u_z*cos(ANGL_UU))*tanhz);
|
||||
} else {
|
||||
mesh->vertex_buffer[VTXBUF_UUX][idx] = AcReal((u_x*cos(ANGL_UU) + u_z*sin(ANGL_UU))*tanhz);
|
||||
mesh->vertex_buffer[VTXBUF_UUY][idx] = AcReal(0.0);
|
||||
mesh->vertex_buffer[VTXBUF_UUZ][idx] = AcReal((-u_x*sin(ANGL_UU) + u_z*cos(ANGL_UU))*tanhz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only x-direction free fall
|
||||
void
|
||||
inflow_freefall_x(AcMesh* mesh)
|
||||
{
|
||||
const int mx = mesh->info.int_params[AC_mx];
|
||||
const int my = mesh->info.int_params[AC_my];
|
||||
const int mz = mesh->info.int_params[AC_mz];
|
||||
|
||||
const double DX = mesh->info.real_params[AC_dsx];
|
||||
|
||||
const double SQ2GM = mesh->info.real_params[AC_sq2GM_star];
|
||||
// const double G_CONST = mesh->info.real_params[AC_G_CONST];
|
||||
|
||||
const double xorig = mesh->info.real_params[AC_xorig];
|
||||
double xx, RR;
|
||||
double delx;
|
||||
double /*u_x,*/ veltot;
|
||||
|
||||
const double star_pos_x = mesh->info.real_params[AC_star_pos_x];
|
||||
|
||||
const double ampl_lnrho = mesh->info.real_params[AC_ampl_lnrho];
|
||||
|
||||
for (int k = 0; k < mz; k++) {
|
||||
for (int j = 0; j < my; j++) {
|
||||
for (int i = 0; i < mx; i++) {
|
||||
int idx = i + j * mx + k * mx * my;
|
||||
xx = DX * double(i) - xorig;
|
||||
|
||||
delx = xx - star_pos_x;
|
||||
|
||||
RR = fabs(delx);
|
||||
|
||||
veltot = SQ2GM/sqrt(RR); //Free fall velocity
|
||||
|
||||
if (isinf(veltot) == 1) printf("xx %e star_pos_x %e delz %e RR %e veltot %e\n",xx, star_pos_x, delx, RR, veltot);
|
||||
|
||||
//Normal velocity components
|
||||
// u_x = - veltot; // Not used
|
||||
|
||||
//Freefall condition
|
||||
//mesh->vertex_buffer[VTXBUF_UUX][idx] = u_x;
|
||||
//mesh->vertex_buffer[VTXBUF_UUY][idx] = 0.0;
|
||||
//mesh->vertex_buffer[VTXBUF_UUZ][idx] = 0.0;
|
||||
|
||||
//Starting with steady state
|
||||
mesh->vertex_buffer[VTXBUF_UUX][idx] = 0.0;
|
||||
mesh->vertex_buffer[VTXBUF_UUY][idx] = 0.0;
|
||||
mesh->vertex_buffer[VTXBUF_UUZ][idx] = 0.0;
|
||||
|
||||
mesh->vertex_buffer[VTXBUF_LNRHO][idx] = AcReal(ampl_lnrho);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
gaussian_radial_explosion(AcMesh* mesh)
|
||||
{
|
||||
AcReal* uu_x = mesh->vertex_buffer[VTXBUF_UUX];
|
||||
AcReal* uu_y = mesh->vertex_buffer[VTXBUF_UUY];
|
||||
AcReal* uu_z = mesh->vertex_buffer[VTXBUF_UUZ];
|
||||
|
||||
const int mx = mesh->info.int_params[AC_mx];
|
||||
const int my = mesh->info.int_params[AC_my];
|
||||
|
||||
const int nx_min = mesh->info.int_params[AC_nx_min];
|
||||
const int nx_max = mesh->info.int_params[AC_nx_max];
|
||||
const int ny_min = mesh->info.int_params[AC_ny_min];
|
||||
const int ny_max = mesh->info.int_params[AC_ny_max];
|
||||
const int nz_min = mesh->info.int_params[AC_nz_min];
|
||||
const int nz_max = mesh->info.int_params[AC_nz_max];
|
||||
|
||||
const double DX = mesh->info.real_params[AC_dsx];
|
||||
const double DY = mesh->info.real_params[AC_dsy];
|
||||
const double DZ = mesh->info.real_params[AC_dsz];
|
||||
|
||||
const double xorig = double(XORIG) - 0.000001;
|
||||
const double yorig = double(YORIG) - 0.000001;
|
||||
const double zorig = double(ZORIG) - 0.000001;
|
||||
|
||||
const double INIT_LOC_UU_X = 0.0;
|
||||
const double INIT_LOC_UU_Y = 0.0;
|
||||
const double INIT_LOC_UU_Z = 0.0;
|
||||
|
||||
const double AMPL_UU = mesh->info.real_params[AC_ampl_uu];
|
||||
const double UU_SHELL_R = 0.8;
|
||||
const double WIDTH_UU = 0.2;
|
||||
|
||||
// Outward explosion with gaussian initial velocity profile.
|
||||
int idx;
|
||||
double xx, yy, zz, rr2, rr, theta = 0.0, phi = 0.0;
|
||||
double uu_radial;
|
||||
|
||||
// double theta_old = 0.0;
|
||||
|
||||
for (int k = nz_min; k < nz_max; k++) {
|
||||
for (int j = ny_min; j < ny_max; j++) {
|
||||
for (int i = nx_min; i < nx_max; i++) {
|
||||
// Calculate the value of velocity in a particular radius.
|
||||
idx = i + j * mx + k * mx * my;
|
||||
// Determine the coordinates
|
||||
xx = DX * (i - nx_min) - xorig;
|
||||
xx = xx - INIT_LOC_UU_X;
|
||||
|
||||
yy = DY * (j - ny_min) - yorig;
|
||||
yy = yy - INIT_LOC_UU_Y;
|
||||
|
||||
zz = DZ * (k - nz_min) - zorig;
|
||||
zz = zz - INIT_LOC_UU_Z;
|
||||
|
||||
rr2 = pow(xx, 2.0) + pow(yy, 2.0) + pow(zz, 2.0);
|
||||
rr = sqrt(rr2);
|
||||
|
||||
// Origin is different!
|
||||
double xx_abs, yy_abs, zz_abs;
|
||||
if (rr > 0.0) {
|
||||
// theta range [0, PI]
|
||||
if (zz >= 0.0) {
|
||||
theta = acos(zz / rr);
|
||||
if (theta > M_PI / 2.0 || theta < 0.0) {
|
||||
printf("Explosion THETA WRONG: zz = %.3f, rr = "
|
||||
"%.3f, theta = %.3e/PI, M_PI = %.3e\n",
|
||||
zz, rr, theta / M_PI, M_PI);
|
||||
}
|
||||
}
|
||||
else {
|
||||
zz_abs = -zz; // Needs a posite value for acos
|
||||
theta = M_PI - acos(zz_abs / rr);
|
||||
if (theta < M_PI / 2.0 || theta > 2 * M_PI) {
|
||||
printf("Explosion THETA WRONG: zz = %.3f, rr = "
|
||||
"%.3f, theta = %.3e/PI, M_PI = %.3e\n",
|
||||
zz, rr, theta / M_PI, M_PI);
|
||||
}
|
||||
}
|
||||
|
||||
// phi range [0, 2*PI]i
|
||||
if (xx != 0.0) {
|
||||
if (xx < 0.0 && yy >= 0.0) {
|
||||
//-+
|
||||
xx_abs = -xx; // Needs a posite value for atan
|
||||
phi = M_PI - atan(yy / xx_abs);
|
||||
if (phi < (M_PI / 2.0) || phi > M_PI) {
|
||||
printf("Explosion PHI WRONG -+: xx = %.3f, yy "
|
||||
"= %.3f, phi = %.3e/PI, M_PI = %.3e\n",
|
||||
xx, yy, phi / M_PI, M_PI);
|
||||
}
|
||||
}
|
||||
else if (xx > 0.0 && yy < 0.0) {
|
||||
//+-
|
||||
yy_abs = -yy;
|
||||
phi = 2.0 * M_PI - atan(yy_abs / xx);
|
||||
if (phi < (3.0 * M_PI) / 2.0 ||
|
||||
phi > (2.0 * M_PI + 1e-6)) {
|
||||
printf("Explosion PHI WRONG +-: xx = %.3f, yy "
|
||||
"= %.3f, phi = %.3e/PI, M_PI = %.3e\n",
|
||||
xx, yy, phi / M_PI, M_PI);
|
||||
}
|
||||
}
|
||||
else if (xx < 0.0 && yy < 0.0) {
|
||||
//--
|
||||
yy_abs = -yy;
|
||||
xx_abs = -xx;
|
||||
phi = M_PI + atan(yy_abs / xx_abs);
|
||||
if (phi < M_PI ||
|
||||
phi > ((3.0 * M_PI) / 2.0 + 1e-6)) {
|
||||
printf("Explosion PHI WRONG --: xx = %.3f, yy "
|
||||
"= %.3f, xx_abs = %.3f, yy_abs = %.3f, "
|
||||
"phi = %.3e, (3.0*M_PI)/2.0 = %.3e\n",
|
||||
xx, yy, xx_abs, yy_abs, phi,
|
||||
(3.0 * M_PI) / 2.0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//++
|
||||
phi = atan(yy / xx);
|
||||
if (phi < 0 || phi > M_PI / 2.0) {
|
||||
printf(
|
||||
"Explosion PHI WRONG --: xx = %.3f, yy = "
|
||||
"%.3f, phi = %.3e, (3.0*M_PI)/2.0 = %.3e\n",
|
||||
xx, yy, phi, (3.0 * M_PI) / 2.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // To avoid div by zero with atan
|
||||
if (yy > 0.0) {
|
||||
phi = M_PI / 2.0;
|
||||
}
|
||||
else if (yy < 0.0) {
|
||||
phi = (3.0 * M_PI) / 2.0;
|
||||
}
|
||||
else {
|
||||
phi = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// Set zero for explicit safekeeping
|
||||
if (xx == 0.0 && yy == 0.0) {
|
||||
phi = 0.0;
|
||||
}
|
||||
|
||||
// Gaussian velocity
|
||||
// uu_radial = AMPL_UU*exp( -rr2 / (2.0*pow(WIDTH_UU, 2.0))
|
||||
// ); New distribution, where that gaussion wave is not in
|
||||
// the exact centre coordinates uu_radial = AMPL_UU*exp(
|
||||
// -pow((rr - 4.0*WIDTH_UU),2.0) / (2.0*pow(WIDTH_UU, 2.0))
|
||||
// ); //TODO: Parametrize the peak location.
|
||||
uu_radial = AMPL_UU * exp(-pow((rr - UU_SHELL_R), 2.0) /
|
||||
(2.0 * pow(WIDTH_UU, 2.0)));
|
||||
}
|
||||
else {
|
||||
uu_radial = 0.0; // TODO: There will be a discontinuity in
|
||||
// the origin... Should the shape of the
|
||||
// distribution be different?
|
||||
}
|
||||
|
||||
// Determine the carthesian velocity components and lnrho
|
||||
uu_x[idx] = AcReal(uu_radial * sin(theta) * cos(phi));
|
||||
uu_y[idx] = AcReal(uu_radial * sin(theta) * sin(phi));
|
||||
uu_z[idx] = AcReal(uu_radial * cos(theta));
|
||||
|
||||
// Temporary diagnosticv output (TODO: Remove after not needed)
|
||||
// if (theta > theta_old) {
|
||||
// if (theta > M_PI || theta < 0.0 || phi < 0.0 || phi > 2*M_PI)
|
||||
// {
|
||||
/* printf("Explosion: xx = %.3f, yy = %.3f, zz = %.3f, rr =
|
||||
%.3f, phi = %.3e/PI, theta = %.3e/PI\n, M_PI = %.3e", xx, yy,
|
||||
zz, rr, phi/M_PI, theta/M_PI, M_PI); printf(" uu_radial =
|
||||
%.3e, uu_x[%i] = %.3e, uu_y[%i] = %.3e, uu_z[%i] = %.3e \n",
|
||||
uu_radial, idx, uu_x[idx], idx, uu_y[idx], idx,
|
||||
uu_z[idx]); theta_old = theta;
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
acmesh_init_to(const InitType& init_type, AcMesh* mesh)
|
||||
{
|
||||
srand(123456789);
|
||||
|
||||
|
||||
const int n = AC_VTXBUF_SIZE(mesh->info);
|
||||
|
||||
const int mx = mesh->info.int_params[AC_mx];
|
||||
const int my = mesh->info.int_params[AC_my];
|
||||
const int mz = mesh->info.int_params[AC_mz];
|
||||
|
||||
const int nx_min = mesh->info.int_params[AC_nx_min];
|
||||
const int nx_max = mesh->info.int_params[AC_nx_max];
|
||||
const int ny_min = mesh->info.int_params[AC_ny_min];
|
||||
const int ny_max = mesh->info.int_params[AC_ny_max];
|
||||
const int nz_min = mesh->info.int_params[AC_nz_min];
|
||||
const int nz_max = mesh->info.int_params[AC_nz_max];
|
||||
|
||||
switch (init_type) {
|
||||
case INIT_TYPE_RANDOM: {
|
||||
acmesh_clear(mesh);
|
||||
const AcReal range = AcReal(0.01);
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
for (int i = 0; i < n; ++i)
|
||||
mesh->vertex_buffer[w][i] = 2 * range * randr() - range;
|
||||
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_GAUSSIAN_RADIAL_EXPL:
|
||||
acmesh_clear(mesh);
|
||||
//acmesh_init_to(INIT_TYPE_RANDOM, mesh);
|
||||
gaussian_radial_explosion(mesh);
|
||||
|
||||
break;
|
||||
case INIT_TYPE_XWAVE:
|
||||
acmesh_clear(mesh);
|
||||
acmesh_init_to(INIT_TYPE_RANDOM, mesh);
|
||||
for (int k = 0; k < mz; k++) {
|
||||
for (int j = 0; j < my; j++) {
|
||||
for (int i = 0; i < mx; i++) {
|
||||
int idx = i + j * mx + k * mx * my;
|
||||
mesh->vertex_buffer[VTXBUF_UUX][idx] = 2*AcReal(sin(j * AcReal(M_PI) / mx)) - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case INIT_TYPE_VEDGE:
|
||||
acmesh_clear(mesh);
|
||||
inflow_vedge_freefall(mesh);
|
||||
break;
|
||||
case INIT_TYPE_VEDGEX:
|
||||
acmesh_clear(mesh);
|
||||
inflow_freefall_x(mesh);
|
||||
break;
|
||||
case INIT_TYPE_RAYLEIGH_TAYLOR:
|
||||
acmesh_clear(mesh);
|
||||
inflow_freefall_x(mesh);
|
||||
lnrho_step(mesh);
|
||||
break;
|
||||
case INIT_TYPE_ABC_FLOW: {
|
||||
acmesh_clear(mesh);
|
||||
acmesh_init_to(INIT_TYPE_RANDOM, mesh);
|
||||
for (int k = nz_min; k < nz_max; k++) {
|
||||
for (int j = ny_min; j < ny_max; j++) {
|
||||
for (int i = nx_min; i < nx_max; i++) {
|
||||
const int idx = i + j * mx + k * mx * my;
|
||||
|
||||
/*
|
||||
const double xx = double(
|
||||
mesh->info.real_params[AC_dsx] *
|
||||
(i - mesh->info.int_params[AC_nx_min]) -
|
||||
XORIG + AcReal(.5) * mesh->info.real_params[AC_dsx]);
|
||||
const double yy = double(
|
||||
mesh->info.real_params[AC_dsy] *
|
||||
(j - mesh->info.int_params[AC_ny_min]) -
|
||||
YORIG + AcReal(.5) * mesh->info.real_params[AC_dsy]);
|
||||
const double zz = double(
|
||||
mesh->info.real_params[AC_dsz] *
|
||||
(k - mesh->info.int_params[AC_nz_min]) -
|
||||
ZORIG + AcReal(.5) * mesh->info.real_params[AC_dsz]);
|
||||
*/
|
||||
|
||||
const AcReal xx = (i - nx_min) * mesh->info.real_params[AC_dsx] - XORIG;
|
||||
const AcReal yy = (j - ny_min) * mesh->info.real_params[AC_dsy] - YORIG;
|
||||
const AcReal zz = (k - nz_min) * mesh->info.real_params[AC_dsz] - ZORIG;
|
||||
|
||||
const AcReal ampl_uu = 0.5;
|
||||
const AcReal ABC_A = 1.;
|
||||
const AcReal ABC_B = 1.;
|
||||
const AcReal ABC_C = 1.;
|
||||
const AcReal kx_uu = 8.;
|
||||
const AcReal ky_uu = 8.;
|
||||
const AcReal kz_uu = 8.;
|
||||
|
||||
mesh->vertex_buffer[VTXBUF_UUX][idx] = ampl_uu * (ABC_A * (AcReal)sin(kz_uu * zz) + ABC_C * (AcReal)cos(ky_uu * yy));
|
||||
mesh->vertex_buffer[VTXBUF_UUY][idx] = ampl_uu * (ABC_B * (AcReal)sin(kx_uu * xx) + ABC_A * (AcReal)cos(kz_uu * zz));
|
||||
mesh->vertex_buffer[VTXBUF_UUZ][idx] = ampl_uu * (ABC_C * (AcReal)sin(ky_uu * yy) + ABC_B * (AcReal)cos(kx_uu * xx));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_RAYLEIGH_BENARD: {
|
||||
acmesh_init_to(INIT_TYPE_RANDOM, mesh);
|
||||
#if LTEMPERATURE
|
||||
vertex_buffer_set(VTXBUF_LNRHO, 1, mesh);
|
||||
const AcReal range = AcReal(0.9);
|
||||
for (int k = nz_min; k < nz_max; k++) {
|
||||
for (int j = ny_min; j < ny_max; j++) {
|
||||
for (int i = nx_min; i < nx_max; i++) {
|
||||
const int idx = i + j * mx + k * mx * my;
|
||||
mesh->vertex_buffer[VTXBUF_TEMPERATURE][idx] = (range * (k - nz_min)) / mesh->info.int_params[AC_nz] + 0.1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
WARNING("INIT_TYPE_RAYLEIGH_BERNARD called even though VTXBUF_TEMPERATURE is not used");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ERROR("Unknown init_type");
|
||||
}
|
||||
|
||||
AcReal max_val = AcReal(-1e-32);
|
||||
AcReal min_val = AcReal(1e32);
|
||||
// Normalize the grid
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w) {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (mesh->vertex_buffer[w][i] < min_val)
|
||||
min_val = mesh->vertex_buffer[w][i];
|
||||
if (mesh->vertex_buffer[w][i] > max_val)
|
||||
max_val = mesh->vertex_buffer[w][i];
|
||||
}
|
||||
}
|
||||
printf("MAX: %f MIN %f\n", double(max_val), double(min_val));
|
||||
/*
|
||||
const AcReal inv_range = AcReal(1.) / fabs(max_val - min_val);
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w) {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
mesh->vertex_buffer[w][i] = 2*inv_range*(mesh->vertex_buffer[w][i] - min_val) - 1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
acmesh_destroy(AcMesh* mesh)
|
||||
{
|
||||
for (int i = 0; i < NUM_VTXBUF_HANDLES; ++i)
|
||||
free(mesh->vertex_buffer[VertexBufferHandle(i)]);
|
||||
|
||||
free(mesh);
|
||||
}
|
||||
|
||||
|
||||
ModelMesh*
|
||||
modelmesh_create(const AcMeshInfo& mesh_info)
|
||||
{
|
||||
ModelMesh* mesh = (ModelMesh*)malloc(sizeof(*mesh));
|
||||
mesh->info = mesh_info;
|
||||
|
||||
const size_t bytes = AC_VTXBUF_SIZE(mesh->info) * sizeof(mesh->vertex_buffer[0][0]);
|
||||
for (int i = 0; i < NUM_VTXBUF_HANDLES; ++i) {
|
||||
mesh->vertex_buffer[VertexBufferHandle(i)] = (ModelScalar*)malloc(bytes);
|
||||
ERRCHK(mesh->vertex_buffer[VertexBufferHandle(i)] != NULL);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
void
|
||||
modelmesh_destroy(ModelMesh* mesh)
|
||||
{
|
||||
for (int i = 0; i < NUM_VTXBUF_HANDLES; ++i)
|
||||
free(mesh->vertex_buffer[VertexBufferHandle(i)]);
|
||||
|
||||
free(mesh);
|
||||
}
|
||||
|
||||
#include <string.h> // memcpy
|
||||
void
|
||||
acmesh_to_modelmesh(const AcMesh& acmesh, ModelMesh* modelmesh)
|
||||
{
|
||||
ERRCHK(sizeof(acmesh.info) == sizeof(modelmesh->info));
|
||||
memcpy(&modelmesh->info, &acmesh.info, sizeof(acmesh.info));
|
||||
|
||||
for (int i = 0; i < NUM_VTXBUF_HANDLES; ++i)
|
||||
for (size_t j = 0; j < AC_VTXBUF_SIZE(acmesh.info); ++j)
|
||||
modelmesh->vertex_buffer[i][j] = (ModelScalar)acmesh.vertex_buffer[i][j];
|
||||
}
|
||||
|
||||
void
|
||||
modelmesh_to_acmesh(const ModelMesh& modelmesh, AcMesh* acmesh)
|
||||
{
|
||||
ERRCHK(sizeof(acmesh->info) == sizeof(modelmesh.info));
|
||||
memcpy(&acmesh->info, &modelmesh.info, sizeof(modelmesh.info));
|
||||
|
||||
for (int i = 0; i < NUM_VTXBUF_HANDLES; ++i)
|
||||
for (size_t j = 0; j < AC_VTXBUF_SIZE(modelmesh.info); ++j)
|
||||
acmesh->vertex_buffer[i][j] = (AcReal)modelmesh.vertex_buffer[i][j];
|
||||
}
|
||||
58
src/standalone/model/host_memory.h
Normal file
58
src/standalone/model/host_memory.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright (C) 2014-2018, Johannes Pekkilae, Miikka Vaeisalae.
|
||||
|
||||
This file is part of Astaroth.
|
||||
|
||||
Astaroth is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Astaroth is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Astaroth. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* \brief Brief info.
|
||||
*
|
||||
* Detailed info.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include "astaroth.h"
|
||||
#include "modelmesh.h"
|
||||
|
||||
// clang-format off
|
||||
#define AC_FOR_INIT_TYPES(FUNC)\
|
||||
FUNC(INIT_TYPE_RANDOM), \
|
||||
FUNC(INIT_TYPE_XWAVE), \
|
||||
FUNC(INIT_TYPE_GAUSSIAN_RADIAL_EXPL), \
|
||||
FUNC(INIT_TYPE_ABC_FLOW) , \
|
||||
FUNC(INIT_TYPE_VEDGE), \
|
||||
FUNC(INIT_TYPE_VEDGEX), \
|
||||
FUNC(INIT_TYPE_RAYLEIGH_TAYLOR), \
|
||||
FUNC(INIT_TYPE_RAYLEIGH_BENARD)
|
||||
// clang-format on
|
||||
|
||||
typedef enum { AC_FOR_INIT_TYPES(AC_GEN_ID), NUM_INIT_TYPES } InitType;
|
||||
|
||||
extern const char* init_type_names[]; // Defined in host_memory.cc
|
||||
|
||||
AcMesh* acmesh_create(const AcMeshInfo& mesh_info);
|
||||
|
||||
void acmesh_clear(AcMesh* mesh);
|
||||
|
||||
void acmesh_init_to(const InitType& type, AcMesh* mesh);
|
||||
|
||||
void acmesh_destroy(AcMesh* mesh);
|
||||
|
||||
ModelMesh* modelmesh_create(const AcMeshInfo& mesh_info);
|
||||
void modelmesh_destroy(ModelMesh* mesh);
|
||||
void acmesh_to_modelmesh(const AcMesh& acmesh, ModelMesh* modelmesh);
|
||||
void modelmesh_to_acmesh(const ModelMesh& model, AcMesh* acmesh);
|
||||
63
src/standalone/model/host_timestep.cc
Normal file
63
src/standalone/model/host_timestep.cc
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
Copyright (C) 2014-2018, Johannes Pekkilae, Miikka Vaeisalae.
|
||||
|
||||
This file is part of Astaroth.
|
||||
|
||||
Astaroth is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Astaroth is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Astaroth. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* \brief Brief info.
|
||||
*
|
||||
* Detailed info.
|
||||
*
|
||||
*/
|
||||
#include "host_timestep.h"
|
||||
|
||||
#include "core/math_utils.h"
|
||||
|
||||
static AcReal timescale = AcReal(1.0);
|
||||
|
||||
AcReal
|
||||
host_timestep(const AcReal& umax, const AcMeshInfo& mesh_info)
|
||||
{
|
||||
const long double cdt = mesh_info.real_params[AC_cdt];
|
||||
const long double cdtv = mesh_info.real_params[AC_cdtv];
|
||||
// const long double cdts = mesh_info.real_params[AC_cdts];
|
||||
const long double cs2_sound = mesh_info.real_params[AC_cs2_sound];
|
||||
const long double nu_visc = mesh_info.real_params[AC_nu_visc];
|
||||
const long double eta = mesh_info.real_params[AC_eta];
|
||||
const long double chi = 0; // mesh_info.real_params[AC_chi]; // TODO not calculated
|
||||
const long double gamma = mesh_info.real_params[AC_gamma];
|
||||
const long double dsmin = mesh_info.real_params[AC_dsmin];
|
||||
|
||||
// Old ones from legacy Astaroth
|
||||
//const long double uu_dt = cdt * (dsmin / (umax + cs_sound));
|
||||
//const long double visc_dt = cdtv * dsmin * dsmin / nu_visc;
|
||||
|
||||
// New, closer to the actual Courant timestep
|
||||
// See Pencil Code user manual p. 38 (timestep section)
|
||||
const long double uu_dt = cdt * dsmin / (fabsl(umax) + sqrtl(cs2_sound + 0.0l));
|
||||
const long double visc_dt = cdtv * dsmin * dsmin / max(max(nu_visc, eta), max(gamma, chi)) + 1; // TODO NOTE: comment the +1 out to get scientifically accurate results
|
||||
|
||||
const long double dt = min(uu_dt, visc_dt);
|
||||
return AcReal(timescale) * AcReal(dt);
|
||||
}
|
||||
|
||||
void
|
||||
set_timescale(const AcReal scale)
|
||||
{
|
||||
timescale = scale;
|
||||
}
|
||||
32
src/standalone/model/host_timestep.h
Normal file
32
src/standalone/model/host_timestep.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright (C) 2014-2018, Johannes Pekkilae, Miikka Vaeisalae.
|
||||
|
||||
This file is part of Astaroth.
|
||||
|
||||
Astaroth is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Astaroth is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Astaroth. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* \brief Brief info.
|
||||
*
|
||||
* Detailed info.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include "astaroth.h"
|
||||
|
||||
AcReal host_timestep(const AcReal& umax, const AcMeshInfo& mesh_info);
|
||||
|
||||
void set_timescale(const AcReal scale);
|
||||
487
src/standalone/model/model_boundconds.cc
Normal file
487
src/standalone/model/model_boundconds.cc
Normal file
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
Copyright (C) 2014-2018, Johannes Pekkilae, Miikka Vaeisalae.
|
||||
|
||||
This file is part of Astaroth.
|
||||
|
||||
Astaroth is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) amy later version.
|
||||
|
||||
Astaroth is distributed in the hope that it will be useful,
|
||||
but WITHOUT Amy WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Astaroth. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* \brief Brief info.
|
||||
*
|
||||
* Detailed info.
|
||||
*
|
||||
*/
|
||||
#include "model_boundconds.h"
|
||||
|
||||
#include "core/errchk.h"
|
||||
|
||||
|
||||
void
|
||||
boundconds(const AcMeshInfo& mesh_info, ModelMesh* mesh)
|
||||
{
|
||||
#pragma omp parallel for
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w) {
|
||||
const int3 start = (int3){0, 0, 0};
|
||||
const int3 end = (int3){
|
||||
mesh_info.int_params[AC_mx],
|
||||
mesh_info.int_params[AC_my],
|
||||
mesh_info.int_params[AC_mz]
|
||||
};
|
||||
|
||||
const int nx = mesh_info.int_params[AC_nx];
|
||||
const int ny = mesh_info.int_params[AC_ny];
|
||||
const int nz = mesh_info.int_params[AC_nz];
|
||||
|
||||
const int nx_min = mesh_info.int_params[AC_nx_min];
|
||||
const int ny_min = mesh_info.int_params[AC_ny_min];
|
||||
const int nz_min = mesh_info.int_params[AC_nz_min];
|
||||
|
||||
// The old kxt was inclusive, but our mx_max is exclusive
|
||||
const int nx_max = mesh_info.int_params[AC_nx_max];
|
||||
const int ny_max = mesh_info.int_params[AC_ny_max];
|
||||
const int nz_max = mesh_info.int_params[AC_nz_max];
|
||||
|
||||
for (int k_dst = start.z; k_dst < end.z; ++k_dst) {
|
||||
for (int j_dst = start.y; j_dst < end.y; ++j_dst) {
|
||||
for (int i_dst = start.x; i_dst < end.x; ++i_dst) {
|
||||
|
||||
// If destination index is inside the computational domain, return since
|
||||
// the boundary conditions are only applied to the ghost zones
|
||||
if (i_dst >= nx_min && i_dst < nx_max &&
|
||||
j_dst >= ny_min && j_dst < ny_max &&
|
||||
k_dst >= nz_min && k_dst < nz_max)
|
||||
continue;
|
||||
|
||||
// Find the source index
|
||||
// Map to nx, ny, nz coordinates
|
||||
int i_src = i_dst - nx_min;
|
||||
int j_src = j_dst - ny_min;
|
||||
int k_src = k_dst - nz_min;
|
||||
|
||||
// Translate (s.t. the index is always positive)
|
||||
i_src += nx;
|
||||
j_src += ny;
|
||||
k_src += nz;
|
||||
|
||||
// Wrap
|
||||
i_src %= nx;
|
||||
j_src %= ny;
|
||||
k_src %= nz;
|
||||
|
||||
// Map to mx, my, mz coordinates
|
||||
i_src += nx_min;
|
||||
j_src += ny_min;
|
||||
k_src += nz_min;
|
||||
|
||||
const size_t src_idx = AC_VTXBUF_IDX(i_src, j_src, k_src, mesh_info);
|
||||
const size_t dst_idx = AC_VTXBUF_IDX(i_dst, j_dst, k_dst, mesh_info);
|
||||
ERRCHK(src_idx < AC_VTXBUF_SIZE(mesh_info));
|
||||
ERRCHK(dst_idx < AC_VTXBUF_SIZE(mesh_info));
|
||||
mesh->vertex_buffer[w][dst_idx] = mesh->vertex_buffer[w][src_idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
boundconds(const AcMeshInfo& mesh_info, ModelMesh* mesh)
|
||||
{
|
||||
const int mx = mesh_info.int_params[AC_mx];
|
||||
const int my = mesh_info.int_params[AC_my];
|
||||
const int mz = mesh_info.int_params[AC_mz];
|
||||
|
||||
// Volatile here suppresses the warning about strict-overflow (i.e. compiler
|
||||
// wanted to optimize these loops by assuming that kxb etc never overflow)
|
||||
// However we do not need the performance improvement (~1-3%) and it's
|
||||
// not either good to
|
||||
// a) get useless warnings originating from here
|
||||
// b) disable the warnings completely
|
||||
volatile const int kxb = mesh_info.int_params[AC_nx_min];
|
||||
volatile const int kyb = mesh_info.int_params[AC_ny_min];
|
||||
volatile const int kzb = mesh_info.int_params[AC_nz_min];
|
||||
|
||||
// The old kxt was inclusive, but our mx_max is exclusive
|
||||
volatile const int kxt = mesh_info.int_params[AC_nx_max] - 1;
|
||||
volatile const int kyt = mesh_info.int_params[AC_ny_max] - 1;
|
||||
volatile const int kzt = mesh_info.int_params[AC_nz_max] - 1;
|
||||
const int bound[3] = {0, 0, 0};
|
||||
|
||||
// Periodic boundary conditions
|
||||
if (bound[0] == 0) {
|
||||
for (int k = kzb; k <= kzt; k++) {
|
||||
for (int j = kyb; j <= kyt; j++) {
|
||||
for (int i = kxb; i <= kxb + 2; i++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (kxt + i - 2) + j * mx + k * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
for (int i = kxt - 2; i <= kxt; i++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i - kxt + 2) + j * mx + k * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bound[1] == 0) {
|
||||
for (int k = kzb; k <= kzt; k++) {
|
||||
for (int i = kxb; i <= kxt; i++) {
|
||||
for (int j = kyb; j <= kyb + 2; j++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = i + (kyt + j - 2) * mx + k * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
for (int j = kyt - 2; j <= kyt; j++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = i + (j - kyt + 2) * mx + k * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bound[2] == 0) {
|
||||
for (int i = kxb; i <= kxt; i++) {
|
||||
for (int j = kyb; j <= kyt; j++) {
|
||||
for (int k = kzb; k <= kzb + 2; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = i + j * mx + (kzt + k - 2) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
for (int k = kzt - 2; k <= kzt; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = i + j * mx + (k - kzt + 2) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the corners in the fully periodic case
|
||||
if (bound[0] == 0 && bound[1] == 0 && bound[2] == 0) {
|
||||
// Source corner: x=0, y=0, z=0
|
||||
for (int i = kxb; i <= kxb + 2; i++) {
|
||||
for (int j = kyb; j <= kyb + 2; j++) {
|
||||
for (int k = kzb; k <= kzb + 2; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i + mx - STENCIL_ORDER) + (j + my - STENCIL_ORDER) * mx +
|
||||
(k + mz - STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source corner: x=1, y=0, z=0
|
||||
for (int i = kxt - 2; i <= kxt; i++) {
|
||||
for (int j = kyb; j <= kyb + 2; j++) {
|
||||
for (int k = kzb; k <= kzb + 2; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i - mx + STENCIL_ORDER) + (j + my - STENCIL_ORDER) * mx +
|
||||
(k + mz - STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source corner: x=0, y=1, z=0
|
||||
for (int i = kxb; i <= kxb + 2; i++) {
|
||||
for (int j = kyt - 2; j <= kyt; j++) {
|
||||
for (int k = kzb; k <= kzb + 2; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i + mx - STENCIL_ORDER) + (j - my + STENCIL_ORDER) * mx +
|
||||
(k + mz - STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source corner: x=0, y=0, z=1
|
||||
for (int i = kxb; i <= kxb + 2; i++) {
|
||||
for (int j = kyb; j <= kyb + 2; j++) {
|
||||
for (int k = kzt - 2; k <= kzt; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i + mx - STENCIL_ORDER) + (j + my - STENCIL_ORDER) * mx +
|
||||
(k - mz + STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source corner: x=1, y=1, z=0
|
||||
for (int i = kxt - 2; i <= kxt; i++) {
|
||||
for (int j = kyt - 2; j <= kyt; j++) {
|
||||
for (int k = kzb; k <= kzb + 2; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i - mx + STENCIL_ORDER) + (j - my + STENCIL_ORDER) * mx +
|
||||
(k + mz - STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source corner: x=1, y=0, z=1
|
||||
for (int i = kxt - 2; i <= kxt; i++) {
|
||||
for (int j = kyb; j <= kyb + 2; j++) {
|
||||
for (int k = kzt - 2; k <= kzt; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i - mx + STENCIL_ORDER) + (j + my - STENCIL_ORDER) * mx +
|
||||
(k - mz + STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source corner: x=0, y=1, z=1
|
||||
for (int i = kxb; i <= kxb + 2; i++) {
|
||||
for (int j = kyt - 2; j <= kyt; j++) {
|
||||
for (int k = kzt - 2; k <= kzt; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i + mx - STENCIL_ORDER) + (j - my + STENCIL_ORDER) * mx +
|
||||
(k - mz + STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source corner: x=1, y=1, z=1
|
||||
for (int i = kxt - 2; i <= kxt; i++) {
|
||||
for (int j = kyt - 2; j <= kyt; j++) {
|
||||
for (int k = kzt - 2; k <= kzt; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i - mx + STENCIL_ORDER) + (j - my + STENCIL_ORDER) * mx +
|
||||
(k - mz + STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ERROR("ONLY FULLY PERIODIC WORKS WITH CORNERS SO FAR! \n");
|
||||
}
|
||||
|
||||
// Copy the edges in the fully periodic case
|
||||
if (bound[0] == 0 && bound[1] == 0 && bound[2] == 0) {
|
||||
// Source edge: x = 0, y = 0
|
||||
for (int i = kxb; i <= kxb + 2; i++) {
|
||||
for (int j = kyb; j <= kyb + 2; j++) {
|
||||
for (int k = kzb; k <= kzt; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i + mx - STENCIL_ORDER) + (j + my - STENCIL_ORDER) * mx +
|
||||
k * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source edge: x = 1, y = 0
|
||||
for (int i = kxt - 2; i <= kxt; i++) {
|
||||
for (int j = kyb; j <= kyb + 2; j++) {
|
||||
for (int k = kzb; k <= kzt; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i - mx + STENCIL_ORDER) + (j + my - STENCIL_ORDER) * mx +
|
||||
k * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source edge: x = 0, y = 1
|
||||
for (int i = kxb; i <= kxb + 2; i++) {
|
||||
for (int j = kyt - 2; j <= kyt; j++) {
|
||||
for (int k = kzb; k <= kzt; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i + mx - STENCIL_ORDER) + (j - my + STENCIL_ORDER) * mx +
|
||||
k * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source edge: x = 1, y = 1
|
||||
for (int i = kxt - 2; i <= kxt; i++) {
|
||||
for (int j = kyt - 2; j <= kyt; j++) {
|
||||
for (int k = kzb; k <= kzt; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i - mx + STENCIL_ORDER) + (j - my + STENCIL_ORDER) * mx +
|
||||
k * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source edge: x = 0, z = 0
|
||||
for (int i = kxb; i <= kxb + 2; i++) {
|
||||
for (int j = kyb; j <= kyt; j++) {
|
||||
for (int k = kzb; k <= kzb + 2; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i + mx - STENCIL_ORDER) + j * mx +
|
||||
(k + mz - STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source edge: x = 1, z = 0
|
||||
for (int i = kxt - 2; i <= kxt; i++) {
|
||||
for (int j = kyb; j <= kyt; j++) {
|
||||
for (int k = kzb; k <= kzb + 2; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i - mx + STENCIL_ORDER) + j * mx +
|
||||
(k + mz - STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source edge: x = 0, z = 1
|
||||
for (int i = kxb; i <= kxb + 2; i++) {
|
||||
for (int j = kyb; j <= kyt; j++) {
|
||||
for (int k = kzt - 2; k <= kzt; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i + mx - STENCIL_ORDER) + j * mx +
|
||||
(k - mz + STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source edge: x = 1, z = 1
|
||||
for (int i = kxt - 2; i <= kxt; i++) {
|
||||
for (int j = kyb; j <= kyt; j++) {
|
||||
for (int k = kzt - 2; k <= kzt; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = (i - mx + STENCIL_ORDER) + j * mx +
|
||||
(k - mz + STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source edge: y = 0, z = 0
|
||||
for (int i = kxb; i <= kxt; i++) {
|
||||
for (int j = kyb; j <= kyb + 2; j++) {
|
||||
for (int k = kzb; k <= kzb + 2; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = i + (j + my - STENCIL_ORDER) * mx +
|
||||
(k + mz - STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source edge: y = 1, z = 0
|
||||
for (int i = kxb; i <= kxt; i++) {
|
||||
for (int j = kyt - 2; j <= kyt; j++) {
|
||||
for (int k = kzb; k <= kzb + 2; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = i + (j - my + STENCIL_ORDER) * mx +
|
||||
(k + mz - STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source edge: y = 0, z = 1
|
||||
for (int i = kxb; i <= kxt; i++) {
|
||||
for (int j = kyb; j <= kyb + 2; j++) {
|
||||
for (int k = kzt - 2; k <= kzt; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = i + (j + my - STENCIL_ORDER) * mx +
|
||||
(k - mz + STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Source edge: y = 1, z = 1
|
||||
for (int i = kxb; i <= kxt; i++) {
|
||||
for (int j = kyt - 2; j <= kyt; j++) {
|
||||
for (int k = kzt - 2; k <= kzt; k++) {
|
||||
const int inds = i + j * mx + k * mx * my;
|
||||
const int indr = i + (j - my + STENCIL_ORDER) * mx +
|
||||
(k - mz + STENCIL_ORDER) * mx * my;
|
||||
for (int w = 0; w < NUM_VTXBUF_HANDLES; ++w)
|
||||
mesh->vertex_buffer[w]
|
||||
[indr] = mesh->vertex_buffer[w]
|
||||
[inds];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ERROR("ONLY FULLY PERIODIC WORKS WITH EDGES SO FAR! \n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
31
src/standalone/model/model_boundconds.h
Normal file
31
src/standalone/model/model_boundconds.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright (C) 2014-2018, Johannes Pekkilae, Miikka Vaeisalae.
|
||||
|
||||
This file is part of Astaroth.
|
||||
|
||||
Astaroth is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Astaroth is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Astaroth. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* \brief Brief info.
|
||||
*
|
||||
* Detailed info.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include "astaroth.h"
|
||||
#include "modelmesh.h"
|
||||
|
||||
void boundconds(const AcMeshInfo& mesh_info, ModelMesh* mesh);
|
||||
353
src/standalone/model/model_diff.h
Normal file
353
src/standalone/model/model_diff.h
Normal file
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
Copyright (C) 2014-2018, Johannes Pekkilae, Miikka Vaeisalae.
|
||||
|
||||
This file is part of Astaroth.
|
||||
|
||||
Astaroth is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Astaroth is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Astaroth. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* \brief Brief info.
|
||||
*
|
||||
* Detailed info.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include "core/errchk.h"
|
||||
|
||||
typedef long double MODEL_REAL;
|
||||
|
||||
typedef enum { AXIS_X, AXIS_Y, AXIS_Z, NUM_AXIS_TYPES } AxisType;
|
||||
|
||||
template <AxisType axis>
|
||||
static inline MODEL_REAL
|
||||
der_scal(const int& i, const int& j, const int& k, const AcMeshInfo& mesh_info,
|
||||
const MODEL_REAL* scal)
|
||||
{
|
||||
MODEL_REAL f0, f1, f2, f4, f5, f6;
|
||||
MODEL_REAL ds;
|
||||
|
||||
switch (axis) {
|
||||
case AXIS_X:
|
||||
f0 = scal[AC_VTXBUF_IDX(i - 3, j, k, mesh_info)];
|
||||
f1 = scal[AC_VTXBUF_IDX(i - 2, j, k, mesh_info)];
|
||||
f2 = scal[AC_VTXBUF_IDX(i - 1, j, k, mesh_info)];
|
||||
f4 = scal[AC_VTXBUF_IDX(i + 1, j, k, mesh_info)];
|
||||
f5 = scal[AC_VTXBUF_IDX(i + 2, j, k, mesh_info)];
|
||||
f6 = scal[AC_VTXBUF_IDX(i + 3, j, k, mesh_info)];
|
||||
ds = mesh_info.real_params[AC_dsx];
|
||||
break;
|
||||
case AXIS_Y:
|
||||
f0 = scal[AC_VTXBUF_IDX(i, j - 3, k, mesh_info)];
|
||||
f1 = scal[AC_VTXBUF_IDX(i, j - 2, k, mesh_info)];
|
||||
f2 = scal[AC_VTXBUF_IDX(i, j - 1, k, mesh_info)];
|
||||
f4 = scal[AC_VTXBUF_IDX(i, j + 1, k, mesh_info)];
|
||||
f5 = scal[AC_VTXBUF_IDX(i, j + 2, k, mesh_info)];
|
||||
f6 = scal[AC_VTXBUF_IDX(i, j + 3, k, mesh_info)];
|
||||
ds = mesh_info.real_params[AC_dsy];
|
||||
break;
|
||||
case AXIS_Z:
|
||||
f0 = scal[AC_VTXBUF_IDX(i, j, k - 3, mesh_info)];
|
||||
f1 = scal[AC_VTXBUF_IDX(i, j, k - 2, mesh_info)];
|
||||
f2 = scal[AC_VTXBUF_IDX(i, j, k - 1, mesh_info)];
|
||||
f4 = scal[AC_VTXBUF_IDX(i, j, k + 1, mesh_info)];
|
||||
f5 = scal[AC_VTXBUF_IDX(i, j, k + 2, mesh_info)];
|
||||
f6 = scal[AC_VTXBUF_IDX(i, j, k + 3, mesh_info)];
|
||||
ds = mesh_info.real_params[AC_dsz];
|
||||
break;
|
||||
default:
|
||||
ERROR("Unknown axis type");
|
||||
}
|
||||
return ((f6 - f0) + MODEL_REAL(-9.) * (f5 - f1) + MODEL_REAL(45.) * (f4 - f2)) /
|
||||
(MODEL_REAL(60.) * ds);
|
||||
}
|
||||
|
||||
template <AxisType axis>
|
||||
static inline MODEL_REAL
|
||||
der2_scal(const int& i, const int& j, const int& k, const AcMeshInfo& mesh_info,
|
||||
const MODEL_REAL* scal)
|
||||
{
|
||||
MODEL_REAL f0, f1, f2, f3, f4, f5, f6;
|
||||
MODEL_REAL ds;
|
||||
|
||||
f3 = scal[AC_VTXBUF_IDX(i, j, k, mesh_info)];
|
||||
|
||||
switch (axis) {
|
||||
case AXIS_X:
|
||||
f0 = scal[AC_VTXBUF_IDX(i - 3, j, k, mesh_info)];
|
||||
f1 = scal[AC_VTXBUF_IDX(i - 2, j, k, mesh_info)];
|
||||
f2 = scal[AC_VTXBUF_IDX(i - 1, j, k, mesh_info)];
|
||||
f4 = scal[AC_VTXBUF_IDX(i + 1, j, k, mesh_info)];
|
||||
f5 = scal[AC_VTXBUF_IDX(i + 2, j, k, mesh_info)];
|
||||
f6 = scal[AC_VTXBUF_IDX(i + 3, j, k, mesh_info)];
|
||||
ds = mesh_info.real_params[AC_dsx];
|
||||
break;
|
||||
case AXIS_Y:
|
||||
f0 = scal[AC_VTXBUF_IDX(i, j - 3, k, mesh_info)];
|
||||
f1 = scal[AC_VTXBUF_IDX(i, j - 2, k, mesh_info)];
|
||||
f2 = scal[AC_VTXBUF_IDX(i, j - 1, k, mesh_info)];
|
||||
f4 = scal[AC_VTXBUF_IDX(i, j + 1, k, mesh_info)];
|
||||
f5 = scal[AC_VTXBUF_IDX(i, j + 2, k, mesh_info)];
|
||||
f6 = scal[AC_VTXBUF_IDX(i, j + 3, k, mesh_info)];
|
||||
ds = mesh_info.real_params[AC_dsy];
|
||||
break;
|
||||
case AXIS_Z:
|
||||
f0 = scal[AC_VTXBUF_IDX(i, j, k - 3, mesh_info)];
|
||||
f1 = scal[AC_VTXBUF_IDX(i, j, k - 2, mesh_info)];
|
||||
f2 = scal[AC_VTXBUF_IDX(i, j, k - 1, mesh_info)];
|
||||
f4 = scal[AC_VTXBUF_IDX(i, j, k + 1, mesh_info)];
|
||||
f5 = scal[AC_VTXBUF_IDX(i, j, k + 2, mesh_info)];
|
||||
f6 = scal[AC_VTXBUF_IDX(i, j, k + 3, mesh_info)];
|
||||
ds = mesh_info.real_params[AC_dsz];
|
||||
break;
|
||||
default:
|
||||
ERROR("Unknown axis type");
|
||||
}
|
||||
return (MODEL_REAL(2.) * (f0 + f6) + MODEL_REAL(-27.) * (f1 + f5) +
|
||||
MODEL_REAL(270.) * (f2 + f4) + MODEL_REAL(-490.) * f3) /
|
||||
(MODEL_REAL(180.) * ds * ds);
|
||||
}
|
||||
|
||||
static MODEL_REAL
|
||||
laplace_scal(const int& i, const int& j, const int& k,
|
||||
const AcMeshInfo& mesh_info, const MODEL_REAL* scal)
|
||||
{
|
||||
return der2_scal<AXIS_X>(i, j, k, mesh_info, scal) +
|
||||
der2_scal<AXIS_Y>(i, j, k, mesh_info, scal) +
|
||||
der2_scal<AXIS_Z>(i, j, k, mesh_info, scal);
|
||||
}
|
||||
|
||||
static void
|
||||
laplace_vec(const int& i, const int& j, const int& k,
|
||||
const AcMeshInfo& mesh_info, const MODEL_REAL* vec_x,
|
||||
const MODEL_REAL* vec_y, const MODEL_REAL* vec_z, MODEL_REAL* laplace_x,
|
||||
MODEL_REAL* laplace_y, MODEL_REAL* laplace_z)
|
||||
{
|
||||
*laplace_x = laplace_scal(i, j, k, mesh_info, vec_x);
|
||||
*laplace_y = laplace_scal(i, j, k, mesh_info, vec_y);
|
||||
*laplace_z = laplace_scal(i, j, k, mesh_info, vec_z);
|
||||
}
|
||||
|
||||
static MODEL_REAL
|
||||
div_vec(const int& i, const int& j, const int& k, const AcMeshInfo& mesh_info,
|
||||
const MODEL_REAL* vec_x, const MODEL_REAL* vec_y, const MODEL_REAL* vec_z)
|
||||
{
|
||||
return der_scal<AXIS_X>(i, j, k, mesh_info, vec_x) +
|
||||
der_scal<AXIS_Y>(i, j, k, mesh_info, vec_y) +
|
||||
der_scal<AXIS_Z>(i, j, k, mesh_info, vec_z);
|
||||
}
|
||||
|
||||
static void
|
||||
grad(const int& i, const int& j, const int& k, const AcMeshInfo& mesh_info,
|
||||
const MODEL_REAL* scal, MODEL_REAL* res_x, MODEL_REAL* res_y, MODEL_REAL* res_z)
|
||||
{
|
||||
*res_x = der_scal<AXIS_X>(i, j, k, mesh_info, scal);
|
||||
*res_y = der_scal<AXIS_Y>(i, j, k, mesh_info, scal);
|
||||
*res_z = der_scal<AXIS_Z>(i, j, k, mesh_info, scal);
|
||||
}
|
||||
|
||||
static MODEL_REAL
|
||||
vec_dot_nabla_scal(const int& i, const int& j, const int& k,
|
||||
const AcMeshInfo& mesh_info, const MODEL_REAL* vec_x,
|
||||
const MODEL_REAL* vec_y, const MODEL_REAL* vec_z, const MODEL_REAL* scal)
|
||||
{
|
||||
const int idx = AC_VTXBUF_IDX(i, j, k, mesh_info);
|
||||
MODEL_REAL ddx_scal, ddy_scal, ddz_scal;
|
||||
grad(i, j, k, mesh_info, scal, &ddx_scal, &ddy_scal, &ddz_scal);
|
||||
return vec_x[idx] * ddx_scal + vec_y[idx] * ddy_scal +
|
||||
vec_z[idx] * ddz_scal;
|
||||
}
|
||||
|
||||
/*
|
||||
* =============================================================================
|
||||
* Viscosity
|
||||
* =============================================================================
|
||||
*/
|
||||
typedef enum { DERNM_XY, DERNM_YZ, DERNM_XZ } DernmType;
|
||||
|
||||
template <DernmType dernm>
|
||||
static MODEL_REAL
|
||||
dernm_scal(const int& i, const int& j, const int& k,
|
||||
const AcMeshInfo& mesh_info, const MODEL_REAL* scal)
|
||||
{
|
||||
|
||||
MODEL_REAL fac;
|
||||
|
||||
const MODEL_REAL dsx = mesh_info.real_params[AC_dsx];
|
||||
const MODEL_REAL dsy = mesh_info.real_params[AC_dsy];
|
||||
const MODEL_REAL dsz = mesh_info.real_params[AC_dsz];
|
||||
|
||||
MODEL_REAL f_p1_p1, f_m1_p1, f_m1_m1, f_p1_m1;
|
||||
MODEL_REAL f_p2_p2, f_m2_p2, f_m2_m2, f_p2_m2;
|
||||
MODEL_REAL f_p3_p3, f_m3_p3, f_m3_m3, f_p3_m3;
|
||||
|
||||
switch (dernm) {
|
||||
case DERNM_XY:
|
||||
fac = MODEL_REAL(1. / 720.) * (MODEL_REAL(1.) / dsx) * (MODEL_REAL(1.) / dsy);
|
||||
f_p1_p1 = scal[AC_VTXBUF_IDX(i + 1, j + 1, k, mesh_info)];
|
||||
f_m1_p1 = scal[AC_VTXBUF_IDX(i - 1, j + 1, k, mesh_info)];
|
||||
f_m1_m1 = scal[AC_VTXBUF_IDX(i - 1, j - 1, k, mesh_info)];
|
||||
f_p1_m1 = scal[AC_VTXBUF_IDX(i + 1, j - 1, k, mesh_info)];
|
||||
|
||||
f_p2_p2 = scal[AC_VTXBUF_IDX(i + 2, j + 2, k, mesh_info)];
|
||||
f_m2_p2 = scal[AC_VTXBUF_IDX(i - 2, j + 2, k, mesh_info)];
|
||||
f_m2_m2 = scal[AC_VTXBUF_IDX(i - 2, j - 2, k, mesh_info)];
|
||||
f_p2_m2 = scal[AC_VTXBUF_IDX(i + 2, j - 2, k, mesh_info)];
|
||||
|
||||
f_p3_p3 = scal[AC_VTXBUF_IDX(i + 3, j + 3, k, mesh_info)];
|
||||
f_m3_p3 = scal[AC_VTXBUF_IDX(i - 3, j + 3, k, mesh_info)];
|
||||
f_m3_m3 = scal[AC_VTXBUF_IDX(i - 3, j - 3, k, mesh_info)];
|
||||
f_p3_m3 = scal[AC_VTXBUF_IDX(i + 3, j - 3, k, mesh_info)];
|
||||
break;
|
||||
case DERNM_YZ:
|
||||
// NOTE this is a bit different from the old one, second is j+1k-1
|
||||
// instead of j-1,k+1
|
||||
fac = MODEL_REAL(1. / 720.) * (MODEL_REAL(1.) / dsy) * (MODEL_REAL(1.) / dsz);
|
||||
f_p1_p1 = scal[AC_VTXBUF_IDX(i, j + 1, k + 1, mesh_info)];
|
||||
f_m1_p1 = scal[AC_VTXBUF_IDX(i, j - 1, k + 1, mesh_info)];
|
||||
f_m1_m1 = scal[AC_VTXBUF_IDX(i, j - 1, k - 1, mesh_info)];
|
||||
f_p1_m1 = scal[AC_VTXBUF_IDX(i, j + 1, k - 1, mesh_info)];
|
||||
|
||||
f_p2_p2 = scal[AC_VTXBUF_IDX(i, j + 2, k + 2, mesh_info)];
|
||||
f_m2_p2 = scal[AC_VTXBUF_IDX(i, j - 2, k + 2, mesh_info)];
|
||||
f_m2_m2 = scal[AC_VTXBUF_IDX(i, j - 2, k - 2, mesh_info)];
|
||||
f_p2_m2 = scal[AC_VTXBUF_IDX(i, j + 2, k - 2, mesh_info)];
|
||||
|
||||
f_p3_p3 = scal[AC_VTXBUF_IDX(i, j + 3, k + 3, mesh_info)];
|
||||
f_m3_p3 = scal[AC_VTXBUF_IDX(i, j - 3, k + 3, mesh_info)];
|
||||
f_m3_m3 = scal[AC_VTXBUF_IDX(i, j - 3, k - 3, mesh_info)];
|
||||
f_p3_m3 = scal[AC_VTXBUF_IDX(i, j + 3, k - 3, mesh_info)];
|
||||
break;
|
||||
case DERNM_XZ:
|
||||
fac = MODEL_REAL(1. / 720.) * (MODEL_REAL(1.) / dsx) * (MODEL_REAL(1.) / dsz);
|
||||
f_p1_p1 = scal[AC_VTXBUF_IDX(i + 1, j, k + 1, mesh_info)];
|
||||
f_m1_p1 = scal[AC_VTXBUF_IDX(i - 1, j, k + 1, mesh_info)];
|
||||
f_m1_m1 = scal[AC_VTXBUF_IDX(i - 1, j, k - 1, mesh_info)];
|
||||
f_p1_m1 = scal[AC_VTXBUF_IDX(i + 1, j, k - 1, mesh_info)];
|
||||
|
||||
f_p2_p2 = scal[AC_VTXBUF_IDX(i + 2, j, k + 2, mesh_info)];
|
||||
f_m2_p2 = scal[AC_VTXBUF_IDX(i - 2, j, k + 2, mesh_info)];
|
||||
f_m2_m2 = scal[AC_VTXBUF_IDX(i - 2, j, k - 2, mesh_info)];
|
||||
f_p2_m2 = scal[AC_VTXBUF_IDX(i + 2, j, k - 2, mesh_info)];
|
||||
|
||||
f_p3_p3 = scal[AC_VTXBUF_IDX(i + 3, j, k + 3, mesh_info)];
|
||||
f_m3_p3 = scal[AC_VTXBUF_IDX(i - 3, j, k + 3, mesh_info)];
|
||||
f_m3_m3 = scal[AC_VTXBUF_IDX(i - 3, j, k - 3, mesh_info)];
|
||||
f_p3_m3 = scal[AC_VTXBUF_IDX(i + 3, j, k - 3, mesh_info)];
|
||||
break;
|
||||
default:
|
||||
ERROR("Invalid dernm type");
|
||||
}
|
||||
return fac * (MODEL_REAL(270.) * (f_p1_p1 - f_m1_p1 + f_m1_m1 - f_p1_m1) -
|
||||
MODEL_REAL(27.) * (f_p2_p2 - f_m2_p2 + f_m2_m2 - f_p2_m2) +
|
||||
MODEL_REAL(2.) * (f_p3_p3 - f_m3_p3 + f_m3_m3 - f_p3_m3));
|
||||
}
|
||||
|
||||
static void
|
||||
grad_div_vec(const int& i, const int& j, const int& k,
|
||||
const AcMeshInfo& mesh_info, const MODEL_REAL* vec_x,
|
||||
const MODEL_REAL* vec_y, const MODEL_REAL* vec_z, MODEL_REAL* gdvx,
|
||||
MODEL_REAL* gdvy, MODEL_REAL* gdvz)
|
||||
{
|
||||
*gdvx = der2_scal<AXIS_X>(i, j, k, mesh_info, vec_x) +
|
||||
dernm_scal<DERNM_XY>(i, j, k, mesh_info, vec_y) +
|
||||
dernm_scal<DERNM_XZ>(i, j, k, mesh_info, vec_z);
|
||||
|
||||
*gdvy = dernm_scal<DERNM_XY>(i, j, k, mesh_info, vec_x) +
|
||||
der2_scal<AXIS_Y>(i, j, k, mesh_info, vec_y) +
|
||||
dernm_scal<DERNM_YZ>(i, j, k, mesh_info, vec_z);
|
||||
|
||||
*gdvz = dernm_scal<DERNM_XZ>(i, j, k, mesh_info, vec_x) +
|
||||
dernm_scal<DERNM_YZ>(i, j, k, mesh_info, vec_y) +
|
||||
der2_scal<AXIS_Z>(i, j, k, mesh_info, vec_z);
|
||||
}
|
||||
|
||||
static void
|
||||
S_grad_lnrho(const int& i, const int& j, const int& k,
|
||||
const AcMeshInfo& mesh_info, const MODEL_REAL* vec_x,
|
||||
const MODEL_REAL* vec_y, const MODEL_REAL* vec_z, const MODEL_REAL* lnrho,
|
||||
MODEL_REAL* sgrhox, MODEL_REAL* sgrhoy, MODEL_REAL* sgrhoz)
|
||||
{
|
||||
const MODEL_REAL c23 = MODEL_REAL(2. / 3.);
|
||||
const MODEL_REAL c13 = MODEL_REAL(1. / 3.);
|
||||
|
||||
const MODEL_REAL Sxx = c23 * der_scal<AXIS_X>(i, j, k, mesh_info, vec_x) -
|
||||
c13 * (der_scal<AXIS_Y>(i, j, k, mesh_info, vec_y) +
|
||||
der_scal<AXIS_Z>(i, j, k, mesh_info, vec_z));
|
||||
const MODEL_REAL Sxy = MODEL_REAL(.5) *
|
||||
(der_scal<AXIS_Y>(i, j, k, mesh_info, vec_x) +
|
||||
der_scal<AXIS_X>(i, j, k, mesh_info, vec_y));
|
||||
const MODEL_REAL Sxz = MODEL_REAL(.5) *
|
||||
(der_scal<AXIS_Z>(i, j, k, mesh_info, vec_x) +
|
||||
der_scal<AXIS_X>(i, j, k, mesh_info, vec_z));
|
||||
|
||||
const MODEL_REAL Syx = Sxy;
|
||||
const MODEL_REAL Syy = c23 * der_scal<AXIS_Y>(i, j, k, mesh_info, vec_y) -
|
||||
c13 * (der_scal<AXIS_X>(i, j, k, mesh_info, vec_x) +
|
||||
der_scal<AXIS_Z>(i, j, k, mesh_info, vec_z));
|
||||
const MODEL_REAL Syz = MODEL_REAL(.5) *
|
||||
(der_scal<AXIS_Z>(i, j, k, mesh_info, vec_y) +
|
||||
der_scal<AXIS_Y>(i, j, k, mesh_info, vec_z));
|
||||
|
||||
const MODEL_REAL Szx = Sxz;
|
||||
const MODEL_REAL Szy = Syz;
|
||||
const MODEL_REAL Szz = c23 *
|
||||
der_scal<AXIS_Z>(
|
||||
i, j, k, mesh_info,
|
||||
vec_z) // replaced from "c23*der_scal<AXIS_Z>(i,
|
||||
// j, k, mesh_info, vec_x)"! TODO recheck
|
||||
// that ddz_uu_z is the correct one
|
||||
- c13 * (der_scal<AXIS_X>(i, j, k, mesh_info, vec_x) +
|
||||
der_scal<AXIS_Y>(i, j, k, mesh_info, vec_y));
|
||||
|
||||
// Grad lnrho
|
||||
|
||||
MODEL_REAL glnx, glny, glnz;
|
||||
|
||||
grad(i, j, k, mesh_info, lnrho, &glnx, &glny, &glnz);
|
||||
|
||||
*sgrhox = Sxx * glnx + Sxy * glny + Sxz * glnz;
|
||||
*sgrhoy = Syx * glnx + Syy * glny + Syz * glnz;
|
||||
*sgrhoz = Szx * glnx + Szy * glny + Szz * glnz;
|
||||
}
|
||||
|
||||
static void
|
||||
nu_const(const int& i, const int& j, const int& k, const AcMeshInfo& mesh_info,
|
||||
const MODEL_REAL* vec_x, const MODEL_REAL* vec_y, const MODEL_REAL* vec_z,
|
||||
const MODEL_REAL* scal, MODEL_REAL* visc_x, MODEL_REAL* visc_y, MODEL_REAL* visc_z)
|
||||
{
|
||||
MODEL_REAL lx, ly, lz;
|
||||
laplace_vec(i, j, k, mesh_info, vec_x, vec_y, vec_z, &lx, &ly, &lz);
|
||||
// lx = ly = lz = .0f;
|
||||
|
||||
MODEL_REAL gx, gy, gz;
|
||||
grad_div_vec(i, j, k, mesh_info, vec_x, vec_y, vec_z, &gx, &gy, &gz);
|
||||
// gx = gy =gz = .0f;
|
||||
|
||||
MODEL_REAL sgrhox, sgrhoy, sgrhoz;
|
||||
S_grad_lnrho(i, j, k, mesh_info, vec_x, vec_y, vec_z, scal, &sgrhox,
|
||||
&sgrhoy, &sgrhoz);
|
||||
// sgrhox = sgrhoy = sgrhoz = .0f;
|
||||
|
||||
*visc_x = mesh_info.real_params[AC_nu_visc] *
|
||||
(lx + MODEL_REAL(1. / 3.) * gx + MODEL_REAL(2.) * sgrhox)
|
||||
+ mesh_info.real_params[AC_zeta] * gx;
|
||||
*visc_y = mesh_info.real_params[AC_nu_visc] *
|
||||
(ly + MODEL_REAL(1. / 3.) * gy + MODEL_REAL(2.) * sgrhoy)
|
||||
+ mesh_info.real_params[AC_zeta] * gy;
|
||||
*visc_z = mesh_info.real_params[AC_nu_visc] *
|
||||
(lz + MODEL_REAL(1. / 3.) * gz + MODEL_REAL(2.) * sgrhoz)
|
||||
+ mesh_info.real_params[AC_zeta] * gz;
|
||||
}
|
||||
203
src/standalone/model/model_reduce.cc
Normal file
203
src/standalone/model/model_reduce.cc
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
Copyright (C) 2014-2018, Johannes Pekkilae, Miikka Vaeisalae.
|
||||
|
||||
This file is part of Astaroth.
|
||||
|
||||
Astaroth is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Astaroth is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Astaroth. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* \brief Brief info.
|
||||
*
|
||||
* Detailed info.
|
||||
*
|
||||
*/
|
||||
#include "model_reduce.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "core/errchk.h"
|
||||
|
||||
// Function pointer definitions
|
||||
typedef ModelScalar (*ReduceFunc)(const ModelScalar&, const ModelScalar&);
|
||||
typedef ModelScalar (*ReduceInitialScalFunc)(const ModelScalar&);
|
||||
typedef ModelScalar (*ReduceInitialVecFunc)(const ModelScalar&, const ModelScalar&,
|
||||
const ModelScalar&);
|
||||
|
||||
// clang-format off
|
||||
/* Comparison funcs */
|
||||
static inline ModelScalar
|
||||
max(const ModelScalar& a, const ModelScalar& b) { return a > b ? a : b; }
|
||||
|
||||
static inline ModelScalar
|
||||
min(const ModelScalar& a, const ModelScalar& b) { return a < b ? a : b; }
|
||||
|
||||
static inline ModelScalar
|
||||
sum(const ModelScalar& a, const ModelScalar& b) { return a + b; }
|
||||
|
||||
/* Function used to determine the values used during reduction */
|
||||
static inline ModelScalar
|
||||
length(const ModelScalar& a) { return (ModelScalar)(a); }
|
||||
|
||||
static inline ModelScalar
|
||||
length(const ModelScalar& a, const ModelScalar& b, const ModelScalar& c) { return sqrtl(a*a + b*b + c*c); }
|
||||
|
||||
static inline ModelScalar
|
||||
squared(const ModelScalar& a) { return (ModelScalar)(a*a); }
|
||||
|
||||
static inline ModelScalar
|
||||
squared(const ModelScalar& a, const ModelScalar& b, const ModelScalar& c) { return squared(a) + squared(b) + squared(c); }
|
||||
|
||||
static inline ModelScalar
|
||||
exp_squared(const ModelScalar& a) { return expl(a)*expl(a); }
|
||||
|
||||
static inline ModelScalar
|
||||
exp_squared(const ModelScalar& a, const ModelScalar& b, const ModelScalar& c) { return exp_squared(a) + exp_squared(b) + exp_squared(c); }
|
||||
// clang-format on
|
||||
|
||||
ModelScalar
|
||||
model_reduce_scal(const ModelMesh& mesh, const ReductionType& rtype,
|
||||
const VertexBufferHandle& a)
|
||||
{
|
||||
ReduceInitialScalFunc reduce_initial;
|
||||
ReduceFunc reduce;
|
||||
|
||||
bool solve_mean = false;
|
||||
|
||||
switch (rtype) {
|
||||
case RTYPE_MAX:
|
||||
reduce_initial = length;
|
||||
reduce = max;
|
||||
break;
|
||||
case RTYPE_MIN:
|
||||
reduce_initial = length;
|
||||
reduce = min;
|
||||
break;
|
||||
case RTYPE_RMS:
|
||||
reduce_initial = squared;
|
||||
reduce = sum;
|
||||
solve_mean = true;
|
||||
break;
|
||||
case RTYPE_RMS_EXP:
|
||||
reduce_initial = exp_squared;
|
||||
reduce = sum;
|
||||
solve_mean = true;
|
||||
break;
|
||||
default:
|
||||
ERROR("Unrecognized RTYPE");
|
||||
}
|
||||
|
||||
const int initial_idx = AC_VTXBUF_IDX(
|
||||
mesh.info.int_params[AC_nx_min], mesh.info.int_params[AC_ny_min],
|
||||
mesh.info.int_params[AC_nz_min], mesh.info);
|
||||
|
||||
ModelScalar res;
|
||||
if (rtype == RTYPE_MAX || rtype == RTYPE_MIN)
|
||||
res = reduce_initial(mesh.vertex_buffer[a][initial_idx]);
|
||||
else
|
||||
res = .0f;
|
||||
|
||||
for (int k = mesh.info.int_params[AC_nz_min];
|
||||
k < mesh.info.int_params[AC_nz_max]; ++k) {
|
||||
for (int j = mesh.info.int_params[AC_ny_min];
|
||||
j < mesh.info.int_params[AC_ny_max]; ++j) {
|
||||
for (int i = mesh.info.int_params[AC_nx_min];
|
||||
i < mesh.info.int_params[AC_nx_max]; ++i) {
|
||||
const int idx = AC_VTXBUF_IDX(i, j, k, mesh.info);
|
||||
const ModelScalar curr_val = reduce_initial(
|
||||
mesh.vertex_buffer[a][idx]);
|
||||
res = reduce(res, curr_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (solve_mean) {
|
||||
const ModelScalar inv_n = 1.0l / mesh.info.int_params[AC_nxyz];
|
||||
return sqrtl(inv_n * res);
|
||||
}
|
||||
else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
ModelScalar
|
||||
model_reduce_vec(const ModelMesh& mesh, const ReductionType& rtype,
|
||||
const VertexBufferHandle& a, const VertexBufferHandle& b,
|
||||
const VertexBufferHandle& c)
|
||||
{
|
||||
// ModelScalar (*reduce_initial)(ModelScalar, ModelScalar, ModelScalar);
|
||||
ReduceInitialVecFunc reduce_initial;
|
||||
ReduceFunc reduce;
|
||||
|
||||
bool solve_mean = false;
|
||||
|
||||
switch (rtype) {
|
||||
case RTYPE_MAX:
|
||||
reduce_initial = length;
|
||||
reduce = max;
|
||||
break;
|
||||
case RTYPE_MIN:
|
||||
reduce_initial = length;
|
||||
reduce = min;
|
||||
break;
|
||||
case RTYPE_RMS:
|
||||
reduce_initial = squared;
|
||||
reduce = sum;
|
||||
solve_mean = true;
|
||||
break;
|
||||
case RTYPE_RMS_EXP:
|
||||
reduce_initial = exp_squared;
|
||||
reduce = sum;
|
||||
solve_mean = true;
|
||||
break;
|
||||
default:
|
||||
ERROR("Unrecognized RTYPE");
|
||||
}
|
||||
|
||||
const int initial_idx = AC_VTXBUF_IDX(
|
||||
mesh.info.int_params[AC_nx_min], mesh.info.int_params[AC_ny_min],
|
||||
mesh.info.int_params[AC_nz_min], mesh.info);
|
||||
|
||||
ModelScalar res;
|
||||
if (rtype == RTYPE_MAX || rtype == RTYPE_MIN)
|
||||
res = reduce_initial(mesh.vertex_buffer[a][initial_idx],
|
||||
mesh.vertex_buffer[b][initial_idx],
|
||||
mesh.vertex_buffer[c][initial_idx]);
|
||||
else
|
||||
res = 0;
|
||||
|
||||
for (int k = mesh.info.int_params[AC_nz_min];
|
||||
k < mesh.info.int_params[AC_nz_max]; k++) {
|
||||
for (int j = mesh.info.int_params[AC_ny_min];
|
||||
j < mesh.info.int_params[AC_ny_max]; j++) {
|
||||
for (int i = mesh.info.int_params[AC_nx_min];
|
||||
i < mesh.info.int_params[AC_nx_max]; i++) {
|
||||
const int idx = AC_VTXBUF_IDX(i, j, k, mesh.info);
|
||||
const ModelScalar curr_val = reduce_initial(
|
||||
mesh.vertex_buffer[a][idx], mesh.vertex_buffer[b][idx],
|
||||
mesh.vertex_buffer[c][idx]);
|
||||
res = reduce(res, curr_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (solve_mean) {
|
||||
const ModelScalar inv_n = 1.0l / mesh.info.int_params[AC_nxyz];
|
||||
return sqrtl(inv_n * res);
|
||||
}
|
||||
else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
37
src/standalone/model/model_reduce.h
Normal file
37
src/standalone/model/model_reduce.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (C) 2014-2018, Johannes Pekkilae, Miikka Vaeisalae.
|
||||
|
||||
This file is part of Astaroth.
|
||||
|
||||
Astaroth is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Astaroth is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Astaroth. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* \brief Brief info.
|
||||
*
|
||||
* Detailed info.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include "astaroth.h"
|
||||
#include "modelmesh.h"
|
||||
|
||||
ModelScalar model_reduce_scal(const ModelMesh& mesh, const ReductionType& rtype,
|
||||
const VertexBufferHandle& a);
|
||||
|
||||
ModelScalar model_reduce_vec(const ModelMesh& mesh, const ReductionType& rtype,
|
||||
const VertexBufferHandle& a,
|
||||
const VertexBufferHandle& b,
|
||||
const VertexBufferHandle& c);
|
||||
1044
src/standalone/model/model_rk3.cc
Normal file
1044
src/standalone/model/model_rk3.cc
Normal file
File diff suppressed because it is too large
Load Diff
33
src/standalone/model/model_rk3.h
Normal file
33
src/standalone/model/model_rk3.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright (C) 2014-2018, Johannes Pekkilae, Miikka Vaeisalae.
|
||||
|
||||
This file is part of Astaroth.
|
||||
|
||||
Astaroth is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Astaroth is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Astaroth. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* \brief Brief info.
|
||||
*
|
||||
* Detailed info.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include "astaroth.h"
|
||||
#include "modelmesh.h"
|
||||
|
||||
void model_rk3(const ModelScalar dt, ModelMesh* mesh);
|
||||
|
||||
void model_rk3_step(const int step_number, const ModelScalar dt, ModelMesh* mesh);
|
||||
36
src/standalone/model/modelmesh.h
Normal file
36
src/standalone/model/modelmesh.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright (C) 2014-2018, Johannes Pekkilae, Miikka Vaeisalae.
|
||||
|
||||
This file is part of Astaroth.
|
||||
|
||||
Astaroth is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Astaroth is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Astaroth. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* \brief Brief info.
|
||||
*
|
||||
* Detailed info.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include "astaroth.h"
|
||||
|
||||
|
||||
typedef long double ModelScalar;
|
||||
|
||||
typedef struct {
|
||||
ModelScalar* vertex_buffer[NUM_VTXBUF_HANDLES];
|
||||
AcMeshInfo info;
|
||||
} ModelMesh;
|
||||
Reference in New Issue
Block a user