Page MenuHomec4science

No OneTemporary

File Metadata

Created
Fri, Mar 28, 23:52
This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/Gadget2 b/Gadget2
index 8b26513..d7e4b27 100755
Binary files a/Gadget2 and b/Gadget2 differ
diff --git a/TODO b/TODO
index aadea5a..f78d223 100644
--- a/TODO
+++ b/TODO
@@ -1,687 +1,693 @@
+multiple IMF :
+----------
+
+- add parameters
+- add code
+- add maxlivetime
new cooling :
----------
--- tester le cooling avec M=4, on devrait avoir Tcool << Tdyn à faire
- ajouter implicit cooling integration ok
+ tester ok, semble bien
- verifier ComovingIntegrationOn à tester
- tester sur cluster à faire
- tester sur boite cosmo à faire
on peut enlever :
DtEgySpecRadSph
DtEntropyRadSph
new sfr :
----------
- crée des étoiles de plus petite masse, et donc, garder la part. de gaz. ok
- utiliser tous les critères, jeans aussi... à faire
- tester un model statique --> loi exp décroissante ok
- transformer toute la particule lorsque elle est trops petite ok
- ecrire les output de StP ok
- prendre en compte l'énergie des étoiles... ok
- conservation de l'énergie ok
1 proc, StarFormationNStarsFromGas = 1 snap00
4 proc, StarFormationNStarsFromGas = 1 snap01 mini diff.
1 proc, StarFormationNStarsFromGas = 4 snap02 sfr correcte, mais
!!! il y a des oscillations...
1 proc, StarFormationNStarsFromGas = 4 snap03 ok, on corrige avec TreeDomainUpdateFrequency = 0
4 proc, StarFormationNStarsFromGas = 4
- permettre : TreeDomainUpdateFrequency > 0 à faire
domain :
----------
- forcer les particules stellaire a etre arrangées dans le block 1 ok
domain.c à faire (difficile)
maxloadsph -> maxloadstars
pour PEANOHILBERT : trier les particules star à faire
peano.c à faire
domain_sumCost -> add local_DomainCountSt à faire (difficile ?)
- modifier StP ok
All.TotN_stars ok
All.MaxPartStars = All.StarFormationNStarsFromGas*All.MaxPartSph ok
+ All.PartAllocFactor * (All.TotN_stars / NTask)
allocate.c ok
All.MaxPartStars
restart.c ok
init.c ok
domain.c ok
starformation.c ok
rearrange_particle_sequence ok
io.c
read_ic.c ok
ok
- vérifier les output ok
int flag_sfr
int flag_feedback
int flag_cooling
int flag_stellarage
int flag_metals
typelist[6] ok
--> 0 si aucune particule de ce type est présente dans le block
get_particles_in_block ok
- vérifier les input ok
- partir avec un fichier qui contiend déjà des étoiles
--> conditions initiales (lit qu'une partie...) ok
--> redémarrage
- partir avec un fichier qui contiend déjà la métalicité du gaz
--> conditions initiales
--> redémarrage
- tester All.TotN_stars ok
- N_stars ok
chimie :
----------
- pour une part. d'étoile, trouver les plus proches particules de gaz ok
- il faut calculer hsml/density (gaz) pour les étoiles... ok
- dans do_chimie, commencer la boucle par la première étoile ok
et non particule
- verifier le bon nombre de voisins pour les étoiles ok
stars_density.c ok
chimie.c ok
tests :
- vérifier la densité (écrire) ok
- vérifier hsml (écrire) ok
-> on écrit dans le fichier de sortie Density,Hsml ok
- vérifier les plus proches voisins ok
--> dans chimie,
-> vérifier : Sum m/rho wij = 1, par example... ok
- initialisation
utiliser get_nelts pour avoir NELEMENTS, ou alors, check.... à faire
- pour une particule stellaire, calculer à faire
- la masse totale ejectée ok
- les métaux éjectés ok
- l'énergie éjectée ok
- injecter la masse au plus proches voisins ok
- enlever mass et elt ejecté par une étoile ok
!!! conservation de l'énergie kin,pot, int
!!! conservation de l'impulsion...
!!! conservation de la masse ok
ok, a 1%pres... a vérifier par la suite...
dans des conditions moins difficiles...
<-------- Wed Jul 22 15:09:25 CEST 2009
- mieux conserver l'énergie lors de feedback thermqie (rendre part. active ?) à faire !!! (ou feedback cinétique...)
- faire un fichier statistique qui comptes ce qui est crée... à faire
- injecter l'énergie thermique ok
- injecter l'énergie cinetique à faire
- utiliser la metallicité pour le cooling ok
- utiliser TreeDomainUpdateFrequency != 0.0 à faire
- vérifier dans chimie.c -> utilisation de vel ou velpred...
- unifier à faire
SolarAbun_Fe = 0.001771 pNbody
SolarAbun_Mg = 0.00091245 pNbody
#define FEH_SOLAR 0.001771 Gadget /* 0.00181 */
#define MGH_SOLAR 0.00091245 Gadget
FeHSolar = 0.00181 Gadget cooling !!!
- vérifier restart -> particulièrement les parametres à faire
??? All.ChimieSupernovaEnergy = all.ChimieSupernovaEnergy
- revoir sticky (faire attention au leap frog, par ex.) à faire
- cooling : on peut completement sortie docooling de timestep, non ?
!! initialisation correcte de : StarEnergyInt,StarEnergyRadSph, à faire
StarEnergyRadSticky...
--> aussi lors d'un restart !!!
--> should be in All.
--------------------------------------------------------------------------------
CPU
--------------------------------------------------------------------------------
timediff(t0, t1) = t1-t0
All.CPU_Total,
run.c : on somme les diff de la boucle principale
All.CPU_Gravity,
accel.c :
gravity_tree()
All.CPU_Hydro,
accel.c :
density()
hydro_force();
All.CPU_Domain,
domain.c :
domain_Decomposition() sans peano_hilbert_order
All.CPU_Potential, potential.c :
compute_potential()
All.CPU_Predict, accel.c :
force_update_hmax(); ???
predic.c :
move_particles()
run.c :
find_next_sync_point_and_drift()
All.CPU_TimeLine, timestep.c :
advance_and_find_timesteps()
All.CPU_Snapshot, io.c
savepositions()
All.CPU_TreeConstruction potential.c
force_treebuild()
gravtree.c
force_treebuild()
All.CPU_TreeWalk, gravtree.c !!!
All.CPU_CommSum, gravtree.c
All.CPU_Imbalance, gravtree.c
All.CPU_TreeWalk += sumt / NTask;
All.CPU_Imbalance += sumimbalance / NTask;
All.CPU_CommSum += sumcomm / NTask;
All.CPU_HydCompWalk, chimie.c density.c hydra.c stars_density.c !!!
All.CPU_HydCommSumm, chimie.c density.c hydra.c stars_density.c
All.CPU_HydImbalance, chimie.c density.c hydra.c stars_density.c
All.CPU_HydImbalance += sumimbalance / NTask;
All.CPU_HydCommSumm += sumcomm / NTask;
All.CPU_HydCompWalk += sumt / NTask;
All.CPU_EnsureNgb, density.c !!!
All.CPU_EnsureNgb += sumtimengb / NTask;
stars_density.c
All.CPU_EnsureNgb += sumtimengb / NTask;
All.CPU_PM, accel.c
long_range_force()
All.CPU_Peano
domain.c : peano_hilbert_order()
on pourait rajouter :
-------------------
All.CPU_Accel
if faut rajouter :
All.CPU_Chimie
All.CPU_StarFormation
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
- sticky bournaud
- faire des tests
- choix du sticky --> pour cluster, mieux dans rayon sph...
- éviter que la densité soit calculée ??? vraiment utiles ?
- conservation de l'énergie pour sticky
----------------------------------------
- improve multiphase computation : only with MULTIPHASE switched on
- test sticky only
* for each particle, find one particle to collide with
* try to do that in the same function than the main hydra (???)
- test sph only
- test dark gas
- test combination of all
check
* indep. of number of proc
##########################################3
MULTIPHASE
##########################################
- part of particles behave differently (sticky)
GAS_SPH -> normal sph
GAS_STICKY -> sticky
GAS_DARK -> no (weak) interaction
functions
multi_hydro_evaluate
sticky_evaluate
ngb_treefind_phase_pairs
io.c ok
init.c ok
read_ic.c ok
run.c ok
density.c ok (rien de particulier)
ngb.c
ngb_treefind_pairs hydra.c
every body sees every body
ngb_treefind_variable density.c
find density and hsml !!!! hsml is then needed to find colliding particules
!!!! but may be problematic if only sph part. are present in hsml !!!
ngb_treefind_phase_pairs bondi_accretion.c
hydra.c !!!!!!!!!!!!
multi_hydro_evaluate(i, 0);
hydro_evaluate(i, 0);
sticky_evaluate(i, 0);
timestep.c
global.c
cooling.c
starformation.c
bubbles.c
##########################################
PHASE_MIXING
##########################################
proto.h
phase_mixing
run.c
phase.c
##########################################
COLDGAS_CYCLE (need MULTIPHASE)
##########################################
- compute cycling or not
---------------------------------------
COLDGAS_CYCLE :parameters
-------------------------
ColdGasCycleTransitionTime;
ColdGasCycleTransitionParameter;
allvars.h ok
begrun.c ok
phase.c ok
##########################################
EXTERNAL_FLUX : really only external flux
##########################################
begrun.c
cooling.c
phase.c
allvars.h
HeatingPeSolarEnergyDensity
HeatingExternalFLuxEnergyDensity
##########################################
STELLAR_FLUX : only stellar flux
##########################################
allvars.h
init.c
gravtree.c
forcetree.c
begrun.c
HeatingPeSolarEnergyDensity;
HeatingPeLMRatioGas;
HeatingPeLMRatioHalo;
HeatingPeLMRatioDisk;
HeatingPeLMRatioBulge;
HeatingPeLMRatioStars;
HeatingPeLMRatioBndry;
HeatingPeLMRatio[6];
####################################################
# sticky_evaluate(i, 0)
####################################################
1) check who can inteact with who ?
- loop over active particles
- ngb_treefind_pairs ! find all particles in h_i ... check !!!
here we could use different fct, depending on the type
- if(P[j].Ti_endstep == All.Ti_Current) only active particles ! ensure symetry,
really necessary ???
- if(SphP[j].Phase == GAS_STICKY) ok, but may be done with "ngb_treefind_pairs"
- if(SphP[j].StickyFlag) SphP[i].StickyFlag = 1; in init.c
SphP[i].StickyFlag is determined in phase.c
2) what is modified by sticky_evaluate
P[target].Vel[k] <------ here, we change the velocity !!!!!!!
P[j].Vel[k]
SphP[target].EgySpecRadSticky <------ here, we count the energy !!!!!!!
SphP[j].EgySpecRadSticky
SphP[target].StickyCollisionNumber++;
SphP[j].StickyCollisionNumber++;
SphP[target].HydroAccel[k] = 0;
SphP[target].StickyFlag = 0;
SphP[target].DtEntropy = 0; /* force dt entropy to zero */
SphP[j].DtEgySpecFeedback = 0; /* should not be there */
!!!! we change the velocity and count energy further
tests:
- only sticky : be sure that particles interact symetrically...
####################################################
# problemes
####################################################
(!!) si Entropy < 0, le gaz est considéré GAS_DARK (output)
-> bien vérifier...
(!!) si une particule oscille frequemment entre dark et visible, elle risque
de colisonner trops souvent... StickyFlag=1 automatique lors du retour au sticky
diff --git a/allvars.h b/allvars.h
index 3d6cc5d..a3fe56b 100644
--- a/allvars.h
+++ b/allvars.h
@@ -1,1614 +1,1615 @@
/*! \file allvars.h
* \brief declares global variables.
*
* This file declares all global variables. Further variables should be added here, and declared as
* 'extern'. The actual existence of these variables is provided by the file 'allvars.c'. To produce
* 'allvars.c' from 'allvars.h', do the following:
*
* - Erase all #define's, typedef's, and enum's
* - add #include "allvars.h", delete the #ifndef ALLVARS_H conditional
* - delete all keywords 'extern'
* - delete all struct definitions enclosed in {...}, e.g.
* "extern struct global_data_all_processes {....} All;"
* becomes "struct global_data_all_processes All;"
*/
#ifndef ALLVARS_H
#define ALLVARS_H
#include <stdio.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_spline.h>
#include <gsl/gsl_integration.h>
#include "tags.h"
#define GADGETVERSION "2.0" /*!< code version string */
#define TIMEBASE (1<<28) /*!< The simulated timespan is mapped onto the integer interval [0,TIMESPAN],
* where TIMESPAN needs to be a power of 2. Note that (1<<28) corresponds to 2^29
*/
#define MAXTOPNODES 200000 /*!< Maximum number of nodes in the top-level tree used for domain decomposition */
typedef long long peanokey; /*!< defines the variable type used for Peano-Hilbert keys */
#define BITS_PER_DIMENSION 18 /*!< Bits per dimension available for Peano-Hilbert order.
Note: If peanokey is defined as type int, the allowed maximum is 10.
If 64-bit integers are used, the maximum is 21 */
#define PEANOCELLS (((peanokey)1)<<(3*BITS_PER_DIMENSION)) /*!< The number of different Peano-Hilbert cells */
#define RNDTABLE 3000 /*!< gives the length of a table with random numbers, refreshed at every timestep.
This is used to allow application of random numbers to a specific particle
in a way that is independent of the number of processors used. */
#define MAX_REAL_NUMBER 1e37
#define MIN_REAL_NUMBER 1e-37
#define MAXLEN_FILENAME 100 /*!< Maximum number of characters for filenames (including the full path) */
#ifdef ISOTHERM_EQS
#define GAMMA (1.0) /*!< index for isothermal gas */
#else
#define GAMMA (5.0/3) /*!< adiabatic index of simulated gas */
#endif
#define GAMMA_MINUS1 (GAMMA-1)
#define HYDROGEN_MASSFRAC 0.76 /*!< mass fraction of hydrogen, relevant only for radiative cooling */
/* Some physical constants in cgs units */
#define GRAVITY 6.672e-8 /*!< Gravitational constant (in cgs units) */
#define SOLAR_MASS 1.989e33
#define SOLAR_LUM 3.826e33
#define RAD_CONST 7.565e-15
#define AVOGADRO 6.0222e23
#define BOLTZMANN 1.3806e-16
#define GAS_CONST 8.31425e7
#define C 2.9979e10
#define PLANCK 6.6262e-27
#define CM_PER_MPC 3.085678e24
#define PROTONMASS 1.6726e-24
#define ELECTRONMASS 9.10953e-28
#define THOMPSON 6.65245e-25
#define ELECTRONCHARGE 4.8032e-10
#define HUBBLE 3.2407789e-18 /* in h/sec */
#define YEAR_IN_SECOND 31536000.0 /* year in sec */
#define PI 3.1415926535897931
#define TWOPI 6.2831853071795862
/* Some conversion factors */
#define SEC_PER_MEGAYEAR 3.155e13
#define SEC_PER_YEAR 3.155e7
#ifndef ASMTH
#define ASMTH 1.25 /*!< ASMTH gives the scale of the short-range/long-range force split in units of FFT-mesh cells */
#endif
#ifndef RCUT
#define RCUT 4.5 /*!< RCUT gives the maximum distance (in units of the scale used for the force split) out to
which short-range forces are evaluated in the short-range tree walk. */
#endif
#define MAX_NGB 20000 /*!< defines maximum length of neighbour list */
#define MAXLEN_OUTPUTLIST 500 /*!< maxmimum number of entries in list of snapshot output times */
#define DRIFT_TABLE_LENGTH 1000 /*!< length of the lookup table used to hold the drift and kick factors */
#define MAXITER 1000 /*!< maxmimum number of steps for SPH neighbour iteration */
#ifdef DOUBLEPRECISION /*!< If defined, the variable type FLOAT is set to "double", otherwise to FLOAT */
#define FLOAT double
#else
#define FLOAT float
#endif
#ifndef TWODIMS
#define NUMDIMS 3 /*!< For 3D-normalized kernel */
#define KERNEL_COEFF_1 2.546479089470 /*!< Coefficients for SPH spline kernel and its derivative */
#define KERNEL_COEFF_2 15.278874536822
#define KERNEL_COEFF_3 45.836623610466
#define KERNEL_COEFF_4 30.557749073644
#define KERNEL_COEFF_5 5.092958178941
#define KERNEL_COEFF_6 (-15.278874536822)
#define NORM_COEFF 4.188790204786 /*!< Coefficient for kernel normalization. Note: 4.0/3 * PI = 4.188790204786 */
#else
#define NUMDIMS 2 /*!< For 2D-normalized kernel */
#define KERNEL_COEFF_1 (5.0/7*2.546479089470) /*!< Coefficients for SPH spline kernel and its derivative */
#define KERNEL_COEFF_2 (5.0/7*15.278874536822)
#define KERNEL_COEFF_3 (5.0/7*45.836623610466)
#define KERNEL_COEFF_4 (5.0/7*30.557749073644)
#define KERNEL_COEFF_5 (5.0/7*5.092958178941)
#define KERNEL_COEFF_6 (5.0/7*(-15.278874536822))
#define NORM_COEFF M_PI /*!< Coefficient for kernel normalization. */
#endif
#ifdef MULTIPHASE
#define GAS_SPH 0
#define GAS_STICKY 1
#define GAS_DARK 2
#endif
#if defined(SFR) || defined(STELLAR_PROP)
#define ST 1
#endif
#ifdef CHIMIE
#define NELEMENTS 5
#define MAXNELEMENTS 64
#define FIRST_ELEMENT "Fe"
#define FE 0
#endif
#ifdef COMPUTE_VELOCITY_DISPERSION
#define VELOCITY_DISPERSION_SIZE 3
#endif
extern int SetMinTimeStepForActives;
extern int ThisTask; /*!< the rank of the local processor */
extern int NTask; /*!< number of processors */
extern int PTask; /*!< smallest integer such that NTask <= 2^PTask */
extern int NumPart; /*!< number of particles on the LOCAL processor */
extern int N_gas; /*!< number of gas particles on the LOCAL processor */
#if defined(SFR) || defined(STELLAR_PROP)
extern int N_stars; /*!< number of stars particle on the LOCAL processor */
#endif
#ifdef MULTIPHASE
extern int N_sph;
extern int N_sticky;
extern int N_stickyflaged;
extern int N_dark;
extern int NumColPotLocal; /*!< local number of potentially collisional particles */
extern int NumColPot; /*!< total number of potentially collisional particles */
extern int NumColLocal; /*!< local number of collisions */
extern int NumCol; /*!< total number of collisions */
extern int NumNoColLocal;
extern int NumNoCol;
#endif
extern long long Ntype[6]; /*!< total number of particles of each type */
extern int NtypeLocal[6]; /*!< local number of particles of each type */
extern int NumForceUpdate; /*!< number of active particles on local processor in current timestep */
extern int NumSphUpdate; /*!< number of active SPH particles on local processor in current timestep */
#ifdef CHIMIE
extern int NumStUpdate;
#endif
extern double CPUThisRun; /*!< Sums the CPU time for the process (current submission only) */
#ifdef SPLIT_DOMAIN_USING_TIME
extern double CPU_Gravity;
#endif
extern int RestartFlag; /*!< taken from command line used to start code. 0 is normal start-up from
initial conditions, 1 is resuming a run from a set of restart files, while 2
marks a restart from a snapshot file. */
extern char *Exportflag; /*!< Buffer used for flagging whether a particle needs to be exported to another process */
extern int *Ngblist; /*!< Buffer to hold indices of neighbours retrieved by the neighbour search routines */
extern int TreeReconstructFlag; /*!< Signals that a new tree needs to be constructed */
#ifdef SFR
extern int RearrangeParticlesFlag;/*!< Signals that particles must be rearanged */
#endif
extern int Flag_FullStep; /*!< This flag signals that the current step involves all particles */
extern gsl_rng *random_generator; /*!< the employed random number generator of the GSL library */
extern double RndTable[RNDTABLE]; /*!< Hold a table with random numbers, refreshed every timestep */
#ifdef SFR
extern double StarFormationRndTable[RNDTABLE]; /*!< Hold a table with random numbers, refreshed every timestep */
#endif
#ifdef FEEDBACK_WIND
extern double FeedbackWindRndTable[RNDTABLE]; /*!< Hold a table with random numbers, refreshed every timestep */
#endif
#ifdef CHIMIE
extern double ChimieRndTable[RNDTABLE]; /*!< Hold a table with random numbers, refreshed every timestep */
#endif
#ifdef CHIMIE_KINETIC_FEEDBACK
extern double ChimieKineticFeedbackRndTable[RNDTABLE]; /*!< Hold a table with random numbers, refreshed every timestep */
#endif
extern double DomainCorner[3]; /*!< gives the lower left corner of simulation volume */
extern double DomainCenter[3]; /*!< gives the center of simulation volume */
extern double DomainLen; /*!< gives the (maximum) side-length of simulation volume */
extern double DomainFac; /*!< factor used for converting particle coordinates to a Peano-Hilbert mesh covering the simulation volume */
extern int DomainMyStart; /*!< first domain mesh cell that resides on the local processor */
extern int DomainMyLast; /*!< last domain mesh cell that resides on the local processor */
extern int *DomainStartList; /*!< a table that lists the first domain mesh cell for all processors */
extern int *DomainEndList; /*!< a table that lists the last domain mesh cell for all processors */
extern double *DomainWork; /*!< a table that gives the total "work" due to the particles stored by each processor */
extern int *DomainCount; /*!< a table that gives the total number of particles held by each processor */
extern int *DomainCountSph; /*!< a table that gives the total number of SPH particles held by each processor */
extern int *DomainTask; /*!< this table gives for each leaf of the top-level tree the processor it was assigned to */
extern int *DomainNodeIndex; /*!< this table gives for each leaf of the top-level tree the corresponding node of the gravitational tree */
extern FLOAT *DomainTreeNodeLen; /*!< this table gives for each leaf of the top-level tree the side-length of the corresponding node of the gravitational tree */
extern FLOAT *DomainHmax; /*!< this table gives for each leaf of the top-level tree the maximum SPH smoothing length among the particles of the corresponding node of the gravitational tree */
extern struct DomainNODE
{
FLOAT s[3]; /*!< center-of-mass coordinates */
FLOAT vs[3]; /*!< center-of-mass velocities */
FLOAT mass; /*!< mass of node */
#ifdef STELLAR_FLUX
FLOAT starlum; /*!< star luminosity of node */
#endif
#ifdef UNEQUALSOFTENINGS
#ifndef ADAPTIVE_GRAVSOFT_FORGAS
int bitflags; /*!< this bit-field encodes the particle type with the largest softening among the particles of the nodes, and whether there are particles with different softening in the node */
#else
FLOAT maxsoft; /*!< hold the maximum gravitational softening of particles in the
node if the ADAPTIVE_GRAVSOFT_FORGAS option is selected */
#endif
#endif
}
*DomainMoment; /*!< this table stores for each node of the top-level tree corresponding node data from the gravitational tree */
extern peanokey *DomainKeyBuf; /*!< this points to a buffer used during the exchange of particle data */
extern peanokey *Key; /*!< a table used for storing Peano-Hilbert keys for particles */
extern peanokey *KeySorted; /*!< holds a sorted table of Peano-Hilbert keys for all particles, used to construct top-level tree */
extern int NTopnodes; /*!< total number of nodes in top-level tree */
extern int NTopleaves; /*!< number of leaves in top-level tree. Each leaf can be assigned to a different processor */
extern struct topnode_data
{
int Daughter; /*!< index of first daughter cell (out of 8) of top-level node */
int Pstart; /*!< for the present top-level node, this gives the index of the first node in the concatenated list of topnodes collected from all processors */
int Blocks; /*!< for the present top-level node, this gives the number of corresponding nodes in the concatenated list of topnodes collected from all processors */
int Leaf; /*!< if the node is a leaf, this gives its number when all leaves are traversed in Peano-Hilbert order */
peanokey Size; /*!< number of Peano-Hilbert mesh-cells represented by top-level node */
peanokey StartKey; /*!< first Peano-Hilbert key in top-level node */
long long Count; /*!< counts the number of particles in this top-level node */
}
*TopNodes; /*!< points to the root node of the top-level tree */
extern double TimeOfLastTreeConstruction; /*!< holds what it says, only used in connection with FORCETEST */
/* variables for input/output, usually only used on process 0 */
extern char ParameterFile[MAXLEN_FILENAME]; /*!< file name of parameterfile used for starting the simulation */
extern FILE *FdInfo; /*!< file handle for info.txt log-file. */
extern FILE *FdLog; /*!< file handle for log.txt log-file. */
extern FILE *FdEnergy; /*!< file handle for energy.txt log-file. */
#ifdef SYSTEMSTATISTICS
extern FILE *FdSystem;
#endif
extern FILE *FdTimings; /*!< file handle for timings.txt log-file. */
extern FILE *FdCPU; /*!< file handle for cpu.txt log-file. */
#ifdef FORCETEST
extern FILE *FdForceTest; /*!< file handle for forcetest.txt log-file. */
#endif
#ifdef SFR
extern FILE *FdSfr; /*!< file handle for sfr.txt log-file. */
#endif
#ifdef CHIMIE
extern FILE *FdChimie; /*!< file handle for chimie log-file. */
#endif
#ifdef MULTIPHASE
extern FILE *FdPhase; /*!< file handle for pase.txt log-file. */
extern FILE *FdSticky; /*!< file handle for sticky.txt log-file. */
#endif
#ifdef AGN_ACCRETION
extern FILE *FdAccretion; /*!< file handle for accretion.txt log-file. */
#endif
#ifdef BONDI_ACCRETION
extern FILE *FdBondi; /*!< file handle for bondi.txt log-file. */
#endif
#ifdef BUBBLES
extern FILE *FdBubble; /*!< file handle for bubble.txt log-file. */
#endif
extern double DriftTable[DRIFT_TABLE_LENGTH]; /*!< table for the cosmological drift factors */
extern double GravKickTable[DRIFT_TABLE_LENGTH]; /*!< table for the cosmological kick factor for gravitational forces */
extern double HydroKickTable[DRIFT_TABLE_LENGTH]; /*!< table for the cosmological kick factor for hydrodynmical forces */
extern void *CommBuffer; /*!< points to communication buffer, which is used in the domain decomposition, the
parallel tree-force computation, the SPH routines, etc. */
/*! This structure contains data which is the SAME for all tasks (mostly code parameters read from the
* parameter file). Holding this data in a structure is convenient for writing/reading the restart file, and
* it allows the introduction of new global variables in a simple way. The only thing to do is to introduce
* them into this structure.
*/
extern struct global_data_all_processes
{
long long TotNumPart; /*!< total particle numbers (global value) */
long long TotN_gas; /*!< total gas particle number (global value) */
#if defined(SFR) || defined(STELLAR_PROP)
long long TotN_stars; /*!< total stars particle number (global value) */
#endif
#ifdef MULTIPHASE
long long TotN_sph; /*!< total sph particle number (global value) */
long long TotN_sticky; /*!< total sticky particle number (global value) */
long long TotN_stickyflaged; /*!< total sticky flaged particle number (global value) */
long long TotN_dark; /*!< total dark particle number (global value) */
#endif
int MaxPart; /*!< This gives the maxmimum number of particles that can be stored on one processor. */
int MaxPartSph; /*!< This gives the maxmimum number of SPH particles that can be stored on one processor. */
#ifdef STELLAR_PROP
int MaxPartStars; /*!< This gives the maxmimum number of Star particles that can be stored on one processor. */
#endif
double BoxSize; /*!< Boxsize in case periodic boundary conditions are used */
int ICFormat; /*!< selects different versions of IC file-format */
int SnapFormat; /*!< selects different versions of snapshot file-formats */
int NumFilesPerSnapshot; /*!< number of files in multi-file snapshot dumps */
int NumFilesWrittenInParallel;/*!< maximum number of files that may be written simultaneously when
writing/reading restart-files, or when writing snapshot files */
int BufferSize; /*!< size of communication buffer in MB */
int BunchSizeForce; /*!< number of particles fitting into the buffer in the parallel tree-force algorithm */
int BunchSizeDensity; /*!< number of particles fitting into the communication buffer in the density computation */
int BunchSizeHydro; /*!< number of particles fitting into the communication buffer in the SPH hydrodynamical force computation */
int BunchSizeDomain; /*!< number of particles fitting into the communication buffer in the domain decomposition */
#ifdef MULTIPHASE
int BunchSizeSticky; /*!< number of particles fitting into the communication buffer in the Chimie computation */
#endif
#ifdef CHIMIE
int BunchSizeChimie; /*!< number of particles fitting into the communication buffer in the Chimie computation */
int BunchSizeStarsDensity; /*!< number of particles fitting into the communication buffer in the star density computation */
#endif
double PartAllocFactor; /*!< in order to maintain work-load balance, the particle load will usually
NOT be balanced. Each processor allocates memory for PartAllocFactor times
the average number of particles to allow for that */
double TreeAllocFactor; /*!< Each processor allocates a number of nodes which is TreeAllocFactor times
the maximum(!) number of particles. Note: A typical local tree for N
particles needs usually about ~0.65*N nodes. */
/* some SPH parameters */
double DesNumNgb; /*!< Desired number of SPH neighbours */
double MaxNumNgbDeviation; /*!< Maximum allowed deviation neighbour number */
double ArtBulkViscConst; /*!< Sets the parameter \f$\alpha\f$ of the artificial viscosity */
double InitGasTemp; /*!< may be used to set the temperature in the IC's */
double MinGasTemp; /*!< may be used to set a floor for the gas temperature */
double MinEgySpec; /*!< the minimum allowed temperature expressed as energy per unit mass */
/* Usefull constants */
double Boltzmann;
double ProtonMass;
double mumh;
#ifdef COOLING
/* Cooling parameters */
double *logT;
double *logL;
gsl_interp_accel *acc_cooling_spline;
gsl_spline *cooling_spline;
double CoolingType;
char CoolingFile[MAXLEN_FILENAME]; /*!< cooling file */
double CutofCoolingTemperature;
double InitGasMetallicity;
/*
new metal dependent cooling
*/
double CoolingParameters_zmin;
double CoolingParameters_zmax;
double CoolingParameters_slz;
double CoolingParameters_tmin;
double CoolingParameters_tmax;
double CoolingParameters_slt;
double CoolingParameters_FeHSolar;
double CoolingParameters_cooling_data_max;
double CoolingParameters_cooling_data[9][171];
int CoolingParameters_p;
int CoolingParameters_q;
#endif
#ifdef CHIMIE
+ int ChimieNumberOfParameterFiles;
char ChimieParameterFile[MAXLEN_FILENAME]; /*!< chimie parameter file */
double ChimieSupernovaEnergy;
double ChimieKineticFeedbackFraction;
double ChimieWindSpeed;
double ChimieWindTime;
double ChimieThermalTime;
double ChimieMaxSizeTimestep;
#endif
#if !defined (HEATING_PE)
double HeatingPeElectronFraction;
#endif
#if !defined (HEATING_PE) || defined (STELLAR_FLUX) || defined (EXTERNAL_FLUX)
double HeatingPeSolarEnergyDensity;
#endif
#if !defined (HEATING_PE) || defined (STELLAR_FLUX)
double HeatingPeLMRatioGas;
double HeatingPeLMRatioHalo;
double HeatingPeLMRatioDisk;
double HeatingPeLMRatioBulge;
double HeatingPeLMRatioStars;
double HeatingPeLMRatioBndry;
double HeatingPeLMRatio[6];
#endif
#ifdef EXTERNAL_FLUX
double HeatingExternalFLuxEnergyDensity;
#endif
#ifdef MULTIPHASE
double CriticalTemperature;
double CriticalEgySpec;
double CriticalNonCollisionalTemperature;
double CriticalNonCollisionalEgySpec;
#ifdef COLDGAS_CYCLE
double ColdGasCycleTransitionTime;
double ColdGasCycleTransitionParameter;
#endif
#endif
#ifdef MULTIPHASE
/* some STICKY parameters */
int StickyUseGridForCollisions;
double StickyTime; /*!< Cooling time of sticky particle collision */
double StickyCollisionTime;
double StickyLastCollisionTime;
double StickyIdleTime;
double StickyMinVelocity;
double StickyMaxVelocity;
int StickyGridNx;
int StickyGridNy;
int StickyGridNz;
double StickyGridXmin;
double StickyGridXmax;
double StickyGridYmin;
double StickyGridYmax;
double StickyGridZmin;
double StickyGridZmax;
double StickyLambda;
double StickyDensity;
double StickyDensityPower;
double StickyBetaR;
double StickyBetaT;
double StickyRsphFact; /*!< Fraction of the sph radius used in sticky particle */
#endif
#ifdef OUTERPOTENTIAL
#ifdef NFW
double HaloConcentration;
double HaloMass;
double GasMassFraction;
double NFWPotentialCte;
double Rs;
#endif
#ifdef PLUMMER
double PlummerMass;
double PlummerSoftenning;
double PlummerPotentialCte;
#endif
#ifdef PISOTHERM
double Rho0;
double Rc;
double PisothermPotentialCte;
double GasMassFraction;
double PotentialInf;
gsl_function PotentialF;
gsl_integration_workspace *Potentialw;
#endif
#ifdef CORIOLIS
double CoriolisOmegaX;
double CoriolisOmegaY;
double CoriolisOmegaZ;
double CoriolisOmegaX0;
double CoriolisOmegaY0;
double CoriolisOmegaZ0;
#endif
#endif
#ifdef SFR
int StarFormationNStarsFromGas;
double StarFormationStarMass;
double StarFormationMgMsFraction;
int StarFormationType;
double StarFormationCstar;
double StarFormationTime;
double StarFormationDensity;
double StarFormationTemperature;
double ThresholdDensity;
#endif
#ifdef FEEDBACK
double SupernovaTime;
#endif
#ifdef FEEDBACK_WIND
double SupernovaWindEgySpecPerMassUnit;
double SupernovaWindFractionInEgyKin;
double SupernovaWindParameter;
double SupernovaWindSpeed;
double SupernovaWindIntAccuracy;
#endif
#ifdef AGN_ACCRETION
double TimeBetAccretion;
double AccretionRadius;
double AGNFactor;
double MinMTotInRa;
double TimeLastAccretion;
double LastMTotInRa;
double MTotInRa;
double dMTotInRa;
#endif
#ifdef BUBBLES
char BubblesInitFile[MAXLEN_FILENAME]; /*!< bubble file */
double *BubblesTime;
double *BubblesD;
double *BubblesR;
double *BubblesE;
double *BubblesA;
double *BubblesB;
int BubblesIndex;
double BubblesAlpha;
double BubblesBeta;
double BubblesDelta;
double BubblesRadiusFactor;
double EnergyBubbles;
#endif
#ifdef AGN_HEATING
double AGNHeatingPower;
double AGNHeatingRmax;
#endif
#ifdef BONDI_ACCRETION
double BondiEfficiency;
double BondiBlackHoleMass;
double BondiHsmlFactor;
double BondiPower;
double BondiTimeBet;
double BondiTimeLast;
#endif
#if defined (AGN_ACCRETION) || defined (BONDI_ACCRETION)
double LightSpeed;
#endif
/* some force counters */
long long TotNumOfForces; /*!< counts total number of force computations */
long long NumForcesSinceLastDomainDecomp; /*!< count particle updates since last domain decomposition */
/* system of units */
double G; /*!< Gravity-constant in internal units */
double UnitTime_in_s; /*!< factor to convert internal time unit to seconds/h */
double UnitMass_in_g; /*!< factor to convert internal mass unit to grams/h */
double UnitVelocity_in_cm_per_s; /*!< factor to convert intqernal velocity unit to cm/sec */
double UnitLength_in_cm; /*!< factor to convert internal length unit to cm/h */
double UnitPressure_in_cgs; /*!< factor to convert internal pressure unit to cgs units (little 'h' still around!) */
double UnitDensity_in_cgs; /*!< factor to convert internal length unit to g/cm^3*h^2 */
double UnitCoolingRate_in_cgs; /*!< factor to convert internal cooling rate to cgs units */
double UnitEnergy_in_cgs; /*!< factor to convert internal energy to cgs units */
double UnitTime_in_Megayears; /*!< factor to convert internal time to megayears/h */
double GravityConstantInternal; /*!< If set to zero in the parameterfile, the internal value of the
gravitational constant is set to the Newtonian value based on the system of
units specified. Otherwise the value provided is taken as internal gravity constant G. */
/* Cosmological parameters */
double Hubble; /*!< Hubble-constant in internal units */
double Omega0; /*!< matter density in units of the critical density (at z=0)*/
double OmegaLambda; /*!< vaccum energy density relative to crictical density (at z=0) */
double OmegaBaryon; /*!< baryon density in units of the critical density (at z=0)*/
double HubbleParam; /*!< little `h', i.e. Hubble constant in units of 100 km/s/Mpc. Only needed to get absolute physical values for cooling physics */
/* Code options */
int ComovingIntegrationOn; /*!< flags that comoving integration is enabled */
int PeriodicBoundariesOn; /*!< flags that periodic boundaries are enabled */
int ResubmitOn; /*!< flags that automatic resubmission of job to queue system is enabled */
int TypeOfOpeningCriterion; /*!< determines tree cell-opening criterion: 0 for Barnes-Hut, 1 for relative criterion */
int TypeOfTimestepCriterion; /*!< gives type of timestep criterion (only 0 supported right now - unlike gadget-1.1) */
int OutputListOn; /*!< flags that output times are listed in a specified file */
/* Parameters determining output frequency */
int SnapshotFileCount; /*!< number of snapshot that is written next */
double TimeBetSnapshot; /*!< simulation time interval between snapshot files */
double TimeOfFirstSnapshot; /*!< simulation time of first snapshot files */
double CpuTimeBetRestartFile; /*!< cpu-time between regularly generated restart files */
double TimeLastRestartFile; /*!< cpu-time when last restart-file was written */
double TimeBetStatistics; /*!< simulation time interval between computations of energy statistics */
double TimeLastStatistics; /*!< simulation time when the energy statistics was computed the last time */
int NumCurrentTiStep; /*!< counts the number of system steps taken up to this point */
/* Current time of the simulation, global step, and end of simulation */
double Time; /*!< current time of the simulation */
double TimeBegin; /*!< time of initial conditions of the simulation */
double TimeStep; /*!< difference between current times of previous and current timestep */
double TimeMax; /*!< marks the point of time until the simulation is to be evolved */
/* variables for organizing discrete timeline */
double Timebase_interval; /*!< factor to convert from floating point time interval to integer timeline */
int Ti_Current; /*!< current time on integer timeline */
int Ti_nextoutput; /*!< next output time on integer timeline */
#ifdef FLEXSTEPS
int PresentMinStep; /*!< If FLEXSTEPS is used, particle timesteps are chosen as multiples of the present minimum timestep. */
int PresentMaxStep; /*!< If FLEXSTEPS is used, this is the maximum timestep in timeline units, rounded down to the next power 2 division */
#endif
#ifdef PMGRID
int PM_Ti_endstep; /*!< begin of present long-range timestep */
int PM_Ti_begstep; /*!< end of present long-range timestep */
#endif
/* Placement of PM grids */
#ifdef PMGRID
double Asmth[2]; /*!< Gives the scale of the long-range/short-range split (in mesh-cells), both for the coarse and the high-res mesh */
double Rcut[2]; /*!< Gives the maximum radius for which the short-range force is evaluated with the tree (in mesh-cells), both for the coarse and the high-res mesh */
double Corner[2][3]; /*!< lower left corner of coarse and high-res PM-mesh */
double UpperCorner[2][3]; /*!< upper right corner of coarse and high-res PM-mesh */
double Xmintot[2][3]; /*!< minimum particle coordinates both for coarse and high-res PM-mesh */
double Xmaxtot[2][3]; /*!< maximum particle coordinates both for coarse and high-res PM-mesh */
double TotalMeshSize[2]; /*!< total extension of coarse and high-res PM-mesh */
#endif
/* Variables that keep track of cumulative CPU consumption */
double TimeLimitCPU; /*!< CPU time limit as defined in parameterfile */
double CPU_TreeConstruction; /*!< time spent for constructing the gravitational tree */
double CPU_TreeWalk; /*!< actual time spent for pure tree-walks */
double CPU_Gravity; /*!< cumulative time used for gravity computation (tree-algorithm only) */
double CPU_Potential; /*!< time used for computing gravitational potentials */
double CPU_Domain; /*!< cumulative time spent for domain decomposition */
double CPU_Snapshot; /*!< time used for writing snapshot files */
double CPU_Total; /*!< cumulative time spent for domain decomposition */
double CPU_CommSum; /*!< accumulated time used for communication, and for collecting partial results, in tree-gravity */
double CPU_Imbalance; /*!< cumulative time lost accross all processors as work-load imbalance in gravitational tree */
double CPU_HydCompWalk; /*!< time used for actual SPH computations, including neighbour search */
double CPU_HydCommSumm; /*!< cumulative time used for communication in SPH, and for collecting partial results */
double CPU_HydImbalance; /*!< cumulative time lost due to work-load imbalance in SPH */
double CPU_Hydro; /*!< cumulative time spent for SPH related computations */
#ifdef SFR
double CPU_StarFormation; /*!< cumulative time spent for star formation computations */
#endif
#ifdef CHIMIE
double CPU_Chimie; /*!< cumulative time spent for chimie computations */
#endif
#ifdef MULTIPHASE
double CPU_Sticky; /*!< cumulative time spent for sticky computations */
#endif
double CPU_EnsureNgb; /*!< time needed to iterate on correct neighbour numbers */
double CPU_Predict; /*!< cumulative time to drift the system forward in time, including dynamic tree updates */
double CPU_TimeLine; /*!< time used for determining new timesteps, and for organizing the timestepping, including kicks of active particles */
double CPU_PM; /*!< time used for long-range gravitational force */
double CPU_Peano; /*!< time required to establish Peano-Hilbert order */
#ifdef DETAILED_CPU_DOMAIN
double CPU_Domain_findExtend;
double CPU_Domain_determineTopTree;
double CPU_Domain_sumCost;
double CPU_Domain_findSplit;
double CPU_Domain_shiftSplit;
double CPU_Domain_countToGo;
double CPU_Domain_exchange;
#endif
#ifdef DETAILED_CPU_GRAVITY
double CPU_Gravity_TreeWalk1;
double CPU_Gravity_TreeWalk2;
double CPU_Gravity_CommSum1;
double CPU_Gravity_CommSum2;
double CPU_Gravity_Imbalance1;
double CPU_Gravity_Imbalance2;
#endif
#ifdef COOLING
double CPU_Cooling;
#endif
#ifdef DETAILED_CPU
double CPU_Leapfrog;
double CPU_Physics;
double CPU_Residual;
double CPU_Accel;
double CPU_Begrun;
#endif
/* tree code opening criterion */
double ErrTolTheta; /*!< BH tree opening angle */
double ErrTolForceAcc; /*!< parameter for relative opening criterion in tree walk */
/* adjusts accuracy of time-integration */
double ErrTolIntAccuracy; /*!< accuracy tolerance parameter \f$ \eta \f$ for timestep criterion. The
timestep is \f$ \Delta t = \sqrt{\frac{2 \eta eps}{a}} \f$ */
double MinSizeTimestep; /*!< minimum allowed timestep. Normally, the simulation terminates if the
timestep determined by the timestep criteria falls below this limit. */
double MaxSizeTimestep; /*!< maximum allowed timestep */
double MaxRMSDisplacementFac; /*!< this determines a global timestep criterion for cosmological simulations
in comoving coordinates. To this end, the code computes the rms velocity
of all particles, and limits the timestep such that the rms displacement
is a fraction of the mean particle separation (determined from the
particle mass and the cosmological parameters). This parameter specifies
this fraction. */
double CourantFac; /*!< SPH-Courant factor */
/* frequency of tree reconstruction/domain decomposition */
double TreeDomainUpdateFrequency; /*!< controls frequency of domain decompositions */
/* Gravitational and hydrodynamical softening lengths (given in terms of an `equivalent' Plummer softening length).
* Five groups of particles are supported 0="gas", 1="halo", 2="disk", 3="bulge", 4="stars", 5="bndry"
*/
double MinGasHsmlFractional; /*!< minimum allowed SPH smoothing length in units of SPH gravitational softening length */
double MinGasHsml; /*!< minimum allowed SPH smoothing length */
double SofteningGas; /*!< comoving gravitational softening lengths for type 0 */
double SofteningHalo; /*!< comoving gravitational softening lengths for type 1 */
double SofteningDisk; /*!< comoving gravitational softening lengths for type 2 */
double SofteningBulge; /*!< comoving gravitational softening lengths for type 3 */
double SofteningStars; /*!< comoving gravitational softening lengths for type 4 */
double SofteningBndry; /*!< comoving gravitational softening lengths for type 5 */
double SofteningGasMaxPhys; /*!< maximum physical softening length for type 0 */
double SofteningHaloMaxPhys; /*!< maximum physical softening length for type 1 */
double SofteningDiskMaxPhys; /*!< maximum physical softening length for type 2 */
double SofteningBulgeMaxPhys; /*!< maximum physical softening length for type 3 */
double SofteningStarsMaxPhys; /*!< maximum physical softening length for type 4 */
double SofteningBndryMaxPhys; /*!< maximum physical softening length for type 5 */
double SofteningTable[6]; /*!< current (comoving) gravitational softening lengths for each particle type */
double ForceSoftening[6]; /*!< the same, but multiplied by a factor 2.8 - at that scale the force is Newtonian */
double MassTable[6]; /*!< Table with particle masses for particle types with equal mass.
If particle masses are all equal for one type, the corresponding entry in MassTable
is set to this value, allowing the size of the snapshot files to be reduced. */
/* some filenames */
char InitCondFile[MAXLEN_FILENAME]; /*!< filename of initial conditions */
char OutputDir[MAXLEN_FILENAME]; /*!< output directory of the code */
char SnapshotFileBase[MAXLEN_FILENAME]; /*!< basename to construct the names of snapshotf files */
char EnergyFile[MAXLEN_FILENAME]; /*!< name of file with energy statistics */
#ifdef SYSTEMSTATISTICS
char SystemFile[MAXLEN_FILENAME];
#endif
char CpuFile[MAXLEN_FILENAME]; /*!< name of file with cpu-time statistics */
char InfoFile[MAXLEN_FILENAME]; /*!< name of log-file with a list of the timesteps taken */
char LogFile[MAXLEN_FILENAME]; /*!< name of log-file with varied info */
#ifdef SFR
char SfrFile[MAXLEN_FILENAME]; /*!< name of file with sfr records */
#endif
#ifdef CHIMIE
char ChimieFile[MAXLEN_FILENAME]; /*!< name of file with chimie records */
#endif
#ifdef MULTIPHASE
char PhaseFile[MAXLEN_FILENAME]; /*!< name of file with phase records */
char StickyFile[MAXLEN_FILENAME]; /*!< name of file with sticky records */
#endif
#ifdef AGN_ACCRETION
char AccretionFile[MAXLEN_FILENAME]; /*!< name of file with accretion records */
#endif
#ifdef BONDI_ACCRETION
char BondiFile[MAXLEN_FILENAME]; /*!< name of file with bondi records */
#endif
#ifdef BUBBLES
char BubbleFile[MAXLEN_FILENAME]; /*!< name of file with bubble records */
#endif
char TimingsFile[MAXLEN_FILENAME]; /*!< name of file with performance metrics of gravitational tree algorithm */
char RestartFile[MAXLEN_FILENAME]; /*!< basename of restart-files */
char ResubmitCommand[MAXLEN_FILENAME]; /*!< name of script-file that will be executed for automatic restart */
char OutputListFilename[MAXLEN_FILENAME]; /*!< name of file with list of desired output times */
double OutputListTimes[MAXLEN_OUTPUTLIST]; /*!< table with desired output times */
int OutputListLength; /*!< number of output times stored in the table of desired output times */
#ifdef RANDOMSEED_AS_PARAMETER
int RandomSeed; /*!< initial random seed >*/
#endif
}
All; /*!< a container variable for global variables that are equal on all processors */
/*! This structure holds all the information that is
* stored for each particle of the simulation.
*/
extern struct particle_data
{
FLOAT Pos[3]; /*!< particle position at its current time */
FLOAT Mass; /*!< particle mass */
FLOAT Vel[3]; /*!< particle velocity at its current time */
FLOAT GravAccel[3]; /*!< particle acceleration due to gravity */
#ifdef PMGRID
FLOAT GravPM[3]; /*!< particle acceleration due to long-range PM gravity force*/
#endif
#ifdef FORCETEST
FLOAT GravAccelDirect[3]; /*!< particle acceleration when computed with direct summation */
#endif
FLOAT Potential; /*!< gravitational potential */
FLOAT OldAcc; /*!< magnitude of old gravitational force. Used in relative opening criterion */
#ifndef LONGIDS
unsigned int ID; /*!< particle identifier */
#else
unsigned long long ID; /*!< particle identifier */
#endif
int Type; /*!< flags particle type. 0=gas, 1=halo, 2=disk, 3=bulge, 4=stars, 5=bndry */
int Ti_endstep; /*!< marks start of current timestep of particle on integer timeline */
int Ti_begstep; /*!< marks end of current timestep of particle on integer timeline */
#ifdef FLEXSTEPS
int FlexStepGrp; /*!< a random 'offset' on the timeline to create a smooth groouping of particles */
#endif
float GravCost; /*!< weight factor used for balancing the work-load */
#ifdef PSEUDOSYMMETRIC
float AphysOld; /*!< magnitude of acceleration in last timestep. Used to make a first order
prediction of the change of acceleration expected in the future, thereby
allowing to guess whether a decrease/increase of the timestep should occur
in the timestep that is started. */
#endif
#ifdef PARTICLE_FLAG
float Flag;
#endif
#ifdef STELLAR_PROP
unsigned int StPIdx; /*!< index to the corresponding StP particle */
#endif
}
*P, /*!< holds particle data on local processor */
*DomainPartBuf; /*!< buffer for particle data used in domain decomposition */
/* the following struture holds data that is stored for each SPH particle in addition to the collisionless
* variables.
*/
extern struct sph_particle_data
{
FLOAT Entropy; /*!< current value of entropy (actually entropic function) of particle */
FLOAT Density; /*!< current baryonic mass density of particle */
FLOAT Hsml; /*!< current smoothing length */
FLOAT Left; /*!< lower bound in iterative smoothing length search */
FLOAT Right; /*!< upper bound in iterative smoothing length search */
FLOAT NumNgb; /*!< weighted number of neighbours found */
#ifdef AVOIDNUMNGBPROBLEM
FLOAT OldNumNgb;
#endif
FLOAT Pressure; /*!< current pressure */
FLOAT DtEntropy; /*!< rate of change of entropy */
#ifdef STELLAR_FLUX
FLOAT EnergyFlux; /*!< current value of local energy flux - Sph particles */
#endif
#ifdef AGN_HEATING
FLOAT EgySpecAGNHeat; /*!< current value of specific energy radiated of particle - Sph particles */
FLOAT DtEgySpecAGNHeat; /*!< rate of change of specific radiated energy - Sph particles */
FLOAT DtEntropyAGNHeat;
#endif
#ifdef MULTIPHASE
FLOAT StickyTime;
int StickyFlag;
#ifdef COUNT_COLLISIONS
float StickyCollisionNumber;
#endif
#endif
#ifdef FEEDBACK
FLOAT EgySpecFeedback;
FLOAT DtEgySpecFeedback;
FLOAT EnergySN;
FLOAT EnergySNrem;
FLOAT TimeSN;
FLOAT FeedbackVel[3]; /*!< kick due to feedback force */
#endif
#ifdef FEEDBACK_WIND
FLOAT FeedbackWindVel[3]; /*!< kick due to feedback force */
#endif
FLOAT HydroAccel[3]; /*!< acceleration due to hydrodynamical force */
FLOAT VelPred[3]; /*!< predicted SPH particle velocity at the current time */
FLOAT DivVel; /*!< local velocity divergence */
FLOAT CurlVel; /*!< local velocity curl */
FLOAT Rot[3]; /*!< local velocity curl */
FLOAT DhsmlDensityFactor; /*!< correction factor needed in the equation of motion of the conservative entropy formulation of SPH */
FLOAT MaxSignalVel; /*!< maximum "signal velocity" occuring for this particle */
#ifdef MULTIPHASE
int Phase;
int StickyIndex;
int StickyNgb;
int StickyMaxID;
float StickyMaxFs;
FLOAT StickyNewVel[3];
#endif
#ifdef OUTPUTOPTVAR
FLOAT OptVar; /*!< optional variable */
#endif
#ifdef COMPUTE_VELOCITY_DISPERSION
FLOAT VelocityDispersion[VELOCITY_DISPERSION_SIZE]; /*!< velocity dispersion */
#endif
#ifdef CHIMIE
FLOAT Metal[NELEMENTS];
FLOAT dMass; /*!< mass variation due to mass transfere */
#ifdef CHIMIE_THERMAL_FEEDBACK
FLOAT DeltaEgySpec;
FLOAT ThermalTime; /*!< flag particles that got energy from SN */
#endif
#ifdef CHIMIE_KINETIC_FEEDBACK
FLOAT WindTime; /*!< flag particles that belongs to the wind */
unsigned int WindFlag; /*!< flag particles that will be part of the wind */
#endif
#endif /*CHIMIE*/
#ifdef ENTROPYPRED
FLOAT EntropyPred; /*!< predicted entropy at the current time */
#endif
}
*SphP, /*!< holds SPH particle data on local processor */
*DomainSphBuf; /*!< buffer for SPH particle data in domain decomposition */
#ifdef STELLAR_PROP
/* the following struture holds data that is stored for each SPH particle in addition to the collisionless
* variables.
*/
extern struct st_particle_data
{
#ifdef CHECK_ID_CORRESPONDENCE
unsigned int ID; /*!< particle identifier (must be the same as P[].ID) only used to check ID correspondance */
#endif
FLOAT FormationTime; /*!< star formation time of particle */
FLOAT InitialMass; /*!< initial stellar mass */
#ifndef LONGIDS
unsigned int IDProj; /*!< id of projenitor particle */
#else
unsigned long long IDProj; /*!< id of projenitor particle */
#endif
FLOAT Metal[NELEMENTS];
FLOAT Density; /*!< current baryonic mass density of particle */
FLOAT Volume; /*!< current volume of particle */
FLOAT Hsml; /*!< current smoothing length */
FLOAT Left; /*!< lower bound in iterative smoothing length search */
FLOAT Right; /*!< upper bound in iterative smoothing length search */
FLOAT NumNgb; /*!< weighted number of neighbours found */
unsigned int PIdx; /*!< index to the corresponding particle */
#ifdef AVOIDNUMNGBPROBLEM
FLOAT OldNumNgb;
#endif
FLOAT DhsmlDensityFactor; /*!< correction factor needed in the equation of motion of the conservative entropy formulation of SPH */
double TotalEjectedGasMass;
double TotalEjectedEltMass[NELEMENTS];
double TotalEjectedEgySpec;
#ifdef CHIMIE_KINETIC_FEEDBACK
double NgbMass; /*!< mass of neighbours */
#endif
#ifdef CHIMIE
unsigned int Flag;
#endif
}
*StP, /*!< holds ST particle data on local processor */
*DomainStBuf; /*!< buffer for ST particle data in domain decomposition */
#endif
/* Variables for Tree
*/
extern int MaxNodes; /*!< maximum allowed number of internal nodes */
extern int Numnodestree; /*!< number of (internal) nodes in each tree */
extern struct NODE
{
FLOAT len; /*!< sidelength of treenode */
FLOAT center[3]; /*!< geometrical center of node */
#ifdef ADAPTIVE_GRAVSOFT_FORGAS
FLOAT maxsoft; /*!< hold the maximum gravitational softening of particles in the
node if the ADAPTIVE_GRAVSOFT_FORGAS option is selected */
#endif
#ifdef STELLAR_FLUX
FLOAT starlum ; /*!< star luminosity of node */
#endif
union
{
int suns[8]; /*!< temporary pointers to daughter nodes */
struct
{
FLOAT s[3]; /*!< center of mass of node */
FLOAT mass; /*!< mass of node */
int bitflags; /*!< a bit-field with various information on the node */
int sibling; /*!< this gives the next node in the walk in case the current node can be used */
int nextnode; /*!< this gives the next node in case the current node needs to be opened */
int father; /*!< this gives the parent node of each node (or -1 if we have the root node) */
}
d;
}
u;
}
*Nodes_base, /*!< points to the actual memory allocted for the nodes */
*Nodes; /*!< this is a pointer used to access the nodes which is shifted such that Nodes[All.MaxPart]
gives the first allocated node */
extern int *Nextnode; /*!< gives next node in tree walk */
extern int *Father; /*!< gives parent node in tree */
extern struct extNODE /*!< this structure holds additional tree-node information which is not needed in the actual gravity computation */
{
FLOAT hmax; /*!< maximum SPH smoothing length in node. Only used for gas particles */
FLOAT vs[3]; /*!< center-of-mass velocity */
}
*Extnodes_base, /*!< points to the actual memory allocted for the extended node information */
*Extnodes; /*!< provides shifted access to extended node information, parallel to Nodes/Nodes_base */
/*! Header for the standard file format.
*/
extern struct io_header
{
int npart[6]; /*!< number of particles of each type in this file */
double mass[6]; /*!< mass of particles of each type. If 0, then the masses are explicitly
stored in the mass-block of the snapshot file, otherwise they are omitted */
double time; /*!< time of snapshot file */
double redshift; /*!< redshift of snapshot file */
int flag_sfr; /*!< flags whether the simulation was including star formation */
int flag_feedback; /*!< flags whether feedback was included (obsolete) */
unsigned int npartTotal[6]; /*!< total number of particles of each type in this snapshot. This can be
different from npart if one is dealing with a multi-file snapshot. */
int flag_cooling; /*!< flags whether cooling was included */
int num_files; /*!< number of files in multi-file snapshot */
double BoxSize; /*!< box-size of simulation in case periodic boundaries were used */
double Omega0; /*!< matter density in units of critical density */
double OmegaLambda; /*!< cosmological constant parameter */
double HubbleParam; /*!< Hubble parameter in units of 100 km/sec/Mpc */
int flag_stellarage; /*!< flags whether the file contains formation times of star particles */
int flag_metals; /*!< flags whether the file contains metallicity values for gas and star particles */
unsigned int npartTotalHighWord[6]; /*!< High word of the total number of particles of each type */
int flag_entropy_instead_u; /*!< flags that IC-file contains entropy instead of u */
int flag_chimie_extraheader; /*!< flags that IC-file contains extra-header for chimie */
#ifdef MULTIPHASE
double critical_energy_spec;
#ifdef MESOMACHINE
char fill[38];
#else
char fill[48]; /* use 42 with regor... */
#endif
#else
char fill[56]; /*!< fills to 256 Bytes */
#endif
}
header; /*!< holds header for snapshot files */
#ifdef CHIMIE_EXTRAHEADER
/*! Header for the chimie part.
*/
extern struct io_chimie_extraheader
{
int nelts; /*!< number of chemical element followed */
float SolarAbundances[NELEMENTS];
char labels[256-4-4*(NELEMENTS)];
}
chimie_extraheader;
#endif
#define IO_NBLOCKS 23 /*!< total number of defined information blocks for snapshot files.
Must be equal to the number of entries in "enum iofields" */
enum iofields /*!< this enumeration lists the defined output blocks in snapshot files. Not all of them need to be present. */
{
IO_POS,
IO_VEL,
IO_ID,
IO_MASS,
IO_U,
IO_RHO,
IO_HSML,
IO_POT,
IO_ACCEL,
IO_DTENTR,
IO_TSTP,
IO_ERADSPH,
IO_ERADSTICKY,
IO_ERADFEEDBACK,
IO_ENERGYFLUX,
IO_OPTVAR,
IO_METALS,
IO_STAR_FORMATIONTIME,
IO_INITIAL_MASS,
IO_STAR_IDPROJ,
IO_STAR_RHO,
IO_STAR_HSML,
IO_STAR_METALS
};
extern char Tab_IO_Labels[IO_NBLOCKS][4]; /*<! This table holds four-byte character tags used for fileformat 2 */
/* global state of system, used for global statistics
*/
extern struct state_of_system
{
double Mass;
double EnergyKin;
double EnergyPot;
double EnergyInt;
#ifdef COOLING
double EnergyRadSph;
#endif
#ifdef AGN_HEATING
double EnergyAGNHeat;
#endif
#ifdef MULTIPHASE
double EnergyRadSticky;
#endif
#ifdef FEEDBACK_WIND
double EnergyFeedbackWind;
#endif
#ifdef BUBBLES
double EnergyBubbles;
#endif
#ifdef CHIMIE_THERMAL_FEEDBACK
double EnergyThermalFeedback;
#endif
#ifdef CHIMIE_KINETIC_FEEDBACK
double EnergyKineticFeedback;
#endif
double EnergyTot;
double Momentum[4];
double AngMomentum[4];
double CenterOfMass[4];
double MassComp[6];
double EnergyKinComp[6];
double EnergyPotComp[6];
double EnergyIntComp[6];
#ifdef COOLING
double EnergyRadSphComp[6];
#endif
#ifdef AGN_HEATING
double EnergyAGNHeatComp[6];
#endif
#ifdef MULTIPHASE
double EnergyRadStickyComp[6];
#endif
#ifdef FEEDBACK_WIND
double EnergyFeedbackWindComp[6];
#endif
#ifdef BUBBLES
double EnergyBubblesComp[6];
#endif
#ifdef CHIMIE_THERMAL_FEEDBACK
double EnergyThermalFeedbackComp[6];
#endif
#ifdef CHIMIE_KINETIC_FEEDBACK
double EnergyKineticFeedbackComp[6];
#endif
double EnergyTotComp[6];
double MomentumComp[6][4];
double AngMomentumComp[6][4];
double CenterOfMassComp[6][4];
}
SysState; /*<! Structure for storing some global statistics about the simulation. */
/*! This structure contains data related to the energy budget.
These values are different for each task. It need to be stored
in the restart flag.
*/
extern struct local_state_of_system
{
double EnergyTest;
double EnergyInt1;
double EnergyInt2;
double EnergyKin1;
double EnergyKin2;
#ifdef COOLING
double RadiatedEnergy;
#endif
#ifdef SFR
double StarEnergyInt;
#ifdef FEEDBACK
double StarEnergyFeedback;
#endif
#endif
#ifdef CHIMIE_THERMAL_FEEDBACK
double EnergyThermalFeedback;
#endif
#ifdef CHIMIE_KINETIC_FEEDBACK
double EnergyKineticFeedback;
#endif
#ifdef MULTIPHASE
double EnergyRadSticky;
#endif
#ifdef FEEDBACK_WIND
double EnergyFeedbackWind;
#endif
}
LocalSysState; /*<! Structure for storing some local statistics about the simulation. */
/* Various structures for communication
*/
extern struct gravdata_in
{
union
{
FLOAT Pos[3];
FLOAT Acc[3];
FLOAT Potential;
}
u;
#if defined(UNEQUALSOFTENINGS) || defined(STELLAR_FLUX)
int Type;
#ifdef ADAPTIVE_GRAVSOFT_FORGAS
FLOAT Soft;
#endif
#endif
#ifdef STELLAR_FLUX
FLOAT EnergyFlux;
#endif
union
{
FLOAT OldAcc;
int Ninteractions;
}
w;
}
*GravDataIn, /*!< holds particle data to be exported to other processors */
*GravDataGet, /*!< holds particle data imported from other processors */
*GravDataResult, /*!< holds the partial results computed for imported particles. Note: We use GravDataResult = GravDataGet, such that the result replaces the imported data */
*GravDataOut; /*!< holds partial results received from other processors. This will overwrite the GravDataIn array */
extern struct gravdata_index
{
int Task;
int Index;
int SortIndex;
}
*GravDataIndexTable; /*!< the particles to be exported are grouped by task-number. This table allows the results to be disentangled again and to be assigned to the correct particle */
extern struct densdata_in
{
FLOAT Pos[3];
FLOAT Vel[3];
FLOAT Hsml;
#ifdef MULTIPHASE
int Phase;
#endif
int Index;
int Task;
}
*DensDataIn, /*!< holds particle data for SPH density computation to be exported to other processors */
*DensDataGet; /*!< holds imported particle data for SPH density computation */
extern struct densdata_out
{
FLOAT Rho;
FLOAT Div, Rot[3];
FLOAT DhsmlDensity;
FLOAT Ngb;
}
*DensDataResult, /*!< stores the locally computed SPH density results for imported particles */
*DensDataPartialResult; /*!< imported partial SPH density results from other processors */
extern struct hydrodata_in
{
FLOAT Pos[3];
FLOAT Vel[3];
FLOAT Hsml;
#ifdef FEEDBACK
FLOAT EnergySN;
#endif
#ifdef MULTIPHASE
int Phase;
FLOAT Entropy;
int StickyFlag;
#endif
FLOAT Mass;
FLOAT Density;
FLOAT Pressure;
FLOAT F1;
FLOAT DhsmlDensityFactor;
int Timestep;
int Task;
int Index;
#ifdef WITH_ID_IN_HYDRA
int ID;
#endif
}
*HydroDataIn, /*!< holds particle data for SPH hydro-force computation to be exported to other processors */
*HydroDataGet; /*!< holds imported particle data for SPH hydro-force computation */
extern struct hydrodata_out
{
FLOAT Acc[3];
FLOAT DtEntropy;
#ifdef FEEDBACK
FLOAT DtEgySpecFeedback;
FLOAT FeedbackAccel[3]; /*!< acceleration due to feedback force */
#endif
FLOAT MaxSignalVel;
#ifdef COMPUTE_VELOCITY_DISPERSION
FLOAT VelocityDispersion[VELOCITY_DISPERSION_SIZE];
#endif
#ifdef MULTIPHASE
FLOAT StickyDVel[3]; /*!< differences in velocities induced by sticky collisions */
#endif
}
*HydroDataResult, /*!< stores the locally computed SPH hydro results for imported particles */
*HydroDataPartialResult; /*!< imported partial SPH hydro-force results from other processors */
#ifdef MULTIPHASE
extern struct stickydata_in
{
FLOAT Pos[3];
FLOAT Vel[3];
FLOAT Mass;
FLOAT Hsml;
int ID;
int StickyMaxID;
int StickyNgb;
float StickyMaxFs;
int Task;
int Index;
}
*StickyDataIn, /*!< holds particle data for sticky computation to be exported to other processors */
*StickyDataGet; /*!< holds imported particle data for sticky computation */
extern struct stickydata_out
{
int StickyMaxID;
int StickyNgb;
float StickyMaxFs;
FLOAT StickyNewVel[3];
}
*StickyDataResult, /*!< stores the locally computed sticky results for imported particles */
*StickyDataPartialResult; /*!< imported partial sticky results from other processors */
extern struct Sticky_index
{
int Index;
int CellIndex;
int Flag;
}
*StickyIndex;
#endif
#ifdef CHIMIE
extern struct chimiedata_in
{
FLOAT Pos[3];
FLOAT Vel[3];
#ifndef LONGIDS
unsigned int ID; /*!< particle identifier */
#else
unsigned long long ID; /*!< particle identifier */
#endif
FLOAT Hsml;
#ifdef FEEDBACK
FLOAT EnergySN;
#endif
#ifdef MULTIPHASE
int Phase;
FLOAT Entropy;
int StickyFlag;
#endif
FLOAT Density;
FLOAT Volume;
FLOAT Pressure;
FLOAT F1;
FLOAT DhsmlDensityFactor;
int Timestep;
int Task;
int Index;
#ifdef WITH_ID_IN_HYDRA
int ID;
#endif
double TotalEjectedGasMass;
double TotalEjectedEltMass[NELEMENTS];
double TotalEjectedEgySpec;
#ifdef CHIMIE_KINETIC_FEEDBACK
FLOAT NgbMass;
#endif
}
*ChimieDataIn, /*!< holds particle data for Chimie computation to be exported to other processors */
*ChimieDataGet; /*!< holds imported particle data for Chimie computation */
extern struct chimiedata_out
{
FLOAT Acc[3];
FLOAT DtEntropy;
#ifdef FEEDBACK
FLOAT DtEgySpecFeedback;
FLOAT FeedbackAccel[3]; /*!< acceleration due to feedback force */
#endif
FLOAT MaxSignalVel;
#ifdef COMPUTE_VELOCITY_DISPERSION
FLOAT VelocityDispersion[VELOCITY_DISPERSION_SIZE];
#endif
#ifdef MULTIPHASE
FLOAT StickyDVel[3]; /*!< differences in velocities induced by sticky collisions */
#endif
}
*ChimieDataResult, /*!< stores the locally computed Chimie results for imported particles */
*ChimieDataPartialResult; /*!< imported partial Chimie results from other processors */
extern struct starsdensdata_in
{
FLOAT Pos[3];
FLOAT Hsml;
int Index;
int Task;
}
*StarsDensDataIn, /*!< holds particle data for SPH density computation to be exported to other processors */
*StarsDensDataGet; /*!< holds imported particle data for SPH density computation */
extern struct starsdensdata_out
{
FLOAT Rho;
FLOAT Volume;
FLOAT DhsmlDensity;
FLOAT Ngb;
#ifdef CHIMIE_KINETIC_FEEDBACK
FLOAT NgbMass;
#endif
}
*StarsDensDataResult, /*!< stores the locally computed SPH density results for imported particles */
*StarsDensDataPartialResult; /*!< imported partial SPH density results from other processors */
#endif
#endif
diff --git a/begrun.c b/begrun.c
index 11c6c1c..f9bc7fc 100644
--- a/begrun.c
+++ b/begrun.c
@@ -1,2015 +1,2019 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <mpi.h>
#include <sys/types.h>
#include <unistd.h>
#include <gsl/gsl_rng.h>
#include "allvars.h"
#include "proto.h"
/*! \file begrun.c
* \brief initial set-up of a simulation run
*
* This file contains various functions to initialize a simulation run. In
* particular, the parameterfile is read in and parsed, the initial
* conditions or restart files are read, and global variables are
* initialized to their proper values.
*/
/*! This function performs the initial set-up of the simulation. First, the
* parameterfile is set, then routines for setting units, reading
* ICs/restart-files are called, auxialiary memory is allocated, etc.
*/
void begrun(void)
{
struct global_data_all_processes all;
#ifdef DETAILED_CPU
double tstart,tend;
tstart = second();
#endif
if(ThisTask == 0)
{
printf("\nThis is Gadget, version `%s'.\n", GADGETVERSION);
printf("\nRunning on %d processors.\n", NTask);
}
read_parameter_file(ParameterFile); /* ... read in parameters for this run */
-
+
allocate_commbuffers(); /* ... allocate buffer-memory for particle
exchange during force computation */
set_units();
#if defined(PERIODIC) && (!defined(PMGRID) || defined(FORCETEST))
ewald_init();
#endif
open_outputfiles();
random_generator = gsl_rng_alloc(gsl_rng_ranlxd1);
#ifdef RANDOMSEED_AS_PARAMETER
if(ThisTask == 0)
printf("Using %d as initial random seed\n",All.RandomSeed);
gsl_rng_set(random_generator, All.RandomSeed); /* start-up seed */
#else
printf("Using %d as initial random seed\n",42);
gsl_rng_set(random_generator, 42); /* start-up seed */
#endif
#ifdef PMGRID
long_range_init();
#endif
All.TimeLastRestartFile = CPUThisRun;
#ifdef MULTIPHASE
All.StickyLastCollisionTime = -1;
#endif
/* other physics initialization */
#ifdef COOLING
if (All.CoolingType==0) /* sutherland */
{
if(ThisTask == 0) printf("Initialize cooling function...\n");
init_cooling(0);
if(ThisTask == 0) printf("Initialize cooling function done.\n");
}
if (All.CoolingType==2) /* cooling with metals */
{
if(ThisTask == 0) printf("Initialize cooling function...\n");
init_cooling_with_metals();
if(ThisTask == 0) printf("Initialize cooling function done.\n");
}
#endif
#ifdef CHIMIE
int i;
if(ThisTask == 0) printf("Initialize chimie...\n");
init_chimie();
check_chimie();
if(ThisTask == 0)
{
for (i=0;i<get_nelts();i++)
printf("solar abundance %s\t= %g\n",get_Element(i),get_SolarAbundance(i));
}
if(ThisTask == 0) printf("Initialize chimie done...\n");
#ifdef COOLING
All.CoolingParameters_FeHSolar = get_SolarAbundance(FE); /* for consitency, use the value defined in chimie file */
#endif
#endif
if(RestartFlag == 0 || RestartFlag == 2)
{
set_random_numbers();
init(); /* ... read in initial model */
init_local_sys_state();
}
else
{
all = All; /* save global variables. (will be read from restart file) */
restart(RestartFlag); /* ... read restart file. Note: This also resets
all variables in the struct `All'.
However, during the run, some variables in the parameter
file are allowed to be changed, if desired. These need to
copied in the way below.
Note: All.PartAllocFactor is treated in restart() separately.
*/
/* yr
if we want a parameter to be taken as the one written in the parameter file,
we have to save it below,
instead, the value of the restart file will be taken.
This is usefull, for example, if stop a run and want it to be restarted with
different parameters.
*/
All.MinSizeTimestep = all.MinSizeTimestep;
All.MaxSizeTimestep = all.MaxSizeTimestep;
All.BufferSize = all.BufferSize;
All.BunchSizeForce = all.BunchSizeForce;
All.BunchSizeDensity = all.BunchSizeDensity;
All.BunchSizeHydro = all.BunchSizeHydro;
All.BunchSizeDomain = all.BunchSizeDomain;
#ifdef MULTIPHASE
All.BunchSizeSticky = all.BunchSizeSticky;
#endif
#ifdef CHIMIE
All.BunchSizeChimie = all.BunchSizeChimie;
#endif
All.TimeLimitCPU = all.TimeLimitCPU;
All.ResubmitOn = all.ResubmitOn;
All.TimeBetSnapshot = all.TimeBetSnapshot;
All.TimeBetStatistics = all.TimeBetStatistics;
All.CpuTimeBetRestartFile = all.CpuTimeBetRestartFile;
All.ErrTolIntAccuracy = all.ErrTolIntAccuracy;
All.MaxRMSDisplacementFac = all.MaxRMSDisplacementFac;
All.ErrTolForceAcc = all.ErrTolForceAcc;
All.TypeOfTimestepCriterion = all.TypeOfTimestepCriterion;
All.TypeOfOpeningCriterion = all.TypeOfOpeningCriterion;
All.NumFilesWrittenInParallel = all.NumFilesWrittenInParallel;
All.TreeDomainUpdateFrequency = all.TreeDomainUpdateFrequency;
All.SnapFormat = all.SnapFormat;
All.NumFilesPerSnapshot = all.NumFilesPerSnapshot;
All.MaxNumNgbDeviation = all.MaxNumNgbDeviation;
All.ArtBulkViscConst = all.ArtBulkViscConst;
All.OutputListOn = all.OutputListOn;
All.CourantFac = all.CourantFac;
All.OutputListLength = all.OutputListLength;
memcpy(All.OutputListTimes, all.OutputListTimes, sizeof(double) * All.OutputListLength);
#ifdef RANDOMSEED_AS_PARAMETER
All.RandomSeed = all.RandomSeed;
#endif
#ifdef MULTIPHASE
All.CriticalTemperature = all.CriticalTemperature;
All.CriticalNonCollisionalTemperature = all.CriticalNonCollisionalTemperature;
All.StickyUseGridForCollisions = all.StickyUseGridForCollisions;
All.StickyTime = all.StickyTime;
All.StickyCollisionTime = all.StickyCollisionTime;
All.StickyIdleTime = all.StickyIdleTime;
All.StickyMinVelocity = all.StickyMinVelocity;
All.StickyMaxVelocity = all.StickyMaxVelocity;
All.StickyLambda = all.StickyLambda;
All.StickyDensity = all.StickyDensity;
All.StickyDensityPower = all.StickyDensityPower;
All.StickyRsphFact = all.StickyRsphFact;
All.StickyBetaR = all.StickyBetaR;
All.StickyBetaT = all.StickyBetaT;
All.StickyGridNx = all.StickyGridNx;
All.StickyGridNy = all.StickyGridNy;
All.StickyGridNz = all.StickyGridNz;
All.StickyGridXmin = all.StickyGridXmin;
All.StickyGridXmax = all.StickyGridXmax;
All.StickyGridYmin = all.StickyGridYmin;
All.StickyGridYmax = all.StickyGridYmax;
All.StickyGridZmin = all.StickyGridZmin;
All.StickyGridZmax = all.StickyGridZmax;
#ifdef COLDGAS_CYCLE
All.ColdGasCycleTransitionTime = all.ColdGasCycleTransitionTime;
All.ColdGasCycleTransitionParameter = all.ColdGasCycleTransitionParameter;
#endif
#endif
#ifdef OUTERPOTENTIAL
#ifdef NFW
All.HaloConcentration = all.HaloConcentration;
All.HaloMass = all.HaloMass;
All.GasMassFraction = all.GasMassFraction;
#endif
#ifdef PLUMMER
All.PlummerMass = all.PlummerMass;
All.PlummerSoftenning = all.PlummerSoftenning;
#endif
#ifdef PISOTHERM
All.Rho0 = all.Rho0;
All.Rc = all.Rc;
All.GasMassFraction = all.GasMassFraction;
#endif
#ifdef CORIOLIS
All.CoriolisOmegaX0 = all.CoriolisOmegaX0;
All.CoriolisOmegaY0 = all.CoriolisOmegaY0;
All.CoriolisOmegaZ0 = all.CoriolisOmegaZ0;
#endif
#endif
#ifdef SFR
//All.StarFormationNStarsFromGas = all.StarFormationNStarsFromGas; /* do not change the param. if restarting, else, StarFormationStarMass will be wrong */
//All.StarFormationStarMass = all.StarFormationStarMass;
All.StarFormationMgMsFraction = all.StarFormationMgMsFraction;
All.StarFormationType = all.StarFormationType;
All.StarFormationCstar = all.StarFormationCstar;
All.StarFormationTime = all.StarFormationTime;
All.StarFormationDensity = all.StarFormationDensity;
All.StarFormationTemperature = all.StarFormationTemperature;
All.ThresholdDensity = all.ThresholdDensity;
#endif
#ifdef COOLING
All.CoolingType = all.CoolingType;
All.CutofCoolingTemperature = all.CutofCoolingTemperature;
All.InitGasMetallicity = all.InitGasMetallicity;
#endif
#ifdef CHIMIE
All.ChimieSupernovaEnergy = all.ChimieSupernovaEnergy; /* do not use this value, use the restartfile one */
All.ChimieKineticFeedbackFraction = all.ChimieKineticFeedbackFraction;
All.ChimieWindSpeed = all.ChimieWindSpeed;
All.ChimieWindTime = all.ChimieWindTime;
All.ChimieThermalTime = all.ChimieThermalTime;
All.ChimieMaxSizeTimestep = all.ChimieMaxSizeTimestep;
#endif
#if defined (HEATING_PE)
All.HeatingPeElectronFraction = all.HeatingPeElectronFraction;
#endif
#if defined (HEATING_PE) || defined (STELLAR_FLUX) || defined (EXTERNAL_FLUX)
All.HeatingPeSolarEnergyDensity = all.HeatingPeSolarEnergyDensity;
#endif
#if defined (HEATING_PE) || defined (STELLAR_FLUX)
All.HeatingPeLMRatioGas = all.HeatingPeLMRatioGas;
All.HeatingPeLMRatioHalo = all.HeatingPeLMRatioHalo;
All.HeatingPeLMRatioDisk = all.HeatingPeLMRatioDisk;
All.HeatingPeLMRatioBulge = all.HeatingPeLMRatioBulge;
All.HeatingPeLMRatioStars = all.HeatingPeLMRatioStars;
All.HeatingPeLMRatioBndry = all.HeatingPeLMRatioBndry;
All.HeatingPeLMRatio[0] = all.HeatingPeLMRatio[0];
All.HeatingPeLMRatio[1] = all.HeatingPeLMRatio[1];
All.HeatingPeLMRatio[2] = all.HeatingPeLMRatio[2];
All.HeatingPeLMRatio[3] = all.HeatingPeLMRatio[3];
All.HeatingPeLMRatio[4] = all.HeatingPeLMRatio[4];
All.HeatingPeLMRatio[5] = all.HeatingPeLMRatio[5];
#endif
#ifdef EXTERNAL_FLUX
All.HeatingExternalFLuxEnergyDensity = all.HeatingExternalFLuxEnergyDensity;
#endif
#ifdef FEEDBACK
All.SupernovaEgySpecPerMassUnit = all.SupernovaEgySpecPerMassUnit;
All.SupernovaFractionInEgyKin = all.SupernovaFractionInEgyKin;
All.SupernovaTime = all.SupernovaTime;
#endif
#ifdef FEEDBACK_WIND
All.SupernovaWindEgySpecPerMassUnit = all.SupernovaWindEgySpecPerMassUnit;
All.SupernovaWindFractionInEgyKin = all.SupernovaWindFractionInEgyKin;
All.SupernovaWindParameter = all.SupernovaWindParameter;
All.SupernovaWindIntAccuracy = all.SupernovaWindIntAccuracy;
#endif
#ifdef BUBBLES
All.BubblesDelta = all.BubblesDelta;
All.BubblesAlpha = all.BubblesAlpha;
All.BubblesRadiusFactor = all.BubblesRadiusFactor;
All.BubblesR = all.BubblesR;
#endif
#ifdef AGN_HEATING
All.AGNHeatingPower = all.AGNHeatingPower;
All.AGNHeatingRmax = all.AGNHeatingRmax;
#endif
#ifdef AGN_ACCRETION
All.TimeBetAccretion = all.TimeBetAccretion;
All.AccretionRadius = all.AccretionRadius;
All.AGNFactor = all.AGNFactor;
All.MinMTotInRa = all.MinMTotInRa;
#endif
#ifdef BONDI_ACCRETION
All.BondiEfficiency = all.BondiEfficiency;
All.BondiBlackHoleMass = all.BondiBlackHoleMass;
All.BondiHsmlFactor = all.BondiHsmlFactor;
All.BondiPower = all.BondiPower;
All.BondiTimeBet = all.BondiTimeBet;
#endif
strcpy(All.ResubmitCommand, all.ResubmitCommand);
strcpy(All.OutputListFilename, all.OutputListFilename);
strcpy(All.OutputDir, all.OutputDir);
strcpy(All.RestartFile, all.RestartFile);
strcpy(All.EnergyFile, all.EnergyFile);
#ifdef SYSTEMSTATISTICS
strcpy(All.SystemFile, all.SystemFile);
#endif
strcpy(All.InfoFile, all.InfoFile);
strcpy(All.CpuFile, all.CpuFile);
strcpy(All.LogFile, all.LogFile);
#ifdef SFR
strcpy(All.SfrFile, all.SfrFile);
#endif
#ifdef CHIMIE
strcpy(All.ChimieFile, all.ChimieFile);
#endif
#ifdef MULTIPHASE
strcpy(All.PhaseFile, all.PhaseFile);
strcpy(All.StickyFile, all.StickyFile);
#endif
#ifdef AGN_ACCRETION
strcpy(All.AccretionFile, all.AccretionFile);
#endif
#ifdef BONDI_ACCRETION
strcpy(All.BondiFile, all.BondiFile);
#endif
#ifdef BUBBLES
strcpy(All.BubbleFile, all.BubbleFile);
#endif
strcpy(All.TimingsFile, all.TimingsFile);
strcpy(All.SnapshotFileBase, all.SnapshotFileBase);
if(All.TimeMax != all.TimeMax)
readjust_timebase(All.TimeMax, all.TimeMax);
}
#ifdef PMGRID
long_range_init_regionsize();
#endif
if(All.ComovingIntegrationOn)
init_drift_table();
if(RestartFlag == 2)
All.Ti_nextoutput = find_next_outputtime(All.Ti_Current + 1);
else
All.Ti_nextoutput = find_next_outputtime(All.Ti_Current);
All.TimeLastRestartFile = CPUThisRun;
/* other initialization for special behavior */
#ifdef SFR
if (ThisTask == 0)
printf("StarFormationStarMass = %g\n\n",All.StarFormationStarMass);
#endif
#ifdef OUTERPOTENTIAL
if(ThisTask == 0) printf("Initialize outer potential...\n");
init_outer_potential();
if(ThisTask == 0) printf("Initialize outer potential done.\n");
#endif
#ifdef BUBBLES
if(ThisTask == 0) printf("Initialize bubble function...\n");
init_bubble();
if(ThisTask == 0) printf("Initialize bubble function done.\n");
#endif
#ifdef MULTIPHASE
if(ThisTask == 0) printf("Initialize sticky...\n");
header.critical_energy_spec = All.CriticalEgySpec;
init_sticky();
if(ThisTask == 0) printf("Initialize sticky done.\n");
#endif
#ifdef DETAILED_CPU
tend = second();
All.CPU_Begrun += timediff(tstart, tend);
All.CPU_Begrun -= All.CPU_Leapfrog;
All.CPU_Begrun -= All.CPU_Domain;
All.CPU_Begrun -= All.CPU_Snapshot;
#endif
}
/*! Computes conversion factors between internal code units and the
* cgs-system.
*/
void set_units(void)
{
double meanweight;
All.UnitTime_in_s = All.UnitLength_in_cm / All.UnitVelocity_in_cm_per_s;
All.UnitTime_in_Megayears = All.UnitTime_in_s / SEC_PER_MEGAYEAR;
if(All.GravityConstantInternal == 0)
All.G = GRAVITY / pow(All.UnitLength_in_cm, 3) * All.UnitMass_in_g * pow(All.UnitTime_in_s, 2);
else
All.G = All.GravityConstantInternal;
All.UnitDensity_in_cgs = All.UnitMass_in_g / pow(All.UnitLength_in_cm, 3);
All.UnitPressure_in_cgs = All.UnitMass_in_g / All.UnitLength_in_cm / pow(All.UnitTime_in_s, 2);
All.UnitCoolingRate_in_cgs = All.UnitPressure_in_cgs / All.UnitTime_in_s;
All.UnitEnergy_in_cgs = All.UnitMass_in_g * pow(All.UnitLength_in_cm, 2) / pow(All.UnitTime_in_s, 2);
/* convert some physical input parameters to internal units */
All.Hubble = HUBBLE * All.UnitTime_in_s;
meanweight = 4.0 / (1 + 3 * HYDROGEN_MASSFRAC); /* note: we assume neutral gas here */
/*meanweight = 4 / (8 - 5 * (1 - HYDROGEN_MASSFRAC));*/ /* note: we assume FULL ionized gas here */
All.Boltzmann = BOLTZMANN /All.UnitEnergy_in_cgs;
All.ProtonMass = PROTONMASS/All.UnitMass_in_g;
All.mumh = All.ProtonMass*meanweight;
#ifdef MULTIPHASE
if (All.ComovingIntegrationOn)
All.StickyTime *= 3.1536e+13*All.HubbleParam/All.UnitTime_in_s; /* Myr to code unit */
else
All.StickyTime *= 3.1536e+13/All.UnitTime_in_s; /* Myr to code unit */
if (All.ComovingIntegrationOn)
All.StickyCollisionTime *= 3.1536e+13*All.HubbleParam/All.UnitTime_in_s; /* Myr to code unit */
else
All.StickyCollisionTime *= 3.1536e+13/All.UnitTime_in_s; /* Myr to code unit */
if (All.ComovingIntegrationOn)
All.StickyIdleTime *= 3.1536e+13*All.HubbleParam/All.UnitTime_in_s; /* Myr to code unit */
else
All.StickyIdleTime *= 3.1536e+13/All.UnitTime_in_s; /* Myr to code unit */
if (All.ComovingIntegrationOn)
{
All.StickyMinVelocity *= 100000/All.UnitTime_in_s; /* km/s to code unit */
printf("here, you must check the unit conversion !");
endrun(9876);
}
else
All.StickyMinVelocity *= 100000/All.UnitVelocity_in_cm_per_s; /* km/s to code unit */
if (All.ComovingIntegrationOn)
{
All.StickyMaxVelocity *= 100000/All.UnitTime_in_s; /* km/s to code unit */
printf("here, you must check the unit conversion !");
endrun(9876);
}
else
All.StickyMaxVelocity *= 100000/All.UnitVelocity_in_cm_per_s; /* km/s to code unit */
if (All.StickyTime==0)
All.StickyLambda = 0;
else
All.StickyLambda = 1./All.StickyTime;
All.CriticalEgySpec = 1./GAMMA_MINUS1 * All.Boltzmann/All.mumh * All.CriticalTemperature;
All.CriticalNonCollisionalEgySpec = 1./GAMMA_MINUS1 * All.Boltzmann/All.mumh * All.CriticalNonCollisionalTemperature;
All.StickyDensity = All.StickyDensity/All.UnitDensity_in_cgs;
// if((All.StickyLambda > 0.1/All.MaxSizeTimestep)&&(ThisTask==0))
// {
// printf("\nStickyLambda is to big and you may experiment numerical problems !\n");
// printf("You should either decrease StickyLambda or decrease MaxSizeTimestep.\n");
// printf("(StickyLambda=%g,maxStickyLambda=%g)\n",All.StickyLambda,0.01/All.MaxSizeTimestep);
// printf("try \n");
// printf("StickyLambda <= %g or MaxSizeTimestep <= %g \n",(0.01/All.MaxSizeTimestep),(0.01/All.StickyLambda));
// fflush(stdout);
// endrun(121212);
// }
#ifdef COLDGAS_CYCLE
if (All.ComovingIntegrationOn)
All.ColdGasCycleTransitionTime *= 3.1536e+13*All.HubbleParam/All.UnitTime_in_s; /* Myr to code unit */
else
All.ColdGasCycleTransitionTime *= 3.1536e+13/All.UnitTime_in_s; /* Myr to code unit */
#endif
#endif
#ifdef SFR
All.StarFormationTime = All.StarFormationTime/All.UnitTime_in_s * 3.1536e16;
All.StarFormationDensity = All.StarFormationDensity/All.UnitDensity_in_cgs;
#endif
#if defined (HEATING_PE) || defined (STELLAR_FLUX)
All.HeatingPeLMRatio[0] = All.HeatingPeLMRatioGas;
All.HeatingPeLMRatio[1] = All.HeatingPeLMRatioHalo;
All.HeatingPeLMRatio[2] = All.HeatingPeLMRatioDisk;
All.HeatingPeLMRatio[3] = All.HeatingPeLMRatioBulge;
All.HeatingPeLMRatio[4] = All.HeatingPeLMRatioStars;
All.HeatingPeLMRatio[5] = All.HeatingPeLMRatioBndry;
int k;
for (k=0;k<6;k++)
{
All.HeatingPeLMRatio[k] *= 1./SOLAR_MASS; /* erg/s/Msol to erg/s/g */
All.HeatingPeLMRatio[k] *= All.UnitMass_in_g*All.UnitTime_in_s / All.UnitEnergy_in_cgs; /* erg/s/g to code unit */
}
#endif
#ifdef FEEDBACK
All.SupernovaEgySpecPerMassUnit *= All.UnitMass_in_g / All.UnitEnergy_in_cgs;
if (All.ComovingIntegrationOn)
All.SupernovaTime *= 3.1536e+13*All.HubbleParam/All.UnitTime_in_s; /* Myr to code unit */
else
All.SupernovaTime *= 3.1536e+13/All.UnitTime_in_s; /* Myr to code unit */
#endif
#ifdef FEEDBACK_WIND
All.SupernovaWindEgySpecPerMassUnit *= All.UnitMass_in_g / All.UnitEnergy_in_cgs;
All.SupernovaWindSpeed = sqrt( 2*All.SupernovaWindFractionInEgyKin * All.SupernovaWindEgySpecPerMassUnit / All.SupernovaWindParameter );
#endif
#if defined (AGN_ACCRETION) || defined (BONDI_ACCRETION)
All.LightSpeed = C/All.UnitVelocity_in_cm_per_s;
#endif
#ifdef CHIMIE
All.ChimieSupernovaEnergy = All.ChimieSupernovaEnergy/All.UnitMass_in_g/pow(All.UnitVelocity_in_cm_per_s,2);
All.ChimieWindSpeed = All.ChimieWindSpeed*1e5/All.UnitVelocity_in_cm_per_s;
All.ChimieWindTime = All.ChimieWindTime*3.1536e13/All.UnitTime_in_s;
All.ChimieThermalTime = All.ChimieThermalTime*3.1536e13/All.UnitTime_in_s;
All.ChimieMaxSizeTimestep = All.ChimieMaxSizeTimestep*3.1536e13/All.UnitTime_in_s;
#endif
if(ThisTask == 0)
{
printf("\nHubble (internal units) = %g\n", All.Hubble);
printf("G (internal units) = %g\n", All.G);
printf("Boltzmann = %g \n", All.Boltzmann);
printf("ProtonMass = %g \n", All.ProtonMass);
printf("mumh = %g \n", All.mumh);
printf("UnitMass_in_g = %g \n", All.UnitMass_in_g);
printf("UnitTime_in_s = %g \n", All.UnitTime_in_s);
printf("UnitVelocity_in_cm_per_s = %g \n", All.UnitVelocity_in_cm_per_s);
printf("UnitDensity_in_cgs = %g \n", All.UnitDensity_in_cgs);
printf("UnitEnergy_in_cgs = %g \n", All.UnitEnergy_in_cgs);
printf("\n");
#ifdef SFR
printf("StarFormationDensity (internal units) = %g \n", All.StarFormationDensity);
printf("StarFormationTime (internal units) = %g \n", All.StarFormationTime);
#endif
#ifdef FEEDBACK
printf("SupernovaTime (internal units) = %g \n", All.SupernovaTime);
printf("SupernovaEgySpecPerMassUnit (internal units) = %g \n", All.SupernovaEgySpecPerMassUnit);
#endif
#ifdef FEEDBACK_WIND
printf("SupernovaWindEgySpecPerMassUnit (internal units) = %g \n", All.SupernovaWindEgySpecPerMassUnit);
printf("SupernovaWindSpeed (internal units) = %g \n", All.SupernovaWindSpeed);
#endif
#ifdef MULTIPHASE
printf("CriticalEgySpec (internal units) = %g \n", All.CriticalEgySpec);
printf("CriticalNonCollisionalEgySpec (internal units) = %g \n", All.CriticalNonCollisionalEgySpec);
printf("StickyCollisionTime (internal units) = %g \n", All.StickyCollisionTime);
printf("StickyIdleTime (internal units) = %g \n", All.StickyIdleTime);
printf("StickyDensity (internal units) = %g \n", All.StickyDensity);
printf("StickyTime (internal units) = %g \n", All.StickyTime);
printf("StickyMinVelocity (internal units) = %g \n", All.StickyMinVelocity);
printf("StickyMaxVelocity (internal units) = %g \n", All.StickyMaxVelocity);
#endif
#ifdef COLDGAS_CYCLE
printf("ColdGasCycleTransitionTime (internal units) = %g \n", All.ColdGasCycleTransitionTime);
#endif
#ifdef CHIMIE
printf("ChimieSupernovaEnergy (internal units) = %g \n", All.ChimieSupernovaEnergy);
printf("ChimieWindSpeed (internal units) = %g \n", All.ChimieWindSpeed);
printf("ChimieWindTime (internal units) = %g \n", All.ChimieWindTime);
printf("ChimieThermalTime (internal units) = %g \n", All.ChimieThermalTime);
printf("ChimieMaxSizeTimestep (internal units) = %g \n", All.ChimieMaxSizeTimestep);
#endif
printf("\n");
}
#ifdef ISOTHERM_EQS
All.MinEgySpec = 0;
#else
All.MinEgySpec = 1 / meanweight * (1.0 / GAMMA_MINUS1) * (BOLTZMANN / PROTONMASS) * All.MinGasTemp;
All.MinEgySpec *= All.UnitMass_in_g / All.UnitEnergy_in_cgs;
#endif
}
/*! Initialize local system state variables
*/
void init_local_sys_state(void)
{
#ifdef SFR
LocalSysState.StarEnergyInt = 0.;
#ifdef COOLING
LocalSysState.RadiatedEnergy = 0.;
#endif
#endif
#ifdef CHIMIE_THERMAL_FEEDBACK
LocalSysState.EnergyThermalFeedback = 0.;
#endif
#ifdef CHIMIE_KINETIC_FEEDBACK
LocalSysState.EnergyKineticFeedback = 0.;
#endif
#ifdef MULTIPHASE
LocalSysState.EnergyRadSticky = 0.;
#endif
#ifdef FEEDBACK_WIND
LocalSysState.EnergyFeedbackWind = 0.;
#endif
}
/*! This function opens various log-files that report on the status and
* performance of the simulstion. On restart from restart-files
* (start-option 1), the code will append to these files.
*/
void open_outputfiles(void)
{
char mode[2], buf[200];
#ifdef ADVANCEDSTATISTICS
int i=0;
#endif
if(ThisTask != 0) /* only the root processor writes to the log files */
return;
if(RestartFlag == 0)
strcpy(mode, "w");
else
strcpy(mode, "a");
sprintf(buf, "%s%s", All.OutputDir, All.CpuFile);
if(!(FdCPU = fopen(buf, mode)))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
#ifdef ADVANCEDCPUSTATISTICS
else
{
if(RestartFlag == 0) /* write the header */
{
fprintf(FdCPU,"# Step ");
fprintf(FdCPU,"Time ");
fprintf(FdCPU,"nCPUs ");
fprintf(FdCPU,"CPU_Total ");
#ifdef DETAILED_CPU
fprintf(FdCPU,"CPU_Leapfrog ");
fprintf(FdCPU,"CPU_Physics ");
fprintf(FdCPU,"CPU_Residual ");
fprintf(FdCPU,"CPU_Accel ");
fprintf(FdCPU,"CPU_Begrun ");
#endif
fprintf(FdCPU,"CPU_Gravity ");
fprintf(FdCPU,"CPU_Hydro ");
#ifdef COOLING
fprintf(FdCPU,"CPU_Cooling ");
#endif
#ifdef SFR
fprintf(FdCPU,"CPU_StarFormation ");
#endif
#ifdef CHIMIE
fprintf(FdCPU,"CPU_Chimie ");
#endif
#ifdef MULTIPHASE
fprintf(FdCPU,"CPU_Sticky ");
#endif
fprintf(FdCPU,"CPU_Domain ");
fprintf(FdCPU,"CPU_Potential ");
fprintf(FdCPU,"CPU_Predict ");
fprintf(FdCPU,"CPU_TimeLine ");
fprintf(FdCPU,"CPU_Snapshot ");
fprintf(FdCPU,"CPU_TreeWalk ");
fprintf(FdCPU,"CPU_TreeConstruction ");
fprintf(FdCPU,"CPU_CommSum ");
fprintf(FdCPU,"CPU_Imbalance ");
fprintf(FdCPU,"CPU_HydCompWalk ");
fprintf(FdCPU,"CPU_HydCommSumm ");
fprintf(FdCPU,"CPU_HydImbalance ");
fprintf(FdCPU,"CPU_EnsureNgb ");
fprintf(FdCPU,"CPU_PM ");
fprintf(FdCPU,"CPU_Peano ");
#ifdef DETAILED_CPU_DOMAIN
fprintf(FdCPU,"CPU_Domain_findExtend ");
fprintf(FdCPU,"CPU_Domain_determineTopTree ");
fprintf(FdCPU,"CPU_Domain_sumCost ");
fprintf(FdCPU,"CPU_Domain_findSplit ");
fprintf(FdCPU,"CPU_Domain_shiftSplit ");
fprintf(FdCPU,"CPU_Domain_countToGo ");
fprintf(FdCPU,"CPU_Domain_exchange ");
#endif
#ifdef DETAILED_CPU_GRAVITY
fprintf(FdCPU,"CPU_Gravity_TreeWalk1 ");
fprintf(FdCPU,"CPU_Gravity_TreeWalk2 ");
fprintf(FdCPU,"CPU_Gravity_CommSum1 ");
fprintf(FdCPU,"CPU_Gravity_CommSum2 ");
fprintf(FdCPU,"CPU_Gravity_Imbalance1 ");
fprintf(FdCPU,"CPU_Gravity_Imbalance2 ");
#endif
/* return */
fprintf(FdCPU,"\n");
fflush(FdCPU);
}
}
#endif
sprintf(buf, "%s%s", All.OutputDir, All.InfoFile);
if(!(FdInfo = fopen(buf, mode)))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
sprintf(buf, "%s%s", All.OutputDir, All.LogFile);
if(!(FdLog = fopen(buf, mode)))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
sprintf(buf, "%s%s", All.OutputDir, All.EnergyFile);
if(!(FdEnergy = fopen(buf, mode)))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
#ifdef ADVANCEDSTATISTICS
else
{
if(RestartFlag == 0) /* write the header */
{
fprintf(FdEnergy,"# Time EnergyInt EnergyPot EnergyKin ");
#ifdef COOLING
fprintf(FdEnergy,"EnergyRadSph ");
#endif
#ifdef AGN_HEATING
fprintf(FdEnergy,"EnergyAGNHeat ");
#endif
#ifdef MULTIPHASE
fprintf(FdEnergy,"EnergyRadSticky ");
#endif
#ifdef FEEDBACK_WIND
fprintf(FdEnergy,"EnergyFeedbackWind ");
#endif
#ifdef BUBBLES
fprintf(FdEnergy,"EnergyBubbles ");
#endif
#ifdef CHIMIE_THERMAL_FEEDBACK
fprintf(FdEnergy,"EnergyThermalFeedback ");
#endif
#ifdef CHIMIE_KINETIC_FEEDBACK
fprintf(FdEnergy,"EnergyKineticFeedback ");
#endif
for (i=0;i<6;i++)
{
fprintf(FdEnergy,"EnergyIntComp%d EnergyPotComp%d EnergyKinComp%d ",i+1,i+1,i+1);
#ifdef COOLING
fprintf(FdEnergy,"EnergyRadSphComp%d ",i+1);
#endif
#ifdef MULTIPHASE
fprintf(FdEnergy,"EnergyRadStickyComp%d ",i+1);
#endif
#ifdef FEEDBACK_WIND
fprintf(FdEnergy,"EnergyFeedbackWindComp%d ",i+1);
#endif
#ifdef BUBBLES
fprintf(FdEnergy,"EnergyBubblesComp%d ",i+1);
#endif
#ifdef CHIMIE_THERMAL_FEEDBACK
fprintf(FdEnergy,"EnergyThermalFeedbackComp%d ",i+1);
#endif
#ifdef CHIMIE_KINETIC_FEEDBACK
fprintf(FdEnergy,"EnergyKineticFeedbackComp%d ",i+1);
#endif
}
for (i=0;i<6;i++)
fprintf(FdEnergy,"MassComp%d ",i+1);
/* return */
fprintf(FdEnergy,"\n");
fflush(FdEnergy);
}
}
#endif
#ifdef SYSTEMSTATISTICS
sprintf(buf, "%s%s", All.OutputDir, All.SystemFile);
if(!(FdSystem = fopen(buf, mode)))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
#endif
sprintf(buf, "%s%s", All.OutputDir, All.TimingsFile);
if(!(FdTimings = fopen(buf, mode)))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
#ifdef FORCETEST
if(RestartFlag == 0)
{
sprintf(buf, "%s%s", All.OutputDir, "forcetest.txt");
if(!(FdForceTest = fopen(buf, "w")))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
fclose(FdForceTest);
}
#endif
#ifdef SFR
sprintf(buf, "%s%s", All.OutputDir, All.SfrFile);
if(!(FdSfr = fopen(buf, mode)))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
#endif
#ifdef CHIMIE
sprintf(buf, "%s%s", All.OutputDir, All.ChimieFile);
if(!(FdChimie = fopen(buf, mode)))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
#endif
#ifdef MULTIPHASE
sprintf(buf, "%s%s", All.OutputDir, All.PhaseFile);
if(!(FdPhase = fopen(buf, mode)))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
sprintf(buf, "%s%s", All.OutputDir, All.StickyFile);
if(!(FdSticky = fopen(buf, mode)))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
#endif
#ifdef AGN_ACCRETION
sprintf(buf, "%s%s", All.OutputDir, All.AccretionFile);
if(!(FdAccretion = fopen(buf, mode)))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
#endif
#ifdef BONDI_ACCRETION
sprintf(buf, "%s%s", All.OutputDir, All.BondiFile);
if(!(FdBondi = fopen(buf, mode)))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
#endif
#ifdef BUBBLES
sprintf(buf, "%s%s", All.OutputDir, All.BubbleFile);
if(!(FdBubble = fopen(buf, mode)))
{
printf("error in opening file '%s'\n", buf);
endrun(1);
}
#endif
}
/*! This function closes the global log-files.
*/
void close_outputfiles(void)
{
if(ThisTask != 0) /* only the root processor writes to the log files */
return;
fclose(FdCPU);
fclose(FdInfo);
fclose(FdLog);
fclose(FdEnergy);
#ifdef SYSTEMSTATISTICS
fclose(FdSystem);
#endif
fclose(FdTimings);
#ifdef FORCETEST
fclose(FdForceTest);
#endif
#ifdef SFR
fclose(FdSfr);
#endif
#ifdef MULTIPHASE
fclose(FdPhase);
fclose(FdSticky);
#endif
#ifdef AGN_ACCRETION
fclose(FdAccretion);
#endif
#ifdef BONDI_ACCRETION
fclose(FdBondi);
#endif
#ifdef BUBBLES
fclose(FdBubble);
#endif
}
/*! This function parses the parameterfile in a simple way. Each paramater
* is defined by a keyword (`tag'), and can be either of type double, int,
* or character string. The routine makes sure that each parameter
* appears exactly once in the parameterfile, otherwise error messages are
* produced that complain about the missing parameters.
*/
void read_parameter_file(char *fname)
{
#define DOUBLE 1
#define STRING 2
#define INT 3
#define MAXTAGS 300
FILE *fd, *fdout;
char buf[200], buf1[200], buf2[200], buf3[400];
int i, j, nt;
int id[MAXTAGS];
void *addr[MAXTAGS];
char tag[MAXTAGS][50];
int errorFlag = 0;
if(sizeof(long long) != 8)
{
if(ThisTask == 0)
printf("\nType `long long' is not 64 bit on this platform. Stopping.\n\n");
endrun(0);
}
if(sizeof(int) != 4)
{
if(ThisTask == 0)
printf("\nType `int' is not 32 bit on this platform. Stopping.\n\n");
endrun(0);
}
if(sizeof(float) != 4)
{
if(ThisTask == 0)
printf("\nType `float' is not 32 bit on this platform. Stopping.\n\n");
endrun(0);
}
if(sizeof(double) != 8)
{
if(ThisTask == 0)
printf("\nType `double' is not 64 bit on this platform. Stopping.\n\n");
endrun(0);
}
if(ThisTask == 0) /* read parameter file on process 0 */
{
nt = 0;
strcpy(tag[nt], "InitCondFile");
addr[nt] = All.InitCondFile;
id[nt++] = STRING;
strcpy(tag[nt], "OutputDir");
addr[nt] = All.OutputDir;
id[nt++] = STRING;
strcpy(tag[nt], "SnapshotFileBase");
addr[nt] = All.SnapshotFileBase;
id[nt++] = STRING;
strcpy(tag[nt], "EnergyFile");
addr[nt] = All.EnergyFile;
id[nt++] = STRING;
#ifdef SYSTEMSTATISTICS
strcpy(tag[nt], "SystemFile");
addr[nt] = All.SystemFile;
id[nt++] = STRING;
#endif
strcpy(tag[nt], "CpuFile");
addr[nt] = All.CpuFile;
id[nt++] = STRING;
#ifdef SFR
strcpy(tag[nt], "SfrFile");
addr[nt] = All.SfrFile;
id[nt++] = STRING;
#endif
#ifdef CHIMIE
strcpy(tag[nt], "ChimieFile");
addr[nt] = All.ChimieFile;
id[nt++] = STRING;
#endif
#ifdef MULTIPHASE
strcpy(tag[nt], "PhaseFile");
addr[nt] = All.PhaseFile;
id[nt++] = STRING;
strcpy(tag[nt], "StickyFile");
addr[nt] = All.StickyFile;
id[nt++] = STRING;
#endif
#ifdef AGN_ACCRETION
strcpy(tag[nt], "AccretionFile");
addr[nt] = All.AccretionFile;
id[nt++] = STRING;
#endif
#ifdef BONDI_ACCRETION
strcpy(tag[nt], "BondiFile");
addr[nt] = All.BondiFile;
id[nt++] = STRING;
#endif
#ifdef BUBBLES
strcpy(tag[nt], "BubbleFile");
addr[nt] = All.BubbleFile;
id[nt++] = STRING;
#endif
strcpy(tag[nt], "InfoFile");
addr[nt] = All.InfoFile;
id[nt++] = STRING;
strcpy(tag[nt], "LogFile");
addr[nt] = All.LogFile;
id[nt++] = STRING;
strcpy(tag[nt], "TimingsFile");
addr[nt] = All.TimingsFile;
id[nt++] = STRING;
strcpy(tag[nt], "RestartFile");
addr[nt] = All.RestartFile;
id[nt++] = STRING;
strcpy(tag[nt], "ResubmitCommand");
addr[nt] = All.ResubmitCommand;
id[nt++] = STRING;
strcpy(tag[nt], "OutputListFilename");
addr[nt] = All.OutputListFilename;
id[nt++] = STRING;
strcpy(tag[nt], "OutputListOn");
addr[nt] = &All.OutputListOn;
id[nt++] = INT;
strcpy(tag[nt], "Omega0");
addr[nt] = &All.Omega0;
id[nt++] = DOUBLE;
strcpy(tag[nt], "OmegaBaryon");
addr[nt] = &All.OmegaBaryon;
id[nt++] = DOUBLE;
strcpy(tag[nt], "OmegaLambda");
addr[nt] = &All.OmegaLambda;
id[nt++] = DOUBLE;
strcpy(tag[nt], "HubbleParam");
addr[nt] = &All.HubbleParam;
id[nt++] = DOUBLE;
strcpy(tag[nt], "BoxSize");
addr[nt] = &All.BoxSize;
id[nt++] = DOUBLE;
strcpy(tag[nt], "PeriodicBoundariesOn");
addr[nt] = &All.PeriodicBoundariesOn;
id[nt++] = INT;
strcpy(tag[nt], "TimeOfFirstSnapshot");
addr[nt] = &All.TimeOfFirstSnapshot;
id[nt++] = DOUBLE;
strcpy(tag[nt], "CpuTimeBetRestartFile");
addr[nt] = &All.CpuTimeBetRestartFile;
id[nt++] = DOUBLE;
strcpy(tag[nt], "TimeBetStatistics");
addr[nt] = &All.TimeBetStatistics;
id[nt++] = DOUBLE;
strcpy(tag[nt], "TimeBegin");
addr[nt] = &All.TimeBegin;
id[nt++] = DOUBLE;
strcpy(tag[nt], "TimeMax");
addr[nt] = &All.TimeMax;
id[nt++] = DOUBLE;
strcpy(tag[nt], "TimeBetSnapshot");
addr[nt] = &All.TimeBetSnapshot;
id[nt++] = DOUBLE;
strcpy(tag[nt], "UnitVelocity_in_cm_per_s");
addr[nt] = &All.UnitVelocity_in_cm_per_s;
id[nt++] = DOUBLE;
strcpy(tag[nt], "UnitLength_in_cm");
addr[nt] = &All.UnitLength_in_cm;
id[nt++] = DOUBLE;
strcpy(tag[nt], "UnitMass_in_g");
addr[nt] = &All.UnitMass_in_g;
id[nt++] = DOUBLE;
strcpy(tag[nt], "TreeDomainUpdateFrequency");
addr[nt] = &All.TreeDomainUpdateFrequency;
id[nt++] = DOUBLE;
strcpy(tag[nt], "ErrTolIntAccuracy");
addr[nt] = &All.ErrTolIntAccuracy;
id[nt++] = DOUBLE;
strcpy(tag[nt], "ErrTolTheta");
addr[nt] = &All.ErrTolTheta;
id[nt++] = DOUBLE;
strcpy(tag[nt], "ErrTolForceAcc");
addr[nt] = &All.ErrTolForceAcc;
id[nt++] = DOUBLE;
strcpy(tag[nt], "MinGasHsmlFractional");
addr[nt] = &All.MinGasHsmlFractional;
id[nt++] = DOUBLE;
strcpy(tag[nt], "MaxSizeTimestep");
addr[nt] = &All.MaxSizeTimestep;
id[nt++] = DOUBLE;
strcpy(tag[nt], "MinSizeTimestep");
addr[nt] = &All.MinSizeTimestep;
id[nt++] = DOUBLE;
strcpy(tag[nt], "MaxRMSDisplacementFac");
addr[nt] = &All.MaxRMSDisplacementFac;
id[nt++] = DOUBLE;
strcpy(tag[nt], "ArtBulkViscConst");
addr[nt] = &All.ArtBulkViscConst;
id[nt++] = DOUBLE;
strcpy(tag[nt], "CourantFac");
addr[nt] = &All.CourantFac;
id[nt++] = DOUBLE;
strcpy(tag[nt], "DesNumNgb");
addr[nt] = &All.DesNumNgb;
id[nt++] = DOUBLE;
strcpy(tag[nt], "MaxNumNgbDeviation");
addr[nt] = &All.MaxNumNgbDeviation;
id[nt++] = DOUBLE;
strcpy(tag[nt], "ComovingIntegrationOn");
addr[nt] = &All.ComovingIntegrationOn;
id[nt++] = INT;
strcpy(tag[nt], "ICFormat");
addr[nt] = &All.ICFormat;
id[nt++] = INT;
strcpy(tag[nt], "SnapFormat");
addr[nt] = &All.SnapFormat;
id[nt++] = INT;
strcpy(tag[nt], "NumFilesPerSnapshot");
addr[nt] = &All.NumFilesPerSnapshot;
id[nt++] = INT;
strcpy(tag[nt], "NumFilesWrittenInParallel");
addr[nt] = &All.NumFilesWrittenInParallel;
id[nt++] = INT;
strcpy(tag[nt], "ResubmitOn");
addr[nt] = &All.ResubmitOn;
id[nt++] = INT;
strcpy(tag[nt], "TypeOfTimestepCriterion");
addr[nt] = &All.TypeOfTimestepCriterion;
id[nt++] = INT;
strcpy(tag[nt], "TypeOfOpeningCriterion");
addr[nt] = &All.TypeOfOpeningCriterion;
id[nt++] = INT;
strcpy(tag[nt], "TimeLimitCPU");
addr[nt] = &All.TimeLimitCPU;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SofteningHalo");
addr[nt] = &All.SofteningHalo;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SofteningDisk");
addr[nt] = &All.SofteningDisk;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SofteningBulge");
addr[nt] = &All.SofteningBulge;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SofteningGas");
addr[nt] = &All.SofteningGas;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SofteningStars");
addr[nt] = &All.SofteningStars;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SofteningBndry");
addr[nt] = &All.SofteningBndry;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SofteningHaloMaxPhys");
addr[nt] = &All.SofteningHaloMaxPhys;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SofteningDiskMaxPhys");
addr[nt] = &All.SofteningDiskMaxPhys;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SofteningBulgeMaxPhys");
addr[nt] = &All.SofteningBulgeMaxPhys;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SofteningGasMaxPhys");
addr[nt] = &All.SofteningGasMaxPhys;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SofteningStarsMaxPhys");
addr[nt] = &All.SofteningStarsMaxPhys;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SofteningBndryMaxPhys");
addr[nt] = &All.SofteningBndryMaxPhys;
id[nt++] = DOUBLE;
strcpy(tag[nt], "BufferSize");
addr[nt] = &All.BufferSize;
id[nt++] = INT;
strcpy(tag[nt], "PartAllocFactor");
addr[nt] = &All.PartAllocFactor;
id[nt++] = DOUBLE;
strcpy(tag[nt], "TreeAllocFactor");
addr[nt] = &All.TreeAllocFactor;
id[nt++] = DOUBLE;
strcpy(tag[nt], "GravityConstantInternal");
addr[nt] = &All.GravityConstantInternal;
id[nt++] = DOUBLE;
strcpy(tag[nt], "InitGasTemp");
addr[nt] = &All.InitGasTemp;
id[nt++] = DOUBLE;
strcpy(tag[nt], "MinGasTemp");
addr[nt] = &All.MinGasTemp;
id[nt++] = DOUBLE;
#ifdef RANDOMSEED_AS_PARAMETER
strcpy(tag[nt], "RandomSeed");
addr[nt] = &All.RandomSeed;
id[nt++] = INT;
#endif
#ifdef COOLING
strcpy(tag[nt], "CoolingFile");
addr[nt] = All.CoolingFile;
id[nt++] = STRING;
strcpy(tag[nt], "CutofCoolingTemperature");
addr[nt] = &All.CutofCoolingTemperature;
id[nt++] = DOUBLE;
strcpy(tag[nt], "InitGasMetallicity");
addr[nt] = &All.InitGasMetallicity;
id[nt++] = DOUBLE;
strcpy(tag[nt], "CoolingType");
addr[nt] = &All.CoolingType;
id[nt++] = DOUBLE;
#endif
#ifdef CHIMIE
+ strcpy(tag[nt], "ChimieNumberOfParameterFiles");
+ addr[nt] = &All.ChimieNumberOfParameterFiles;
+ id[nt++] = INT;
+
strcpy(tag[nt], "ChimieParameterFile");
addr[nt] = All.ChimieParameterFile;
id[nt++] = STRING;
strcpy(tag[nt], "ChimieSupernovaEnergy");
addr[nt] = &All.ChimieSupernovaEnergy;
id[nt++] = DOUBLE;
strcpy(tag[nt], "ChimieKineticFeedbackFraction");
addr[nt] = &All.ChimieKineticFeedbackFraction;
id[nt++] = DOUBLE;
strcpy(tag[nt], "ChimieWindSpeed");
addr[nt] = &All.ChimieWindSpeed;
id[nt++] = DOUBLE;
strcpy(tag[nt], "ChimieWindTime");
addr[nt] = &All.ChimieWindTime;
id[nt++] = DOUBLE;
strcpy(tag[nt], "ChimieThermalTime");
addr[nt] = &All.ChimieThermalTime;
id[nt++] = DOUBLE;
strcpy(tag[nt], "ChimieMaxSizeTimestep");
addr[nt] = &All.ChimieMaxSizeTimestep;
id[nt++] = DOUBLE;
#endif
#if defined (HEATING_PE)
strcpy(tag[nt], "HeatingPeElectronFraction");
addr[nt] = &All.HeatingPeElectronFraction;
id[nt++] = DOUBLE;
#endif
#if defined (HEATING_PE) || defined (STELLAR_FLUX) || defined (EXTERNAL_FLUX)
strcpy(tag[nt], "HeatingPeSolarEnergyDensity");
addr[nt] = &All.HeatingPeSolarEnergyDensity;
id[nt++] = DOUBLE;
#endif
#if defined (HEATING_PE) || defined (STELLAR_FLUX)
strcpy(tag[nt], "HeatingPeLMRatioGas");
addr[nt] = &All.HeatingPeLMRatioGas;
id[nt++] = DOUBLE;
strcpy(tag[nt], "HeatingPeLMRatioHalo");
addr[nt] = &All.HeatingPeLMRatioHalo;
id[nt++] = DOUBLE;
strcpy(tag[nt], "HeatingPeLMRatioDisk");
addr[nt] = &All.HeatingPeLMRatioDisk;
id[nt++] = DOUBLE;
strcpy(tag[nt], "HeatingPeLMRatioBulge");
addr[nt] = &All.HeatingPeLMRatioBulge;
id[nt++] = DOUBLE;
strcpy(tag[nt], "HeatingPeLMRatioStars");
addr[nt] = &All.HeatingPeLMRatioStars;
id[nt++] = DOUBLE;
strcpy(tag[nt], "HeatingPeLMRatioBndry");
addr[nt] = &All.HeatingPeLMRatioBndry;
id[nt++] = DOUBLE;
#endif
#ifdef EXTERNAL_FLUX
strcpy(tag[nt], "HeatingExternalFLuxEnergyDensity");
addr[nt] = &All.HeatingExternalFLuxEnergyDensity;
id[nt++] = DOUBLE;
#endif
#ifdef MULTIPHASE
strcpy(tag[nt], "CriticalTemperature");
addr[nt] = &All.CriticalTemperature;
id[nt++] = DOUBLE;
strcpy(tag[nt], "CriticalNonCollisionalTemperature");
addr[nt] = &All.CriticalNonCollisionalTemperature;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyUseGridForCollisions");
addr[nt] = &All.StickyUseGridForCollisions;
id[nt++] = INT;
strcpy(tag[nt], "StickyTime");
addr[nt] = &All.StickyTime;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyCollisionTime");
addr[nt] = &All.StickyCollisionTime;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyIdleTime");
addr[nt] = &All.StickyIdleTime;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyMinVelocity");
addr[nt] = &All.StickyMinVelocity;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyMaxVelocity");
addr[nt] = &All.StickyMaxVelocity;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyBetaR");
addr[nt] = &All.StickyBetaR;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyBetaT");
addr[nt] = &All.StickyBetaT;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyGridNx");
addr[nt] = &All.StickyGridNx;
id[nt++] = INT;
strcpy(tag[nt], "StickyGridNy");
addr[nt] = &All.StickyGridNy;
id[nt++] = INT;
strcpy(tag[nt], "StickyGridNz");
addr[nt] = &All.StickyGridNz;
id[nt++] = INT;
strcpy(tag[nt], "StickyGridXmin");
addr[nt] = &All.StickyGridXmin;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyGridXmax");
addr[nt] = &All.StickyGridXmax;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyGridYmin");
addr[nt] = &All.StickyGridYmin;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyGridYmax");
addr[nt] = &All.StickyGridYmax;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyGridZmin");
addr[nt] = &All.StickyGridZmin;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyGridZmax");
addr[nt] = &All.StickyGridZmax;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyDensity");
addr[nt] = &All.StickyDensity;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyDensityPower");
addr[nt] = &All.StickyDensityPower;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StickyRsphFact");
addr[nt] = &All.StickyRsphFact;
id[nt++] = DOUBLE;
#ifdef COLDGAS_CYCLE
strcpy(tag[nt], "ColdGasCycleTransitionTime");
addr[nt] = &All.ColdGasCycleTransitionTime;
id[nt++] = DOUBLE;
strcpy(tag[nt], "ColdGasCycleTransitionParameter");
addr[nt] = &All.ColdGasCycleTransitionParameter;
id[nt++] = DOUBLE;
#endif
#endif
#ifdef OUTERPOTENTIAL
#ifdef NFW
strcpy(tag[nt], "HaloConcentration");
addr[nt] = &All.HaloConcentration;
id[nt++] = DOUBLE;
strcpy(tag[nt], "HaloMass");
addr[nt] = &All.HaloMass;
id[nt++] = DOUBLE;
strcpy(tag[nt], "GasMassFraction");
addr[nt] = &All.GasMassFraction;
id[nt++] = DOUBLE;
#endif
#ifdef PLUMMER
strcpy(tag[nt], "PlummerMass");
addr[nt] = &All.PlummerMass;
id[nt++] = DOUBLE;
strcpy(tag[nt], "PlummerSoftenning");
addr[nt] = &All.PlummerSoftenning;
id[nt++] = DOUBLE;
#endif
#ifdef PISOTHERM
strcpy(tag[nt], "Rho0");
addr[nt] = &All.Rho0;
id[nt++] = DOUBLE;
strcpy(tag[nt], "Rc");
addr[nt] = &All.Rc;
id[nt++] = DOUBLE;
strcpy(tag[nt], "GasMassFraction");
addr[nt] = &All.GasMassFraction;
id[nt++] = DOUBLE;
#endif
#ifdef CORIOLIS
strcpy(tag[nt], "CoriolisOmegaX0");
addr[nt] = &All.CoriolisOmegaX0;
id[nt++] = DOUBLE;
strcpy(tag[nt], "CoriolisOmegaY0");
addr[nt] = &All.CoriolisOmegaY0;
id[nt++] = DOUBLE;
strcpy(tag[nt], "CoriolisOmegaZ0");
addr[nt] = &All.CoriolisOmegaZ0;
id[nt++] = DOUBLE;
#endif
#endif
#ifdef SFR
strcpy(tag[nt], "StarFormationNStarsFromGas");
addr[nt] = &All.StarFormationNStarsFromGas;
id[nt++] = INT;
strcpy(tag[nt], "StarFormationMgMsFraction");
addr[nt] = &All.StarFormationMgMsFraction;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StarFormationStarMass");
addr[nt] = &All.StarFormationStarMass;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StarFormationType");
addr[nt] = &All.StarFormationType;
id[nt++] = INT;
strcpy(tag[nt], "StarFormationCstar");
addr[nt] = &All.StarFormationCstar;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StarFormationTime");
addr[nt] = &All.StarFormationTime;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StarFormationDensity");
addr[nt] = &All.StarFormationDensity;
id[nt++] = DOUBLE;
strcpy(tag[nt], "StarFormationTemperature");
addr[nt] = &All.StarFormationTemperature;
id[nt++] = DOUBLE;
#endif
#ifdef FEEDBACK
strcpy(tag[nt], "SupernovaEgySpecPerMassUnit");
addr[nt] = &All.SupernovaEgySpecPerMassUnit;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SupernovaFractionInEgyKin");
addr[nt] = &All.SupernovaFractionInEgyKin;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SupernovaTime");
addr[nt] = &All.SupernovaTime;
id[nt++] = DOUBLE;
#endif
#ifdef FEEDBACK_WIND
strcpy(tag[nt], "SupernovaWindEgySpecPerMassUnit");
addr[nt] = &All.SupernovaWindEgySpecPerMassUnit;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SupernovaWindFractionInEgyKin");
addr[nt] = &All.SupernovaWindFractionInEgyKin;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SupernovaWindParameter");
addr[nt] = &All.SupernovaWindParameter;
id[nt++] = DOUBLE;
strcpy(tag[nt], "SupernovaWindIntAccuracy");
addr[nt] = &All.SupernovaWindIntAccuracy;
id[nt++] = DOUBLE;
#endif
#ifdef AGN_ACCRETION
strcpy(tag[nt], "TimeBetAccretion");
addr[nt] = &All.TimeBetAccretion;
id[nt++] = DOUBLE;
strcpy(tag[nt], "AccretionRadius");
addr[nt] = &All.AccretionRadius;
id[nt++] = DOUBLE;
strcpy(tag[nt], "AGNFactor");
addr[nt] = &All.AGNFactor;
id[nt++] = DOUBLE;
strcpy(tag[nt], "MinMTotInRa");
addr[nt] = &All.MinMTotInRa;
id[nt++] = DOUBLE;
#endif
#ifdef BUBBLES
strcpy(tag[nt], "BubblesDelta");
addr[nt] = &All.BubblesDelta;
id[nt++] = DOUBLE;
strcpy(tag[nt], "BubblesAlpha");
addr[nt] = &All.BubblesAlpha;
id[nt++] = DOUBLE;
strcpy(tag[nt], "BubblesRadiusFactor");
addr[nt] = &All.BubblesRadiusFactor;
id[nt++] = DOUBLE;
strcpy(tag[nt], "BubblesInitFile");
addr[nt] = All.BubblesInitFile;
id[nt++] = STRING;
#endif
#ifdef AGN_HEATING
strcpy(tag[nt], "AGNHeatingPower");
addr[nt] = &All.AGNHeatingPower;
id[nt++] = DOUBLE;
strcpy(tag[nt], "AGNHeatingRmax");
addr[nt] = &All.AGNHeatingRmax;
id[nt++] = DOUBLE;
#endif
#ifdef BONDI_ACCRETION
strcpy(tag[nt], "BondiEfficiency");
addr[nt] = &All.BondiEfficiency;
id[nt++] = DOUBLE;
strcpy(tag[nt], "BondiBlackHoleMass");
addr[nt] = &All.BondiBlackHoleMass;
id[nt++] = DOUBLE;
strcpy(tag[nt], "BondiHsmlFactor");
addr[nt] = &All.BondiHsmlFactor;
id[nt++] = DOUBLE;
strcpy(tag[nt], "BondiTimeBet");
addr[nt] = &All.BondiTimeBet;
id[nt++] = DOUBLE;
#endif
if((fd = fopen(fname, "r")))
{
sprintf(buf, "%s%s", fname, "-usedvalues");
if(!(fdout = fopen(buf, "w")))
{
printf("error opening file '%s' \n", buf);
errorFlag = 1;
}
else
{
while(!feof(fd))
{
*buf = 0;
fgets(buf, 200, fd);
if(sscanf(buf, "%s%s%s", buf1, buf2, buf3) < 2)
continue;
if(buf1[0] == '%')
continue;
for(i = 0, j = -1; i < nt; i++)
if(strcmp(buf1, tag[i]) == 0)
{
j = i;
tag[i][0] = 0;
break;
}
if(j >= 0)
{
switch (id[j])
{
case DOUBLE:
*((double *) addr[j]) = atof(buf2);
fprintf(fdout, "%-35s%g\n", buf1, *((double *) addr[j]));
break;
case STRING:
strcpy(addr[j], buf2);
fprintf(fdout, "%-35s%s\n", buf1, buf2);
break;
case INT:
*((int *) addr[j]) = atoi(buf2);
fprintf(fdout, "%-35s%d\n", buf1, *((int *) addr[j]));
break;
}
}
else
{
fprintf(stdout, "Error in file %s: Tag '%s' not allowed or multiple defined.\n",
fname, buf1);
errorFlag = 1;
}
}
fclose(fd);
fclose(fdout);
i = strlen(All.OutputDir);
if(i > 0)
if(All.OutputDir[i - 1] != '/')
strcat(All.OutputDir, "/");
/* copy parameters-usedvalues file*/
sprintf(buf1, "%s%s", fname, "-usedvalues");
sprintf(buf2, "%s%s", All.OutputDir, "parameters-usedvalues");
fd = fopen(buf1,"r");
fdout = fopen(buf2,"w");
while(1)
{
fgets(buf, 200, fd);
if (feof(fd)) break;
fprintf(fdout, buf, 200);
}
fclose(fd);
fclose(fdout);
}
}
else
{
printf("\nParameter file %s not found.\n\n", fname);
errorFlag = 2;
}
if(errorFlag != 2)
for(i = 0; i < nt; i++)
{
if(*tag[i])
{
printf("Error. I miss a value for tag '%s' in parameter file '%s'.\n", tag[i], fname);
errorFlag = 1;
}
}
if(All.OutputListOn && errorFlag == 0)
errorFlag += read_outputlist(All.OutputListFilename);
else
All.OutputListLength = 0;
}
MPI_Bcast(&errorFlag, 1, MPI_INT, 0, MPI_COMM_WORLD);
if(errorFlag)
{
MPI_Finalize();
exit(0);
}
/* now communicate the relevant parameters to the other processes */
MPI_Bcast(&All, sizeof(struct global_data_all_processes), MPI_BYTE, 0, MPI_COMM_WORLD);
if(All.NumFilesWrittenInParallel < 1)
{
if(ThisTask == 0)
printf("NumFilesWrittenInParallel MUST be at least 1\n");
endrun(0);
}
if(All.NumFilesWrittenInParallel > NTask)
{
if(ThisTask == 0)
printf("NumFilesWrittenInParallel MUST be smaller than number of processors\n");
endrun(0);
}
#ifdef PERIODIC
if(All.PeriodicBoundariesOn == 0)
{
if(ThisTask == 0)
{
printf("Code was compiled with periodic boundary conditions switched on.\n");
printf("You must set `PeriodicBoundariesOn=1', or recompile the code.\n");
}
endrun(0);
}
#else
if(All.PeriodicBoundariesOn == 1)
{
if(ThisTask == 0)
{
printf("Code was compiled with periodic boundary conditions switched off.\n");
printf("You must set `PeriodicBoundariesOn=0', or recompile the code.\n");
}
endrun(0);
}
#endif
if(All.TypeOfTimestepCriterion >= 1)
{
if(ThisTask == 0)
{
printf("The specified timestep criterion\n");
printf("is not valid\n");
}
endrun(0);
}
#if defined(LONG_X) || defined(LONG_Y) || defined(LONG_Z)
#ifndef NOGRAVITY
if(ThisTask == 0)
{
printf("Code was compiled with LONG_X/Y/Z, but not with NOGRAVITY.\n");
printf("Stretched periodic boxes are not implemented for gravity yet.\n");
}
endrun(0);
#endif
#endif
#undef DOUBLE
#undef STRING
#undef INT
#undef MAXTAGS
}
/*! this function reads a table with a list of desired output times. The
* table does not have to be ordered in any way, but may not contain more
* than MAXLEN_OUTPUTLIST entries.
*/
int read_outputlist(char *fname)
{
FILE *fd;
if(!(fd = fopen(fname, "r")))
{
printf("can't read output list in file '%s'\n", fname);
return 1;
}
All.OutputListLength = 0;
do
{
if(fscanf(fd, " %lg ", &All.OutputListTimes[All.OutputListLength]) == 1)
All.OutputListLength++;
else
break;
}
while(All.OutputListLength < MAXLEN_OUTPUTLIST);
fclose(fd);
printf("\nfound %d times in output-list.\n", All.OutputListLength);
return 0;
}
/*! If a restart from restart-files is carried out where the TimeMax
* variable is increased, then the integer timeline needs to be
* adjusted. The approach taken here is to reduce the resolution of the
* integer timeline by factors of 2 until the new final time can be
* reached within TIMEBASE.
*/
void readjust_timebase(double TimeMax_old, double TimeMax_new)
{
int i;
long long ti_end;
if(ThisTask == 0)
{
printf("\nAll.TimeMax has been changed in the parameterfile\n");
printf("Need to adjust integer timeline\n\n\n");
}
if(TimeMax_new < TimeMax_old)
{
if(ThisTask == 0)
printf("\nIt is not allowed to reduce All.TimeMax\n\n");
endrun(556);
}
if(All.ComovingIntegrationOn)
ti_end = log(TimeMax_new / All.TimeBegin) / All.Timebase_interval;
else
ti_end = (TimeMax_new - All.TimeBegin) / All.Timebase_interval;
while(ti_end > TIMEBASE)
{
All.Timebase_interval *= 2.0;
ti_end /= 2;
All.Ti_Current /= 2;
#ifdef PMGRID
All.PM_Ti_begstep /= 2;
All.PM_Ti_endstep /= 2;
#endif
for(i = 0; i < NumPart; i++)
{
P[i].Ti_begstep /= 2;
P[i].Ti_endstep /= 2;
}
}
All.TimeMax = TimeMax_new;
}
diff --git a/chimie.c b/chimie.c
index d72d012..0d71093 100644
--- a/chimie.c
+++ b/chimie.c
@@ -1,2470 +1,2556 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <mpi.h>
#include <gsl/gsl_math.h>
#include "allvars.h"
#include "proto.h"
#ifdef CHIMIE
/*! \file hydra.c
* \brief 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.
*/
static double hubble_a, atime, hubble_a2, fac_mu, fac_vsic_fix, a3inv, fac_egy;
#ifdef FEEDBACK
static double fac_pow;
#endif
#ifdef PERIODIC
static double boxSize, boxHalf;
#ifdef LONG_X
static double boxSize_X, boxHalf_X;
#else
#define boxSize_X boxSize
#define boxHalf_X boxHalf
#endif
#ifdef LONG_Y
static double boxSize_Y, boxHalf_Y;
#else
#define boxSize_Y boxSize
#define boxHalf_Y boxHalf
#endif
#ifdef LONG_Z
static double boxSize_Z, boxHalf_Z;
#else
#define boxSize_Z boxSize
#define boxHalf_Z boxHalf
#endif
#endif
/****************************************************************************************/
/*
/*
/*
/* GADGET CHIMIE PART
/*
/*
/*
/****************************************************************************************/
#define MAXPTS 10
#define MAXDATASIZE 200
#define KPC_IN_CM 3.085e+21
static int verbose=0;
static double *MassFracSNII;
static double *SingleMassFracSNII;
static double *EjectedMass;
static double *SingleEjectedMass;
-
+static double **MassFracSNIIs;
+static double **SingleMassFracSNIIs;
+static double **EjectedMasss;
+static double **SingleEjectedMasss;
/* intern global variables */
static struct local_params_chimie
{
float coeff_z[3][3];
float Mmin,Mmax;
int n;
float ms[MAXPTS];
float as[MAXPTS+1];
float bs[MAXPTS+1];
float fs[MAXPTS];
double imf_Ntot;
float SNII_Mmin;
float SNII_Mmax;
float SNII_cte;
float SNII_a;
float SNIa_Mpl;
float SNIa_Mpu;
float SNIa_a;
float SNIa_cte;
float SNIa_Mdl1;
float SNIa_Mdu1;
float SNIa_a1;
float SNIa_b1;
float SNIa_cte1;
float SNIa_bb1;
float SNIa_Mdl2;
float SNIa_Mdu2;
float SNIa_a2;
float SNIa_b2;
float SNIa_cte2;
float SNIa_bb2;
float Mco;
int npts;
int nelts;
}
- Cp;
+ *Cps,*Cp;
static struct local_elts_chimie
{
float Mmin; /* minimal mass */
float Step; /* log of mass step */
float Array[MAXDATASIZE]; /* data */
float Metal[MAXDATASIZE]; /* data */
float MSNIa;
float SolarAbundance;
char label[72];
}
- *Elt;
+ **Elts,*Elt;
+
+
+void allocate_chimie()
+ {
+
+ int j;
+
+ /* allocate Cp */
+ Cps = malloc((All.ChimieNumberOfParameterFiles) * sizeof(struct local_params_chimie));
+
+ /* allocate elts */
+ Elts = malloc((All.ChimieNumberOfParameterFiles) * sizeof(struct local_elts_chimie));
+ //for (j=0;j<All.ChimieNumberOfParameterFiles;j++)
+ // Elt[j] = malloc((nelts) * sizeof(struct local_elts_chimie));
+
+
+ MassFracSNIIs = malloc((All.ChimieNumberOfParameterFiles) * sizeof(double));
+ EjectedMasss = malloc((All.ChimieNumberOfParameterFiles) * sizeof(double));
+ SingleMassFracSNIIs= malloc((All.ChimieNumberOfParameterFiles) * sizeof(double));
+ SingleEjectedMasss = malloc((All.ChimieNumberOfParameterFiles) * sizeof(double));
+
+ }
+
+
+void set_table(int i)
+ {
+
+ if (i>=All.ChimieNumberOfParameterFiles)
+ {
+ printf("\n set_table : i>= %d !!!\n\n",All.ChimieNumberOfParameterFiles);
+ endrun(88809);
+ }
+ else
+ {
+ Cp = &Cps[i];
+ Elt = Elts[i];
+ MassFracSNII = MassFracSNIIs[i];
+ SingleMassFracSNII = SingleMassFracSNIIs[i];
+ EjectedMass = EjectedMasss[i];
+ SingleEjectedMass = SingleEjectedMasss[i];
+
+
+ }
+
+ }
-void read_chimie()
+void read_chimie(char * filename,int it)
{
char line[72];
FILE *fd;
int i,j;
-
- fd = fopen(All.ChimieParameterFile,"r");
+
+ printf("reading %s ...\n",filename);
+ fd = fopen(filename,"r");
/* read Lifetime */
fgets(line, sizeof(line), fd);
fgets(line, sizeof(line), fd);
- fscanf(fd, "%g %g %g\n", &Cp.coeff_z[0][0],&Cp.coeff_z[0][1],&Cp.coeff_z[0][2]);
- fscanf(fd, "%g %g %g\n", &Cp.coeff_z[1][0],&Cp.coeff_z[1][1],&Cp.coeff_z[1][2]);
- fscanf(fd, "%g %g %g\n", &Cp.coeff_z[2][0],&Cp.coeff_z[2][1],&Cp.coeff_z[2][2]);
+ fscanf(fd, "%g %g %g\n", &Cps[it].coeff_z[0][0],&Cps[it].coeff_z[0][1],&Cps[it].coeff_z[0][2]);
+ fscanf(fd, "%g %g %g\n", &Cps[it].coeff_z[1][0],&Cps[it].coeff_z[1][1],&Cps[it].coeff_z[1][2]);
+ fscanf(fd, "%g %g %g\n", &Cps[it].coeff_z[2][0],&Cps[it].coeff_z[2][1],&Cps[it].coeff_z[2][2]);
fgets(line, sizeof(line), fd);
/* IMF Parameters */
fgets(line, sizeof(line), fd);
- fscanf(fd, "%g %g\n",&Cp.Mmin,&Cp.Mmax);
- fscanf(fd, "%d\n",&Cp.n);
+ fscanf(fd, "%g %g\n",&Cps[it].Mmin,&Cps[it].Mmax);
+ fscanf(fd, "%d\n",&Cps[it].n);
- if (Cp.n>0)
- for (i=0;i<Cp.n;i++)
- fscanf(fd,"%g",&Cp.ms[i]);
+ if (Cps[it].n>0)
+ for (i=0;i<Cps[it].n;i++)
+ fscanf(fd,"%g",&Cps[it].ms[i]);
else
fgets(line, sizeof(line), fd);
- for (i=0;i<Cp.n+1;i++)
- fscanf(fd,"%g",&Cp.as[i]);
+ for (i=0;i<Cps[it].n+1;i++)
+ fscanf(fd,"%g",&Cps[it].as[i]);
fgets(line, sizeof(line), fd);
/* Parameters for SNII Rates */
fgets(line, sizeof(line), fd);
fgets(line, sizeof(line), fd);
- fscanf(fd, "%g \n",&Cp.SNII_Mmin);
+ fscanf(fd, "%g \n",&Cps[it].SNII_Mmin);
fgets(line, sizeof(line), fd);
/* Parameters for SNIa Rates */
fgets(line, sizeof(line), fd);
- fscanf(fd, "%g %g\n",&Cp.SNIa_Mpl,&Cp.SNIa_Mpu);
- fscanf(fd, "%g \n",&Cp.SNIa_a);
- fscanf(fd, "%g %g %g\n",&Cp.SNIa_Mdl1,&Cp.SNIa_Mdu1,&Cp.SNIa_bb1);
- fscanf(fd, "%g %g %g\n",&Cp.SNIa_Mdl2,&Cp.SNIa_Mdu2,&Cp.SNIa_bb2);
+ fscanf(fd, "%g %g\n",&Cps[it].SNIa_Mpl,&Cps[it].SNIa_Mpu);
+ fscanf(fd, "%g \n",&Cps[it].SNIa_a);
+ fscanf(fd, "%g %g %g\n",&Cps[it].SNIa_Mdl1,&Cps[it].SNIa_Mdu1,&Cps[it].SNIa_bb1);
+ fscanf(fd, "%g %g %g\n",&Cps[it].SNIa_Mdl2,&Cps[it].SNIa_Mdu2,&Cps[it].SNIa_bb2);
fgets(line, sizeof(line), fd);
/* Metal injection SNII */
fgets(line, sizeof(line), fd);
fgets(line, sizeof(line), fd);
- fscanf(fd, "%d %d\n",&Cp.npts,&Cp.nelts);
+ fscanf(fd, "%d %d\n",&Cps[it].npts,&Cps[it].nelts);
/* allocate memory for elts */
- if (Cp.npts<=MAXDATASIZE)
+ if (Cps[it].npts<=MAXDATASIZE)
{
- Elt = malloc((Cp.nelts+2) * sizeof(struct local_elts_chimie));
+ Elts[it] = malloc((Cps[it].nelts+2) * sizeof(struct local_elts_chimie));
}
else
{
- printf("\n Cp.npts = %d > MAXDATASIZE = %d !!!\n\n",Cp.npts,MAXDATASIZE);
+ printf("\n Cps[it].npts = %d > MAXDATASIZE = %d !!!\n\n",Cps[it].npts,MAXDATASIZE);
endrun(88800);
}
+
+ /* allocate memory */
+ MassFracSNIIs[it] = malloc((Cps[it].nelts+2) * sizeof(double));
+ EjectedMasss[it] = malloc((Cps[it].nelts+2) * sizeof(double));
+ SingleMassFracSNIIs[it] = malloc((Cps[it].nelts+2) * sizeof(double));
+ SingleEjectedMasss[it] = malloc((Cps[it].nelts+2) * sizeof(double));
+
+
+
+
/* injected metals */
- for (i=0;i<Cp.nelts+2;i++)
+ for (i=0;i<Cps[it].nelts+2;i++)
{
fgets(line, sizeof(line), fd);
/* strip trailing line */
for (j = 0; j < strlen(line); j++)
if ( line[j] == '\n' || line[j] == '\r' )
line[j] = '\0';
/* copy labels */
- strcpy(Elt[i].label,line);
- strcpy(Elt[i].label,&Elt[i].label[2]);
+ strcpy(Elts[it][i].label,line);
+ strcpy(Elts[it][i].label,&Elts[it][i].label[2]);
fgets(line, sizeof(line), fd);
- fscanf(fd, "%g %g\n",&Elt[i].Mmin,&Elt[i].Step);
+ fscanf(fd, "%g %g\n",&Elts[it][i].Mmin,&Elts[it][i].Step);
- for (j=0;j<Cp.npts;j++)
+ for (j=0;j<Cps[it].npts;j++)
{
- fscanf(fd, "%g\n",&Elt[i].Metal[j]);
+ fscanf(fd, "%g\n",&Elts[it][i].Metal[j]);
}
}
/* integrals of injected metals */
fgets(line, sizeof(line), fd);
fgets(line, sizeof(line), fd);
- fscanf(fd, "%d %d\n",&Cp.npts,&Cp.nelts);
+ fscanf(fd, "%d %d\n",&Cps[it].npts,&Cps[it].nelts);
fgets(line, sizeof(line), fd);
fgets(line, sizeof(line), fd);
/* integrals of injected metals */
- for (i=0;i<Cp.nelts+2;i++)
+ for (i=0;i<Cps[it].nelts+2;i++)
{
fgets(line, sizeof(line), fd);
fgets(line, sizeof(line), fd);
- fscanf(fd, "%g %g\n",&Elt[i].Mmin,&Elt[i].Step);
+ fscanf(fd, "%g %g\n",&Elts[it][i].Mmin,&Elts[it][i].Step);
- for (j=0;j<Cp.npts;j++)
+ for (j=0;j<Cps[it].npts;j++)
{
- fscanf(fd, "%g\n",&Elt[i].Array[j]);
+ fscanf(fd, "%g\n",&Elts[it][i].Array[j]);
}
}
/* Metal injection SNIa */
fgets(line, sizeof(line), fd);
fgets(line, sizeof(line), fd);
- fscanf(fd, "%g\n",&Cp.Mco);
+ fscanf(fd, "%g\n",&Cps[it].Mco);
fgets(line, sizeof(line), fd);
fgets(line, sizeof(line), fd);
fgets(line, sizeof(line), fd);
int nelts;
char label[72];
fscanf(fd, "%d\n",&nelts);
/* check */
- if (nelts != Cp.nelts)
+ if (nelts != Cps[it].nelts)
{
- printf("\nThe number of elements in SNII (=%d) is not identical to the on of SNIa (=%d) !!!\n\n",Cp.nelts,nelts);
+ printf("\nThe number of elements in SNII (=%d) is not identical to the on of SNIa (=%d) !!!\n\n",Cps[it].nelts,nelts);
printf("This is not supported by the current implementation !!!\n");
endrun(88805);
}
- for (i=0;i<Cp.nelts+2;i++)
+ for (i=0;i<Cps[it].nelts+2;i++)
{
fgets(line, sizeof(line), fd); /* label */
/* check label */
/* strip trailing line */
for (j = 0; j < strlen(line); j++)
if ( line[j] == '\n' || line[j] == '\r' )
line[j] = '\0';
strcpy(label,line);
strcpy(label,&label[2]);
- if (strcmp(label,Elt[i].label)!=0)
+ if (strcmp(label,Elts[it][i].label)!=0)
{
- printf("\nLabel of SNII element %d (=%s) is different from the SNIa one (=%s) !!!\n\n",i,Elt[i].label,label);
+ printf("\nLabel of SNII element %d (=%s) is different from the SNIa one (=%s) !!!\n\n",i,Elts[it][i].label,label);
endrun(88806);
}
//fgets(line, sizeof(line), fd);
- fscanf(fd, "%g\n",&Elt[i].MSNIa);
+ fscanf(fd, "%g\n",&Elts[it][i].MSNIa);
}
/* Solar Abundances */
fgets(line, sizeof(line), fd);
fgets(line, sizeof(line), fd);
fgets(line, sizeof(line), fd);
fgets(line, sizeof(line), fd);
fscanf(fd, "%d\n",&nelts);
/* check */
- if (nelts != Cp.nelts)
+ if (nelts != Cps[it].nelts)
{
- printf("\nThe number of elements in SolarAbundances (=%d) is not identical to the on of SNIa (=%d) !!!\n\n",Cp.nelts,nelts);
+ printf("\nThe number of elements in SolarAbundances (=%d) is not identical to the on of SNIa (=%d) !!!\n\n",Cps[it].nelts,nelts);
printf("This is not supported by the current implementation !!!\n");
endrun(88805);
}
- for (i=0;i<Cp.nelts;i++)
+ for (i=0;i<Cps[it].nelts;i++)
{
fgets(line, sizeof(line), fd); /* label */
/* check label */
/* strip trailing line */
for (j = 0; j < strlen(line); j++)
if ( line[j] == '\n' || line[j] == '\r' )
line[j] = '\0';
strcpy(label,line);
strcpy(label,&label[2]);
- if (strcmp(label,Elt[i+2].label)!=0)
+ if (strcmp(label,Elts[it][i+2].label)!=0)
{
- printf("\nLabel of SNII element %d (=%s) is different from the SNIa one (=%s) !!!\n\n",i,Elt[i+2].label,label);
+ printf("\nLabel of SNII element %d (=%s) is different from the SNIa one (=%s) !!!\n\n",i,Elts[it][i+2].label,label);
endrun(88806);
}
//fgets(line, sizeof(line), fd);
- fscanf(fd, "%g\n",&Elt[i+2].SolarAbundance);
+ fscanf(fd, "%g\n",&Elts[it][i+2].SolarAbundance);
}
fclose(fd);
-
-
+
if (verbose && ThisTask==0)
{
- printf("%g %g %g\n", Cp.coeff_z[0][0],Cp.coeff_z[0][1],Cp.coeff_z[0][2]);
- printf("%g %g %g\n", Cp.coeff_z[1][0],Cp.coeff_z[1][1],Cp.coeff_z[1][2]);
- printf("%g %g %g\n", Cp.coeff_z[2][0],Cp.coeff_z[2][1],Cp.coeff_z[2][2]);
+ printf("%g %g %g\n", Cps[it].coeff_z[0][0],Cps[it].coeff_z[0][1],Cps[it].coeff_z[0][2]);
+ printf("%g %g %g\n", Cps[it].coeff_z[1][0],Cps[it].coeff_z[1][1],Cps[it].coeff_z[1][2]);
+ printf("%g %g %g\n", Cps[it].coeff_z[2][0],Cps[it].coeff_z[2][1],Cps[it].coeff_z[2][2]);
printf("\n");
printf("\nIMF\n");
- printf("%g %g\n",Cp.Mmin,Cp.Mmax);
- printf("%d\n",Cp.n);
- for (i=0;i<Cp.n;i++)
- printf( "ms : %g ",Cp.ms[i]);
+ printf("%g %g\n",Cps[it].Mmin,Cps[it].Mmax);
+ printf("%d\n",Cps[it].n);
+ for (i=0;i<Cps[it].n;i++)
+ printf( "ms : %g ",Cps[it].ms[i]);
printf("\n");
- for (i=0;i<Cp.n+1;i++)
- printf( "as : %g ",Cp.as[i]);
+ for (i=0;i<Cps[it].n+1;i++)
+ printf( "as : %g ",Cps[it].as[i]);
printf("\n");
printf("\nRate SNII\n");
- printf("%g ",Cp.SNII_Mmin);
+ printf("%g ",Cps[it].SNII_Mmin);
printf("\n");
printf("\nRate SNIa\n");
- printf("%g %g\n",Cp.SNIa_Mpl,Cp.SNIa_Mpu);
- printf("%g \n",Cp.SNIa_a);
- printf("%g %g %g\n",Cp.SNIa_Mdl1,Cp.SNIa_Mdu1,Cp.SNIa_b1);
- printf("%g %g %g\n",Cp.SNIa_Mdl2,Cp.SNIa_Mdu2,Cp.SNIa_b2);
+ printf("%g %g\n",Cps[it].SNIa_Mpl,Cps[it].SNIa_Mpu);
+ printf("%g \n",Cps[it].SNIa_a);
+ printf("%g %g %g\n",Cps[it].SNIa_Mdl1,Cps[it].SNIa_Mdu1,Cps[it].SNIa_b1);
+ printf("%g %g %g\n",Cps[it].SNIa_Mdl2,Cps[it].SNIa_Mdu2,Cps[it].SNIa_b2);
printf("\n");
- for (i=0;i<Cp.nelts+2;i++)
+ for (i=0;i<Cps[it].nelts+2;i++)
{
- printf("> %g %g\n",Elt[i].Mmin,Elt[i].Step);
+ printf("> %g %g\n",Elts[it][i].Mmin,Elts[it][i].Step);
- for (j=0;j<Cp.npts;j++)
+ for (j=0;j<Cps[it].npts;j++)
{
- printf(" %g\n",Elt[i].Array[j]);
+ printf(" %g\n",Elts[it][i].Array[j]);
}
}
printf("\n");
- printf("%g\n",Cp.Mco);
- for (i=0;i<Cp.nelts+2;i++)
- printf("%g\n",Elt[i].MSNIa);
+ printf("%g\n",Cps[it].Mco);
+ for (i=0;i<Cps[it].nelts+2;i++)
+ printf("%g\n",Elts[it][i].MSNIa);
printf("\n");
}
}
/*
This function returns the mass fraction of a star of mass m
using the current IMF
*/
-static float get_imf(double m)
+static double get_imf(double m)
{
int i;
int n;
- n = Cp.n;
+ n = Cp->n;
/* convert m in msol */
m = m*All.UnitMass_in_g / SOLAR_MASS;
-
if (n==0)
- return Cp.bs[0]* pow(m,Cp.as[0]);
- else
- {
-
- for (i=0;i<n;i++)
- if (m < Cp.ms[i])
- return Cp.bs[i]* pow(m,Cp.as[i]);
-
- return Cp.bs[n-1]* pow(m,Cp.as[n-1]);
-
- }
+ return Cp->bs[0]* pow(m,Cp->as[0]);
+ else
+ {
+ for (i=0;i<n;i++)
+ if (m < Cp->ms[i])
+ return Cp->bs[i]* pow(m,Cp->as[i]);
+
+ return Cp->bs[n]* pow(m,Cp->as[n]);
+ }
}
/*
This function returns the mass fraction between m1 and m2
per mass unit, using the current IMF
*/
static double get_imf_M(double m1, double m2)
{
int i;
int n;
double p;
double integral=0;
double mmin,mmax;
- n = Cp.n;
+ n = Cp->n;
/* convert m in msol */
m1 = m1*All.UnitMass_in_g / SOLAR_MASS;
m2 = m2*All.UnitMass_in_g / SOLAR_MASS;
if (n==0)
{
- p = Cp.as[0]+1;
- integral = (Cp.bs[0]/p) * ( pow(m2,p) - pow(m1,p) );
+ p = Cp->as[0]+1;
+ integral = (Cp->bs[0]/p) * ( pow(m2,p) - pow(m1,p) );
+ //printf("--> %g %g %g %g int=%g\n",m1,m2,pow(m2,p), pow(m1,p),integral);
}
else
{
integral = 0;
/* first */
- if (m1<Cp.ms[0])
+ if (m1<Cp->ms[0])
{
mmin = m1;
- mmax = dmin(Cp.ms[0],m2);
- p = Cp.as[0] + 1;
- integral += (Cp.bs[0]/p) * ( pow(mmax,p) - pow(mmin,p) );
+ mmax = dmin(Cp->ms[0],m2);
+ p = Cp->as[0] + 1;
+ integral += (Cp->bs[0]/p) * ( pow(mmax,p) - pow(mmin,p) );
}
/* last */
- if (m2>Cp.ms[n-1])
+ if (m2>Cp->ms[n-1])
{
- mmin = dmax(Cp.ms[n-1],m1);
+ mmin = dmax(Cp->ms[n-1],m1);
mmax = m2;
- p = Cp.as[n] + 1;
- integral += (Cp.bs[n]/p) * ( pow(mmax,p) - pow(mmin,p) );
+ p = Cp->as[n] + 1;
+ integral += (Cp->bs[n]/p) * ( pow(mmax,p) - pow(mmin,p) );
}
/* loop over other segments */
for (i=0;i<n-1;i++)
{
- mmin = dmax(Cp.ms[i ],m1);
- mmax = dmin(Cp.ms[i+1],m2);
+ mmin = dmax(Cp->ms[i ],m1);
+ mmax = dmin(Cp->ms[i+1],m2);
if (mmin<mmax)
{
- p = Cp.as[i+1] + 1;
- integral += (Cp.bs[i+1]/p) * ( pow(mmax,p) - pow(mmin,p) );
+ p = Cp->as[i+1] + 1;
+ integral += (Cp->bs[i+1]/p) * ( pow(mmax,p) - pow(mmin,p) );
}
}
}
/* convert into mass unit mass unit */
/* integral = integral * SOLAR_MASS/All.UnitMass_in_g;*/
return integral;
}
/*
This function returns the number fraction between m1 and m2
per mass unit, using the current IMF
*/
static double get_imf_N(double m1, double m2)
{
int i;
int n;
double p;
double integral=0;
double mmin,mmax;
- n = Cp.n;
+ n = Cp->n;
/* convert m in msol */
m1 = m1*All.UnitMass_in_g / SOLAR_MASS;
m2 = m2*All.UnitMass_in_g / SOLAR_MASS;
if (n==0)
{
- p = Cp.as[0];
- integral = (Cp.bs[0]/p) * ( pow(m2,p) - pow(m1,p) );
+ p = Cp->as[0];
+ integral = (Cp->bs[0]/p) * ( pow(m2,p) - pow(m1,p) );
}
else
{
integral = 0;
/* first */
- if (m1<Cp.ms[0])
+ if (m1<Cp->ms[0])
{
mmin = m1;
- mmax = dmin(Cp.ms[0],m2);
- p = Cp.as[0];
- integral += (Cp.bs[0]/p) * ( pow(mmax,p) - pow(mmin,p) );
+ mmax = dmin(Cp->ms[0],m2);
+ p = Cp->as[0];
+ integral += (Cp->bs[0]/p) * ( pow(mmax,p) - pow(mmin,p) );
}
/* last */
- if (m2>Cp.ms[n-1])
+ if (m2>Cp->ms[n-1])
{
- mmin = dmax(Cp.ms[n-1],m1);
+ mmin = dmax(Cp->ms[n-1],m1);
mmax = m2;
- p = Cp.as[n];
- integral += (Cp.bs[n]/p) * ( pow(mmax,p) - pow(mmin,p) );
+ p = Cp->as[n];
+ integral += (Cp->bs[n]/p) * ( pow(mmax,p) - pow(mmin,p) );
}
/* loop over other segments */
for (i=0;i<n-1;i++)
{
- mmin = dmax(Cp.ms[i ],m1);
- mmax = dmin(Cp.ms[i+1],m2);
+ mmin = dmax(Cp->ms[i ],m1);
+ mmax = dmin(Cp->ms[i+1],m2);
if (mmin<mmax)
{
- p = Cp.as[i+1];
- integral += (Cp.bs[i+1]/p) * ( pow(mmax,p) - pow(mmin,p) );
+ p = Cp->as[i+1];
+ integral += (Cp->bs[i+1]/p) * ( pow(mmax,p) - pow(mmin,p) );
}
}
}
/* convert into mass unit mass unit */
integral = integral / SOLAR_MASS*All.UnitMass_in_g;
return integral;
}
/*
This function returns the number fraction between m1 and m2
per mass unit, using the current IMF
*/
static double imf_sampling()
{
int i;
int n;
double m;
double f;
double pmin,pmax;
- n = Cp.n;
+ n = Cp->n;
/* init random */
//srandom(irand);
f = (double)random()/(double)RAND_MAX;
if (n==0)
{
- pmin = pow(Cp.Mmin,Cp.as[0]);
- pmax = pow(Cp.Mmax,Cp.as[0]);
- m = pow(f*(pmax - pmin) + pmin ,1./Cp.as[0]);
+ pmin = pow(Cp->Mmin,Cp->as[0]);
+ pmax = pow(Cp->Mmax,Cp->as[0]);
+ m = pow(f*(pmax - pmin) + pmin ,1./Cp->as[0]);
return m* SOLAR_MASS/All.UnitMass_in_g;
}
else
{
- if (f<Cp.fs[0])
+ if (f<Cp->fs[0])
{
- pmin = pow(Cp.Mmin ,Cp.as[0]);
- m = pow(Cp.imf_Ntot*Cp.as[0]/Cp.bs[0]* (f-0) + pmin ,1./Cp.as[0]);
+ pmin = pow(Cp->Mmin ,Cp->as[0]);
+ m = pow(Cp->imf_Ntot*Cp->as[0]/Cp->bs[0]* (f-0) + pmin ,1./Cp->as[0]);
return m* SOLAR_MASS/All.UnitMass_in_g;
}
for (i=0;i<n-1;i++)
{
- if (f<Cp.fs[i+1])
+ if (f<Cp->fs[i+1])
{
- pmin = pow(Cp.ms[i] ,Cp.as[i+1]);
- m = pow(Cp.imf_Ntot*Cp.as[i+1]/Cp.bs[i+1]* (f-Cp.fs[i]) + pmin ,1./Cp.as[i+1]);
+ pmin = pow(Cp->ms[i] ,Cp->as[i+1]);
+ m = pow(Cp->imf_Ntot*Cp->as[i+1]/Cp->bs[i+1]* (f-Cp->fs[i]) + pmin ,1./Cp->as[i+1]);
return m* SOLAR_MASS/All.UnitMass_in_g;
}
}
/* last portion */
- pmin = pow(Cp.ms[n-1] ,Cp.as[n]);
- m = pow(Cp.imf_Ntot*Cp.as[n]/Cp.bs[n]* (f-Cp.fs[n-1]) + pmin ,1./Cp.as[n]);
+ pmin = pow(Cp->ms[n-1] ,Cp->as[n]);
+ m = pow(Cp->imf_Ntot*Cp->as[n]/Cp->bs[n]* (f-Cp->fs[n-1]) + pmin ,1./Cp->as[n]);
return m* SOLAR_MASS/All.UnitMass_in_g;
}
}
/*
This function initialized the imf parameters
defined in the chimie file
*/
void init_imf(void)
{
float integral = 0;
float p;
float cte;
int i,n;
double mmin,mmax;
- n = Cp.n;
+ n = Cp->n;
if (n==0)
{
- p = Cp.as[0]+1;
- integral = integral + ( pow(Cp.Mmax,p)-pow(Cp.Mmin,p))/(p) ;
- Cp.bs[0] = 1./integral ;
+ p = Cp->as[0]+1;
+ integral = integral + ( pow(Cp->Mmax,p)-pow(Cp->Mmin,p))/(p) ;
+ Cp->bs[0] = 1./integral ;
}
else
{
cte = 1.0;
- if (Cp.Mmin < Cp.ms[0])
+ if (Cp->Mmin < Cp->ms[0])
{
- p = Cp.as[0]+1;
- integral = integral + (pow(Cp.ms[0],p) - pow(Cp.Mmin,p))/p;
+ p = Cp->as[0]+1;
+ integral = integral + (pow(Cp->ms[0],p) - pow(Cp->Mmin,p))/p;
}
for (i=0;i<n-1;i++)
{
- cte = cte* pow( Cp.ms[i],( Cp.as[i] - Cp.as[i+1] ));
- p = Cp.as[i+1]+1;
- integral = integral + cte*(pow(Cp.ms[i+1],p) - pow(Cp.ms[i],p))/p;
+ cte = cte* pow( Cp->ms[i],( Cp->as[i] - Cp->as[i+1] ));
+ p = Cp->as[i+1]+1;
+ integral = integral + cte*(pow(Cp->ms[i+1],p) - pow(Cp->ms[i],p))/p;
}
- if (Cp.Mmax > Cp.ms[-1])
+ if (Cp->Mmax > Cp->ms[-1])
{
- cte = cte* pow( Cp.ms[n-1] , ( Cp.as[n-1] - Cp.as[n] ) );
- p = Cp.as[n]+1;
- integral = integral + cte*(pow(Cp.Mmax,p) - pow(Cp.ms[n-1],p))/p;
+ cte = cte* pow( Cp->ms[n-1] , ( Cp->as[n-1] - Cp->as[n] ) );
+ p = Cp->as[n]+1;
+ integral = integral + cte*(pow(Cp->Mmax,p) - pow(Cp->ms[n-1],p))/p;
}
/* compute all b */
- Cp.bs[0] = 1./integral;
+ Cp->bs[0] = 1./integral;
for (i=0;i<n;i++)
{
- Cp.bs[i+1] = Cp.bs[i] * pow( Cp.ms[i],( Cp.as[i] - Cp.as[i+1] ));
+ Cp->bs[i+1] = Cp->bs[i] * pow( Cp->ms[i],( Cp->as[i] - Cp->as[i+1] ));
}
}
if (verbose && ThisTask==0)
{
printf("-- bs -- \n");
for (i=0;i<n+1;i++)
- printf("%g ",Cp.bs[i]);
+ printf("%g ",Cp->bs[i]);
printf("\n");
}
- mmin = Cp.Mmin / All.UnitMass_in_g * SOLAR_MASS; /* in mass unit */
- mmax = Cp.Mmax / All.UnitMass_in_g * SOLAR_MASS; /* in mass unit */
- Cp.imf_Ntot = get_imf_N(mmin,mmax) *SOLAR_MASS/All.UnitMass_in_g;
+ mmin = Cp->Mmin / All.UnitMass_in_g * SOLAR_MASS; /* in mass unit */
+ mmax = Cp->Mmax / All.UnitMass_in_g * SOLAR_MASS; /* in mass unit */
+ Cp->imf_Ntot = get_imf_N(mmin,mmax) *SOLAR_MASS/All.UnitMass_in_g;
/* init fs : mass fraction at ms */
if (n>0)
{
for (i=0;i<n+1;i++)
{
- mmax = Cp.ms[i] / All.UnitMass_in_g * SOLAR_MASS; /* in mass unit */
- Cp.fs[i] = SOLAR_MASS/All.UnitMass_in_g*get_imf_N(mmin,mmax)/Cp.imf_Ntot;
+ mmax = Cp->ms[i] / All.UnitMass_in_g * SOLAR_MASS; /* in mass unit */
+ Cp->fs[i] = SOLAR_MASS/All.UnitMass_in_g*get_imf_N(mmin,mmax)/Cp->imf_Ntot;
}
}
}
/*
This function init the chime parameters
*/
void init_chimie(void)
{
- int i;
+ int i,nf;
double u_lt;
double UnitLength_in_kpc;
double UnitMass_in_Msol;
-
+ char filename[500];
+ char ext[100];
+
UnitLength_in_kpc = All.UnitLength_in_cm / KPC_IN_CM;
UnitMass_in_Msol = All.UnitMass_in_g / SOLAR_MASS;
u_lt = -log10( 4.7287e11*sqrt(pow(UnitLength_in_kpc,3)/UnitMass_in_Msol));
-
- read_chimie();
-
- /* Conversion into program time unit */
- Cp.coeff_z[2][2] = Cp.coeff_z[2][2] + u_lt;
-
- for (i=0;i<3;i++)
- Cp.coeff_z[1][i] = Cp.coeff_z[1][i]/2.0;
-
-
- /* init imf parameters */
- init_imf();
-
+
+ allocate_chimie();
- /* init SNII parameters */
- if (Cp.n==0)
+ for (nf=0;nf<All.ChimieNumberOfParameterFiles;nf++)
{
- //Cp.SNII_cte[0] = Cp.bs[0]/Cp.as[0];
- Cp.SNII_cte = Cp.bs[0]/Cp.as[0];
- Cp.SNII_a = Cp.as[0];
- }
- else
- {
- //for (i=0;i<Cp.n+1;i++) /* if multiple power law in the SNII mass range */
- // Cp.SNII_cte[i] = Cp.bs[i]/Cp.as[i];
- Cp.SNII_cte = Cp.bs[Cp.n]/Cp.as[Cp.n];
- Cp.SNII_a = Cp.as[Cp.n];
- }
+
+ if (All.ChimieNumberOfParameterFiles==1)
+ sprintf(filename,"%s",All.ChimieParameterFile);
+ else
+ sprintf(filename,"%s.%d",All.ChimieParameterFile,nf);
+
+ read_chimie(filename,nf);
- /* init SNIa parameters */
- Cp.SNIa_a1 = Cp.SNIa_a;
- Cp.SNIa_b1 = (Cp.SNIa_a1+1)/(pow(Cp.SNIa_Mdu1,Cp.SNIa_a1+1)-pow(Cp.SNIa_Mdl1,Cp.SNIa_a1+1));
- Cp.SNIa_cte1 = Cp.SNIa_b1/Cp.SNIa_a1;
+ /* set the table */
+ set_table(nf);
+
- Cp.SNIa_a2 = Cp.SNIa_a;
- Cp.SNIa_b2 = (Cp.SNIa_a2+1)/(pow(Cp.SNIa_Mdu2,Cp.SNIa_a2+1)-pow(Cp.SNIa_Mdl2,Cp.SNIa_a2+1));
- Cp.SNIa_cte2 = Cp.SNIa_b2/Cp.SNIa_a2;
+ /* Conversion into program time unit */
+ Cp->coeff_z[2][2] = Cp->coeff_z[2][2] + u_lt;
+ for (i=0;i<3;i++)
+ Cp->coeff_z[1][i] = Cp->coeff_z[1][i]/2.0;
- /* init SNII parameters */
- if (Cp.n==0)
- {
- Cp.SNIa_cte = Cp.bs[0]/Cp.as[0];
- Cp.SNIa_a = Cp.as[0];
- }
- else
- {
- Cp.SNIa_cte = Cp.bs[Cp.n]/Cp.as[Cp.n];
- Cp.SNIa_a = Cp.as[Cp.n];
- }
-
-
-
- Cp.SNII_Mmax = Cp.Mmax;
-
-
-
- /* init metals ejection parameters */
- MassFracSNII = malloc((Cp.nelts+2) * sizeof(double));
- EjectedMass = malloc((Cp.nelts+2) * sizeof(double));
- SingleMassFracSNII = malloc((Cp.nelts+2) * sizeof(double));
- SingleEjectedMass = malloc((Cp.nelts+2) * sizeof(double));
-
- for (i=0;i<Cp.nelts+2;i++)
- Elt[i].Mmin = log10(Elt[i].Mmin);
-
-
-
-
+
+ /* init imf parameters */
+ init_imf();
+
+
+ /* init SNII parameters */
+ if (Cp->n==0)
+ {
+ //Cp->SNII_cte[0] = Cp->bs[0]/Cp->as[0];
+ Cp->SNII_cte = Cp->bs[0]/Cp->as[0];
+ Cp->SNII_a = Cp->as[0];
+ }
+ else
+ {
+ //for (i=0;i<Cp->n+1;i++) /* if multiple power law in the SNII mass range */
+ // Cp->SNII_cte[i] = Cp->bs[i]/Cp->as[i];
+ Cp->SNII_cte = Cp->bs[Cp->n]/Cp->as[Cp->n];
+ Cp->SNII_a = Cp->as[Cp->n];
+ }
+
+
+ /* init SNIa parameters */
+ Cp->SNIa_a1 = Cp->SNIa_a;
+ Cp->SNIa_b1 = (Cp->SNIa_a1+1)/(pow(Cp->SNIa_Mdu1,Cp->SNIa_a1+1)-pow(Cp->SNIa_Mdl1,Cp->SNIa_a1+1));
+ Cp->SNIa_cte1 = Cp->SNIa_b1/Cp->SNIa_a1;
+
+ Cp->SNIa_a2 = Cp->SNIa_a;
+ Cp->SNIa_b2 = (Cp->SNIa_a2+1)/(pow(Cp->SNIa_Mdu2,Cp->SNIa_a2+1)-pow(Cp->SNIa_Mdl2,Cp->SNIa_a2+1));
+ Cp->SNIa_cte2 = Cp->SNIa_b2/Cp->SNIa_a2;
+
+
+ /* init SNII parameters */
+ if (Cp->n==0)
+ {
+ Cp->SNIa_cte = Cp->bs[0]/Cp->as[0];
+ Cp->SNIa_a = Cp->as[0];
+ }
+ else
+ {
+ Cp->SNIa_cte = Cp->bs[Cp->n]/Cp->as[Cp->n];
+ Cp->SNIa_a = Cp->as[Cp->n];
+ }
+
+
+
+ Cp->SNII_Mmax = Cp->Mmax;
+
+
+ for (i=0;i<Cp->nelts+2;i++)
+ Elt[i].Mmin = log10(Elt[i].Mmin);
+
+
+
- /* output info */
- if (verbose && ThisTask==0)
- {
- printf("-- SNII_cte -- \n");
- //for (i=0;i<Cp.n+1;i++)
- // printf("%g ",Cp.SNII_cte[i]);
- printf("%g ",Cp.SNII_cte);
-
- printf("\n");
- }
+ /* output info */
+ if (verbose && ThisTask==0)
+ {
+ printf("-- SNII_cte -- \n");
+ //for (i=0;i<Cp->n+1;i++)
+ // printf("%g ",Cp->SNII_cte[i]);
+ printf("%g ",Cp->SNII_cte);
+
+ printf("\n");
+ }
+
+
+
+
+ /* check that the masses are higher than the last IMF elbow */
+ if (Cp->n>0)
+ {
+ if (Cp->SNIa_Mpl < Cp->ms[Cp->n-1])
+ {
+ printf("\nSNIa_Mpl = %g < ms[n-1] = %g !!!\n\n",Cp->SNIa_Mpl,Cp->ms[Cp->n-1]);
+ printf("This is not supported by the current implementation !!!\n");
+ endrun(88801);
+ }
+
+ if (Cp->SNIa_Mpu < Cp->ms[Cp->n-1])
+ {
+ printf("\nSNIa_Mpu = %g < ms[n-1] = %g !!!\n\n",Cp->SNIa_Mpu,Cp->ms[Cp->n-1]);
+ printf("This is not supported by the current implementation !!!\n");
+ endrun(88802);
+ }
+
+ if (Cp->SNII_Mmin < Cp->ms[Cp->n-1])
+ {
+ printf("\nSNII_Mmin = %g < ms[n-1] = %g !!!\n\n",Cp->SNII_Mmin,Cp->ms[Cp->n-1]);
+ printf("This is not supported by the current implementation !!!\n");
+ endrun(88803);
+ }
+
+ if (Cp->SNII_Mmax < Cp->ms[Cp->n-1])
+ {
+ printf("\nSNII_Mmax = %g < ms[n-1] = %g !!!\n\n",Cp->SNII_Mmax,Cp->ms[Cp->n-1]);
+ printf("This is not supported by the current implementation !!!\n");
+ endrun(88804);
+ }
+ }
- /* check that the masses are higher than the last IMF elbow */
- if (Cp.n>0)
- {
- if (Cp.SNIa_Mpl < Cp.ms[Cp.n-1])
- {
- printf("\nSNIa_Mpl = %g < ms[n-1] = %g !!!\n\n",Cp.SNIa_Mpl,Cp.ms[Cp.n-1]);
- printf("This is not supported by the current implementation !!!\n");
- endrun(88801);
- }
-
- if (Cp.SNIa_Mpu < Cp.ms[Cp.n-1])
- {
- printf("\nSNIa_Mpu = %g < ms[n-1] = %g !!!\n\n",Cp.SNIa_Mpu,Cp.ms[Cp.n-1]);
- printf("This is not supported by the current implementation !!!\n");
- endrun(88802);
- }
- if (Cp.SNII_Mmin < Cp.ms[Cp.n-1])
- {
- printf("\nSNII_Mmin = %g < ms[n-1] = %g !!!\n\n",Cp.SNII_Mmin,Cp.ms[Cp.n-1]);
- printf("This is not supported by the current implementation !!!\n");
- endrun(88803);
- }
-
- if (Cp.SNII_Mmax < Cp.ms[Cp.n-1])
- {
- printf("\nSNII_Mmax = %g < ms[n-1] = %g !!!\n\n",Cp.SNII_Mmax,Cp.ms[Cp.n-1]);
- printf("This is not supported by the current implementation !!!\n");
- endrun(88804);
- }
- }
+
+ }
}
void check_chimie(void)
{
int i;
- printf("(Taks=%d) Number of elts : %d\n",ThisTask,Cp.nelts);
- for(i=2;i<Cp.nelts+2;i++)
+ printf("(Taks=%d) Number of elts : %d\n",ThisTask,Cp->nelts);
+ for(i=2;i<Cp->nelts+2;i++)
printf("%s ",&Elt[i].label);
printf("\n");
/* check number of elements */
- if (NELEMENTS != Cp.nelts)
+ if (NELEMENTS != Cp->nelts)
{
- printf("(Taks=%d) NELEMENTS (=%d) != Cp.nelts (=%d) : please check !!!\n\n",ThisTask,NELEMENTS,Cp.nelts);
+ printf("(Taks=%d) NELEMENTS (=%d) != Cp->nelts (=%d) : please check !!!\n\n",ThisTask,NELEMENTS,Cp->nelts);
endrun(88807);
}
/* check that iron is the first element */
if ((strcmp("Fe",Elt[2].label))!=0)
{
printf("(Taks=%d) first element (=%s) is not %s !!!\n\n",ThisTask,Elt[2].label,FIRST_ELEMENT);
endrun(88808);
}
}
int get_nelts()
{
- return Cp.nelts;
+ return Cp->nelts;
}
float get_SolarAbundance(i)
{
return Elt[i+2].SolarAbundance;
}
char* get_Element(i)
{
return Elt[i+2].label;
}
+
+
+
+
double star_lifetime(double z,double m)
{
/* z is the mass fraction of metals, ie, the metallicity */
/* m is the stellar mass in code unit */
/* Return t in code time unit */
int i;
double a,b,c;
double coeff[3];
double logm,twologm,logm2,time;
/* convert m in msol */
m = m*All.UnitMass_in_g / SOLAR_MASS;
for (i=0;i<3;i++)
- coeff[i] = ( Cp.coeff_z[i][0]*z+Cp.coeff_z[i][1] )*z+Cp.coeff_z[i][2];
+ coeff[i] = ( Cp->coeff_z[i][0]*z+Cp->coeff_z[i][1] )*z+Cp->coeff_z[i][2];
a = coeff[0];
b = coeff[1];
c = coeff[2];
logm = log10(m);
twologm = 2.0 * logm;
logm2 = logm*logm;
time = pow(10.,(a*logm2+b*twologm+c));
return time;
}
double star_mass_from_age(double z,double t)
{
/* z is the mass fraction of metals, ie, the metallicity */
/* t is the star life time */
/* return the stellar mass (in code unit) that has a lifetime equal to t */
/* this is the inverse of star_lifetime */
int i;
double a,b,c;
double coeff[3];
double m;
for (i=0;i<3;i++)
- coeff[i] = ( Cp.coeff_z[i][0]*z+Cp.coeff_z[i][1] )*z+Cp.coeff_z[i][2];
+ coeff[i] = ( Cp->coeff_z[i][0]*z+Cp->coeff_z[i][1] )*z+Cp->coeff_z[i][2];
a = coeff[0];
b = coeff[1];
c = coeff[2];
m = -(b+sqrt(b*b-a*(c-log10(t))))/a;
m = pow(10,m); /* here, m is in solar mass */
m = m*SOLAR_MASS/All.UnitMass_in_g; /* Msol to mass unit */
return m;
}
/****************************************************************************************/
/*
/* Supernova rate : number of supernova per mass unit
/*
/****************************************************************************************/
double SNII_rate(double m1,double m2)
{
/*
masses in code unit
*/
double RSNII;
double md,mu;
RSNII = 0.0;
/* convert m in msol */
m1 = m1*All.UnitMass_in_g / SOLAR_MASS;
m2 = m2*All.UnitMass_in_g / SOLAR_MASS;
/* (1) find md, mu */
- md = dmax(m1,Cp.SNII_Mmin);
- mu = dmin(m2,Cp.SNII_Mmax);
+ md = dmax(m1,Cp->SNII_Mmin);
+ mu = dmin(m2,Cp->SNII_Mmax);
if (mu<=md) /* no SNII in that mass range */
return 0.0;
- RSNII = Cp.SNII_cte * (pow(mu,Cp.SNII_a)-pow(md,Cp.SNII_a)); /* number per solar mass */
+ RSNII = Cp->SNII_cte * (pow(mu,Cp->SNII_a)-pow(md,Cp->SNII_a)); /* number per solar mass */
/* convert in number per solar mass to number per mass unit */
RSNII = RSNII *All.UnitMass_in_g / SOLAR_MASS;
return RSNII;
}
double SNIa_rate(double m1,double m2)
{
/*
masses in code unit
*/
double RSNIa;
double md,mu;
RSNIa = 0.0;
/* convert m in msol */
m1 = m1*All.UnitMass_in_g / SOLAR_MASS;
m2 = m2*All.UnitMass_in_g / SOLAR_MASS;
/* RG contribution */
- md = dmax(m1,Cp.SNIa_Mdl1);
- mu = dmin(m2,Cp.SNIa_Mdu1);
+ md = dmax(m1,Cp->SNIa_Mdl1);
+ mu = dmin(m2,Cp->SNIa_Mdu1);
if (md<mu)
- RSNIa = RSNIa + Cp.SNIa_bb1 * Cp.SNIa_cte1 * (pow(mu,Cp.SNIa_a1)-pow(md,Cp.SNIa_a1));
+ RSNIa = RSNIa + Cp->SNIa_bb1 * Cp->SNIa_cte1 * (pow(mu,Cp->SNIa_a1)-pow(md,Cp->SNIa_a1));
/* MS contribution */
- md = dmax(m1,Cp.SNIa_Mdl2);
- mu = dmin(m2,Cp.SNIa_Mdu2);
+ md = dmax(m1,Cp->SNIa_Mdl2);
+ mu = dmin(m2,Cp->SNIa_Mdu2);
if (md<mu)
- RSNIa = RSNIa + Cp.SNIa_bb2 * Cp.SNIa_cte2 * (pow(mu,Cp.SNIa_a2)-pow(md,Cp.SNIa_a2));
+ RSNIa = RSNIa + Cp->SNIa_bb2 * Cp->SNIa_cte2 * (pow(mu,Cp->SNIa_a2)-pow(md,Cp->SNIa_a2));
/* WD contribution */
- md = dmax(m1,Cp.SNIa_Mpl); /* select stars that have finished their life -> WD */
- mu = Cp.SNIa_Mpu; /* no upper bond */
+ md = dmax(m1,Cp->SNIa_Mpl); /* select stars that have finished their life -> WD */
+ mu = Cp->SNIa_Mpu; /* no upper bond */
if (mu<=md) /* no SNIa in that mass range */
return 0.0;
- RSNIa = RSNIa * Cp.SNIa_cte * (pow(mu,Cp.SNIa_a)-pow(md,Cp.SNIa_a)); /* number per solar mass */
+ RSNIa = RSNIa * Cp->SNIa_cte * (pow(mu,Cp->SNIa_a)-pow(md,Cp->SNIa_a)); /* number per solar mass */
/* convert in number per solar mass to number per mass unit */
RSNIa = RSNIa *All.UnitMass_in_g / SOLAR_MASS;
return RSNIa;
}
void SNII_mass_ejection(double m1,double m2)
{
double l1,l2;
int i1,i2,i1p,i2p,j;
double f1,f2;
double v1,v2;
/* convert m in msol */
m1 = m1*All.UnitMass_in_g / SOLAR_MASS;
m2 = m2*All.UnitMass_in_g / SOLAR_MASS;
j = 0;
l1 = ( log10(m1) - Elt[j].Mmin) / Elt[j].Step ;
l2 = ( log10(m2) - Elt[j].Mmin) / Elt[j].Step ;
if (l1 < 0.0) l1 = 0.0;
if (l2 < 0.0) l2 = 0.0;
i1 = (int)l1;
i2 = (int)l2;
i1p = i1 + 1;
i2p = i2 + 1;
f1 = l1 - i1;
f2 = l2 - i2;
/* check (yr) */
if (i1<0) i1=0;
if (i2<0) i2=0;
/* --------- TOTAL GAS ---------- */
j = 0;
v1 = f1 * ( Elt[j].Array[i1p] - Elt[j].Array[i1] ) + Elt[j].Array[i1];
v2 = f2 * ( Elt[j].Array[i2p] - Elt[j].Array[i2] ) + Elt[j].Array[i2];
MassFracSNII[j] = v2-v1;
/* --------- He core therm ---------- */
j = 1;
v1 = f1 * ( Elt[j].Array[i1p] - Elt[j].Array[i1] ) + Elt[j].Array[i1];
v2 = f2 * ( Elt[j].Array[i2p] - Elt[j].Array[i2] ) + Elt[j].Array[i2];
MassFracSNII[j] = v2-v1;
/* ---------------------------- */
/* --------- Metals ---------- */
/* ---------------------------- */
j = 2;
l1 = ( log10(m1) - Elt[j].Mmin) / Elt[j].Step ;
l2 = ( log10(m2) - Elt[j].Mmin) / Elt[j].Step ;
if (l1 < 0.0) l1 = 0.0;
if (l2 < 0.0) l2 = 0.0;
i1 = (int)l1;
i2 = (int)l2;
i1p = i1 + 1;
i2p = i2 + 1;
f1 = l1 - i1;
f2 = l2 - i2;
/* check (yr) */
if (i1<0) i1=0;
if (i2<0) i2=0;
- for (j=2;j<Cp.nelts+2;j++)
+ for (j=2;j<Cp->nelts+2;j++)
{
v1 = f1 * ( Elt[j].Array[i1p] - Elt[j].Array[i1] ) + Elt[j].Array[i1];
v2 = f2 * ( Elt[j].Array[i2p] - Elt[j].Array[i2] ) + Elt[j].Array[i2];
MassFracSNII[j] = v2-v1;
}
}
void SNII_single_mass_ejection(double m1)
{
double l1;
int i1,i1p,j;
double f1;
double v1;
/* convert m in msol */
m1 = m1*All.UnitMass_in_g / SOLAR_MASS;
j = 0;
l1 = ( log10(m1) - Elt[j].Mmin) / Elt[j].Step ;
if (l1 < 0.0) l1 = 0.0;
i1 = (int)l1;
i1p = i1 + 1;
f1 = l1 - i1;
/* check (yr) */
if (i1<0) i1=0;
/* --------- TOTAL GAS ---------- */
j = 0;
v1 = f1 * ( Elt[j].Metal[i1p] - Elt[j].Metal[i1] ) + Elt[j].Metal[i1];
SingleMassFracSNII[j] = v1;
/* --------- He core therm ---------- */
j = 1;
v1 = f1 * ( Elt[j].Metal[i1p] - Elt[j].Metal[i1] ) + Elt[j].Metal[i1];
SingleMassFracSNII[j] = v1;
/* ---------------------------- */
/* --------- Metals ---------- */
/* ---------------------------- */
j = 2;
l1 = ( log10(m1) - Elt[j].Mmin) / Elt[j].Step ;
if (l1 < 0.0) l1 = 0.0;
i1 = (int)l1;
i1p = i1 + 1;
f1 = l1 - i1;
/* check (yr) */
if (i1<0) i1=0;
- for (j=2;j<Cp.nelts+2;j++)
+ for (j=2;j<Cp->nelts+2;j++)
{
v1 = f1 * ( Elt[j].Metal[i1p] - Elt[j].Metal[i1] ) + Elt[j].Metal[i1];
SingleMassFracSNII[j] = v1;
}
}
void Total_mass_ejection(double m1,double m2,double M0,double *z)
{
int j;
double NSNIa;
/* compute SNII mass ejection -> MassFracSNII */
SNII_mass_ejection(m1,m2);
/* number of SNIa per mass unit between time and time+dt */
NSNIa = SNIa_rate(m1,m2)*M0;
/* number of SNII per mass unit between time and time+dt */
//NSNII = SNII_rate(m1,m2)*M0; /* useless (only for energy) */
/* total ejected gas mass */
- EjectedMass[0] = M0 * MassFracSNII[0] + Cp.Mco/All.UnitMass_in_g*SOLAR_MASS * NSNIa;
+ EjectedMass[0] = M0 * MassFracSNII[0] + Cp->Mco/All.UnitMass_in_g*SOLAR_MASS * NSNIa;
/* ejected mass per element */
- for (j=2;j<Cp.nelts+2;j++)
+ for (j=2;j<Cp->nelts+2;j++)
EjectedMass[j] = M0*(MassFracSNII[j] +z[j-2]*MassFracSNII[1]) + NSNIa* Elt[j].MSNIa/All.UnitMass_in_g*SOLAR_MASS;
/* not used */
EjectedMass[1] = -1;
}
void Total_single_mass_ejection(double m1,double *z)
{
/*
!!! we do not take into account SNIa
*/
int j;
float M0;
M0 = m1;
/* compute SNII mass ejection -> SingleMassFracSNII */
SNII_single_mass_ejection(m1);
/* total ejected gas mass */
- SingleEjectedMass[0] = M0 * SingleMassFracSNII[0]; /* + Cp.Mco/All.UnitMass_in_g*SOLAR_MASS * NSNIa; */
+ SingleEjectedMass[0] = M0 * SingleMassFracSNII[0]; /* + Cp->Mco/All.UnitMass_in_g*SOLAR_MASS * NSNIa; */
/* ejected mass per element */
- for (j=2;j<Cp.nelts+2;j++)
+ for (j=2;j<Cp->nelts+2;j++)
SingleEjectedMass[j] = M0*(SingleMassFracSNII[j] +z[j-2]*SingleMassFracSNII[1]); /* + NSNIa* Elt[j].MSNIa/All.UnitMass_in_g*SOLAR_MASS; */
/* not used */
SingleEjectedMass[1] = -1;
}
+
/**********************************************************************************************
END OF CHIMIE FUNCTIONS
**********************************************************************************************/
#if defined(CHIMIE_THERMAL_FEEDBACK) && defined(CHIMIE_COMPUTE_THERMAL_FEEDBACK_ENERGY)
void chimie_compute_energy_int(int mode)
{
int i;
double DeltaEgyInt;
double Tot_DeltaEgyInt;
DeltaEgyInt = 0;
Tot_DeltaEgyInt = 0;
if (mode==1)
{
LocalSysState.EnergyInt1 = 0;
LocalSysState.EnergyInt2 = 0;
}
for(i = 0; i < N_gas; i++)
{
if (P[i].Type==0)
{
if (mode==1)
LocalSysState.EnergyInt1 += P[i].Mass * SphP[i].EntropyPred / (GAMMA_MINUS1) * pow(SphP[i].Density, GAMMA_MINUS1);
else
LocalSysState.EnergyInt2 += P[i].Mass * SphP[i].EntropyPred / (GAMMA_MINUS1) * pow(SphP[i].Density, GAMMA_MINUS1);
}
}
if (mode==2)
{
DeltaEgyInt = LocalSysState.EnergyInt2 - LocalSysState.EnergyInt1;
MPI_Reduce(&DeltaEgyInt, &Tot_DeltaEgyInt, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
LocalSysState.EnergyThermalFeedback -= DeltaEgyInt;
}
}
#endif
#if defined(CHIMIE_KINETIC_FEEDBACK) && defined(CHIMIE_COMPUTE_KINETIC_FEEDBACK_ENERGY)
void chimie_compute_energy_kin(int mode)
{
int i;
double DeltaEgyKin;
double Tot_DeltaEgyKin;
DeltaEgyKin = 0;
Tot_DeltaEgyKin = 0;
if (mode==1)
{
LocalSysState.EnergyKin1 = 0;
LocalSysState.EnergyKin2 = 0;
}
for(i = 0; i < N_gas; i++)
{
if (P[i].Type==0)
{
if (mode==1)
LocalSysState.EnergyKin1 += 0.5 * P[i].Mass * (P[i].Vel[0]*P[i].Vel[0]+P[i].Vel[1]*P[i].Vel[1]+P[i].Vel[2]*P[i].Vel[2]);
else
LocalSysState.EnergyKin2 += 0.5 * P[i].Mass * (P[i].Vel[0]*P[i].Vel[0]+P[i].Vel[1]*P[i].Vel[1]+P[i].Vel[2]*P[i].Vel[2]);
}
}
if (mode==2)
{
DeltaEgyKin = LocalSysState.EnergyKin2 - LocalSysState.EnergyKin1;
MPI_Reduce(&DeltaEgyKin, &Tot_DeltaEgyKin, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
LocalSysState.EnergyKineticFeedback -= DeltaEgyKin;
}
}
#endif
#ifdef CHIMIE_THERMAL_FEEDBACK
void chimie_apply_thermal_feedback(void)
{
int i;
double EgySpec,NewEgySpec,DeltaEntropy;
for(i = 0; i < N_gas; i++)
{
if (P[i].Type==0)
{
if (SphP[i].DeltaEgySpec > 0)
{
/* spec energy at current step */
EgySpec = SphP[i].EntropyPred / GAMMA_MINUS1 * pow(SphP[i].Density, GAMMA_MINUS1);
/* new egyspec */
NewEgySpec = EgySpec + SphP[i].DeltaEgySpec;
LocalSysState.EnergyThermalFeedback -= SphP[i].DeltaEgySpec*P[i].Mass;
/* new entropy */
DeltaEntropy = GAMMA_MINUS1*NewEgySpec/pow(SphP[i].Density, GAMMA_MINUS1) - SphP[i].EntropyPred;
SphP[i].EntropyPred += DeltaEntropy;
SphP[i].Entropy += DeltaEntropy;
/* reset variable */
SphP[i].DeltaEgySpec = 0;
/* recode time */
SphP[i].ThermalTime = All.Time;
}
}
}
}
#endif
#ifdef CHIMIE_KINETIC_FEEDBACK
void chimie_apply_wind(void)
{
/* apply wind */
int i;
double e1,e2;
double phi,costh,sinth,vx,vy,vz;
for(i = 0; i < N_gas; i++)
{
if (P[i].Type==0)
{
if (SphP[i].WindFlag)
{
phi = get_ChimieKineticFeedback_random_number(P[i].ID)*PI*2.;
costh = 1.-2.*get_ChimieKineticFeedback_random_number(P[i].ID+1);
sinth = sqrt(1.-pow(costh,2));
vx = All.ChimieWindSpeed*sinth*cos(phi);
vy = All.ChimieWindSpeed*sinth*sin(phi);
vz = All.ChimieWindSpeed*costh;
e1 = 0.5*P[i].Mass * ( SphP[i].VelPred[0]*SphP[i].VelPred[0] + SphP[i].VelPred[1]*SphP[i].VelPred[1] + SphP[i].VelPred[2]*SphP[i].VelPred[2]);
P[i].Vel[0] += vx;
P[i].Vel[1] += vy;
P[i].Vel[2] += vz;
SphP[i].VelPred[0] += vx;
SphP[i].VelPred[1] += vy;
SphP[i].VelPred[2] += vz;
e2 = 0.5*P[i].Mass * ( SphP[i].VelPred[0]*SphP[i].VelPred[0] + SphP[i].VelPred[1]*SphP[i].VelPred[1] + SphP[i].VelPred[2]*SphP[i].VelPred[2]);
LocalSysState.EnergyKineticFeedback -= e2-e1;
SphP[i].WindFlag = 0;
}
}
}
}
#endif
/*! This function is the driver routine for the calculation of chemical evolution
*/
void chimie(void)
{
double t0, t1;
t0 = second(); /* measure the time for the full chimie computation */
if (ThisTask==0)
printf("Start Chimie computation.\n");
/* apply thermal feedback on selected particles */
#ifdef CHIMIE_THERMAL_FEEDBACK
chimie_apply_thermal_feedback();
#endif
/* apply wind on selected particles */
#ifdef CHIMIE_KINETIC_FEEDBACK
chimie_apply_wind();
#endif
stars_density(); /* compute density */
do_chimie(); /* chimie */
if (ThisTask==0)
printf("Chimie computation done.\n");
t1 = second();
All.CPU_Chimie += timediff(t0, t1);
}
/*! This function is the driver routine for the calculation of chemical evolution
*/
void do_chimie(void)
{
long long ntot, ntotleft;
int i, j, k, n, m, ngrp, maxfill, source, ndone;
int *nbuffer, *noffset, *nsend_local, *nsend, *numlist, *ndonelist;
int level, sendTask, recvTask, nexport, place;
double tstart, tend, sumt, sumcomm;
double timecomp = 0, timecommsumm = 0, timeimbalance = 0, sumimbalance;
int flag_chimie;
MPI_Status status;
double t1,t2;
double a1,a2;
- double minlivetime,star_age;
+ double minlivetime,maxlivetime,star_age;
double m1,m2,M0;
double NSNIa,NSNII;
double NSNIa_tot,NSNII_tot,NSNIa_totlocal,NSNII_totlocal;
double EgySN,EgySNlocal;
double EgySNThermal,EgySNKinetic;
int Nchim,Nchimlocal;
int Nwind,Nwindlocal;
int Nflag,Nflaglocal;
int Noldwind,Noldwindlocal;
double metals[NELEMENTS];
#ifdef PERIODIC
boxSize = All.BoxSize;
boxHalf = 0.5 * All.BoxSize;
#ifdef LONG_X
boxHalf_X = boxHalf * LONG_X;
boxSize_X = boxSize * LONG_X;
#endif
#ifdef LONG_Y
boxHalf_Y = boxHalf * LONG_Y;
boxSize_Y = boxSize * LONG_Y;
#endif
#ifdef LONG_Z
boxHalf_Z = boxHalf * LONG_Z;
boxSize_Z = boxSize * LONG_Z;
#endif
#endif
#ifdef COMPUTE_VELOCITY_DISPERSION
double v1m,v2m;
#endif
if(All.ComovingIntegrationOn)
{
/* Factors for comoving integration of hydro */
hubble_a = All.Omega0 / (All.Time * All.Time * All.Time)
+ (1 - All.Omega0 - All.OmegaLambda) / (All.Time * All.Time) + All.OmegaLambda;
hubble_a = All.Hubble * sqrt(hubble_a);
hubble_a2 = All.Time * All.Time * hubble_a;
fac_mu = pow(All.Time, 3 * (GAMMA - 1) / 2) / All.Time;
fac_egy = pow(All.Time, 3 * (GAMMA - 1));
fac_vsic_fix = hubble_a * pow(All.Time, 3 * GAMMA_MINUS1);
a3inv = 1 / (All.Time * All.Time * All.Time);
atime = All.Time;
#ifdef FEEDBACK
fac_pow = fac_egy*atime*atime;
#endif
}
else
{
hubble_a = hubble_a2 = atime = fac_mu = fac_vsic_fix = a3inv = fac_egy = 1.0;
#ifdef FEEDBACK
fac_pow = 1.0;
#endif
}
/* `NumStUpdate' gives the number of particles on this processor that want a chimie computation */
for(n = 0, NumStUpdate = 0; n < N_gas+N_stars; n++)
{
if(P[n].Ti_endstep == All.Ti_Current)
if(P[n].Type == ST)
NumStUpdate++;
if(P[n].Type == 0)
SphP[n].dMass = 0.;
}
numlist = malloc(NTask * sizeof(int) * NTask);
MPI_Allgather(&NumStUpdate, 1, MPI_INT, numlist, 1, MPI_INT, MPI_COMM_WORLD);
for(i = 0, ntot = 0; i < NTask; i++)
ntot += numlist[i];
free(numlist);
noffset = malloc(sizeof(int) * NTask); /* offsets of bunches in common list */
nbuffer = malloc(sizeof(int) * NTask);
nsend_local = malloc(sizeof(int) * NTask);
nsend = malloc(sizeof(int) * NTask * NTask);
ndonelist = malloc(sizeof(int) * NTask);
i = 0; /* first gas particle, because stars may be hidden among gas particles */
ntotleft = ntot; /* particles left for all tasks together */
NSNIa_tot = 0;
NSNII_tot = 0;
NSNIa_totlocal = 0;
NSNII_totlocal = 0;
EgySN = 0;
EgySNlocal =0;
Nchimlocal = 0;
Nchim = 0;
Nwindlocal = 0;
Nwind = 0;
Noldwindlocal = 0;
Noldwind = 0;
Nflaglocal = 0;
Nflag = 0;
while(ntotleft > 0)
{
for(j = 0; j < NTask; j++)
nsend_local[j] = 0;
/* do local particles and prepare export list */
tstart = second();
for(nexport = 0, ndone = 0; i < N_gas+N_stars && nexport < All.BunchSizeChimie - NTask; i++)
/* only active particles and stars */
if((P[i].Ti_endstep == All.Ti_Current)&&(P[i].Type == ST))
{
if(P[i].Type != ST)
{
printf("P[i].Type != ST, we better stop.\n");
printf("N_gas=%d (type=%d) i=%d (type=%d)\n",N_gas,P[N_gas].Type,i,P[i].Type);
printf("Please, check that you do not use PEANOHILBERT\n");
endrun(777001);
}
m = P[i].StPIdx;
flag_chimie = 0;
/******************************************/
/* do chimie */
/******************************************/
/*****************************************************/
/* look if a SN may have explode during the last step
/*****************************************************/
+
+
+ /* set the right table base of the metallicity */
+ set_table(All.ChimieNumberOfParameterFiles-1);
+
/* minimum live time for a given metallicity */
- minlivetime = star_lifetime(StP[m].Metal[NELEMENTS-1],Cp.Mmax*SOLAR_MASS/All.UnitMass_in_g);
+ minlivetime = star_lifetime(StP[m].Metal[NELEMENTS-1],Cp->Mmax*SOLAR_MASS/All.UnitMass_in_g);
+
+ /* maximum live time for a given metallicity */
+ maxlivetime = star_lifetime(StP[m].Metal[NELEMENTS-1],Cp->Mmin*SOLAR_MASS/All.UnitMass_in_g);
+
t1 = P[i].Ti_begstep * All.Timebase_interval / hubble_a; /* t1<t2 */
t2 = All.Ti_Current * All.Timebase_interval / hubble_a;
star_age = t2-StP[m].FormationTime;
- if (star_age>minlivetime)
+ if ((star_age>minlivetime)&&(star_age<=maxlivetime))
{
Nchimlocal++;
StP[m].Flag = 1; /* mark it as active */
- //printf("(%d) minlivetime=%g star_age=%g (metalicity=%g Mmax=%g)\n",ThisTask,minlivetime,star_age,StP[m].Metal[NELEMENTS-1],Cp.Mmax);
+ //printf("(%d) minlivetime=%g star_age=%g (metalicity=%g Mmax=%g)\n",ThisTask,minlivetime,star_age,StP[m].Metal[NELEMENTS-1],Cp->Mmax);
//printf("(%d) t1=%g t2=%g StP[m].FormationTime=%g\n",ThisTask,t1,t2,StP[m].FormationTime);
a1 = t2-StP[m].FormationTime;
a2 = t1-StP[m].FormationTime;
/*
find m1 and m2
m1 = min mass of stars that may explode between t1 and t2
m2 = max mass of stars that may explode between t1 and t2
*/
m1 = star_mass_from_age(StP[m].Metal[NELEMENTS-1],a1);
if (a2 >= minlivetime)
m2 = star_mass_from_age(StP[m].Metal[NELEMENTS-1],a2);
else
- m2 = Cp.Mmax*SOLAR_MASS/All.UnitMass_in_g;
+ m2 = Cp->Mmax*SOLAR_MASS/All.UnitMass_in_g;
//printf("(%d) m1=%g (%g Msol), m2=%g (%g Msol)\n",ThisTask,m1,m1*All.UnitMass_in_g/SOLAR_MASS,m2,m2*All.UnitMass_in_g/SOLAR_MASS);
if (m1>m2)
{
printf("m1=%g (%g Msol) > m2=%g (%g Msol) !!!\n\n",m1,m1*All.UnitMass_in_g/SOLAR_MASS,m2,m2*All.UnitMass_in_g/SOLAR_MASS);
endrun(777002);
}
M0 = StP[m].InitialMass;
for (k=0;k<NELEMENTS;k++)
metals[k] = StP[m].Metal[k];
/* number of SNIa */
NSNIa = SNIa_rate(m1,m2)*M0;
/* number of SNII */
NSNII = SNII_rate(m1,m2)*M0;
NSNIa_totlocal += NSNIa;
NSNII_totlocal += NSNII;
/* compute ejectas */
Total_mass_ejection(m1,m2,M0,metals);
StP[m].TotalEjectedGasMass = EjectedMass[0]; /* gas mass */
for (k=0;k<NELEMENTS;k++)
StP[m].TotalEjectedEltMass[k] = EjectedMass[k+2]; /* metal mass */
if (StP[m].TotalEjectedGasMass>0)
flag_chimie=1;
/* compute injected energy */
StP[m].TotalEjectedEgySpec = All.ChimieSupernovaEnergy* (NSNIa + NSNII) /StP[m].TotalEjectedGasMass;
EgySNlocal += All.ChimieSupernovaEnergy* (NSNIa + NSNII);
/* correct mass particle */
P[i].Mass = P[i].Mass-StP[m].TotalEjectedGasMass;
float Fe,Mg;
Fe = StP[m].TotalEjectedEltMass[0];
Mg = StP[m].TotalEjectedEltMass[1];
}
/******************************************/
/* end do chimie */
/******************************************/
ndone++;
if (flag_chimie)
{
for(j = 0; j < NTask; j++)
Exportflag[j] = 0;
chimie_evaluate(i, 0);
for(j = 0; j < NTask; j++)
{
if(Exportflag[j])
{
for(k = 0; k < 3; k++)
{
ChimieDataIn[nexport].Pos[k] = P[i].Pos[k];
ChimieDataIn[nexport].Vel[k] = P[i].Vel[k];
}
ChimieDataIn[nexport].ID = P[i].ID;
ChimieDataIn[nexport].Timestep = P[i].Ti_endstep - P[i].Ti_begstep;
ChimieDataIn[nexport].Hsml = StP[m].Hsml;
ChimieDataIn[nexport].Density = StP[m].Density;
ChimieDataIn[nexport].Volume = StP[m].Volume;
#ifdef CHIMIE_KINETIC_FEEDBACK
ChimieDataIn[nexport].NgbMass = StP[m].NgbMass;
#endif
ChimieDataIn[nexport].TotalEjectedGasMass = StP[m].TotalEjectedGasMass;
for(k = 0; k < NELEMENTS; k++)
ChimieDataIn[nexport].TotalEjectedEltMass[k] = StP[m].TotalEjectedEltMass[k];
ChimieDataIn[nexport].TotalEjectedEgySpec = StP[m].TotalEjectedEgySpec;
#ifdef WITH_ID_IN_HYDRA
ChimieDataIn[nexport].ID = P[i].ID;
#endif
ChimieDataIn[nexport].Index = i;
ChimieDataIn[nexport].Task = j;
nexport++;
nsend_local[j]++;
}
}
}
}
tend = second();
timecomp += timediff(tstart, tend);
qsort(ChimieDataIn, nexport, sizeof(struct chimiedata_in), chimie_compare_key);
for(j = 1, noffset[0] = 0; j < NTask; j++)
noffset[j] = noffset[j - 1] + nsend_local[j - 1];
tstart = second();
MPI_Allgather(nsend_local, NTask, MPI_INT, nsend, NTask, MPI_INT, MPI_COMM_WORLD);
tend = second();
timeimbalance += timediff(tstart, tend);
/* now do the particles that need to be exported */
for(level = 1; level < (1 << PTask); level++)
{
tstart = second();
for(j = 0; j < NTask; j++)
nbuffer[j] = 0;
for(ngrp = level; ngrp < (1 << PTask); ngrp++)
{
maxfill = 0;
for(j = 0; j < NTask; j++)
{
if((j ^ ngrp) < NTask)
if(maxfill < nbuffer[j] + nsend[(j ^ ngrp) * NTask + j])
maxfill = nbuffer[j] + nsend[(j ^ ngrp) * NTask + j];
}
if(maxfill >= All.BunchSizeChimie)
break;
sendTask = ThisTask;
recvTask = ThisTask ^ ngrp;
if(recvTask < NTask)
{
if(nsend[ThisTask * NTask + recvTask] > 0 || nsend[recvTask * NTask + ThisTask] > 0)
{
/* get the particles */
MPI_Sendrecv(&ChimieDataIn[noffset[recvTask]],
nsend_local[recvTask] * sizeof(struct chimiedata_in), MPI_BYTE,
recvTask, TAG_CHIMIE_A,
&ChimieDataGet[nbuffer[ThisTask]],
nsend[recvTask * NTask + ThisTask] * sizeof(struct chimiedata_in), MPI_BYTE,
recvTask, TAG_CHIMIE_A, MPI_COMM_WORLD, &status);
}
}
for(j = 0; j < NTask; j++)
if((j ^ ngrp) < NTask)
nbuffer[j] += nsend[(j ^ ngrp) * NTask + j];
}
tend = second();
timecommsumm += timediff(tstart, tend);
/* now do the imported particles */
tstart = second();
for(j = 0; j < nbuffer[ThisTask]; j++)
chimie_evaluate(j, 1);
tend = second();
timecomp += timediff(tstart, tend);
/* do a block to measure imbalance */
tstart = second();
MPI_Barrier(MPI_COMM_WORLD);
tend = second();
timeimbalance += timediff(tstart, tend);
/* get the result */
tstart = second();
for(j = 0; j < NTask; j++)
nbuffer[j] = 0;
for(ngrp = level; ngrp < (1 << PTask); ngrp++)
{
maxfill = 0;
for(j = 0; j < NTask; j++)
{
if((j ^ ngrp) < NTask)
if(maxfill < nbuffer[j] + nsend[(j ^ ngrp) * NTask + j])
maxfill = nbuffer[j] + nsend[(j ^ ngrp) * NTask + j];
}
if(maxfill >= All.BunchSizeChimie)
break;
sendTask = ThisTask;
recvTask = ThisTask ^ ngrp;
if(recvTask < NTask)
{
if(nsend[ThisTask * NTask + recvTask] > 0 || nsend[recvTask * NTask + ThisTask] > 0)
{
/* send the results */
MPI_Sendrecv(&ChimieDataResult[nbuffer[ThisTask]],
nsend[recvTask * NTask + ThisTask] * sizeof(struct chimiedata_out),
MPI_BYTE, recvTask, TAG_CHIMIE_B,
&ChimieDataPartialResult[noffset[recvTask]],
nsend_local[recvTask] * sizeof(struct chimiedata_out),
MPI_BYTE, recvTask, TAG_CHIMIE_B, MPI_COMM_WORLD, &status);
/* add the result to the particles */
for(j = 0; j < nsend_local[recvTask]; j++)
{
source = j + noffset[recvTask];
place = ChimieDataIn[source].Index;
// for(k = 0; k < 3; k++)
// SphP[place].HydroAccel[k] += HydroDataPartialResult[source].Acc[k];
//
// SphP[place].DtEntropy += HydroDataPartialResult[source].DtEntropy;
//#ifdef FEEDBACK
// SphP[place].DtEgySpecFeedback += HydroDataPartialResult[source].DtEgySpecFeedback;
//#endif
// if(SphP[place].MaxSignalVel < HydroDataPartialResult[source].MaxSignalVel)
// SphP[place].MaxSignalVel = HydroDataPartialResult[source].MaxSignalVel;
//#ifdef COMPUTE_VELOCITY_DISPERSION
// for(k = 0; k < VELOCITY_DISPERSION_SIZE; k++)
// SphP[place].VelocityDispersion[k] += HydroDataPartialResult[source].VelocityDispersion[k];
//#endif
}
}
}
for(j = 0; j < NTask; j++)
if((j ^ ngrp) < NTask)
nbuffer[j] += nsend[(j ^ ngrp) * NTask + j];
}
tend = second();
timecommsumm += timediff(tstart, tend);
level = ngrp - 1;
}
MPI_Allgather(&ndone, 1, MPI_INT, ndonelist, 1, MPI_INT, MPI_COMM_WORLD);
for(j = 0; j < NTask; j++)
ntotleft -= ndonelist[j];
}
free(ndonelist);
free(nsend);
free(nsend_local);
free(nbuffer);
free(noffset);
/* do final operations on results */
tstart = second();
for(i = 0; i < N_gas; i++)
{
if (P[i].Type==0)
{
P[i].Mass += SphP[i].dMass;
SphP[i].dMass = 0.;
}
}
tend = second();
timecomp += timediff(tstart, tend);
/* collect some timing information */
MPI_Reduce(&timecomp, &sumt, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&timecommsumm, &sumcomm, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&timeimbalance, &sumimbalance, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
// if(ThisTask == 0)
// {
// All.CPU_HydCompWalk += sumt / NTask;
// All.CPU_HydCommSumm += sumcomm / NTask;
// All.CPU_HydImbalance += sumimbalance / NTask;
// }
/* collect some chimie informations */
MPI_Reduce(&NSNIa_totlocal, &NSNIa_tot, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&NSNII_totlocal, &NSNII_tot, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&EgySNlocal, &EgySN, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&Nchimlocal, &Nchim, 1, MPI_INT , MPI_SUM, 0, MPI_COMM_WORLD);
#ifdef CHIMIE_THERMAL_FEEDBACK
EgySNThermal = EgySN*(1-All.ChimieKineticFeedbackFraction);
#else
EgySNThermal = 0;
#endif
#ifdef CHIMIE_KINETIC_FEEDBACK
EgySNKinetic = EgySN*All.ChimieKineticFeedbackFraction;
/* count number of wind particles */
for(i = 0; i < N_gas; i++)
{
if (P[i].Type==0)
{
if (SphP[i].WindTime >= (All.Time-All.ChimieWindTime))
Nwindlocal++;
//else
// if (SphP[i].WindTime > All.TimeBegin-2*All.ChimieWindTime)
// Noldwindlocal++;
if (SphP[i].WindFlag)
Nflaglocal++;
}
}
MPI_Reduce(&Nwindlocal, &Nwind, 1, MPI_INT , MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&Noldwindlocal, &Noldwind, 1, MPI_INT , MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Allreduce(&Nflaglocal, &Nflag, 1, MPI_INT , MPI_SUM, MPI_COMM_WORLD);
#else
EgySNKinetic = 0;
#endif
/* write some info */
if (ThisTask==0)
{
fprintf(FdChimie, "%15g %10d %15g %15g %15g %15g %15g %10d %10d %10d\n",All.Time,Nchim,NSNIa_tot,NSNII_tot,EgySN,EgySNThermal,EgySNKinetic,Nwind,Noldwind,Nflag);
fflush(FdChimie);
}
if (Nflag>0)
{
SetMinTimeStepForActives=1;
if (ThisTask==0)
fprintf(FdLog,"%g : !!! set min timestep for active particles !!!\n",All.Time);
}
}
/*! This function is the 'core' of the Chemie computation. A target
* particle is specified which may either be local, or reside in the
* communication buffer.
*/
void chimie_evaluate(int target, int mode)
{
int j, n, startnode, numngb,numngb_inbox,k;
FLOAT *pos,*vel;
//FLOAT *vel;
//FLOAT mass;
double h, h2;
double acc[3];
double dx, dy, dz;
double wk, r, r2, u=0;
double hinv=1, hinv3;
int target_stp;
double density;
double volume;
#ifdef CHIMIE_KINETIC_FEEDBACK
double ngbmass;
double p;
#endif
double aij;
double ejectedGasMass;
double ejectedEltMass[NELEMENTS];
double ejectedEgySpec;
double mass_k;
double NewMass;
double fv,vi2,vj2;
double EgySpec,NewEgySpec;
double DeltaEntropy;
double DeltaVel[3];
#ifndef LONGIDS
unsigned int id; /*!< particle identifier */
#else
unsigned long long id; /*!< particle identifier */
#endif
if(mode == 0)
{
pos = P[target].Pos;
vel = P[target].Vel;
id = P[target].ID;
target_stp = P[target].StPIdx;
h = StP[target_stp].Hsml;
density = StP[target_stp].Density;
volume = StP[target_stp].Volume;
#ifdef CHIMIE_KINETIC_FEEDBACK
ngbmass = StP[target_stp].NgbMass;
#endif
ejectedGasMass = StP[target_stp].TotalEjectedGasMass;
for(k=0;k<NELEMENTS;k++)
ejectedEltMass[k] = StP[target_stp].TotalEjectedEltMass[k];
ejectedEgySpec = StP[target_stp].TotalEjectedEgySpec;
}
else
{
pos = ChimieDataGet[target].Pos;
vel = ChimieDataGet[target].Vel;
id = ChimieDataGet[target].ID;
h = ChimieDataGet[target].Hsml;
density = ChimieDataGet[target].Density;
volume = ChimieDataGet[target].Volume;
#ifdef CHIMIE_KINETIC_FEEDBACK
ngbmass = ChimieDataGet[target].NgbMass;
#endif
ejectedGasMass = ChimieDataGet[target].TotalEjectedGasMass;
for(k=0;k<NELEMENTS;k++)
ejectedEltMass[k] = ChimieDataGet[target].TotalEjectedEltMass[k];
ejectedEgySpec = ChimieDataGet[target].TotalEjectedEgySpec;
}
/* initialize variables before SPH loop is started */
acc[0] = acc[1] = acc[2] = 0;
vi2 = 0;
for(k=0;k<3;k++)
vi2 += vel[k]*vel[k];
h2 = h * h;
hinv = 1.0 / h;
#ifndef TWODIMS
hinv3 = hinv * hinv * hinv;
#else
hinv3 = hinv * hinv / boxSize_Z;
#endif
/* Now start the actual SPH computation for this particle */
startnode = All.MaxPart;
numngb = 0;
do
{
numngb_inbox = ngb_treefind_variable_for_chimie(&pos[0], h, &startnode);
for(n = 0; n < numngb_inbox; n++)
{
j = Ngblist[n];
dx = pos[0] - P[j].Pos[0];
dy = pos[1] - P[j].Pos[1];
dz = pos[2] - P[j].Pos[2];
#ifdef PERIODIC /* now find the closest image in the given box size */
if(dx > boxHalf_X)
dx -= boxSize_X;
if(dx < -boxHalf_X)
dx += boxSize_X;
if(dy > boxHalf_Y)
dy -= boxSize_Y;
if(dy < -boxHalf_Y)
dy += boxSize_Y;
if(dz > boxHalf_Z)
dz -= boxSize_Z;
if(dz < -boxHalf_Z)
dz += boxSize_Z;
#endif
r2 = dx * dx + dy * dy + dz * dz;
if(r2 < h2)
{
numngb++;
r = sqrt(r2);
u = r * hinv;
if(u < 0.5)
{
wk = hinv3 * (KERNEL_COEFF_1 + KERNEL_COEFF_2 * (u - 1) * u * u);
}
else
{
wk = hinv3 * KERNEL_COEFF_5 * (1.0 - u) * (1.0 - u) * (1.0 - u);
}
/* normalisation using mass */
aij = P[j].Mass*wk/density;
/* normalisation using volume */
/* !!! si on utilise, il faut stoquer une nouvelle variable : OldDensity, car density est modifié plus bas... */
//aij = P[j].Mass/SphP[j].Density*wk/volume;
/* metal injection */
for(k=0;k<NELEMENTS;k++)
{
mass_k = SphP[j].Metal[k]*P[j].Mass; /* mass of elt k */
SphP[j].Metal[k] = ( mass_k + aij*ejectedEltMass[k] )/( P[j].Mass + aij*ejectedGasMass );
}
/* new mass */
NewMass = P[j].Mass + aij*ejectedGasMass;
/* new velocity */
vj2 = 0;
for(k=0;k<3;k++)
vj2 += SphP[j].VelPred[k]*SphP[j].VelPred[k];
fv = sqrt( (P[j].Mass/NewMass) + aij*(ejectedGasMass/NewMass) * (vi2/vj2) );
for(k=0;k<3;k++)
{
DeltaVel[k] = fv*SphP[j].VelPred[k] - SphP[j].VelPred[k];
SphP[j].VelPred[k] += DeltaVel[k];
P[j].Vel [k] += DeltaVel[k];
}
/* spec energy at current step */
EgySpec = SphP[j].EntropyPred / GAMMA_MINUS1 * pow(SphP[j].Density, GAMMA_MINUS1);
/* new egyspec */
NewEgySpec = (EgySpec )*(P[j].Mass/NewMass);
/* new density */
SphP[j].Density = SphP[j].Density*NewMass/P[j].Mass;
/* new entropy */
DeltaEntropy = GAMMA_MINUS1*NewEgySpec/pow(SphP[j].Density, GAMMA_MINUS1) - SphP[j].EntropyPred;
SphP[j].EntropyPred += DeltaEntropy;
SphP[j].Entropy += DeltaEntropy;
#ifdef CHIMIE_THERMAL_FEEDBACK
SphP[j].DeltaEgySpec += (1.-All.ChimieKineticFeedbackFraction)*(ejectedGasMass*ejectedEgySpec)* aij/NewMass;
#endif
#ifdef CHIMIE_KINETIC_FEEDBACK
p = (All.ChimieKineticFeedbackFraction*ejectedEgySpec*ejectedGasMass)/(0.5*ngbmass*All.ChimieWindSpeed*All.ChimieWindSpeed);
double r;
r = get_Chimie_random_number(P[j].ID+id);
if ( r < p) /* we should maybe have a 2d table here... */
{
if (SphP[j].WindTime < (All.Time-All.ChimieWindTime)) /* not a wind particle */
{
SphP[j].WindFlag = 1;
SphP[j].WindTime = All.Time;
}
}
#endif
#ifdef CHECK_ENTROPY_SIGN
if ((SphP[j].EntropyPred < 0)||(SphP[j].Entropy < 0))
{
printf("\ntask=%d: entropy less than zero in chimie_evaluate !\n", ThisTask);
printf("ID=%d Entropy=%g EntropyPred=%g DeltaEntropy=%g\n",P[j].ID,SphP[j].Entropy,SphP[j].EntropyPred,DeltaEntropy);
fflush(stdout);
endrun(777003);
}
#endif
/* store mass diff. */
SphP[j].dMass += NewMass-P[j].Mass;
}
}
}
while(startnode >= 0);
/* Now collect the result at the right place */
if(mode == 0)
{
// for(k = 0; k < 3; k++)
// SphP[target].HydroAccel[k] = acc[k];
// SphP[target].DtEntropy = dtEntropy;
//#ifdef FEEDBACK
// SphP[target].DtEgySpecFeedback = dtEgySpecFeedback;
//#endif
// SphP[target].MaxSignalVel = maxSignalVel;
//#ifdef COMPUTE_VELOCITY_DISPERSION
// for(k = 0; k < VELOCITY_DISPERSION_SIZE; k++)
// SphP[target].VelocityDispersion[k] = VelocityDispersion[k];
//#endif
}
else
{
// for(k = 0; k < 3; k++)
// HydroDataResult[target].Acc[k] = acc[k];
// HydroDataResult[target].DtEntropy = dtEntropy;
//#ifdef FEEDBACK
// HydroDataResult[target].DtEgySpecFeedback = dtEgySpecFeedback;
//#endif
// HydroDataResult[target].MaxSignalVel = maxSignalVel;
//#ifdef COMPUTE_VELOCITY_DISPERSION
// for(k = 0; k < VELOCITY_DISPERSION_SIZE; k++)
// HydroDataResult[target].VelocityDispersion[k] = VelocityDispersion[k];
//#endif
}
}
/*! This is a comparison kernel for a sort routine, which is used to group
* particles that are going to be exported to the same CPU.
*/
int chimie_compare_key(const void *a, const void *b)
{
if(((struct chimiedata_in *) a)->Task < (((struct chimiedata_in *) b)->Task))
return -1;
if(((struct chimiedata_in *) a)->Task > (((struct chimiedata_in *) b)->Task))
return +1;
return 0;
}
#endif
diff --git a/proto.h b/proto.h
index 62f4c2d..16fc6ef 100644
--- a/proto.h
+++ b/proto.h
@@ -1,399 +1,400 @@
/*! \file proto.h
* \brief this file contains all function prototypes of the code
*/
#ifndef ALLVARS_H
#include "allvars.h"
#endif
#ifdef HAVE_HDF5
#include <hdf5.h>
#endif
void advance_and_find_timesteps(void);
void allocate_commbuffers(void);
void allocate_memory(void);
void begrun(void);
int blockpresent(enum iofields blocknr);
#ifdef BLOCK_SKIPPING
int blockabsent(enum iofields blocknr);
#endif
void catch_abort(int sig);
void catch_fatal(int sig);
void check_omega(void);
void close_outputfiles(void);
int compare_key(const void *a, const void *b);
void compute_accelerations(int mode);
void compute_global_quantities_of_system(void);
void compute_potential(void);
int dens_compare_key(const void *a, const void *b);
void density(int mode);
void density_decouple(void);
void density_evaluate(int i, int mode);
#ifdef CHIMIE
int stars_dens_compare_key(const void *a, const void *b);
void stars_density(void);
void stars_density_evaluate(int i, int mode);
#endif
void distribute_file(int nfiles, int firstfile, int firsttask, int lasttask, int *filenr, int *master, int *last);
double dmax(double, double);
double dmin(double, double);
void do_box_wrapping(void);
void domain_Decomposition(void);
int domain_compare_key(const void *a, const void *b);
int domain_compare_key(const void *a, const void *b);
int domain_compare_toplist(const void *a, const void *b);
void domain_countToGo(void);
void domain_decompose(void);
void domain_determineTopTree(void);
void domain_exchangeParticles(int partner, int sphflag, int send_count, int recv_count);
void domain_findExchangeNumbers(int task, int partner, int sphflag, int *send, int *recv);
void domain_findExtent(void);
int domain_findSplit(int cpustart, int ncpu, int first, int last);
int domain_findSplityr(int cpustart, int ncpu, int first, int last);
void domain_shiftSplit(void);
void domain_shiftSplityr(void);
void domain_sumCost(void);
void domain_topsplit(int node, peanokey startkey);
void domain_topsplit_local(int node, peanokey startkey);
double drift_integ(double a, void *param);
void dump_particles(void);
void empty_read_buffer(enum iofields blocknr, int offset, int pc, int type);
void endrun(int);
void energy_statistics(void);
#ifdef ADVANCEDSTATISTICS
void advanced_energy_statistics(void);
#endif
void every_timestep_stuff(void);
void ewald_corr(double dx, double dy, double dz, double *fper);
void ewald_force(int ii, int jj, int kk, double x[3], double force[3]);
void ewald_init(void);
double ewald_pot_corr(double dx, double dy, double dz);
double ewald_psi(double x[3]);
void fill_Tab_IO_Labels(void);
void fill_write_buffer(enum iofields blocknr, int *pindex, int pc, int type);
void find_dt_displacement_constraint(double hfac);
int find_files(char *fname);
int find_next_outputtime(int time);
void find_next_sync_point_and_drift(void);
void force_create_empty_nodes(int no, int topnode, int bits, int x, int y, int z, int *nodecount, int *nextfree);
void force_exchange_pseudodata(void);
void force_flag_localnodes(void);
void force_insert_pseudo_particles(void);
void force_setupnonrecursive(int no);
void force_treeallocate(int maxnodes, int maxpart);
int force_treebuild(int npart);
int force_treebuild_single(int npart);
int force_treeevaluate(int target, int mode, double *ewaldcountsum);
int force_treeevaluate_direct(int target, int mode);
int force_treeevaluate_ewald_correction(int target, int mode, double pos_x, double pos_y, double pos_z, double aold);
void force_treeevaluate_potential(int target, int type);
void force_treeevaluate_potential_shortrange(int target, int mode);
int force_treeevaluate_shortrange(int target, int mode);
void force_treefree(void);
void force_treeupdate_pseudos(void);
void force_update_hmax(void);
void force_update_len(void);
void force_update_node(int no, int flag);
void force_update_node_hmax_local(void);
void force_update_node_hmax_toptree(void);
void force_update_node_len_local(void);
void force_update_node_len_toptree(void);
void force_update_node_recursive(int no, int sib, int father);
void force_update_pseudoparticles(void);
void force_update_size_of_parent_node(int no);
void free_memory(void);
int get_bytes_per_blockelement(enum iofields blocknr);
void get_dataset_name(enum iofields blocknr, char *buf);
int get_datatype_in_block(enum iofields blocknr);
double get_drift_factor(int time0, int time1);
double get_gravkick_factor(int time0, int time1);
double get_hydrokick_factor(int time0, int time1);
int get_particles_in_block(enum iofields blocknr, int *typelist);
double get_random_number(int id);
#ifdef SFR
double get_StarFormation_random_number(int id);
#endif
#ifdef FEEDBACK_WIND
double get_FeedbackWind_random_number(int id);
#endif
#ifdef CHIMIE
double get_Chimie_random_number(int id);
#endif
#ifdef CHIMIE_KINETIC_FEEDBACK
double get_ChimieKineticFeedback_random_number(int id);
#endif
int get_timestep(int p, double *a, int flag);
int get_values_per_blockelement(enum iofields blocknr);
int grav_tree_compare_key(const void *a, const void *b);
void gravity_forcetest(void);
void gravity_tree(void);
void gravity_tree_shortrange(void);
double gravkick_integ(double a, void *param);
int hydro_compare_key(const void *a, const void *b);
void hydro_evaluate(int target, int mode);
void hydro_force(void);
double hydrokick_integ(double a, void *param);
int imax(int, int);
int imin(int, int);
void init(void);
void init_drift_table(void);
void init_peano_map(void);
void long_range_force(void);
void long_range_init(void);
void long_range_init_regionsize(void);
void move_particles(int time0, int time1);
size_t my_fread(void *ptr, size_t size, size_t nmemb, FILE * stream);
size_t my_fwrite(void *ptr, size_t size, size_t nmemb, FILE * stream);
int ngb_clear_buf(FLOAT searchcenter[3], FLOAT hguess, int numngb);
void ngb_treeallocate(int npart);
void ngb_treebuild(void);
int ngb_treefind_pairs(FLOAT searchcenter[3], FLOAT hsml, int phase, int *startnode);
#ifdef MULTIPHASE
int ngb_treefind_phase_pairs(FLOAT searchcenter[3], FLOAT hsml, int phase, int *startnode);
int ngb_treefind_sticky_collisions(FLOAT searchcenter[3], FLOAT hguess, int phase, int *startnode);
#endif
int ngb_treefind_variable(FLOAT searchcenter[3], FLOAT hguess, int phase, int *startnode);
#ifdef CHIMIE
int ngb_treefind_variable_for_chimie(FLOAT searchcenter[3], FLOAT hguess, int *startnode);
#endif
void ngb_treefree(void);
void ngb_treesearch(int);
void ngb_treesearch_pairs(int);
void ngb_update_nodes(void);
void open_outputfiles(void);
peanokey peano_hilbert_key(int x, int y, int z, int bits);
void peano_hilbert_order(void);
void pm_init_nonperiodic(void);
void pm_init_nonperiodic_allocate(int dimprod);
void pm_init_nonperiodic_free(void);
void pm_init_periodic(void);
void pm_init_periodic_allocate(int dimprod);
void pm_init_periodic_free(void);
void pm_init_regionsize(void);
void pm_setup_nonperiodic_kernel(void);
int pmforce_nonperiodic(int grnr);
void pmforce_periodic(void);
int pmpotential_nonperiodic(int grnr);
void pmpotential_periodic(void);
double pow(double, double); /* on some old DEC Alphas, the correct prototype for pow() is missing, even when math.h is included */
void read_file(char *fname, int readTask, int lastTask);
void read_header_attributes_in_hdf5(char *fname);
void read_ic(char *fname);
int read_outputlist(char *fname);
void read_parameter_file(char *fname);
void readjust_timebase(double TimeMax_old, double TimeMax_new);
void reorder_gas(void);
void reorder_particles(void);
#ifdef STELLAR_PROP
void reorder_stars(void);
void reorder_st(void);
#endif
void restart(int mod);
void run(void);
void savepositions(int num);
double second(void);
void seed_glass(void);
void set_random_numbers(void);
void set_softenings(void);
void set_units(void);
void init_local_sys_state(void);
void setup_smoothinglengths(void);
#ifdef CHIMIE
void stars_setup_smoothinglengths(void);
#endif
void statistics(void);
void terminate_processes(void);
double timediff(double t0, double t1);
#ifdef HAVE_HDF5
void write_header_attributes_in_hdf5(hid_t handle);
#endif
void write_file(char *fname, int readTask, int lastTask);
void write_pid_file(void);
#ifdef COOLING
int init_cooling(FLOAT metallicity);
int init_cooling_with_metals();
double cooling_function(double temperature);
double cooling_function_with_metals(double temperature,double metal);
void init_from_new_redshift(double Redshift);
double J_0();
double J_nu(double e);
double sigma_rad_HI(double e);
double sigma_rad_HeI(double e);
double sigma_rad_HeII(double e);
double cooling_bremstrahlung_HI(double T);
double cooling_bremstrahlung_HeI(double T);
double cooling_bremstrahlung_HeII(double T);
double cooling_ionization_HI(double T);
double cooling_ionization_HeI(double T);
double cooling_ionization_HeII(double T);
double cooling_recombination_HI(double T);
double cooling_recombination_HeI(double T);
double cooling_recombination_HeII(double T);
double cooling_dielectric_recombination(double T);
double cooling_excitation_HI(double T);
double cooling_excitation_HII(double T);
double cooling_compton(double T);
double A_HII(double T);
double A_HeIId(double T);
double A_HeII(double T);
double A_HeIII(double T);
double G_HI(double T);
double G_HeI(double T);
double G_HeII(double T);
double G_gHI();
double G_gHeI();
double G_gHeII();
double G_gHI_t(double J0);
double G_gHeI_t(double J0);
double G_gHeII_t(double J0);
double G_gHI_w();
double G_gHeI_w();
double G_gHeII_w();
double heating_radiative_HI();
double heating_radiative_HeI();
double heating_radiative_HeII();
double heating_radiative_HI_t(double J0);
double heating_radiative_HeI_t(double J0);
double heating_radiative_HeII_t(double J0);
double heating_radiative_HI_w();
double heating_radiative_HeI_w();
double heating_radiative_HeII_w();
double heating_compton();
void print_cooling(double T,double c1,double c2,double c3,double c4,double c5,double c6,double c7,double c8,double c9,double c10,double c11,double c12,double c13,double h1, double h2, double h3, double h4);
void compute_densities(double T,double X,double* n_H, double* n_HI,double* n_HII,double* n_HEI,double* n_HEII,double* n_HEIII,double* n_E,double* mu);
void compute_cooling_from_T_and_Nh(double T,double X,double n_H,double *c1,double *c2,double *c3,double *c4,double *c5,double *c6,double *c7,double *c8,double *c9,double *c10,double *c11,double *c12,double *c13,double *h1, double *h2, double *h3, double *h4);
double compute_cooling_from_Egyspec_and_Density(double Egyspec,double Density, double *MeanWeight);
double DoCooling(FLOAT Density,FLOAT Entropy,int Phase,int i,FLOAT DtEntropyVisc, double dt, double hubble_a);
void CoolingForOne(int i,int t0,int t1,double a3inv,double hubble_a);
void cooling();
double lambda(FLOAT density,FLOAT egyspec, int phase, int i);
#endif
#ifdef HEATING
void heating();
double gamma_fct(FLOAT Density,FLOAT Entropy,int i);
#endif
#ifdef AGN_HEATING
void agn_heating();
double gamma_fct(FLOAT density,double r, double SpecPower);
double HeatingRadialDependency(double r);
#endif
#ifdef MULTIPHASE
void update_phase(void);
void init_sticky(void);
void sticky(void);
void sticky_compute_energy_kin(int mode);
void sticky_collisions(void);
void sticky_collisions2(int loop);
void sticky_evaluate(int target, int mode, int loop);
int sticky_compare_key(const void *a, const void *b);
#endif
#ifdef FEEDBACK_WIND
void feedbackwind_compute_energy_kin(int mode);
#endif
#ifdef CHIMIE
void init_chimie(void);
+void check_chimie(void);
void chimie(void);
void do_chimie(void);
void chimie_evaluate(int target, int mode);
int chimie_compare_key(const void *a, const void *b);
int get_nelts();
char* get_Element(i);
float get_SolarAbundance(i);
#if defined(CHIMIE_THERMAL_FEEDBACK) && defined(CHIMIE_COMPUTE_THERMAL_FEEDBACK_ENERGY)
void chimie_compute_energy_int(int mode);
#endif
#if defined(CHIMIE_KINETIC_FEEDBACK) && defined(CHIMIE_COMPUTE_KINETIC_FEEDBACK_ENERGY)
void chimie_compute_energy_kin(int mode);
#endif
#ifdef CHIMIE_KINETIC_FEEDBACK
void chimie_apply_wind(void);
#endif
#endif
#ifdef OUTERPOTENTIAL
void init_outer_potential(void);
void outer_forces(void);
void outer_potential(void);
#ifdef NFW
void init_outer_potential_nfw(void);
void outer_forces_nfw(void);
void outer_potential_nfw(void);
#endif
#ifdef PLUMMER
void init_outer_potential_plummer(void);
void outer_forces_plummer(void);
void outer_potential_plummer(void);
#endif
#ifdef PISOTHERM
void init_outer_potential_pisotherm(void);
void outer_forces_pisotherm(void);
void outer_potential_pisotherm(void);
double potential_f(double r, void * params);
double get_potential(double r);
#endif
#ifdef CORIOLIS
void init_outer_potential_coriolis(void);
void set_outer_potential_coriolis(void);
void outer_forces_coriolis(void);
void outer_potential_coriolis(void);
#endif
#endif
#ifdef SFR
void star_formation(void);
void rearrange_particle_sequence(void);
void sfr_compute_energy_int(int mode);
void sfr_check_number_of_stars(int mode);
#endif
#ifdef AGN_ACCRETION
void compute_agn_accretion(void);
#endif
#ifdef BUBBLES
void init_bubble(void);
void make_bubble(void);
void create_bubble(int sign);
#endif
#ifdef BONDI_ACCRETION
void bondi_accretion(void);
#endif

Event Timeline