MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
Classes | Macros | Functions | Variables
hydra.c File Reference

Computation of SPH forces and rate of entropy generation. More...

#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <gsl/gsl_math.h>
#include "physconst.h"
#include "walltime.h"
#include "slotsmanager.h"
#include "treewalk.h"
#include "density.h"
#include "hydra.h"
#include "winds.h"
#include "utils.h"
Include dependency graph for hydra.c:

Go to the source code of this file.

Classes

struct  hydro_params
 
struct  HydraPriv
 
struct  TreeWalkQueryHydro
 
struct  TreeWalkResultHydro
 
struct  TreeWalkNgbIterHydro
 

Macros

#define HYDRA_GET_PRIV(tw)   ((struct HydraPriv*) ((tw)->priv))
 

Functions

void set_hydro_params (ParameterSet *ps)
 
int DensityIndependentSphOn (void)
 
static MyFloat SPH_EOMDensity (const struct sph_particle_data *const pi)
 
static double PressurePred (MyFloat EOMDensityPred, double EntVarPred)
 
static int hydro_haswork (int n, TreeWalk *tw)
 
static void hydro_postprocess (int i, TreeWalk *tw)
 
static void hydro_ngbiter (TreeWalkQueryHydro *I, TreeWalkResultHydro *O, TreeWalkNgbIterHydro *iter, LocalTreeWalk *lv)
 
static void hydro_copy (int place, TreeWalkQueryHydro *input, TreeWalk *tw)
 
static void hydro_reduce (int place, TreeWalkResultHydro *result, enum TreeWalkReduceMode mode, TreeWalk *tw)
 
void hydro_force (const ActiveParticles *act, const double atime, struct sph_pred_data *SPH_predicted, double MinEgySpec, const DriftKickTimes times, Cosmology *CP, const ForceTree *const tree)
 
double SPH_DensityPred (MyFloat Density, MyFloat DivVel, double dtdrift)
 

Variables

static struct hydro_params HydroParams
 

Detailed Description

Computation of SPH forces and rate of entropy generation.

This file contains the "second SPH loop", where the SPH forces are computed, and where the rate of change of entropy due to the shock heating (via artificial viscosity) is computed.

Definition in file hydra.c.

Macro Definition Documentation

◆ HYDRA_GET_PRIV

#define HYDRA_GET_PRIV (   tw)    ((struct HydraPriv*) ((tw)->priv))

Definition at line 89 of file hydra.c.

Function Documentation

◆ DensityIndependentSphOn()

int DensityIndependentSphOn ( void  )

Definition at line 49 of file hydra.c.

50 {
52 }
static struct hydro_params HydroParams
int DensityIndependentSphOn
Definition: hydra.c:28

References hydro_params::DensityIndependentSphOn, and HydroParams.

Referenced by register_io_blocks(), run(), setup_density_indep_entropy(), and setup_smoothinglengths().

Here is the caller graph for this function:

◆ hydro_copy()

static void hydro_copy ( int  place,
TreeWalkQueryHydro input,
TreeWalk tw 
)
static

Definition at line 242 of file hydra.c.

243 {
244  double soundspeed_i;
245  MyFloat * velpred = HYDRA_GET_PRIV(tw)->SPH_predicted->VelPred;
246  /*Compute predicted velocity*/
247  input->Vel[0] = velpred[3 * P[place].PI];
248  input->Vel[1] = velpred[3 * P[place].PI + 1];
249  input->Vel[2] = velpred[3 * P[place].PI + 2];
250  input->Hsml = P[place].Hsml;
251  input->Mass = P[place].Mass;
252  input->Density = SPHP(place).Density;
253 
255  input->EgyRho = SPHP(place).EgyWtDensity;
256  MyFloat * entvarpred = HYDRA_GET_PRIV(tw)->SPH_predicted->EntVarPred;
257 
258  input->EntVarPred = entvarpred[P[place].PI];
259  }
260 
261  input->SPH_DhsmlDensityFactor = SPHP(place).DhsmlEgyDensityFactor;
262 
263  input->Pressure = HYDRA_GET_PRIV(tw)->PressurePred[P[place].PI];
264  input->dloga = get_dloga_for_bin(P[place].TimeBin, HYDRA_GET_PRIV(tw)->times->Ti_Current);
265  /* calculation of F1 */
266  soundspeed_i = sqrt(GAMMA * input->Pressure / SPH_EOMDensity(&SPHP(place)));
267  input->F1 = fabs(SPHP(place).DivVel) /
268  (fabs(SPHP(place).DivVel) + SPHP(place).CurlVel +
269  0.0001 * soundspeed_i / P[place].Hsml / HYDRA_GET_PRIV(tw)->fac_mu);
270 }
static MyFloat SPH_EOMDensity(const struct sph_particle_data *const pi)
Definition: hydra.c:56
#define HYDRA_GET_PRIV(tw)
Definition: hydra.c:89
#define P
Definition: partmanager.h:88
#define GAMMA
Definition: physconst.h:34
#define SPHP(i)
Definition: slotsmanager.h:124
double Vel[3]
Definition: hydra.c:97
MyFloat EntVarPred
Definition: hydra.c:95
MyFloat Hsml
Definition: hydra.c:98
MyFloat Pressure
Definition: hydra.c:101
MyFloat EgyRho
Definition: hydra.c:94
MyFloat F1
Definition: hydra.c:102
MyFloat Density
Definition: hydra.c:100
MyFloat Mass
Definition: hydra.c:99
MyFloat dloga
Definition: hydra.c:104
MyFloat SPH_DhsmlDensityFactor
Definition: hydra.c:103
double get_dloga_for_bin(int timebin, const inttime_t Ti_Current)
Definition: timebinmgr.c:279
LOW_PRECISION MyFloat
Definition: types.h:19

