Peano
Loading...
Searching...
No Matches
hydro_iact.h
Go to the documentation of this file.
1/*******************************************************************************
2 * This file is part of SWIFT.
3 * Copyright (c) 2016 Matthieu Schaller (schaller@strw.leidenuniv.nl)
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 ******************************************************************************/
19#ifndef SWIFT_MINIMAL_HYDRO_IACT_H
20#define SWIFT_MINIMAL_HYDRO_IACT_H
21
36#include "adiabatic_index.h"
37#include "hydro_parameters.h"
38//#include "minmax.h"
39#include "signal_velocity.h"
40
53__attribute__((always_inline)) INLINE static void runner_iact_density(
54 const float r2, const float dx[3], const float hi, const float hj,
55 struct part *restrict pi, struct part *restrict pj, const float a,
56 const float H) {
57
58 float wi, wj, wi_dx, wj_dx;
59
60#ifdef SWIFT_DEBUG_CHECKS
61 if (pi->time_bin >= time_bin_inhibited)
62 error("Inhibited pi in interaction function!");
63 if (pj->time_bin >= time_bin_inhibited)
64 error("Inhibited pj in interaction function!");
65#endif
66
67 /* Get r and 1/r. */
68 const float r = sqrtf(r2);
69 const float r_inv = r ? 1.0f / r : 0.0f;
70
71 /* Get the masses. */
72 const float mi = pi->mass;
73 const float mj = pj->mass;
74
75 /* Compute density of pi. */
76 const float hi_inv = 1.f / hi;
77 const float ui = r * hi_inv;
78 kernel_deval(ui, &wi, &wi_dx);
79
80 pi->rho += mj * wi;
81 pi->density.rho_dh -= mj * (hydro_dimension * wi + ui * wi_dx);
82 pi->density.wcount += wi;
83 pi->density.wcount_dh -= (hydro_dimension * wi + ui * wi_dx);
85
86 /* Compute density of pj. */
87 const float hj_inv = 1.f / hj;
88 const float uj = r * hj_inv;
89 kernel_deval(uj, &wj, &wj_dx);
90
91 pj->rho += mi * wj;
92 pj->density.rho_dh -= mi * (hydro_dimension * wj + uj * wj_dx);
93 pj->density.wcount += wj;
94 pj->density.wcount_dh -= (hydro_dimension * wj + uj * wj_dx);
96
97 /* Compute dv dot r */
98 float dv[3], curlvr[3];
99
100 const float faci = mj * wi_dx * r_inv;
101 const float facj = mi * wj_dx * r_inv;
102
103 dv[0] = pi->v[0] - pj->v[0];
104 dv[1] = pi->v[1] - pj->v[1];
105 dv[2] = pi->v[2] - pj->v[2];
106 const float dvdr = dv[0] * dx[0] + dv[1] * dx[1] + dv[2] * dx[2];
107
108 pi->density.div_v -= faci * dvdr;
109 pj->density.div_v -= facj * dvdr;
110
111 /* Compute dv cross r */
112 curlvr[0] = dv[1] * dx[2] - dv[2] * dx[1];
113 curlvr[1] = dv[2] * dx[0] - dv[0] * dx[2];
114 curlvr[2] = dv[0] * dx[1] - dv[1] * dx[0];
115
116 pi->density.rot_v[0] += faci * curlvr[0];
117 pi->density.rot_v[1] += faci * curlvr[1];
118 pi->density.rot_v[2] += faci * curlvr[2];
119
120 pj->density.rot_v[0] += facj * curlvr[0];
121 pj->density.rot_v[1] += facj * curlvr[1];
122 pj->density.rot_v[2] += facj * curlvr[2];
123}
124
137__attribute__((always_inline)) INLINE static void runner_iact_nonsym_density(
138 const float r2, const float dx[3], const float hi, const float hj,
139 struct part *restrict pi, const struct part *restrict pj, const float a,
140 const float H) {
141
142 float wi, wi_dx;
143
144#ifdef SWIFT_DEBUG_CHECKS
145 if (pi->time_bin >= time_bin_inhibited)
146 error("Inhibited pi in interaction function!");
147 if (pj->time_bin >= time_bin_inhibited)
148 error("Inhibited pj in interaction function!");
149#endif
150
151 /* Get the masses. */
152 const float mj = pj->mass;
153
154 /* Get r and 1/r. */
155 const float r = sqrtf(r2);
156 const float r_inv = r ? 1.0f / r : 0.0f;
157
158 const float h_inv = 1.f / hi;
159 const float ui = r * h_inv;
160 kernel_deval(ui, &wi, &wi_dx);
161
162 pi->rho += mj * wi;
163 pi->density.rho_dh -= mj * (hydro_dimension * wi + ui * wi_dx);
164 pi->density.wcount += wi;
165 pi->density.wcount_dh -= (hydro_dimension * wi + ui * wi_dx);
167
168 /* Compute dv dot r */
169 float dv[3], curlvr[3];
170
171 const float faci = mj * wi_dx * r_inv;
172
173 dv[0] = pi->v[0] - pj->v[0];
174 dv[1] = pi->v[1] - pj->v[1];
175 dv[2] = pi->v[2] - pj->v[2];
176 const float dvdr = dv[0] * dx[0] + dv[1] * dx[1] + dv[2] * dx[2];
177
178 pi->density.div_v -= faci * dvdr;
179
180 /* Compute dv cross r */
181 curlvr[0] = dv[1] * dx[2] - dv[2] * dx[1];
182 curlvr[1] = dv[2] * dx[0] - dv[0] * dx[2];
183 curlvr[2] = dv[0] * dx[1] - dv[1] * dx[0];
184
185 pi->density.rot_v[0] += faci * curlvr[0];
186 pi->density.rot_v[1] += faci * curlvr[1];
187 pi->density.rot_v[2] += faci * curlvr[2];
188}
189
205__attribute__((always_inline)) INLINE static void runner_iact_gradient(
206 const float r2, const float dx[3], const float hi, const float hj,
207 struct part *restrict pi, struct part *restrict pj, const float a,
208 const float H) {}
209
226__attribute__((always_inline)) INLINE static void runner_iact_nonsym_gradient(
227 const float r2, const float dx[3], const float hi, const float hj,
228 struct part *restrict pi, struct part *restrict pj, const float a,
229 const float H) {}
230
243__attribute__((always_inline)) INLINE static void runner_iact_force(
244 const float r2, const float dx[3], const float hi, const float hj,
245 struct part *restrict pi, struct part *restrict pj, const float a,
246 const float H) {
247
248#ifdef SWIFT_DEBUG_CHECKS
249 if (pi->time_bin >= time_bin_inhibited)
250 error("Inhibited pi in interaction function!");
251 if (pj->time_bin >= time_bin_inhibited)
252 error("Inhibited pj in interaction function!");
253#endif
254
255 /* Cosmological factors entering the EoMs */
256 const float fac_mu = pow_three_gamma_minus_five_over_two(a);
257 const float a2_Hubble = a * a * H;
258
259 /* Get r and 1/r. */
260 const float r = sqrtf(r2);
261 const float r_inv = r ? 1.0f / r : 0.0f;
262
263 /* Recover some data */
264 const float mi = pi->mass;
265 const float mj = pj->mass;
266 const float rhoi = pi->rho;
267 const float rhoj = pj->rho;
268 const float pressurei = pi->force.pressure;
269 const float pressurej = pj->force.pressure;
270
271 /* Get the kernel for hi. */
272 const float hi_inv = 1.0f / hi;
273 const float hid_inv = pow_dimension_plus_one(hi_inv); /* 1/h^(d+1) */
274 const float xi = r * hi_inv;
275 float wi, wi_dx;
276 kernel_deval(xi, &wi, &wi_dx);
277 const float wi_dr = hid_inv * wi_dx;
278
279 /* Get the kernel for hj. */
280 const float hj_inv = 1.0f / hj;
281 const float hjd_inv = pow_dimension_plus_one(hj_inv); /* 1/h^(d+1) */
282 const float xj = r * hj_inv;
283 float wj, wj_dx;
284 kernel_deval(xj, &wj, &wj_dx);
285 const float wj_dr = hjd_inv * wj_dx;
286
287 /* Variable smoothing length term */
288 const float f_ij = 1.f - pi->force.f / mj;
289 const float f_ji = 1.f - pj->force.f / mi;
290
291 /* Compute gradient terms */
292 const float P_over_rho2_i = pressurei / (rhoi * rhoi) * f_ij;
293 const float P_over_rho2_j = pressurej / (rhoj * rhoj) * f_ji;
294
295 /* Compute dv dot r. */
296 const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] +
297 (pi->v[1] - pj->v[1]) * dx[1] +
298 (pi->v[2] - pj->v[2]) * dx[2];
299
300 /* Add Hubble flow */
301 const float dvdr_Hubble = dvdr + a2_Hubble * r2;
302
303 /* Are the particles moving towards each others ? */
304 const float omega_ij = MIN(dvdr_Hubble, 0.f);
305 const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */
306
307 /* Compute signal velocity */
308 const float v_sig = signal_velocity(dx, pi, pj, mu_ij, const_viscosity_beta);
309
310 /* Grab balsara switches */
311 const float balsara_i = pi->force.balsara;
312 const float balsara_j = pj->force.balsara;
313
314 /* Construct the full viscosity term */
315 const float rho_ij = 0.5f * (rhoi + rhoj);
316 const float visc = -0.25f * v_sig * (balsara_i + balsara_j) * mu_ij / rho_ij;
317
318 /* Convolve with the kernel */
319 const float visc_acc_term =
320 0.5f * visc * (wi_dr * f_ij + wj_dr * f_ji) * r_inv;
321
322 /* SPH acceleration term */
323 const float sph_acc_term =
324 (P_over_rho2_i * wi_dr + P_over_rho2_j * wj_dr) * r_inv;
325
326 /* Adaptive softening acceleration term */
327 const float adapt_soft_acc_term =
328 adaptive_softening_get_acc_term(pi, pj, wi_dr, wj_dr, f_ij, f_ji, r_inv);
329
330 /* Assemble the acceleration */
331 const float acc = sph_acc_term + visc_acc_term + adapt_soft_acc_term;
332
333 /* Use the force Luke ! */
334 pi->a_hydro[0] -= mj * acc * dx[0];
335 pi->a_hydro[1] -= mj * acc * dx[1];
336 pi->a_hydro[2] -= mj * acc * dx[2];
337
338 pj->a_hydro[0] += mi * acc * dx[0];
339 pj->a_hydro[1] += mi * acc * dx[1];
340 pj->a_hydro[2] += mi * acc * dx[2];
341
342 /* Get the time derivative for u. */
343 const float sph_du_term_i = P_over_rho2_i * dvdr * r_inv * wi_dr;
344 const float sph_du_term_j = P_over_rho2_j * dvdr * r_inv * wj_dr;
345
346 /* Viscosity term */
347 const float visc_du_term = 0.5f * visc_acc_term * dvdr_Hubble;
348
349 /* Assemble the energy equation term */
350 const float du_dt_i = sph_du_term_i + visc_du_term;
351 const float du_dt_j = sph_du_term_j + visc_du_term;
352
353 /* Internal energy time derivatibe */
354 pi->u_dt += du_dt_i * mj;
355 pj->u_dt += du_dt_j * mi;
356
357 /* Get the time derivative for h. */
358 pi->force.h_dt -= mj * dvdr * r_inv / rhoj * wi_dr * f_ij;
359 pj->force.h_dt -= mi * dvdr * r_inv / rhoi * wj_dr * f_ji;
360
361 /* Update the signal velocity. */
362 pi->force.v_sig = MAX(pi->force.v_sig, v_sig);
364}
365
378__attribute__((always_inline)) INLINE static void runner_iact_nonsym_force(
379 const float r2, const float dx[3], const float hi, const float hj,
380 struct part *restrict pi, const struct part *restrict pj, const float a,
381 const float H) {
382
383#ifdef SWIFT_DEBUG_CHECKS
384 if (pi->time_bin >= time_bin_inhibited)
385 error("Inhibited pi in interaction function!");
386 if (pj->time_bin >= time_bin_inhibited)
387 error("Inhibited pj in interaction function!");
388#endif
389
390 /* Cosmological factors entering the EoMs */
391 const float fac_mu = pow_three_gamma_minus_five_over_two(a);
392 const float a2_Hubble = a * a * H;
393
394 /* Get r and 1/r. */
395 const float r = sqrtf(r2);
396 const float r_inv = r ? 1.0f / r : 0.0f;
397
398 /* Recover some data */
399 const float mi = pi->mass;
400 const float mj = pj->mass;
401 const float rhoi = pi->rho;
402 const float rhoj = pj->rho;
403 const float pressurei = pi->force.pressure;
404 const float pressurej = pj->force.pressure;
405
406 /* Get the kernel for hi. */
407 const float hi_inv = 1.0f / hi;
408 const float hid_inv = pow_dimension_plus_one(hi_inv); /* 1/h^(d+1) */
409 const float xi = r * hi_inv;
410 float wi, wi_dx;
411 kernel_deval(xi, &wi, &wi_dx);
412 const float wi_dr = hid_inv * wi_dx;
413
414 /* Get the kernel for hj. */
415 const float hj_inv = 1.0f / hj;
416 const float hjd_inv = pow_dimension_plus_one(hj_inv); /* 1/h^(d+1) */
417 const float xj = r * hj_inv;
418 float wj, wj_dx;
419 kernel_deval(xj, &wj, &wj_dx);
420 const float wj_dr = hjd_inv * wj_dx;
421
422 /* Variable smoothing length term */
423 const float f_ij = 1.f - pi->force.f / mj;
424 const float f_ji = 1.f - pj->force.f / mi;
425
426 /* Compute gradient terms */
427 const float P_over_rho2_i = pressurei / (rhoi * rhoi) * f_ij;
428 const float P_over_rho2_j = pressurej / (rhoj * rhoj) * f_ji;
429
430 /* Compute dv dot r. */
431 const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] +
432 (pi->v[1] - pj->v[1]) * dx[1] +
433 (pi->v[2] - pj->v[2]) * dx[2];
434
435 /* Add Hubble flow */
436 const float dvdr_Hubble = dvdr + a2_Hubble * r2;
437
438 /* Are the particles moving towards each others ? */
439 const float omega_ij = MIN(dvdr_Hubble, 0.f);
440 const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */
441
442 /* Compute signal velocity */
443 const float v_sig = signal_velocity(dx, pi, pj, mu_ij, const_viscosity_beta);
444
445 /* Grab balsara switches */
446 const float balsara_i = pi->force.balsara;
447 const float balsara_j = pj->force.balsara;
448
449 /* Construct the full viscosity term */
450 const float rho_ij = 0.5f * (rhoi + rhoj);
451 const float visc = -0.25f * v_sig * (balsara_i + balsara_j) * mu_ij / rho_ij;
452
453 /* Convolve with the kernel */
454 const float visc_acc_term =
455 0.5f * visc * (wi_dr * f_ij + wj_dr * f_ji) * r_inv;
456
457 /* SPH acceleration term */
458 const float sph_acc_term =
459 (P_over_rho2_i * wi_dr + P_over_rho2_j * wj_dr) * r_inv;
460
461 /* Adaptive softening acceleration term */
462 const float adapt_soft_acc_term =
463 adaptive_softening_get_acc_term(pi, pj, wi_dr, wj_dr, f_ij, f_ji, r_inv);
464
465 /* Assemble the acceleration */
466 const float acc = sph_acc_term + visc_acc_term + adapt_soft_acc_term;
467
468 /* Use the force Luke ! */
469 pi->a_hydro[0] -= mj * acc * dx[0];
470 pi->a_hydro[1] -= mj * acc * dx[1];
471 pi->a_hydro[2] -= mj * acc * dx[2];
472
473 /* Get the time derivative for u. */
474 const float sph_du_term_i = P_over_rho2_i * dvdr * r_inv * wi_dr;
475
476 /* Viscosity term */
477 const float visc_du_term = 0.5f * visc_acc_term * dvdr_Hubble;
478
479 /* Assemble the energy equation term */
480 const float du_dt_i = sph_du_term_i + visc_du_term;
481
482 /* Internal energy time derivatibe */
483 pi->u_dt += du_dt_i * mj;
484
485 /* Get the time derivative for h. */
486 pi->force.h_dt -= mj * dvdr * r_inv / rhoj * wi_dr * f_ij;
487
488 /* Update the signal velocity. */
489 pi->force.v_sig = MAX(pi->force.v_sig, v_sig);
490}
491
492#endif /* SWIFT_MINIMAL_HYDRO_IACT_H */
Defines the adiabatic index (polytropix index) of the problem and (fast) mathematical functions invo...
p force v_sig
Definition hydro.h:379
const float const float const float hj
Definition hydro_iact.h:54
const float dx[3]
Definition hydro_iact.h:54
const float const float hi
Definition hydro_iact.h:54
adaptive_softening_add_correction_term(pi, ui, hi_inv, mj)
const float hj_inv
Definition hydro_iact.h:87
const float r_inv
Definition hydro_iact.h:69
const float hi_inv
Definition hydro_iact.h:76
const float const float const float struct part *restrict struct part *restrict pj
Definition hydro_iact.h:55
kernel_deval(ui, &wi, &wi_dx)
float curlvr[3]
Definition hydro_iact.h:98
const float faci
Definition hydro_iact.h:100
const float const float const float struct part *restrict struct part *restrict const float const float H
Definition hydro_iact.h:56
const float facj
Definition hydro_iact.h:101
const float mj
Definition hydro_iact.h:73
const float const float const float struct part *restrict struct part *restrict const float a
Definition hydro_iact.h:55
const float r
Definition hydro_iact.h:68
const float uj
Definition hydro_iact.h:88
float dv[3]
Definition hydro_iact.h:98
__attribute__((always_inline)) INLINE static void runner_iact_density(const float r2
Density interaction between two particles.
const float mi
Definition hydro_iact.h:72
const float ui
Definition hydro_iact.h:77
const float dvdr
Definition hydro_iact.h:106
const float h_inv
Definition hydro_iact.h:158
#define const_viscosity_beta
#define INLINE
Defines inline.
Definition inline.h:36
#define MIN(a, b)
Minimum of two numbers.
Definition minmax.h:27
#define MAX(a, b)
Maximum of two numbers.
Definition minmax.h:39
InlineMethod T pow_dimension_plus_one(T x)
returns x^{ndim+1}
const struct part *restrict const struct part *restrict const float mu_ij
Particle fields for the SPH particles.
Definition hydro_part.h:99
float wcount
Definition hydro_part.h:144
float mass
Definition hydro_part.h:117
float rot_v[3]
Definition hydro_part.h:156
float h_dt
Definition hydro_part.h:182
float rho
Definition hydro_part.h:129
float wcount_dh
Definition hydro_part.h:147
float a_hydro[3]
Definition hydro_part.h:114
float rho_dh
Definition hydro_part.h:150
float pressure
Definition hydro_part.h:173
struct part::@3::@6 force
Structure for the variables only used in the force loop over neighbours.
float u_dt
Definition hydro_part.h:126
struct part::@3::@5 density
Structure for the variables only used in the density loop over neighbours.
float f
Definition hydro_part.h:170
float v[3]
Definition hydro_part.h:111
float balsara
Definition hydro_part.h:185
float div_v
Definition hydro_part.h:153
float v_sig
Definition hydro_part.h:179