Draft: Add magma2 SPH scheme
I just added the MAGMA2 scheme in the branch MAGMA2 and are there some advices for the future implementation?
I added the two extra profiles:
- hydro_iact_cosmo.h and hydro_iact_sphenix.h. One is added the cosmological term and another is using the sphenix's diffusion parameter.
- There is a parameter called h_crit in the runner_iact_force and runner_iact_nonsym_force , which is the inverse of the resolution eta. And everytime I just change the parameter manually
- Also for the matrix inversion, I just paste the function invert_dimension_by_dimension_matrixin swift, and it might need clear a bit and call the function instead
- And I just directly use constant viscosity and diffusion parameters into the function without define it in the hydro_parameter.h. It also might need to change a bit
- Last thing is MAGMA2 use the quadratically mid point reconstruction and it is also worth to test the linearly reconstruction. Since it may increases the computing effciency.
Merge request reports
Activity
requested review from @bvandenbroucke
added SPH enhancement labels
@jborrow will also be interested.
- Resolved by Zhen Xiang
- Resolved by Zhen Xiang
- Resolved by Zhen Xiang
- Resolved by Zhen Xiang
- Resolved by Zhen Xiang
- src/hydro/MAGMA/hydro_iact.h 0 → 100644
462 for (int i = 0; i < 3; i++) { 463 A_i += pi->fder_u[i] * dx[i]; 464 A_j += pj->fder_u[i] * dx[i]; 465 for (int j = 0; j < 3; j++) { 466 Av_i += pi->fder_v[i][j] * dx[i] * dx[j]; 467 Av_j += pj->fder_v[i][j] * dx[i] * dx[j]; 468 } 469 } 470 471 const float A_ij = A_i / A_j; 472 const float A_ji = A_j / A_i; 473 const float Av_ij = Av_i / Av_j; 474 const float Av_ji = Av_j / Av_i; 475 476 /* Compute slope limiter. */ 477 const float Ai_min = 4.f * A_ij / ((1 + A_ij) * (1 + A_ij)); changed this line in version 6 of the diff
Change the value into float.
All these denominators can be zero, so that I write a few lines to prevent the issue.
if (A_i == 0.f && A_j == 0.f){ A_ij = 1.f; A_ji = 1.f; } else if ((A_i == 0.f && A_j != 0.f) || (A_j == 0.f && A_i != 0.f)){ A_ij = 0.f; A_ji = 0.f; } else{ A_ij = A_i / A_j; A_ji = A_j / A_i; } if (Av_i == 0.f && Av_j == 0.f){ Av_ij = 1.f; Av_ji = 1.f; } else if ((Av_i == 0.f && Av_j != 0.f) || (Av_j == 0.f && Av_i != 0.f)){ Av_ij = 0.f; Av_ji = 0.f; } else{ Av_ij = Av_i / Av_j; Av_ji = Av_j / Av_i; }
if (A_i == 0.f && A_j == 0.f) { /* For smooth internal energy field, we turn off diffusion term*/ A_ij = 1.f; A_ji = 1.f; } else if ((A_i == 0.f && A_j != 0.f) || (A_j == 0.f && A_i != 0.f)) { /* For extreme values, we add diffusion term*/ A_ij = 0.f; A_ji = 0.f; } else { A_ij = A_i / A_j; A_ji = A_j / A_i; }
When A_i and A_j are both zero, it means two particles in the smoothed field. We will set A_ij and A_ji to 1, and it will turn off the diffusion term, same as the viscosity term. When one of A_i/A_j is zero, it encounters discontinuity or some extreme values. We set A_ij/A_ji to zero, so that it will add diffusion term to fix the discontinuity.
- Resolved by Zhen Xiang
- Resolved by Zhen Xiang
- Resolved by Zhen Xiang
- Resolved by Matthieu Schaller
- Resolved by Zhen Xiang
This looks very good! I have left some comments for you. Since there is a lot of duplicate code in
hydro_iact
, some comments apply to multiple lines and I have not always put them everywhere.Can you explain to me again what the difference is between
hydro_iact
,hydro_iact_sphenix
andhydro_iact_cosmo
and why we have all 3 of them? I think onlyhydro_iact
is actually used? A quickdiff
shows that these files are almost the same. There are probably better ways to have different versions without having to duplicate all the code.