References TreeWalkQueryHydro::Density, hydro_params::DensityIndependentSphOn, TreeWalkQueryHydro::dloga, TreeWalkQueryHydro::EgyRho, TreeWalkQueryHydro::EntVarPred, TreeWalkQueryHydro::F1, GAMMA, get_dloga_for_bin(), TreeWalkQueryHydro::Hsml, HYDRA_GET_PRIV, HydroParams, TreeWalkQueryHydro::Mass, P, TreeWalkQueryHydro::Pressure, TreeWalkQueryHydro::SPH_DhsmlDensityFactor, SPH_EOMDensity(), SPHP, DriftKickTimes::Ti_Current, HydraPriv::times, and TreeWalkQueryHydro::Vel.

Referenced by hydro_force().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ hydro_force()

void hydro_force ( const ActiveParticles act,
const double  atime,
struct sph_pred_data SPH_predicted,
double  MinEgySpec,
const DriftKickTimes  times,
Cosmology CP,
const ForceTree *const  tree 
)

This function is the driver routine for the calculation of hydrodynamical force and rate of change of entropy due to shock heating for all active particles .

Definition at line 147 of file hydra.c.

148 {
149  int i;
150  TreeWalk tw[1] = {{0}};
151 
152  struct HydraPriv priv[1];
153 
154  tw->ev_label = "HYDRO";
158  tw->haswork = hydro_haswork;
164  tw->tree = tree;
165  tw->priv = priv;
166 
167  if(!tree->hmax_computed_flag)
168  endrun(5, "Hydro called before hmax computed\n");
169  /* Cache the pressure for speed*/
170  HYDRA_GET_PRIV(tw)->SPH_predicted = SPH_predicted;
171  HYDRA_GET_PRIV(tw)->PressurePred = (double *) mymalloc("PressurePred", SlotsManager->info[0].size * sizeof(double));
172  memset(HYDRA_GET_PRIV(tw)->PressurePred, 0, SlotsManager->info[0].size * sizeof(double));
173 
174  /* Compute pressure for active particles*/
175  if(act->ActiveParticle) {
176  #pragma omp parallel for
177  for(i = 0; i < act->NumActiveParticle; i++) {
178  int p_i = act->ActiveParticle[i];
179  if(P[p_i].Type != 0)
180  continue;
181  int pi = P[p_i].PI;
182  HYDRA_GET_PRIV(tw)->PressurePred[pi] = PressurePred(SPH_EOMDensity(&SphP[pi]), SPH_predicted->EntVarPred[pi]);
183  }
184  }
185  else{
186  /* Do it in slot order for memory locality*/
187  #pragma omp parallel for
188  for(i = 0; i < SlotsManager->info[0].size; i++)
189  HYDRA_GET_PRIV(tw)->PressurePred[i] = PressurePred(SPH_EOMDensity(&SphP[i]), SPH_predicted->EntVarPred[i]);
190  }
191 
192 
193  double timeall = 0, timenetwork = 0;
194  double timecomp, timecomm, timewait;
195 
196  walltime_measure("/SPH/Hydro/Init");
197 
198  /* Initialize some time factors*/
199  const double hubble = hubble_function(CP, atime);
200  HYDRA_GET_PRIV(tw)->fac_mu = pow(atime, 3 * (GAMMA - 1) / 2) / atime;
201  HYDRA_GET_PRIV(tw)->fac_vsic_fix = hubble * pow(atime, 3 * GAMMA_MINUS1);
202  HYDRA_GET_PRIV(tw)->atime = atime;
203  HYDRA_GET_PRIV(tw)->hubble_a2 = hubble * atime * atime;
204  priv->MinEgySpec = MinEgySpec;
205  priv->times = &times;
207  memset(priv->gravkicks, 0, sizeof(priv->gravkicks[0])*(TIMEBINS+1));
208  memset(priv->hydrokicks, 0, sizeof(priv->hydrokicks[0])*(TIMEBINS+1));
209  memset(priv->drifts, 0, sizeof(priv->drifts[0])*(TIMEBINS+1));
210  /* Compute the factors to move a current kick times velocity to the drift time velocity.
211  * We need to do the computation for all timebins up to the maximum because even inactive
212  * particles may have interactions. */
213  #pragma omp parallel for
214  for(i = times.mintimebin; i <= TIMEBINS; i++)
215  {
216  priv->gravkicks[i] = get_exact_gravkick_factor(CP, times.Ti_kick[i], times.Ti_Current);
217  priv->hydrokicks[i] = get_exact_hydrokick_factor(CP, times.Ti_kick[i], times.Ti_Current);
218  /* For density: last active drift time is Ti_kick - 1/2 timestep as the kick time is half a timestep ahead.
219  * For active particles no density drift is needed.*/
222  }
223 
225 
227  /* collect some timing information */
228 
229  timeall += walltime_measure(WALLTIME_IGNORE);
230 
231  timecomp = tw->timecomp1 + tw->timecomp2 + tw->timecomp3;
232  timewait = tw->timewait1 + tw->timewait2;
233  timecomm = tw->timecommsumm1 + tw->timecommsumm2;
234 
235  walltime_add("/SPH/Hydro/Compute", timecomp);
236  walltime_add("/SPH/Hydro/Wait", timewait);
237  walltime_add("/SPH/Hydro/Comm", timecomm);
238  walltime_add("/SPH/Hydro/Misc", timeall - (timecomp + timewait + timecomm + timenetwork));
239 }
double hubble_function(const Cosmology *CP, double a)
Definition: cosmology.c:58
void endrun(int where, const char *fmt,...)
Definition: endrun.c:147
static void hydro_reduce(int place, TreeWalkResultHydro *result, enum TreeWalkReduceMode mode, TreeWalk *tw)
Definition: hydra.c:273
static void hydro_copy(int place, TreeWalkQueryHydro *input, TreeWalk *tw)
Definition: hydra.c:242
static void hydro_ngbiter(TreeWalkQueryHydro *I, TreeWalkResultHydro *O, TreeWalkNgbIterHydro *iter, LocalTreeWalk *lv)
Definition: hydra.c:305
static void hydro_postprocess(int i, TreeWalk *tw)
Definition: hydra.c:501
static double PressurePred(MyFloat EOMDensityPred, double EntVarPred)
Definition: hydra.c:67
static int hydro_haswork(int n, TreeWalk *tw)
Definition: hydra.c:495
#define mymalloc(name, size)
Definition: mymalloc.h:15
#define myfree(x)
Definition: mymalloc.h:19
#define GAMMA_MINUS1
Definition: physconst.h:35
static Cosmology * CP
Definition: power.c:27
struct slots_manager_type SlotsManager[1]
Definition: slotsmanager.c:7
#define SphP
Definition: slotsmanager.h:119
int * ActiveParticle
Definition: timestep.h:13
int64_t NumActiveParticle
Definition: timestep.h:12
inttime_t PM_kick
Definition: timestep.h:31
inttime_t Ti_lastactivedrift[TIMEBINS+1]
Definition: timestep.h:25
inttime_t Ti_Current
Definition: timestep.h:27
inttime_t Ti_kick[TIMEBINS+1]
Definition: timestep.h:23
int mintimebin
Definition: timestep.h:20
int hmax_computed_flag
Definition: forcetree.h:80
double MinEgySpec
Definition: hydra.c:82
double atime
Definition: hydra.c:80
DriftKickTimes const * times
Definition: hydra.c:81
struct sph_pred_data * SPH_predicted
Definition: hydra.c:74
void * priv
Definition: treewalk.h:85
TreeWalkHasWorkFunction haswork
Definition: treewalk.h:100
size_t ngbiter_type_elsize
Definition: treewalk.h:97
double timecomp2
Definition: treewalk.h:124
double timecomp3
Definition: treewalk.h:125
double timecommsumm1
Definition: treewalk.h:126
const ForceTree * tree
Definition: treewalk.h:88
TreeWalkProcessFunction postprocess
Definition: treewalk.h:104
TreeWalkNgbIterFunction ngbiter
Definition: treewalk.h:103
TreeWalkReduceResultFunction reduce
Definition: treewalk.h:102
const char * ev_label
Definition: treewalk.h:91
double timewait2
Definition: treewalk.h:122
TreeWalkVisitFunction visit
Definition: treewalk.h:99
size_t result_type_elsize
Definition: treewalk.h:96
TreeWalkFillQueryFunction fill
Definition: treewalk.h:101
double timecomp1
Definition: treewalk.h:123
double timewait1
Definition: treewalk.h:121
double timecommsumm2
Definition: treewalk.h:127
size_t query_type_elsize
Definition: treewalk.h:95
int64_t size
Definition: slotsmanager.h:12
struct slot_info info[6]
Definition: slotsmanager.h:112
MyFloat * EntVarPred
Definition: density.h:28
#define TIMEBINS
Definition: timebinmgr.h:13
double get_exact_hydrokick_factor(Cosmology *CP, inttime_t ti0, inttime_t ti1)
Definition: timefac.c:75
double get_exact_drift_factor(Cosmology *CP, inttime_t ti0, inttime_t ti1)
Definition: timefac.c:64
double get_exact_gravkick_factor(Cosmology *CP, inttime_t ti0, inttime_t ti1)
Definition: timefac.c:70
int is_timebin_active(int i, inttime_t current)
Definition: timestep.c:149
int treewalk_visit_ngbiter(TreeWalkQueryBase *I, TreeWalkResultBase *O, LocalTreeWalk *lv)
Definition: treewalk.c:924
void treewalk_run(TreeWalk *tw, int *active_set, size_t size)
Definition: treewalk.c:619
int(* TreeWalkVisitFunction)(TreeWalkQueryBase *input, TreeWalkResultBase *output, LocalTreeWalk *lv)
Definition: treewalk.h:68
void(* TreeWalkReduceResultFunction)(const int j, TreeWalkResultBase *result, const enum TreeWalkReduceMode mode, TreeWalk *tw)
Definition: treewalk.h:76
void(* TreeWalkProcessFunction)(const int i, TreeWalk *tw)
Definition: treewalk.h:73
void(* TreeWalkNgbIterFunction)(TreeWalkQueryBase *input, TreeWalkResultBase *output, TreeWalkNgbIterBase *iter, LocalTreeWalk *lv)
Definition: treewalk.h:70
void(* TreeWalkFillQueryFunction)(const int j, TreeWalkQueryBase *query, TreeWalk *tw)
Definition: treewalk.h:75
#define walltime_measure(name)
Definition: walltime.h:8
#define WALLTIME_IGNORE
Definition: walltime.h:6
#define walltime_add(name, dt)
Definition: walltime.h:9

