40 #define MAXDMDEVIATION 2
75 MPI_Comm_rank(MPI_COMM_WORLD, &
ThisTask);
97 init_winds(
double FactorSN,
double EgySpecSN,
double PhysDensThresh,
double UnitTime_in_s)
127 &&
P[i].Type == 0 &&
SPHP(i).DelayTime > 0)
136 for(k = 0; k < 3; k++)
137 SPHP(i).HydroAccel[k] = 0;
139 SPHP(i).DtEntropy = 0;
142 const double fac_mu = pow(atime, 3 * (
GAMMA - 1) / 2) / atime;
145 SPHP(i).MaxSignalVel = hsml_c *
DMAX((2 * windspeed),
SPHP(i).MaxSignalVel);
149 wind_do_kick(
int other,
double vel,
double therm,
double atime);
155 get_wind_params(
double * vel,
double * windeff,
double * utherm,
const double vdisp,
const double time);
250 #define WIND_GET_PRIV(tw) ((struct WindPriv *) (tw->priv))
251 #define WINDP(i, wind) wind[P[i].PI]
276 int64_t totalleft = 0;
286 memset(
WIND_GET_PRIV(tw)->nvisited, 0, omp_get_max_threads()*
sizeof(
int));
290 #pragma omp parallel for
291 for (i = 0; i < NumNewStars; i++) {
292 int n = NewStars ? NewStars[i] : i;
312 if(!
MPIU_Any(NumMaybeWind > 0, MPI_COMM_WORLD))
320 for(n = 0; n < NumMaybeWind; n++)
322 int i = MaybeWind ? MaybeWind[n] : n;
324 MyFloat sm = StellarMasses[
P[i].PI];
339 if(!
MPIU_Any(NumNewStars > 0, MPI_COMM_WORLD))
347 for (i = 1; i < omp_get_max_threads(); i++)
372 int64_t last_part = -1;
374 for(i = 0; i < priv->
nkicks; i++) {
384 endrun(5,
"Odd v: other = %d, DT = %g v = %g i = %d, nkicks %d maxkicks %d dist %g id %ld\n",
390 int64_t tot_newstars, tot_kicks, tot_applied;
392 MPI_Allreduce(&priv->
nkicks, &tot_kicks, 1,
MPI_INT64, MPI_SUM, MPI_COMM_WORLD);
393 MPI_Allreduce(&nkicked, &tot_applied, 1,
MPI_INT64, MPI_SUM, MPI_COMM_WORLD);
394 message(0,
"Made %ld gas wind, discarded %ld kicks from %d stars\n", tot_applied, tot_kicks - tot_applied, tot_newstars);
407 SPHP(i).DelayTime = 0;
410 if(
SPHP(i).DelayTime > 0) {
425 double left =
WINDP(place, Windd).Left;
426 double right =
WINDP(place, Windd).Right;
429 right =
WINDP(place, Windd).DMRadius;
432 left = 0.1 *
WINDP(place, Windd).DMRadius;
434 double rvol = pow(right, 3);
435 double lvol = pow(left, 3);
436 return pow((1.0*i+1)/(1.0*
NWINDHSML+1) * (rvol - lvol) + lvol, 1./3);
445 const int maxcmpt =
WINDP(i, Windd).maxcmpte;
448 for(j = 0; j < maxcmpt; j++){
452 WINDP(i, Windd).DMRadius =
ngb_narrow_down(&
WINDP(i, Windd).
Right, &
WINDP(i, Windd).
Left, evaldmradius,
WINDP(i, Windd).
Ngb, maxcmpt,
NUMDMNGB, &close, tw->
tree->
BoxSize);
453 double numngb =
WINDP(i, Windd).Ngb[close];
455 int tid = omp_get_thread_num();
464 double vdisp =
WINDP(i, Windd).V2sum[close] / numngb;
466 for(d = 0; d<3; d++){
467 vdisp -= pow(
WINDP(i, Windd).
V1sum[close][d] / numngb,2);
470 WINDP(i, Windd).Vdisp = sqrt(vdisp / 3);
492 for(k = 0; k < 3; k ++) {
506 input->
ID =
P[place].ID;
508 input->
Mass =
P[place].Mass;
509 input->
Hsml =
P[place].Hsml;
514 input->
Vel[i] =
P[place].Vel[i];
539 double r = iter->
base.
r;
542 if(
P[other].Type == 0) {
543 if(r > I->
Hsml)
return;
546 if(
SPHP(other).DelayTime > 0)
return;
557 if(
P[other].Type == 1) {
563 for(d = 0; d < 3; d ++) {
565 double vel =
P[other].Vel[d] - I->
Vel[d] +
WIND_GET_PRIV(lv->
tw)->hubble * atime * atime * dist[d];
566 O->
V1sum[i][d] += vel;
567 O->
V2sum[i] += vel * vel;
596 if(vel > 0 && atime > 0) {
597 for(j = 0; j < 3; j++)
599 P[other].Vel[j] += vel * dir[j];
603 SPHP(other).Entropy += therm/enttou;
608 SPHP(other).DelayTime = delay;
622 dir[0] = sin(theta) * cos(phi);
623 dir[1] = sin(theta) * sin(phi);
630 get_wind_params(
double * vel,
double * windeff,
double * utherm,
const double vdisp,
const double time)
633 double vphys = vdisp / time;
665 double r = iter->
base.
r;
669 if(r > I->
Hsml)
return;
672 if(
SPHP(other).DelayTime > 0)
return;
678 if(
P[other].Type != 0 ||
P[other].IsGarbage ||
P[other].Swallowed)
682 double utherm = 0, v=0, windeff = 0;
688 if (random < p && v > 0) {
696 endrun(5,
"Not enough room in kick queue: %ld > %ld for particle %d starid %ld distance %g\n",
714 double utherm = 0, vel=0, windeff = 0;
719 double pw = windeff * sm /
P[i].Mass;
720 double prob = 1 - exp(-pw);
double(* wk)(DensityKernel *kernel, double q)
void message(int where, const char *fmt,...)
void endrun(int where, const char *fmt,...)
#define mymalloc(name, size)
#define ta_malloc(name, type, nele)
double param_get_double(ParameterSet *ps, const char *name)
int param_get_enum(ParameterSet *ps, const char *name)
struct slots_manager_type SlotsManager[1]
enum NgbTreeFindSymmetric symmetric
double DMRadius[NWINDHSML]
double V1sum[NWINDHSML][3]
TreeWalkHasWorkFunction haswork
size_t ngbiter_type_elsize
TreeWalkProcessFunction postprocess
TreeWalkNgbIterFunction ngbiter
TreeWalkReduceResultFunction reduce
TreeWalkVisitFunction visit
size_t result_type_elsize
TreeWalkFillQueryFunction fill
double WindFreeTravelDensThresh
double WindEnergyFraction
double WindFreeTravelLength
double WindFreeTravelDensFac
double MaxWindFreeTravelTime
struct winddata * Winddata
double V1sum[NWINDHSML][3]
double get_random_number(uint64_t id)
void sumup_large_ints(int n, int *src, int64_t *res)
int MPIU_Any(int condition, MPI_Comm comm)
static int64_t atomic_fetch_and_add_64(int64_t *ptr, int64_t value)
double get_dloga_for_bin(int timebin, const inttime_t Ti_Current)
int treewalk_visit_nolist_ngbiter(TreeWalkQueryBase *I, TreeWalkResultBase *O, LocalTreeWalk *lv)
void treewalk_run(TreeWalk *tw, int *active_set, size_t size)
double ngb_narrow_down(double *right, double *left, const double *radius, const double *numNgb, int maxcmpt, int desnumngb, int *closeidx, double BoxSize)
void treewalk_do_hsml_loop(TreeWalk *tw, int *queue, int64_t queuesize, int update_hsml)
int(* TreeWalkVisitFunction)(TreeWalkQueryBase *input, TreeWalkResultBase *output, LocalTreeWalk *lv)
void(* TreeWalkReduceResultFunction)(const int j, TreeWalkResultBase *result, const enum TreeWalkReduceMode mode, TreeWalk *tw)
void(* TreeWalkProcessFunction)(const int i, TreeWalk *tw)
void(* TreeWalkNgbIterFunction)(TreeWalkQueryBase *input, TreeWalkResultBase *output, TreeWalkNgbIterBase *iter, LocalTreeWalk *lv)
void(* TreeWalkFillQueryFunction)(const int j, TreeWalkQueryBase *query, TreeWalk *tw)
#define TREEWALK_REDUCE(A, B)
@ NGB_TREEFIND_ASYMMETRIC
#define walltime_measure(name)
static void sfr_wind_reduce_weight(int place, TreeWalkResultWind *remote, enum TreeWalkReduceMode mode, TreeWalk *tw)
static double effdmradius(int place, int i, TreeWalk *tw)
void winds_evolve(int i, double a3inv, double hubble)
void winds_subgrid(int *MaybeWind, int NumMaybeWind, const double Time, const double hubble, ForceTree *tree, MyFloat *StellarMasses)
#define WIND_GET_PRIV(tw)
static void wind_do_kick(int other, double vel, double therm, double atime)
static void sfr_wind_weight_ngbiter(TreeWalkQueryWind *I, TreeWalkResultWind *O, TreeWalkNgbIterWind *iter, LocalTreeWalk *lv)
static void sfr_wind_weight_postprocess(const int i, TreeWalk *tw)
static void sfr_wind_feedback_ngbiter(TreeWalkQueryWind *I, TreeWalkResultWind *O, TreeWalkNgbIterWind *iter, LocalTreeWalk *lv)
int winds_ever_decouple(void)
int cmp_by_part_id(const void *a, const void *b)
int winds_is_particle_decoupled(int i)
int winds_are_subgrid(void)
static void get_wind_params(double *vel, double *windeff, double *utherm, const double vdisp, const double time)
void set_winds_params(ParameterSet *ps)
static int get_wind_dir(int i, double dir[3])
static struct WindParams wind_params
void winds_decoupled_hydro(int i, double atime)
int winds_make_after_sf(int i, double sm, double vdisp, double atime)
static void winds_find_weights(TreeWalk *tw, struct WindPriv *priv, int *NewStars, int NumNewStars, const double Time, const double hubble, ForceTree *tree)
static void sfr_wind_copy(int place, TreeWalkQueryWind *input, TreeWalk *tw)
void winds_and_feedback(int *NewStars, int NumNewStars, const double Time, const double hubble, ForceTree *tree)
void init_winds(double FactorSN, double EgySpecSN, double PhysDensThresh, double UnitTime_in_s)