Fixed on/off switch for forcing and accretion, now forcing only happens for first 1000 steps (currently hard-coded), and accretion only happen after 1000 steps.
This commit is contained in:
@@ -82,6 +82,7 @@
|
|||||||
FUNC(AC_M_sink_Msun),\
|
FUNC(AC_M_sink_Msun),\
|
||||||
FUNC(AC_soft),\
|
FUNC(AC_soft),\
|
||||||
FUNC(AC_accretion_range),\
|
FUNC(AC_accretion_range),\
|
||||||
|
FUNC(AC_switch_accretion),\
|
||||||
/* Run params */\
|
/* Run params */\
|
||||||
FUNC(AC_cdt), \
|
FUNC(AC_cdt), \
|
||||||
FUNC(AC_cdtv), \
|
FUNC(AC_cdtv), \
|
||||||
|
@@ -68,7 +68,6 @@ sink_gravity(int3 globalVertexIdx){
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if LSINK
|
#if LSINK
|
||||||
// Give Truelove density
|
// Give Truelove density
|
||||||
Scalar
|
Scalar
|
||||||
@@ -93,33 +92,39 @@ sink_accretion(int3 globalVertexIdx, in ScalarField lnrho, Scalar dt){
|
|||||||
DCONST_REAL(AC_sink_pos_z)};
|
DCONST_REAL(AC_sink_pos_z)};
|
||||||
const Scalar profile_range = DCONST_REAL(AC_accretion_range);
|
const Scalar profile_range = DCONST_REAL(AC_accretion_range);
|
||||||
const Scalar accretion_distance = length(grid_pos - sink_pos);
|
const Scalar accretion_distance = length(grid_pos - sink_pos);
|
||||||
|
int accretion_switch = DCONST_INT(AC_switch_accretion);
|
||||||
Scalar accretion_density;
|
Scalar accretion_density;
|
||||||
|
|
||||||
Scalar weight;
|
Scalar weight;
|
||||||
// const Scalar weight = exp(-(accretion_distance/profile_range));
|
|
||||||
// Step function weighting
|
|
||||||
if ((accretion_distance) <= profile_range){
|
|
||||||
weight = Scalar(1.0);
|
|
||||||
} else {
|
|
||||||
weight = Scalar(0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// const Scalar lnrho_min = Scalar(-10.0); //TODO Define from astaroth.conf
|
if (accretion_switch == 1){
|
||||||
const Scalar lnrho_min = log(truelove_density(lnrho));
|
// const Scalar weight = exp(-(accretion_distance/profile_range));
|
||||||
// const Scalar sink_mass = DCONST_REAL(AC_M_sink);
|
// Step function weighting
|
||||||
// const Scalar B = Scalar(0.5);
|
if ((accretion_distance) <= profile_range){
|
||||||
// const Scalar k = Scalar(1.5);
|
weight = Scalar(1.0);
|
||||||
// const Scalar rate = B * (pow(sink_mass, k) / (dsx * dsy * dsz));
|
} else {
|
||||||
Scalar rate;
|
weight = Scalar(0.0);
|
||||||
if (value(lnrho) > lnrho_min) {
|
}
|
||||||
rate = (exp(value(lnrho)) - exp(lnrho_min)) / dt;
|
|
||||||
|
// const Scalar lnrho_min = Scalar(-10.0); //TODO Define from astaroth.conf
|
||||||
|
const Scalar lnrho_min = log(truelove_density(lnrho));
|
||||||
|
// const Scalar sink_mass = DCONST_REAL(AC_M_sink);
|
||||||
|
// const Scalar B = Scalar(0.5);
|
||||||
|
// const Scalar k = Scalar(1.5);
|
||||||
|
// const Scalar rate = B * (pow(sink_mass, k) / (dsx * dsy * dsz));
|
||||||
|
Scalar rate;
|
||||||
|
if (value(lnrho) > lnrho_min) {
|
||||||
|
rate = (exp(value(lnrho)) - exp(lnrho_min)) / dt;
|
||||||
|
} else {
|
||||||
|
rate = Scalar(0.0);
|
||||||
|
}
|
||||||
|
accretion_density = weight * rate ;
|
||||||
} else {
|
} else {
|
||||||
rate = Scalar(0.0);
|
accretion_density = 0;
|
||||||
}
|
}
|
||||||
accretion_density = weight * rate ;
|
|
||||||
return accretion_density;
|
return accretion_density;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector
|
Vector
|
||||||
sink_accretion_velocity(int3 globalVertexIdx, in VectorField uu, Scalar dt) {
|
sink_accretion_velocity(int3 globalVertexIdx, in VectorField uu, Scalar dt) {
|
||||||
const Vector grid_pos = (Vector){(globalVertexIdx.x - nx_min) * dsx,
|
const Vector grid_pos = (Vector){(globalVertexIdx.x - nx_min) * dsx,
|
||||||
@@ -130,24 +135,28 @@ sink_accretion_velocity(int3 globalVertexIdx, in VectorField uu, Scalar dt) {
|
|||||||
DCONST_REAL(AC_sink_pos_z)};
|
DCONST_REAL(AC_sink_pos_z)};
|
||||||
const Scalar profile_range = DCONST_REAL(AC_accretion_range);
|
const Scalar profile_range = DCONST_REAL(AC_accretion_range);
|
||||||
const Scalar accretion_distance = length(grid_pos - sink_pos);
|
const Scalar accretion_distance = length(grid_pos - sink_pos);
|
||||||
|
int accretion_switch = DCONST_INT(AC_switch_accretion);
|
||||||
Vector accretion_velocity;
|
Vector accretion_velocity;
|
||||||
|
|
||||||
Scalar weight;
|
if (accretion_switch == 1){
|
||||||
// Step function weighting
|
Scalar weight;
|
||||||
if ((accretion_distance) <= profile_range){
|
// Step function weighting
|
||||||
|
if ((accretion_distance) <= profile_range){
|
||||||
weight = Scalar(1.0);
|
weight = Scalar(1.0);
|
||||||
} else {
|
} else {
|
||||||
weight = Scalar(0.0);
|
weight = Scalar(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector rate;
|
Vector rate;
|
||||||
if (length(value(uu)) > Scalar(0.0)) {
|
if (length(value(uu)) > Scalar(0.0)) {
|
||||||
rate = (Scalar(1.0)/dt) * value(uu);
|
rate = (Scalar(1.0)/dt) * value(uu);
|
||||||
|
} else {
|
||||||
|
rate = (Vector){0.0, 0.0, 0.0};
|
||||||
|
}
|
||||||
|
accretion_velocity = weight * rate ;
|
||||||
} else {
|
} else {
|
||||||
rate = (Vector){0.0, 0.0, 0.0};
|
accretion_velocity = (Vector){0.0, 0.0, 0.0};
|
||||||
}
|
}
|
||||||
accretion_velocity = weight * rate ;
|
|
||||||
return accretion_velocity;
|
return accretion_velocity;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -303,7 +312,7 @@ entropy(in ScalarField ss, in VectorField uu, in ScalarField lnrho, in VectorFie
|
|||||||
const Vector j = (Scalar(1.) / mu0) * (gradient_of_divergence(aa) - laplace_vec(aa)); // Current density
|
const Vector j = (Scalar(1.) / mu0) * (gradient_of_divergence(aa) - laplace_vec(aa)); // Current density
|
||||||
const Scalar RHS = H_CONST - C_CONST
|
const Scalar RHS = H_CONST - C_CONST
|
||||||
+ eta * (mu0) * dot(j, j)
|
+ eta * (mu0) * dot(j, j)
|
||||||
+ Scalar(2.) * exp(value(lnrho)) * nu_visc * contract(S)
|
+ Scalar(2.) * exp(value(lnrho)) * nu_visc * contract(S)
|
||||||
+ zeta * exp(value(lnrho)) * divergence(uu) * divergence(uu);
|
+ zeta * exp(value(lnrho)) * divergence(uu) * divergence(uu);
|
||||||
|
|
||||||
return - dot(value(uu), gradient(ss))
|
return - dot(value(uu), gradient(ss))
|
||||||
@@ -326,88 +335,111 @@ heat_transfer(in VectorField uu, in ScalarField lnrho, in ScalarField tt)
|
|||||||
|
|
||||||
#if LFORCING
|
#if LFORCING
|
||||||
Vector
|
Vector
|
||||||
simple_vortex_forcing(Vector a, Vector b, Scalar magnitude)
|
simple_vortex_forcing(Vector a, Vector b, Scalar magnitude){
|
||||||
{
|
int accretion_switch = DCONST_INT(AC_switch_accretion);
|
||||||
return magnitude * cross(normalized(b - a), (Vector){0, 0, 1}); // Vortex
|
|
||||||
|
if (accretion_switch == 0){
|
||||||
|
return magnitude * cross(normalized(b - a), (Vector){ 0, 0, 1}); // Vortex
|
||||||
|
} else {
|
||||||
|
return (Vector){0,0,0};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Vector
|
||||||
|
simple_outward_flow_forcing(Vector a, Vector b, Scalar magnitude){
|
||||||
|
int accretion_switch = DCONST_INT(AC_switch_accretion);
|
||||||
|
if (accretion_switch == 0){
|
||||||
|
return magnitude * (1 / length(b - a)) * normalized(b - a); // Outward flow
|
||||||
|
} else {
|
||||||
|
return (Vector){0,0,0};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector
|
|
||||||
simple_outward_flow_forcing(Vector a, Vector b, Scalar magnitude)
|
|
||||||
{
|
|
||||||
return magnitude * (1 / length(b - a)) * normalized(b - a); // Outward flow
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// The Pencil Code forcing_hel_noshear(), manual Eq. 222, inspired forcing function with adjustable helicity
|
// The Pencil Code forcing_hel_noshear(), manual Eq. 222, inspired forcing function with adjustable helicity
|
||||||
Vector
|
Vector
|
||||||
helical_forcing(Scalar magnitude, Vector k_force, Vector xx, Vector ff_re, Vector ff_im, Scalar phi)
|
helical_forcing(Scalar magnitude, Vector k_force, Vector xx, Vector ff_re, Vector ff_im, Scalar phi)
|
||||||
{
|
{
|
||||||
// JP: This looks wrong:
|
int accretion_switch = DCONST_INT(AC_switch_accretion);
|
||||||
// 1) Should it be dsx * nx instead of dsx * ny?
|
if (accretion_switch == 0){
|
||||||
// 2) Should you also use globalGrid.n instead of the local n?
|
|
||||||
// MV: You are rigth. Made a quickfix. I did not see the error because multigpu is split
|
|
||||||
// in z direction not y direction.
|
|
||||||
// 3) Also final point: can we do this with vectors/quaternions instead?
|
|
||||||
// Tringonometric functions are much more expensive and inaccurate/
|
|
||||||
// MV: Good idea. No an immediate priority.
|
|
||||||
// Fun related article:
|
|
||||||
// https://randomascii.wordpress.com/2014/10/09/intel-underestimates-error-bounds-by-1-3-quintillion/
|
|
||||||
xx.x = xx.x*(2.0*M_PI/(dsx*globalGridN.x));
|
|
||||||
xx.y = xx.y*(2.0*M_PI/(dsy*globalGridN.y));
|
|
||||||
xx.z = xx.z*(2.0*M_PI/(dsz*globalGridN.z));
|
|
||||||
|
|
||||||
Scalar cos_phi = cos(phi);
|
|
||||||
Scalar sin_phi = sin(phi);
|
|
||||||
Scalar cos_k_dot_x = cos(dot(k_force, xx));
|
|
||||||
Scalar sin_k_dot_x = sin(dot(k_force, xx));
|
|
||||||
// Phase affect only the x-component
|
|
||||||
//Scalar real_comp = cos_k_dot_x;
|
|
||||||
//Scalar imag_comp = sin_k_dot_x;
|
|
||||||
Scalar real_comp_phase = cos_k_dot_x*cos_phi - sin_k_dot_x*sin_phi;
|
|
||||||
Scalar imag_comp_phase = cos_k_dot_x*sin_phi + sin_k_dot_x*cos_phi;
|
|
||||||
|
|
||||||
|
|
||||||
Vector force = (Vector){ ff_re.x*real_comp_phase - ff_im.x*imag_comp_phase,
|
// JP: This looks wrong:
|
||||||
ff_re.y*real_comp_phase - ff_im.y*imag_comp_phase,
|
// 1) Should it be dsx * nx instead of dsx * ny?
|
||||||
ff_re.z*real_comp_phase - ff_im.z*imag_comp_phase};
|
// 2) Should you also use globalGrid.n instead of the local n?
|
||||||
|
// MV: You are rigth. Made a quickfix. I did not see the error because multigpu is split
|
||||||
|
// in z direction not y direction.
|
||||||
|
// 3) Also final point: can we do this with vectors/quaternions instead?
|
||||||
|
// Tringonometric functions are much more expensive and inaccurate/
|
||||||
|
// MV: Good idea. No an immediate priority.
|
||||||
|
// Fun related article:
|
||||||
|
// https://randomascii.wordpress.com/2014/10/09/intel-underestimates-error-bounds-by-1-3-quintillion/
|
||||||
|
xx.x = xx.x*(2.0*M_PI/(dsx*globalGridN.x));
|
||||||
|
xx.y = xx.y*(2.0*M_PI/(dsy*globalGridN.y));
|
||||||
|
xx.z = xx.z*(2.0*M_PI/(dsz*globalGridN.z));
|
||||||
|
|
||||||
return force;
|
Scalar cos_phi = cos(phi);
|
||||||
|
Scalar sin_phi = sin(phi);
|
||||||
|
Scalar cos_k_dot_x = cos(dot(k_force, xx));
|
||||||
|
Scalar sin_k_dot_x = sin(dot(k_force, xx));
|
||||||
|
// Phase affect only the x-component
|
||||||
|
//Scalar real_comp = cos_k_dot_x;
|
||||||
|
//Scalar imag_comp = sin_k_dot_x;
|
||||||
|
Scalar real_comp_phase = cos_k_dot_x*cos_phi - sin_k_dot_x*sin_phi;
|
||||||
|
Scalar imag_comp_phase = cos_k_dot_x*sin_phi + sin_k_dot_x*cos_phi;
|
||||||
|
|
||||||
|
|
||||||
|
Vector force = (Vector){ ff_re.x*real_comp_phase - ff_im.x*imag_comp_phase,
|
||||||
|
ff_re.y*real_comp_phase - ff_im.y*imag_comp_phase,
|
||||||
|
ff_re.z*real_comp_phase - ff_im.z*imag_comp_phase};
|
||||||
|
|
||||||
|
|
||||||
|
return force;
|
||||||
|
} else {
|
||||||
|
return (Vector){0,0,0};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector
|
Vector
|
||||||
forcing(int3 globalVertexIdx, Scalar dt)
|
forcing(int3 globalVertexIdx, Scalar dt)
|
||||||
{
|
{
|
||||||
Vector a = Scalar(.5) * (Vector){globalGridN.x * dsx,
|
int accretion_switch = DCONST_INT(AC_switch_accretion);
|
||||||
globalGridN.y * dsy,
|
if (accretion_switch == 0){
|
||||||
globalGridN.z * dsz}; // source (origin)
|
|
||||||
Vector xx = (Vector){(globalVertexIdx.x - nx_min) * dsx,
|
|
||||||
(globalVertexIdx.y - ny_min) * dsy,
|
|
||||||
(globalVertexIdx.z - nz_min) * dsz}; // sink (current index)
|
|
||||||
const Scalar cs2 = cs2_sound;
|
|
||||||
const Scalar cs = sqrt(cs2);
|
|
||||||
|
|
||||||
//Placeholders until determined properly
|
Vector a = Scalar(.5) * (Vector){globalGridN.x * dsx,
|
||||||
Scalar magnitude = DCONST_REAL(AC_forcing_magnitude);
|
globalGridN.y * dsy,
|
||||||
Scalar phase = DCONST_REAL(AC_forcing_phase);
|
globalGridN.z * dsz}; // source (origin)
|
||||||
Vector k_force = (Vector){ DCONST_REAL(AC_k_forcex), DCONST_REAL(AC_k_forcey), DCONST_REAL(AC_k_forcez)};
|
Vector xx = (Vector){(globalVertexIdx.x - nx_min) * dsx,
|
||||||
Vector ff_re = (Vector){DCONST_REAL(AC_ff_hel_rex), DCONST_REAL(AC_ff_hel_rey), DCONST_REAL(AC_ff_hel_rez)};
|
(globalVertexIdx.y - ny_min) * dsy,
|
||||||
Vector ff_im = (Vector){DCONST_REAL(AC_ff_hel_imx), DCONST_REAL(AC_ff_hel_imy), DCONST_REAL(AC_ff_hel_imz)};
|
(globalVertexIdx.z - nz_min) * dsz}; // sink (current index)
|
||||||
|
const Scalar cs2 = cs2_sound;
|
||||||
|
const Scalar cs = sqrt(cs2);
|
||||||
|
|
||||||
|
//Placeholders until determined properly
|
||||||
|
Scalar magnitude = DCONST_REAL(AC_forcing_magnitude);
|
||||||
|
Scalar phase = DCONST_REAL(AC_forcing_phase);
|
||||||
|
Vector k_force = (Vector){ DCONST_REAL(AC_k_forcex), DCONST_REAL(AC_k_forcey), DCONST_REAL(AC_k_forcez)};
|
||||||
|
Vector ff_re = (Vector){DCONST_REAL(AC_ff_hel_rex), DCONST_REAL(AC_ff_hel_rey), DCONST_REAL(AC_ff_hel_rez)};
|
||||||
|
Vector ff_im = (Vector){DCONST_REAL(AC_ff_hel_imx), DCONST_REAL(AC_ff_hel_imy), DCONST_REAL(AC_ff_hel_imz)};
|
||||||
|
|
||||||
|
|
||||||
//Determine that forcing funtion type at this point.
|
//Determine that forcing funtion type at this point.
|
||||||
//Vector force = simple_vortex_forcing(a, xx, magnitude);
|
//Vector force = simple_vortex_forcing(a, xx, magnitude);
|
||||||
//Vector force = simple_outward_flow_forcing(a, xx, magnitude);
|
//Vector force = simple_outward_flow_forcing(a, xx, magnitude);
|
||||||
Vector force = helical_forcing(magnitude, k_force, xx, ff_re,ff_im, phase);
|
Vector force = helical_forcing(magnitude, k_force, xx, ff_re,ff_im, phase);
|
||||||
|
|
||||||
//Scaling N = magnitude*cs*sqrt(k*cs/dt) * dt
|
//Scaling N = magnitude*cs*sqrt(k*cs/dt) * dt
|
||||||
const Scalar NN = cs*sqrt(DCONST_REAL(AC_kaver)*cs);
|
const Scalar NN = cs*sqrt(DCONST_REAL(AC_kaver)*cs);
|
||||||
//MV: Like in the Pencil Code. I don't understandf the logic here.
|
//MV: Like in the Pencil Code. I don't understandf the logic here.
|
||||||
force.x = sqrt(dt)*NN*force.x;
|
force.x = sqrt(dt)*NN*force.x;
|
||||||
force.y = sqrt(dt)*NN*force.y;
|
force.y = sqrt(dt)*NN*force.y;
|
||||||
force.z = sqrt(dt)*NN*force.z;
|
force.z = sqrt(dt)*NN*force.z;
|
||||||
|
|
||||||
if (is_valid(force)) { return force; }
|
if (is_valid(force)) { return force; }
|
||||||
else { return (Vector){0, 0, 0}; }
|
else { return (Vector){0, 0, 0}; }
|
||||||
|
} else {
|
||||||
|
return (Vector){0,0,0};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // LFORCING
|
#endif // LFORCING
|
||||||
|
|
||||||
|
@@ -252,11 +252,11 @@ run_simulation(void)
|
|||||||
#if LSINK
|
#if LSINK
|
||||||
|
|
||||||
const AcReal sum_mass = acReduceScal(RTYPE_MAX, VTXBUF_ACCRETION);
|
const AcReal sum_mass = acReduceScal(RTYPE_MAX, VTXBUF_ACCRETION);
|
||||||
if (i > 1000) {
|
// if (i > 1000) {
|
||||||
accreted_mass = accreted_mass + sum_mass;
|
accreted_mass = accreted_mass + sum_mass;
|
||||||
} else {
|
// } else {
|
||||||
accreted_mass = 0.0;
|
// accreted_mass = 0.0;
|
||||||
}
|
// }
|
||||||
AcReal sink_mass = 0.0;
|
AcReal sink_mass = 0.0;
|
||||||
//if (i > 1000 ) {
|
//if (i > 1000 ) {
|
||||||
sink_mass = mesh_info.real_params[AC_M_sink_init] + accreted_mass;
|
sink_mass = mesh_info.real_params[AC_M_sink_init] + accreted_mass;
|
||||||
@@ -265,14 +265,19 @@ run_simulation(void)
|
|||||||
printf("accreted mass is: %e \n", accreted_mass);
|
printf("accreted mass is: %e \n", accreted_mass);
|
||||||
acLoadDeviceConstant(AC_M_sink, sink_mass);
|
acLoadDeviceConstant(AC_M_sink, sink_mass);
|
||||||
vertex_buffer_set(VTXBUF_ACCRETION, 0.0, mesh);
|
vertex_buffer_set(VTXBUF_ACCRETION, 0.0, mesh);
|
||||||
|
|
||||||
|
int on_off_switch;
|
||||||
|
if (i < 1000) {
|
||||||
|
on_off_switch = 0; //accretion is off till 1000 steps.
|
||||||
|
} else {
|
||||||
|
on_off_switch = 1;
|
||||||
|
}
|
||||||
|
acLoadDeviceConstant(AC_switch_accretion, on_off_switch);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LFORCING
|
#if LFORCING
|
||||||
const ForcingParams forcing_params = generateForcingParams(mesh_info);
|
const ForcingParams forcing_params = generateForcingParams(mesh_info);
|
||||||
if (i > 1000) {
|
loadForcingParamsToDevice(forcing_params);
|
||||||
loadForcingParamsToDevice(forcing_params);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user