References ActiveParticles::ActiveParticle, HydraPriv::atime, CP, HydraPriv::drifts, endrun(), sph_pred_data::EntVarPred, TreeWalk::ev_label, HydraPriv::FgravkickB, TreeWalk::fill, GAMMA, GAMMA_MINUS1, get_exact_drift_factor(), get_exact_gravkick_factor(), get_exact_hydrokick_factor(), HydraPriv::gravkicks, TreeWalk::haswork, ForceTree::hmax_computed_flag, hubble_function(), HYDRA_GET_PRIV, hydro_copy(), hydro_haswork(), hydro_ngbiter(), hydro_postprocess(), hydro_reduce(), HydraPriv::hydrokicks, slots_manager_type::info, is_timebin_active(), HydraPriv::MinEgySpec, DriftKickTimes::mintimebin, myfree, mymalloc, TreeWalk::ngbiter, TreeWalk::ngbiter_type_elsize, ActiveParticles::NumActiveParticle, P, DriftKickTimes::PM_kick, TreeWalk::postprocess, PressurePred(), TreeWalk::priv, TreeWalk::query_type_elsize, TreeWalk::reduce, TreeWalk::result_type_elsize, slot_info::size, SlotsManager, SPH_EOMDensity(), HydraPriv::SPH_predicted, SphP, DriftKickTimes::Ti_Current, DriftKickTimes::Ti_kick, DriftKickTimes::Ti_lastactivedrift, TIMEBINS, TreeWalk::timecommsumm1, TreeWalk::timecommsumm2, TreeWalk::timecomp1, TreeWalk::timecomp2, TreeWalk::timecomp3, HydraPriv::times, TreeWalk::timewait1, TreeWalk::timewait2, TreeWalk::tree, treewalk_run(), treewalk_visit_ngbiter(), TreeWalk::visit, walltime_add, WALLTIME_IGNORE, and walltime_measure.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ hydro_haswork()

static int hydro_haswork ( int  n,
TreeWalk tw 
)
static

Definition at line 495 of file hydra.c.

496 {
497  return P[i].Type == 0;
498 }

References P.

Referenced by hydro_force().

Here is the caller graph for this function:

◆ hydro_ngbiter()

static void hydro_ngbiter ( TreeWalkQueryHydro I,
TreeWalkResultHydro O,
TreeWalkNgbIterHydro iter,
LocalTreeWalk lv 
)
static

This function is the 'core' of the SPH force computation. A target particle is specified which may either be local, or reside in the communication buffer.

Definition at line 305 of file hydra.c.

311 {
312  if(iter->base.other == -1) {
313  iter->base.Hsml = I->Hsml;
314  iter->base.mask = 1;
316 
318  iter->soundspeed_i = sqrt(GAMMA * I->Pressure / I->EgyRho);
319  else
320  iter->soundspeed_i = sqrt(GAMMA * I->Pressure / I->Density);
321 
322  /* initialize variables before SPH loop is started */
323 
324  O->Acc[0] = O->Acc[1] = O->Acc[2] = O->DtEntropy = 0;
326 
328  iter->p_over_rho2_i = I->Pressure / (I->EgyRho * I->EgyRho);
329  else
330  iter->p_over_rho2_i = I->Pressure / (I->Density * I->Density);
331 
332  O->MaxSignalVel = iter->soundspeed_i;
333  return;
334  }
335 
336  int other = iter->base.other;
337  double rsq = iter->base.r2;
338  double * dist = iter->base.dist;
339  double r = iter->base.r;
340 
341  if(P[other].Mass == 0) {
342  endrun(12, "Encountered zero mass particle during hydro;"
343  " We haven't implemented tracer particles and this shall not happen\n");
344  }
345 
346  /* Wind particles do not interact hydrodynamically: don't produce hydro acceleration
347  * or change the signalvel.*/
348  if(winds_is_particle_decoupled(other))
349  return;
350 
351  DensityKernel kernel_j;
352 
353  density_kernel_init(&kernel_j, P[other].Hsml, GetDensityKernelType());
354 
355  /* Check we are within the density kernel*/
356  if(rsq <= 0 || !(rsq < iter->kernel_i.HH || rsq < kernel_j.HH))
357  return;
358 
359  struct HydraPriv * priv = HYDRA_GET_PRIV(lv->tw);
360 
361  double EntVarPred;
362  #pragma omp atomic read
363  EntVarPred = HYDRA_GET_PRIV(lv->tw)->SPH_predicted->EntVarPred[P[other].PI];
364  /* Lazily compute the predicted quantities. We need to do this again here, even though we do it in density,
365  * because this treewalk is symmetric and that one is asymmetric. In density() hmax has not been computed
366  * yet so we cannot merge them. We can do this
367  * with minimal locking since nothing happens should we compute them twice.
368  * Zero can be the special value since there should never be zero entropy.*/
369  MyFloat VelPred[3];
370  if(EntVarPred == 0) {
371  int bin = P[other].TimeBin;
372  double a3inv = pow(priv->atime, -3);
373  double dloga = dloga_from_dti(priv->times->Ti_Current - priv->times->Ti_kick[bin], priv->times->Ti_Current);
374  EntVarPred = SPH_EntVarPred(P[other].PI, priv->MinEgySpec, a3inv, dloga);
375  SPH_VelPred(other, VelPred, priv->FgravkickB, priv->gravkicks[bin], priv->hydrokicks[bin]);
376  /* Note this goes first to avoid threading issues: EntVarPred will only be set after this is done.
377  * The worst that can happen is that some data points get copied twice.*/
378  int i;
379  for(i = 0; i < 3; i++) {
380  #pragma omp atomic write
381  priv->SPH_predicted->VelPred[3 * P[other].PI + i] = VelPred[i];
382  }
383  #pragma omp atomic write
384  priv->SPH_predicted->EntVarPred[P[other].PI] = EntVarPred;
385  }
386  else {
387  int i;
388  for(i = 0; i < 3; i++) {
389  #pragma omp atomic read
390  VelPred[i] = priv->SPH_predicted->VelPred[3 * P[other].PI + i];
391  }
392  }
393 
394  /* Predict densities. Note that for active timebins the density is up to date so SPH_DensityPred is just returns the current densities.
395  * This improves on the technique used in Gadget-2 by being a linear prediction that does not become pathological in deep timebins.*/
396  int bin = P[other].TimeBin;
397  const double density_j = SPH_DensityPred(SPHP(other).Density, SPHP(other).DivVel, priv->drifts[bin]);
398  const double eomdensity = SPH_DensityPred(SPH_EOMDensity(&SPHP(other)), SPHP(other).DivVel, priv->drifts[bin]);;
399 
400  /* Compute pressure lazily*/
401  double Pressure_j;
402  #pragma omp atomic read
403  Pressure_j = HYDRA_GET_PRIV(lv->tw)->PressurePred[P[other].PI];
404  if(Pressure_j == 0) {
405  Pressure_j = PressurePred(eomdensity, EntVarPred);
406  #pragma omp atomic write
407  priv->PressurePred[P[other].PI] = Pressure_j;
408  }
409 
410  double p_over_rho2_j = Pressure_j / (eomdensity * eomdensity);
411  double soundspeed_j = sqrt(GAMMA * Pressure_j / eomdensity);
412 
413  double dv[3];
414  int d;
415  for(d = 0; d < 3; d++) {
416  dv[d] = I->Vel[d] - VelPred[d];
417  }
418 
419  double vdotr = dotproduct(dist, dv);
420  double vdotr2 = vdotr + HYDRA_GET_PRIV(lv->tw)->hubble_a2 * rsq;
421 
422  double dwk_i = density_kernel_dwk(&iter->kernel_i, r * iter->kernel_i.Hinv);
423  double dwk_j = density_kernel_dwk(&kernel_j, r * kernel_j.Hinv);
424 
425  double visc = 0;
426 
427  if(vdotr2 < 0) /* ... artificial viscosity visc is 0 by default*/
428  {
429  /*See Gadget-2 paper: eq. 13*/
430  const double mu_ij = HYDRA_GET_PRIV(lv->tw)->fac_mu * vdotr2 / r; /* note: this is negative! */
431  const double rho_ij = 0.5 * (I->Density + density_j);
432  double vsig = iter->soundspeed_i + soundspeed_j;
433 
434  vsig -= 3 * mu_ij;
435 
436  if(vsig > O->MaxSignalVel)
437  O->MaxSignalVel = vsig;
438 
439  /* Note this uses the CurlVel of an inactive particle, which is not at the present drift time*/
440  const double f2 = fabs(SPHP(other).DivVel) / (fabs(SPHP(other).DivVel) +
441  SPHP(other).CurlVel + 0.0001 * soundspeed_j / HYDRA_GET_PRIV(lv->tw)->fac_mu / P[other].Hsml);
442 
443  /*Gadget-2 paper, eq. 14*/
444  visc = 0.25 * HydroParams.ArtBulkViscConst * vsig * (-mu_ij) / rho_ij * (I->F1 + f2);
445  /* .... end artificial viscosity evaluation */
446  /* now make sure that viscous acceleration is not too large */
447 
448  /*XXX: why is this dloga ?*/
449  double dloga = 2 * DMAX(I->dloga, get_dloga_for_bin(P[other].TimeBin, HYDRA_GET_PRIV(lv->tw)->times->Ti_Current));
450  if(dloga > 0 && (dwk_i + dwk_j) < 0)
451  {
452  if((I->Mass + P[other].Mass) > 0) {
453  visc = DMIN(visc, 0.5 * HYDRA_GET_PRIV(lv->tw)->fac_vsic_fix * vdotr2 /
454  (0.5 * (I->Mass + P[other].Mass) * (dwk_i + dwk_j) * r * dloga));
455  }
456  }
457  }
458  const double hfc_visc = 0.5 * P[other].Mass * visc * (dwk_i + dwk_j) / r;
459  double hfc = hfc_visc;
460  double rr1 = 1, rr2 = 1;
461 
463  /*This enables the grad-h corrections*/
464  rr1 = 0, rr2 = 0;
465  /* leading-order term */
466  hfc += P[other].Mass *
467  (dwk_i*iter->p_over_rho2_i*EntVarPred/I->EntVarPred +
468  dwk_j*p_over_rho2_j*I->EntVarPred/EntVarPred) / r;
469 
470  /* enable grad-h corrections only if contrastlimit is non negative */
472  rr1 = I->EgyRho / I->Density;
473  rr2 = eomdensity / density_j;
475  /* apply the limit if it is enabled > 0*/
478  }
479  }
480  }
481 
482  /* grad-h corrections: enabled if DensityIndependentSphOn = 0, or DensityConstrastLimit >= 0 */
483  /* Formulation derived from the Lagrangian */
484  hfc += P[other].Mass * (iter->p_over_rho2_i*I->SPH_DhsmlDensityFactor * dwk_i * rr1
485  + p_over_rho2_j*SPHP(other).DhsmlEgyDensityFactor * dwk_j * rr2) / r;
486 
487  for(d = 0; d < 3; d ++)
488  O->Acc[d] += (-hfc * dist[d]);
489 
490  O->DtEntropy += (0.5 * hfc_visc * vdotr2);
491 
492 }
void SPH_VelPred(int i, MyFloat *VelPred, const double FgravkickB, double gravkick, double hydrokick)
Definition: density.c:89
MyFloat SPH_EntVarPred(int PI, double MinEgySpec, double a3inv, double dloga)
Definition: density.c:71
enum DensityKernelType GetDensityKernelType(void)
Definition: density.c:63
double density_kernel_dwk(DensityKernel *kernel, double u)
void density_kernel_init(DensityKernel *kernel, double H, enum DensityKernelType type)
static double dotproduct(const double v1[3], const double v2[3])
Definition: densitykernel.h:53
double SPH_DensityPred(MyFloat Density, MyFloat DivVel, double dtdrift)
Definition: hydra.c:294
static double dloga
Definition: lightcone.c:21
double drifts[TIMEBINS+1]
Definition: hydra.c:86
double gravkicks[TIMEBINS+1]
Definition: hydra.c:84
double * PressurePred
Definition: hydra.c:73
double FgravkickB
Definition: hydra.c:83
double hydrokicks[TIMEBINS+1]
Definition: hydra.c:85
TreeWalk * tw
Definition: treewalk.h:47
double dist[3]
Definition: treewalk.h:40
enum NgbTreeFindSymmetric symmetric
Definition: treewalk.h:37
DensityKernel kernel_i
Definition: hydra.c:119
double soundspeed_i
Definition: hydra.c:117
TreeWalkNgbIterBase base
Definition: hydra.c:115
double p_over_rho2_i
Definition: hydra.c:116
MyFloat Acc[3]
Definition: hydra.c:109
MyFloat DtEntropy
Definition: hydra.c:110
MyFloat MaxSignalVel
Definition: hydra.c:111
double DensityContrastLimit
Definition: hydra.c:30
double ArtBulkViscConst
Definition: hydra.c:32
MyFloat * VelPred
Definition: density.h:34
#define DMIN(x, y)
Definition: test_interp.c:12
#define DMAX(x, y)
Definition: test_interp.c:11
double dloga_from_dti(inttime_t dti, const inttime_t Ti_Current)
Definition: timebinmgr.c:256
@ NGB_TREEFIND_SYMMETRIC
Definition: treewalk.h:11
int winds_is_particle_decoupled(int i)
Definition: winds.c:124

References TreeWalkResultHydro::Acc, hydro_params::ArtBulkViscConst, HydraPriv::atime, TreeWalkNgbIterHydro::base, TreeWalkQueryHydro::Density, density_kernel_dwk(), density_kernel_init(), hydro_params::DensityContrastLimit, hydro_params::DensityIndependentSphOn, TreeWalkNgbIterBase::dist, TreeWalkQueryHydro::dloga, dloga, dloga_from_dti(), DMAX, DMIN, dotproduct(), HydraPriv::drifts, TreeWalkResultHydro::DtEntropy, TreeWalkQueryHydro::EgyRho, endrun(), sph_pred_data::EntVarPred, TreeWalkQueryHydro::EntVarPred, TreeWalkQueryHydro::F1, HydraPriv::FgravkickB, GAMMA, get_dloga_for_bin(), GetDensityKernelType(), HydraPriv::gravkicks, DensityKernel::HH, DensityKernel::Hinv, TreeWalkQueryHydro::Hsml, TreeWalkNgbIterBase::Hsml, HYDRA_GET_PRIV, HydraPriv::hydrokicks, HydroParams, TreeWalkNgbIterHydro::kernel_i, TreeWalkNgbIterBase::mask, TreeWalkQueryHydro::Mass, TreeWalkResultHydro::MaxSignalVel, HydraPriv::MinEgySpec, NGB_TREEFIND_SYMMETRIC, TreeWalkNgbIterBase::other, P, TreeWalkNgbIterHydro::p_over_rho2_i, TreeWalkQueryHydro::Pressure, PressurePred(), HydraPriv::PressurePred, TreeWalkNgbIterBase::r, TreeWalkNgbIterBase::r2, TreeWalkNgbIterHydro::soundspeed_i, SPH_DensityPred(), TreeWalkQueryHydro::SPH_DhsmlDensityFactor, SPH_EntVarPred(), SPH_EOMDensity(), HydraPriv::SPH_predicted, SPH_VelPred(), SPHP, TreeWalkNgbIterBase::symmetric, DriftKickTimes::Ti_Current, DriftKickTimes::Ti_kick, HydraPriv::times, LocalTreeWalk::tw, TreeWalkQueryHydro::Vel, sph_pred_data::VelPred, and winds_is_particle_decoupled().

Referenced by hydro_force().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ hydro_postprocess()

static void hydro_postprocess ( int  i,
TreeWalk tw 
)
static

Definition at line 501 of file hydra.c.

502 {
503  if(P[i].Type == 0)
504  {
505  /* Translate energy change rate into entropy change rate */
506  SPHP(i).DtEntropy *= GAMMA_MINUS1 / (HYDRA_GET_PRIV(tw)->hubble_a2 * pow(SPHP(i).Density, GAMMA_MINUS1));
507 
508  /* if we have winds, we decouple particles briefly if delaytime>0 */
510  {
511  winds_decoupled_hydro(i, HYDRA_GET_PRIV(tw)->atime);
512  }
513  }
514 }
void winds_decoupled_hydro(int i, double atime)
Definition: winds.c:133

References HydraPriv::atime, GAMMA_MINUS1, HYDRA_GET_PRIV, P, SPHP, winds_decoupled_hydro(), and winds_is_particle_decoupled().

Referenced by hydro_force().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ hydro_reduce()

static void hydro_reduce ( int  place,
TreeWalkResultHydro result,
enum TreeWalkReduceMode  mode,
TreeWalk tw 
)
static

Definition at line 273 of file hydra.c.

274 {
275  int k;
276 
277  for(k = 0; k < 3; k++)
278  {
279  TREEWALK_REDUCE(SPHP(place).HydroAccel[k], result->Acc[k]);
280  }
281 
282  TREEWALK_REDUCE(SPHP(place).DtEntropy, result->DtEntropy);
283 
284  if(mode == TREEWALK_PRIMARY || SPHP(place).MaxSignalVel < result->MaxSignalVel)
285  SPHP(place).MaxSignalVel = result->MaxSignalVel;
286 
287 }
@ TREEWALK_PRIMARY
Definition: treewalk.h:16
#define TREEWALK_REDUCE(A, B)
Definition: treewalk.h:189

References TreeWalkResultHydro::Acc, TreeWalkResultHydro::DtEntropy, TreeWalkResultHydro::MaxSignalVel, SPHP, TREEWALK_PRIMARY, and TREEWALK_REDUCE.

Referenced by hydro_force().

Here is the caller graph for this function:

◆ PressurePred()

static double PressurePred ( MyFloat  EOMDensityPred,
double  EntVarPred 
)
static

Definition at line 67 of file hydra.c.

68 {
69  return pow(EntVarPred * EOMDensityPred, GAMMA);
70 }

References GAMMA.

Referenced by hydro_force(), and hydro_ngbiter().

Here is the caller graph for this function:

◆ set_hydro_params()

void set_hydro_params ( ParameterSet ps)

Definition at line 37 of file hydra.c.

38 {
39  int ThisTask;
40  MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask);
41  if(ThisTask == 0) {
42  HydroParams.ArtBulkViscConst = param_get_double(ps, "ArtBulkViscConst");
43  HydroParams.DensityContrastLimit = param_get_double(ps, "DensityContrastLimit");
44  HydroParams.DensityIndependentSphOn= param_get_int(ps, "DensityIndependentSphOn");
45  }
46  MPI_Bcast(&HydroParams, sizeof(struct hydro_params), MPI_BYTE, 0, MPI_COMM_WORLD);
47 }
double param_get_double(ParameterSet *ps, const char *name)
Definition: paramset.c:336
int param_get_int(ParameterSet *ps, const char *name)
Definition: paramset.c:368
int ThisTask
Definition: test_exchange.c:23

References hydro_params::ArtBulkViscConst, hydro_params::DensityContrastLimit, hydro_params::DensityIndependentSphOn, HydroParams, param_get_double(), param_get_int(), and ThisTask.

Referenced by read_parameter_file().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SPH_DensityPred()

double SPH_DensityPred ( MyFloat  Density,
MyFloat  DivVel,
double  dtdrift 
)

Definition at line 294 of file hydra.c.

295 {
296  /* Note minus sign!*/
297  return Density - DivVel * Density * dtdrift;
298 }

Referenced by hydro_ngbiter().

Here is the caller graph for this function:

◆ SPH_EOMDensity()

static MyFloat SPH_EOMDensity ( const struct sph_particle_data *const  pi)
static

Definition at line 56 of file hydra.c.

57 {
59  return pi->EgyWtDensity;
60  else
61  return pi->Density;
62 }
MyFloat EgyWtDensity
Definition: slotsmanager.h:85

References sph_particle_data::Density, hydro_params::DensityIndependentSphOn, sph_particle_data::EgyWtDensity, and HydroParams.

Referenced by hydro_copy(), hydro_force(), and hydro_ngbiter().

Here is the caller graph for this function:

Variable Documentation

◆ HydroParams

struct hydro_params HydroParams
static