Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
binary_c_structures.h 63.02 KiB
#pragma once
#ifndef BINARY_STRUCTURES_H
#define BINARY_STRUCTURES_H

/*
 * The binary_c stellar population nucleosynthesis framework.
 *
 * Contact: r.izzard@surrey.ac.uk or rob.izzard@gmail.com
 *
 * http://personal.ph.surrey.ac.uk/~ri0005/binary_c.html
 * https://gitlab.eps.surrey.ac.uk/ri0005/binary_c
 * https://groups.google.com/forum/#!forum/binary_c-nucsyn-announce
 * https://groups.google.com/forum/#!forum/binary_c-nucsyn-devel
 * https://twitter.com/binary_c_code
 * https://www.facebook.com/groups/149489915089142/
 *
 * Please see the files README, LICENCE and CHANGES,
 * and the doc/ directory for documentation.
 *
 *
 *
 * This header file contains the definitions of 
 * the memory structures used by binary_c/nucsyn, 
 * so is where variables and their types are defined.
 * 
 *
 * Please try to order structures efficently:
 *
 * 1) pack long items first (e.g. doubles and pointers), 
 * 2) pack short items at the end (e.g. ints and Booleans).
 *
 */
#include <stdio.h>
#include <setjmp.h>
#include "binary_c_code_options.h"
#include "binary_c_parameters.h" 
#include "binary_c_macros.h" 
#include "binary_c_types.h"
#ifdef CODESTATS
#include "binary_c_codestats.h"
#endif //CODESTATS
#include "memory/memory_function_macros.h"

#ifdef NUCSYN
/* Grab the settings for the nucleosynthesis */
#include "nucsyn/nucsyn_parameters.h"
#include "nucsyn/nucsyn_macros.h"
#include "nucsyn/nucsyn_isotopes.h"
#include "nucsyn/nucsyn_ensemble.h"
#endif /* NUCSYN */


#ifdef DISCS
#include "disc/disc_parameters.h"
#include "disc/disc_macros.h"
#include "disc/disc_function_macros.h"
#include "disc/disc_power_laws.h"
#include "disc/disc_constraints.h"
#endif//DISCS
#include "timestep/timestep.h"
/*
 * Data table plus 
 */
struct data_table_t {
    double *data;
    int nlines,nparam,ndata;
};


#ifdef USE_MERSENNE_TWISTER
#include "maths/mersenne_twister_macros.h"
/*
 * Mersenne random number generator data
 */
struct mersenne_twister_data_t {
    /* The array for the state vector */
    unsigned long long int mt[MERSENNE_TWISTER_NN];
    int mti;
};

#endif // USE_MERSENNE_TWISTER

/*
 * Generic random buffer type
 */
struct binary_c_random_buffer_t {
    Random_buffer buffer;
    long int count;
    Boolean set;
};


/*
 * custom file struct: use this with
 * binary_c_fopen, binary_c_fclose 
 * binary_c_fprintf and binary_c_fflush
 *
 * This enables you to specify your own
 * maximum file lengths and monitor file size. 
 */
struct binary_c_file_t {
#ifdef MEMOIZE
    struct memoize_hash_t * memo;
#endif//MEMOIZE
    FILE * fp;
    size_t size; // bytes
    size_t maxsize; // bytes
    char path[STRING_LENGTH];
};



struct difflogitem_t {
    struct stardata_t * stardata;
    double m[NUMBER_OF_STARS];
    char * string;
    size_t n;
};
    
struct difflogstack_t {
    struct difflogitem_t ** items;
    size_t n;
    size_t alloc_size;
};



#if defined MEMOIZE && !defined __HAVE_LIBMEMOIZE__
#include "libmemoize/memoize.h"
#endif // MEMOIZE && !__HAVE_LIBMEMOIZE__

/* data structure to handle fixed timestepping */
struct binary_c_fixed_timestep_t {
    /*
     * Note: times are linear if log is FALSE, otherwise they are log10(times)
     */
    double previous_test; /* previous time the trigger was checked */
    double previous_trigger; /* previous time it triggered */
    double step; /* the fixed timestep */
    double next; /* next time */
    double begin; /* start time of this being active */
    double end;  /* end time of this being active */
    Boolean logarithmic; /* if TRUE work in log time, if FALSE (default) linear time */
    Boolean enabled; /* disabled by default (when enable == 0 == FALSE) */
    Boolean final; /* if TRUE always trigger on final timestep */
};

/*
 * Persistant stored data: 
 * note that this struct is set up by binary_c when run,
 * and is NOT required to be copied around, hence the data 
 * in it is always assigned on the heap via Calloc, Malloc or
 * Realloc.
 */
struct store_t {
    
#ifdef NUCSYN
    Nuclear_mass *mnuc; /* Nuclear masses */
    Nuclear_mass *imnuc; /* 1.0/ Nuclear masses */
    Nuclear_mass *mnuc_amu; /* Nuclear masses divided by AMU */
    Nuclear_mass *imnuc_amu; /* 1.0 / (Nuclear masses divided by AMU) */
    double *molweight; /* factor used in molecular weight calculation */
    double *ZonA; /* factor used in molecular weight calculation */
    Atomic_number *atomic_number; /* Atomic numbers */
    int *nucleon_number; /* Nucleon numbers (mass numbers) */
    struct hsearch_data * atomic_number_hash;
    struct element_info_t * element_info;
    Isotope ** icache;//[NUMBER_OF_ELEMENTS+2][MAX_ISOTOPES_PER_ELEMENT];
#endif // NUCSYN
    
    /*
     * The collision matrix - i.e. what to do when the binary
     * star collides - see instar.c for details and setup. 
     * NB This is a square array of width COLLISION_MATRIX_SIZE.
     */
    Stellar_type *collision_matrix[COLLISION_MATRIX_SIZE];

    /* log file labels */
    const char *label[NLOG_LABELS];

    /*
     * Data tables
     */
    struct data_table_t * jaschek_jaschek_dwarf;
    struct data_table_t * jaschek_jaschek_giant;
    struct data_table_t * jaschek_jaschek_supergiant;
    struct data_table_t * miller_bertolami;
    struct data_table_t * miller_bertolami_coeffs_L;
    struct data_table_t * miller_bertolami_coeffs_R;
    
#ifdef MAIN_SEQUENCE_STRIP
    struct data_table_t * MS_strip;
#endif // MAIN_SEQUENCE_STRIP
#ifdef FIRST_DREDGE_UP_HOLLY
    struct data_table_t * Holly_1DUP_table;
#endif // FIRST_DREDGE_UP_HOLLY
#ifdef FIRST_DREDGE_UP_EVERT
    struct data_table_t * Evert_1DUP_table;
#endif //FIRST_DREDGE_UP_EVERT
#ifdef USE_2012_MAIN_SEQUENCE_LIFETIMES_TABLE
    struct data_table_t * massive_MS_lifetimes;
#endif // USE_2012_MAIN_SEQUENCE_LIFETIMES_TABLE
#ifdef STELLAR_COLOURS
    struct data_table_t * Eldridge2012_colours;
#endif // STELLAR_COLOURS

#ifdef NUCSYN
#ifdef NUCSYN_SIGMAV_PRE_INTERPOLATE
    struct data_table_t * sigmav;
#endif //NUCSYN_SIGMAV_PRE_INTERPOLATE
#ifdef NUCSYN_STRIP_AND_MIX
    struct data_table_t * TAMS;
#endif//NUCSYN_STRIP_AND_MIX
#ifdef NUCSYN_S_PROCESS
    struct data_table_t * s_process_Gallino;
#endif//NUCSYN_S_PROCESS
#ifdef NUCSYN_NOVAE
    struct data_table_t * novae_JH98_CO;
    struct data_table_t * novae_JH98_ONe;
#endif //NUCSYN_NOVAE
#endif //NUCSYN

#ifdef LAMBDA_CE_WANG_2016
    double *tableh1,*tableh2,*tableh3,
        *tableb1,*tableb2,*tableb3,
        *tableg1,*tableg2,*tableg3;
    struct data_table_t * comenv_maxR_table;
#endif//LAMBDA_CE_WANG_2016
#ifdef COMENV_POLYTROPES
    struct data_table_t * comenv_polytrope_2d;
    struct data_table_t * comenv_polytrope_3d;
    struct data_table_t * comenv_polytrope_rsms;
#endif//COMENV_POLYTROPES
#ifdef STELLAR_COLOURS
    double * zgr;
    double * tgr;
    double * ggr;
    double ****ubv; //double ubv[KURUCZ_NZGR+1][KURUCZ_NTGR+1][KURUCZ_NGGR+1][6];
#endif//STELLAR_COLOURS

#ifdef USE_BSE_MS_LR
    struct data_table_t * BSE_MS_LR;
#endif//USE_BSE_MS_LR
#ifdef USE_BSE_TIMESCALES_H
    struct data_table_t * BSE_TIMESCALES_H;
#endif//USE_BSE_TIMESCALES_H
    struct data_table_t * Karakas_ncal;
    struct data_table_t * Karakas2002_lumfunc;
    struct data_table_t * Karakas2002_radius;
#ifdef OPACITY_ALGORITHMS
#ifdef OPACITY_ENABLE_ALGORITHM_PACZYNSKI
    double kap_paczynski[52][32];
    struct data_table_t * opacity_STARS;
#endif//OPACITY_ENABLE_ALGORITHM_PACZYNSKI
#ifdef OPACITY_ENABLE_ALGORITHM_FERGUSON_OPAL
    struct data_table_t * opacity_ferguson_opal;
#endif//
#endif // OPACITY_ALGORITHMS
#ifdef BINT
    struct data_table_t * BINT_MS;
#endif//BINT

    Boolean built;
    Boolean debug_stopping;
};

/*
 * The tmpstore contains chunks of memory that 
 * can be deleted at any time (except during stellar evolution), 
 * but are useful to allocate just once as they are used a lot. 
 *
 * Subroutines which use tmpstore should check if the
 * pointer they are looking at is NULL, and if so they
 * should allocate memory.
 * 
 * The free_tmpstore function frees memory and zeros the
 * tmpstore structure. This is only called outside of 
 * the evolution loop, when a system is not being evolved.
 * Thus the tmpstore will not disappear during stellar evolution.
 *
 * You should not free the tmpstore yourself, use free_tmpstore.
 *
 * The tmpstore should be considered as non-persistent storage, 
 * so any data that is not required outside a subroutine should
 * only be allocated and freed inside that subroutine.
 *
 */
struct tmpstore_t {
    struct cmd_line_arg_t *cmd_line_args;
#ifdef ALPHA_ARGS
    struct cmd_line_arg_t ** cmd_line_args_alpha;
    unsigned int * cmd_line_args_alpha_count;
#endif//ALPHA_ARGS
    unsigned int arg_count;

#ifdef KICK_CDF_TABLE
    struct data_table_t * cdf_table;
#endif//KICK_CDF_TABLE
    struct data_table_t * Peters_grav_wave_merger_time_table;
    struct rinterpolate_data_t * rinterpolate_data;
    struct data_table_t * comenv_lambda_table;
#ifdef DISCS
    struct binary_c_file_t * disc_logfile;
    struct binary_c_file_t * disc_logfile2d;
#endif//DISCS
    struct difflogstack_t * logstack;
    struct star_t * stellar_structure_newstar;
    struct star_t * stellar_evolution_newstar;
    char * buffer_string;
#ifdef STELLAR_TIMESCALES_CACHE
    double Aligned stellar_timescales_cache_mass[Align(STELLAR_TIMESCALES_CACHE_SIZE)];
    double Aligned stellar_timescales_cache_mt[Align(STELLAR_TIMESCALES_CACHE_SIZE)];
    double Aligned stellar_timescales_cache_mc[Align(STELLAR_TIMESCALES_CACHE_SIZE)];
    double Aligned stellar_timescales_cache_GB[Align(STELLAR_TIMESCALES_CACHE_SIZE)][Align(GB_ARRAY_SIZE)];
    double Aligned stellar_timescales_cache_luminosities[Align(STELLAR_TIMESCALES_CACHE_SIZE)][Align(LUMS_ARRAY_SIZE)];
    double Aligned stellar_timescales_cache_timescales[Align(STELLAR_TIMESCALES_CACHE_SIZE)][Align(TSCLS_ARRAY_SIZE)];
    double Aligned stellar_timescales_cache_tm[Align(STELLAR_TIMESCALES_CACHE_SIZE)];
    double Aligned stellar_timescales_cache_tn[Align(STELLAR_TIMESCALES_CACHE_SIZE)];
    Stellar_type Aligned stellar_timescales_cache_stellar_type[Align(STELLAR_TIMESCALES_CACHE_SIZE)];
#endif

    char Aligned * raw_buffer;
    char Aligned * error_buffer; 
#ifdef BATCHMODE
    char Aligned * batchstring;
    char Aligned * batchstring2;
    char Aligned ** batchargs;
#endif//BATCHMOD
#ifdef WTTS_LOG
    FILE *fp_sys;
    FILE *fp_star[2];
#endif//WTTS_LOG

#ifdef NUCSYN

#ifdef NUCSYN_STRIP_AND_MIX
    FILE * strip_and_mix_fp[NUMBER_OF_STARS];
#endif//NUCSYN_STRIP_AND_MIX

#ifdef NUCSYN_STELLAR_POPULATIONS_ENSEMBLE
    Ensemble_type * ensemble_type;
#endif//NUCSYN_STELLAR_POPULATIONS_ENSEMBLE

    /*
     * Memory used in nucsyn_update_abundances
     */
    Abundance *Xacc[NUMBER_OF_STARS];
    Abundance *Xenv[NUMBER_OF_STARS];
    Abundance *nXacc[NUMBER_OF_STARS];
    Abundance *nXenv[NUMBER_OF_STARS];
    Abundance *Xwind_gain;
#ifdef NUCSYN_NOVAE
    Abundance *Xnovae;
#endif//NOVAE

#endif//NUCSYN
    double * unresolved_magnitudes;
    double * stellar_magnitudes[NUMBER_OF_STARS];
    double * comenv_lambda_data;
    double * Peters_grav_wave_merger_time_data;
    size_t raw_buffer_size;
    size_t raw_buffer_alloced;
#ifdef DISCS
    int disc_logfilecount;
    int disc_logfilecount2d;
#endif//DISCS

#ifdef LOG_SUPERNOVAE
    Boolean sn_header_printed;
#endif//LOG_SUPERNOVAE
    Boolean error_buffer_set;
};


/* new supernova struct */
struct new_supernova_t {
    struct star_t * new_stellar_structure;
    struct star_t * new_companion_structure;
#ifdef NUCSYN
    Abundance X[ISOTOPE_ARRAY_SIZE];
#endif//NUCSYN
};

/*
 * The preferences struct, deals with physics options, output files etc.
 */
#include "timestep/timestep.h"
struct preferences_t {

    void (*stellar_structure_function)(const Caller_id caller_id,
                                       ...);
    void (*custom_output_function)(struct stardata_t * stardata);

#ifdef BINT
    char * BINT_dir;
#endif//BINT

#ifdef EVOLUTION_SPLITTING
    struct splitinfo_t * splitinfo[EVOLUTION_SPLITTING_HARD_MAX_DEPTH];   
#endif//EVOLUTION_SPLITTING
    
    /* double parameters */

    double initial_M1;
    double initial_M2;
    double initial_orbital_separation;
    double initial_orbital_period;
    double initial_orbital_eccentricity;
    double initial_probability;
    Abundance metallicity;
    Abundance effective_metallicity;
#ifdef NUCSYN
    Abundance nucsyn_metallicity;
#endif
    double max_evolution_time;
    
    double timestep_multipliers[DT_NUMBER_OF_TIMESTEP_LIMITERS];    
    /* critical mass ratios per stellar type */
    double qcrit[NUMBER_OF_STELLAR_TYPES];
    double qcrit_degenerate[NUMBER_OF_STELLAR_TYPES];
    double sn_kick_dispersion[NUM_SN_TYPES];
    double sn_kick_companion[NUM_SN_TYPES];

#ifdef NUCSYN    
    Abundance the_initial_abundances[ISOTOPE_ARRAY_SIZE];
    Abundance initial_abundance_multiplier[ISOTOPE_ARRAY_SIZE];

#ifdef NUCSYN_THIRD_DREDGE_UP_MULTIPLIERS
    double third_dup_multiplier[ISOTOPE_ARRAY_SIZE];
#endif//NUCSYN_THIRD_DREDGE_UP_MULTIPLIERS

#ifdef NUCLEAR_REACTION_RATE_MULTIPLIERS
    // reaction rate multipliers
    double reaction_rate_multipliers[SIGMAV_SIZE];
#endif//NUCLEAR_REACTION_RATE_MULTIPLIERS
    
    double hbbtfac;// HBB temperature factor
#ifdef NUCSYN_S_PROCESS
    double c13_eff,mc13_pocket_multiplier;
#endif//NUCSYN_S_PROCESS

#ifdef USE_TABULAR_INTERSHELL_ABUNDANCES_KARAKAS_2012
    double pmz_mass; //CAB
#endif//USE_TABULAR_INTERSHELL_ABUNDANCES_KARAKAS_2012

#ifdef NUCSYN_CEMP_LOGGING
    double CEMP_cfe_minimum;
    double CEMP_minimum_age;
    double CEMP_logg_maximum;
#endif//NUCSYN_CEMP_LOGGING
    
#ifdef NUCSYN_GCE_OUTFLOW_CHECKS
    double escape_velocity; // galactic escape velocity
    double escape_fraction; // for stuff over escape velocity, what fraction
#endif // NUCSYN_GCE_OUTFLOW_CHECKS

#ifdef NUCSYN_YIELDS
    double yields_dt;
    double yields_logdt;
#endif//NUCSYN_SPARSE_YIELDS

    double yields_startlogtime;

#ifdef CN_THICK_DISC
    double thick_disc_start_age, thick_disc_end_age;
    double thick_disc_logg_min,thick_disc_logg_max;
#endif // CN_THICK_DISC
    

#ifdef LITHIUM_TABLES
    double lithium_hbb_multiplier;
    double lithium_GB_post_1DUP;
    double lithium_GB_post_Heflash;
#endif // LITHIUM_TABLES

#ifdef NUCSYN_ANGELOU_LITHIUM
    /* start times */
    double angelou_lithium_MS_time;
    double angelou_lithium_LMMS_time;
    double angelou_lithium_HG_time;
    double angelou_lithium_GB_time;
    double angelou_lithium_CHeB_time;
    double angelou_lithium_EAGB_time;
    double angelou_lithium_TPAGB_time;

    /* or use a vrot (or vrot/vkep) trigger */
    double angelou_lithium_vrot_trigger;
    double angelou_lithium_vrotfrac_trigger;
    
    /* decay times */
    double angelou_lithium_MS_decay_time;
    double angelou_lithium_LMMS_decay_time;
    double angelou_lithium_HG_decay_time;
    double angelou_lithium_GB_decay_time;
    double angelou_lithium_CHeB_decay_time;
    double angelou_lithium_EAGB_decay_time;
    double angelou_lithium_TPAGB_decay_time;

    /* mass fraction of lithium when it is created */
    double angelou_lithium_MS_massfrac;
    double angelou_lithium_LMMS_massfrac;
    double angelou_lithium_HG_massfrac;
    double angelou_lithium_GB_massfrac;
    double angelou_lithium_CHeB_massfrac;
    double angelou_lithium_EAGB_massfrac;
    double angelou_lithium_TPAGB_massfrac;
#endif // NUCSYN_ANGELOU_LITHIUM

#endif // NUCSYN

    // minimum and maximum timesteps 
    double minimum_timestep,maximum_timestep;
    // maximum timestep when nuclear burning
    double maximum_nuclear_burning_timestep;
    // maximum factor between timestep from step to step
    double maximum_timestep_factor;
    // factors to decrease and increase timestep when zooming
    double zoomfac_multiplier_decrease;
    double zoomfac_multiplier_increase;
    // timestep solver factor (see timestep_limits.c)
    double timestep_solver_factor;
    // Choice for mira period at which the superwind switches on during TPAGB
    double tpagb_superwind_mira_switchon;
    // Choice for Reimers eta on the TPAGB
    double tpagb_reimers_eta;
    // wind velocity multiplier (not for TPAGB stars)
    double vwind_multiplier; 

    /* accretion rates on each star  */
    double mass_accretion_rate1;
    double mass_accretion_rate2;
    double angular_momentum_accretion_rate1;
    double angular_momentum_accretion_rate2;
    /* and on the orbit */
    double angular_momentum_accretion_rate_orbit;
    /* start and end times */
    double accretion_start_time;
    double accretion_end_time;
    double minimum_donor_menv_for_comenv;
    double magnetic_braking_factor;
    double magnetic_braking_gamma;
    
    // Wolf Rayet wind selection
    /* Wolf-Rayet wind multiplication factor */
    double wr_wind_fac;
    /* Common envelope parameters */
    double alpha_ce;
    double lambda_ce;
    double lambda_ionisation;
    double lambda_enthalpy;
    
    /*
     * Accretion limit multipliers
     */
    double accretion_limit_eddington_multiplier;
    double accretion_limit_thermal_multiplier;
    double accretion_limit_dynamical_multiplier;
        
    /*
     * Donor limit multipliers
     */
    double donor_limit_thermal_multiplier;
    double donor_limit_dynamical_multiplier;
    double donor_limit_envelope_multiplier;

    // more free parameters
    // fraction of matter retained in a nova explosion
    double nova_retention_fraction; // 0.001
    double beta_reverse_nova;
    double nova_irradiation_multiplier;
    double nova_faml_multiplier;

    double nova_timestep_accelerator_num;
    double nova_timestep_accelerator_index;
    double nova_timestep_accelerator_max;
    
    // gamma is the angular momentum factor for mass lost during Roche (-1.0)
    double rlof_angmom_gamma; // 0.0
    // gamma for non-conservative mass transfer
    double nonconservative_angmom_gamma; 

#ifdef CIRCUMBINARY_DISK_DERMINE
    // fraction of mass loss which is feeding the circumbinary disk
    double alphaCB;
#endif // CIRCUMBINARY_DISK_DERMINE

    // Remiers GB mass loss eta factor
    double gb_reimers_eta;
    // Binary enhanced wind loss factor
    double CRAP_parameter;
    // Bondi-Hoyle accretion factor
    double Bondi_Hoyle_accretion_factor;

    /* various limiting core masses */
    double max_tpagb_core_mass;
    double chandrasekhar_mass;
    double max_neutron_star_mass;
    double minimum_mass_for_carbon_ignition;
    double minimum_mass_for_neon_ignition;
    double max_HeWD_mass;
    double minimum_helium_ignition_core_mass;
    
    /* multipliers */
    double gbwindfac,agbwindfac;
    double tidal_strength_factor;
    double merger_angular_momentum_factor;
    double wind_djorb_fac;
    /* orbital angular momentum loss factor from winds */
    double lw;
    // mass required to be accreted to make an ELD
    double mass_accretion_for_eld;
    
    // WD mass accretion limits
    double WD_accretion_rate_novae_upper_limit_hydrogen_donor;
    double WD_accretion_rate_novae_upper_limit_helium_donor;
    double WD_accretion_rate_novae_upper_limit_other_donor;
    double WD_accretion_rate_new_giant_envelope_lower_limit_hydrogen_donor;
    double WD_accretion_rate_new_giant_envelope_lower_limit_helium_donor;
    double WD_accretion_rate_new_giant_envelope_lower_limit_other_donor;

    // He Star Ia limits
    double mass_for_Hestar_Ia_lower;
    double mass_for_Hestar_Ia_upper;

#ifdef VW93_MIRA_SHIFT
    double vw93_mira_shift;
#endif// VW93_MIRA_SHIFT

#ifdef VW93_MULTIPLIER
    double vw93_multiplier;
#endif// VW93_MULTIPLIER

#ifdef COMENV_NS_ACCRETION
    // accretion onto neutron stars during comenv
    double comenv_ns_accretion_fraction;
    double comenv_ns_accretion_mass;
#endif// COMENV_NS_ACCRETION

#ifdef COMENV_MS_ACCRETION
    // accretion onto MS stars during comenv
    double comenv_ms_accretion_mass;
#endif// COMENV_MS_ACCRETION

#ifdef COMENV_POLYTROPES
    double comenv_splitmass;
#endif//COMENV_POLYTROPES
    double nelemans_gamma;
    double nelemans_minq;
    double nelemans_max_frac_j_change;
    
    
    double comenv_post_eccentricity;
    
    /* Hachisu 1996 disk wind for Ia Supernovae,
     * Their limit is multiplied by this factor, which 
     * is 1e20 by default
     */
    double hachisu_qcrit;

    double gravitational_radiation_modulator_J;
    double gravitational_radiation_modulator_e;
#ifdef TIMESTEP_MODULATION
    double timestep_modulator;
#endif//TIMESTEP_MODULATION

#ifdef RLOF_TIMESTEP_MODULATION
    double RLOF_timestep_modulator;
#endif//RLOF_TIMESTEP_MODULATION
    
#ifdef RLOF_MDOT_MODULATION
    double RLOF_mdot_factor;
#endif //RLOF_MDOT_MODULATION

#ifdef RLOF_RADIATION_CORRECTION
    // ratio of radiation to gravitational force in Roche lobe
    double RLOF_f;
#endif// RLOF_RADIATION_CORRECTION
    
#ifdef SELMA_BETTER_TREATMENT_OF_MS_MERGERS
    // the fraction of the combined mass of two main sequence stars that
    // is lost when they merge during the merger: - SdM May 2011 [0.1]
    double f_massloss_during_MS_mergers;
    // parameter regulating the amount of mixing during the merger of two MS stars
    // It is equal to the fraction of the "envelope" that is mixed (besides the core which is always mixed).
    // Note that the "envelope" may contain he rich material of the core of the secondary [0-1]
    double mixingpar_MS_mergers;
#endif //SELMA_BETTER_TREATMENT_OF_MS_MERGERS

    /* third dredge up */
    double minimum_envelope_mass_for_third_dredgeup;

    /* third dredge-up calibration parameters */
    double lambda_min;
    double delta_mcmin;
    double lambda_multiplier;

    // AGB timestep multiplication factor
    double dtfac;
#ifdef DISCS
    double cbdisc_max_lifetime;
    double disc_timestep_factor;
    double cbdisc_gamma;
    double cbdisc_alpha;
    double cbdisc_kappa;
    double cbdisc_torqueF;
    double cbdisc_init_dM;
    double cbdisc_init_dJdM;

#ifdef DISCS_CIRCUMBINARY_FROM_COMENV
    double comenv_disc_angmom_fraction;
    double comenv_disc_mass_fraction;
#endif // DISCS_CIRCUMBINARY_FROM_COMENV

#ifdef DISCS_CIRCUMBINARY_FROM_WIND
    double wind_disc_mass_fraction;
    double wind_disc_angmom_fraction;
#endif

    double cbdisc_minimum_evaporation_timescale;
    double cbdisc_mass_loss_constant_rate;
    double cbdisc_mass_loss_inner_viscous_multiplier;
    double cbdisc_mass_loss_inner_viscous_angular_momentum_multiplier;
    double cbdisc_mass_loss_inner_L2_cross_multiplier;
    double cbdisc_mass_loss_ISM_ram_pressure_multiplier;
    double cbdisc_mass_loss_ISM_pressure;
    double cbdisc_mass_loss_FUV_multiplier;
    double cbdisc_mass_loss_Xray_multiplier;
    double cbdisc_minimum_luminosity;
    double cbdisc_minimum_mass;
    double cbdisc_resonance_multiplier;
    double cbdisc_minimum_fRing;
    double disc_log_dt;

#endif // DISCS

    double observable_radial_velocity_minimum;
    double start_time;
    double max_stellar_angmom_change;
    
    double rotationally_enhanced_exponent;

#ifdef GAIAHRD
    double gaia_L_binwidth;
    double gaia_Teff_binwidth;
#endif //GAIAHRD
    
    /* 
     * Strings (e.g. Filenames)
     * Note: if these are passed in, they MUST be 
     * of length STRING_LENGTH to work with 
     * the command line parser.
     */
#ifdef BINARY_C_API
    char api_log_filename_prefix[STRING_LENGTH];
#endif // BINARY_C_API
    char stardata_dump_filename[STRING_LENGTH];
    char stardata_load_filename[STRING_LENGTH];
   
#ifdef FILE_LOG
    /* file log name */
    char log_filename[STRING_LENGTH];
#endif//FILE_LOG

#ifdef LOG_SUPERNOVAE
    char sn_dat_filename[STRING_LENGTH];
#endif//LOG_SUPERNOAVE
    
#ifdef BATCHMODE
    //char batchmode_string[BATCHMODE_STRING_LENGTH];
#endif // BATCHMOD

#ifdef NUCSYN
    char Seitenzahl2013_model[12];
#endif//NUCSYN
    
#if defined DISCS &&                            \
    (defined DISC_LOG ||                        \
     defined DISC_LOG_2D)
    char disc_log_directory[STRING_LENGTH];
#endif // DISCS && (DISC_LOG || DISC_LOG_2D)



    
    /* integer parameters */

    /* random number seed */
    long int cmd_line_random_seed;
    long int random_skip;

    Stellar_type initial_stellar_type1;
    Stellar_type initial_stellar_type2;
    
    int nelemans_n_comenvs;
    
#ifdef DISCS
    int cbdisc_eccentricity_pumping_method;
    int cbdisc_mass_loss_inner_viscous_accretion_method;
    int cbdisc_viscous_photoevaporation_coupling;
    int cbdisc_viscous_L2_coupling;
    int cbdisc_inner_edge_stripping_timescale;
    int cbdisc_outer_edge_stripping_timescale;
    int disc_log;
    int disc_log2d;
    int disc_n_monte_carlo_guesses;
#endif // DISCS
    
#ifdef EVOLUTION_SPLITTING
    int current_splitdepth;
    int evolution_splitting_maxdepth;
    /* number of splits for various cases */
    int evolution_splitting_sn_n;
#endif//EVOLUTION_SPLITTING
    
    /* maximum number of models */
    int max_model_number;
        
#ifdef OPACITY_ALGORITHMS
    int opacity_algorithm;
#endif// OPACITY_ALGORITHMS
    
#ifdef EQUATION_OF_STATE_ALGORITHMS
    int equation_of_state_algorithm;
#endif//EQUATION_OF_STATE_ALGORITHMS
    
    /* different wind choices */
    int gbwind,tpagbwind,wr_wind;

    /* algorithm to handle overspin */
    int overspin_algorithm;
    
#ifdef WD_KICKS
    /* when do we apply WD kicks? */
    int wd_kick_when;
    int wd_kick_pulse_number;
    /* WD kick direction */
    int wd_kick_direction;
#endif // WD_KICKS

    /* SN kick speed distribution: 
     * 0=KICK_VELOCITY_FIXED=fixed (but random direction),
     * 1=KICK_VELOCITY_MAXWELLIAN = maxwellian as in Hurley et al 2002
     * 2=custom function (see monte_carlo_kick.c for setup)
     */
    kick_dist sn_kick_distribution[NUM_SN_TYPES];
    
    /* orbital angular momentum loss prescription */
    int wind_angular_momentum_loss;

    /* angular momentum transfer model (RLOF) */ 
    int RLOF_angular_momentum_transfer_model;

    /* gravitational radiation model */
    int gravitational_radiation_model;

    /* Black hole formation prescription */
    int BH_prescription;

    /* E2 (conv. core tides) prescription */
    int E2_prescription;

    /*
     * RLOF interpolation method
     */
    int RLOF_interpolation_method;

    /*
     * Method for calculating the amount of
     * material accreted during novae
     */
    int nova_retention_method;

    int solver;
    
    /* evolution algorithm : currently have only BSE */
    unsigned int evolution_algorithm;    
    
    /* Wind-RLOF parameter */
#ifdef WRLOF_MASS_TRANSFER
    int WRLOF_method;
#endif//WRLOF_MASS_TRANSFER


   
    /* Wind mass loss options */
    Wind_loss_algorithm wind_mass_loss;
    int wind_mass_loss_algorithm;
    
    /* common envelope prescription changer */
    int comenv_prescription;
    int qcrit_giant_branch_method;

    /* common envelope spin behaviour */
    int comenv_ejection_spin_method;
    int comenv_merger_spin_method;

    /* magnetic braking algorithm */
    int magnetic_braking_algorithm;
    
    int post_SN_orbit_method;
    
    
#ifdef RANDOM_SYSTEMS
    int random_systems;
#endif//RANDOM_SYSTEMS

#ifdef BATCHMODE
    int batchmode;
    int batch_submode;
#endif//BATCHMODE
  
    int rotationally_enhanced_mass_loss;

    int repeat;
#ifdef MATTSSON_MASS_LOSS
    /* the wind to use when Mattsson's C-rich prescription is 
       not appropriate */
    int mattsson_Orich_tpagbwind;
#endif //MATTSSON_MASS_LOSS
    
    int RLOF_method;
    int small_envelope_method;
    int WDWD_merger_algorithm;

#ifdef NUCSYN
    /* which abundance mixture on the ZAMS? */
    Abundance_mix initial_abundance_mix;
    int type_Ia_MCh_supernova_algorithm;
    int type_Ia_sub_MCh_supernova_algorithm;

#ifdef NUCSYN_ANGELOU_LITHIUM
    int angelou_lithium_decay_function;
#endif//NUCSYN_ANGELOU_LITHIUM

#endif//NUCSYN
    
    int internal_buffering;

#ifdef GALACTIC_MODEL
    int galactic_model;
#endif//GALACTIC_MODEL

    int stellar_structure_algorithm;
    int AGB_core_algorithm;
    int AGB_radius_algorithm;
    int AGB_luminosity_algorithm;
    int AGB_3dup_algorithm;

    /* Boolean parameters */

    
#ifdef HRDIAG
    Boolean hrdiag_output;
#endif//HRDIAG

    Boolean individual_novae;
    Boolean use_fixed_timestep[NUMBER_OF_FIXED_TIMESTEPS];
    
    /* when events are better tested, this will be removed */
    Boolean disable_events; 
      
    Boolean force_corotation_on_RLOF;
    Boolean speedtests;
    
    /* Boolean to specify monte-carlo SN kicks or not */
    Boolean monte_carlo_sn_kicks;
    Boolean third_dup; // set third dredge up on and off
    Boolean rlperi;
    Boolean hachisu_disk_wind;
    Boolean show_minimum_separation_for_instant_RLOF;
    Boolean show_minimum_orbital_period_for_instant_RLOF;
#ifdef DISCS
    Boolean cbdisc_resonance_damping;
    Boolean cbdisc_fail_ring_inside_separation;
    Boolean cbdisc_inner_edge_stripping;
    Boolean cbdisc_outer_edge_stripping;
#endif//DISCS
#ifdef NUCSYN
    Boolean initial_abunds_only;

#ifdef NUCSYN_THIRD_DREDGE_UP_MULTIPLIERS
    Boolean boost_third_dup;
#endif // NUCSYN_THIRD_DREDGE_UP_MULTIPLIERS
#ifdef NUCSYN_TPAGB_HBB
    Boolean NeNaMgAl;
#endif//NUCSYN_TPAGB_HBB
#ifdef NUCSYN_YIELDS
    Boolean yields_logtimes;
#endif//NUCSYN_YIELDS
#ifdef NUCSYN_ALLOW_NO_PRODUCTION
    Boolean no_production;
#endif // NUCSYN_ALLOW_NO_PRODUCTION
    Boolean no_thermohaline_mixing;

#endif // NUCSYN


    
#ifdef PRE_MAIN_SEQUENCE
    Boolean pre_main_sequence,pre_main_sequence_fit_lobes;
#endif // PRE_MAIN_SEQUENCE
  
#ifdef DEBUG_FAIL_ON_NAN
    Boolean allow_debug_nan;
#endif//DEBUG_FAIL_ON_NAN

#ifdef DEBUG_FAIL_ON_INF
    Boolean allow_debug_inf;
#endif// DEBUG_FAIL_ON_INF

#ifdef REVERSE_TIME
    Boolean reverse_time;
#endif// REVERSE_TIME

#ifdef EVOLUTION_SPLITTING
    Boolean evolution_splitting;
#endif//EVOLUTION_SPLITTING
    Boolean nelemans_recalc_eccentricity;
};

#ifdef EVOLUTION_SPLITTING

struct splitinfo_t
{
    struct stardata_t * stardata;
    struct stardata_t ** previous_stardatas;
    int n_previous_stardatas;
    int depth;
    int count;
};

#endif//EVOLUTION_SPLITTING

/* struct to store data that is compared for logging purposes */
struct diffstats_t
{
    double mass[NUMBER_OF_STARS],mc[NUMBER_OF_STARS];
    double radius[NUMBER_OF_STARS],roche_radius[NUMBER_OF_STARS];
    double age[NUMBER_OF_STARS],tms[NUMBER_OF_STARS],omega[NUMBER_OF_STARS];
    double luminosity[NUMBER_OF_STARS],accretion_luminosity[NUMBER_OF_STARS];
    double orbital_separation;
    double orbital_period;
    double orbital_eccentricity;
    double orbital_angular_frequency;
    double novarate[NUMBER_OF_STARS],v_eq_ratio[NUMBER_OF_STARS];
    Time time;
    Stellar_type stellar_type[NUMBER_OF_STARS],hybrid_HeCOWD[NUMBER_OF_STARS];
    Supernova_type SN_type[NUMBER_OF_STARS];
    Nova_type nova[NUMBER_OF_STARS];
    Boolean sgl,artificial_accretion;
};

struct probability_distribution_t
{
    double (*func)(double*); // the generating functions
    double xmin; // the n range minima
    double xmax; // the n range maxima
    double x; // the generated co-ordinate
    double *table; // interpolation tables
    int nlines; // number of lines in the table 
    int maxcount; // max number of guesses at reconstruction (100)
    int error; // error code (0)
};


#ifdef DISCS

/* structure to define a power law */
struct power_law_t { 
    /* power law A(R) = A0 * (R/Rstart)^exponent from Rstart to Rend */
    double R0, R1, A0, A1, exponent;

};

/*
 * Structure to defined the contents of a disc, circumstellar or
 * circumbinary
 */
struct disc_thermal_zone_t {
    /*
     * Tlaw is required. This is the T(R) power law, it is 
     * a special case.
     */
    struct power_law_t Tlaw;
    
    /*
     * Alternative power laws, e.g. sigma(R)
     */
    struct power_law_t power_laws[DISCS_NUMBER_OF_POWER_LAWS];

    double rstart,rend;// start and end radii

    int type; // must not be unsigned (-1 is undef)

    Boolean valid; // TRUE if zone is valid (used during construction)
};


/*
 * Mass(etc) transfer struct
 */
struct disc_loss_t {
    double mdot; // mass loss rate
    double jdot; // angular momentum loss rate
    double edot; // eccentricity change rate
};

struct disc_t {
    struct memoize_hash_t * memo; /* memoize data */
    double M; // disc total mass
    double alpha; // disc viscosity constant (dimensionless)
    double gamma; // adiabatic exponent (dimensionless)
    double torqueF; // binary torque multiplication factor (dimensionless)
    double torqueF_for_Rin; // binary torque multiplication factor used to fix Rin (dimensionless)
    double fuv; // Far UV mass flux in g/cm^2/s
    double kappa; // Opacity in cm^2/g (assumed constant, only valid at low T)
    double Rin; // inner radius (cm)
    double Rout; // outer radius (cm)
    double Rin_min; // minimum inner radius
    double Rout_max; // maximum outer radius
    double lifetime; // lifetime of the disc (seconds)
    double dt; // natural timestep (seconds)
    double J; // total angular momentum
    double sigma0; // to be removed
    double mu;
    double Tvisc0;
    double F;
    double dM_binary,Mdot_binary;
    double dM_ejected,Mdot_ejected;
    double dJ_binary,Jdot_binary;
    double dJ_ejected,Jdot_ejected;
    double dT;
    double de_binary,edot_binary;
    double Tvisc,Tradin,Tradout;
    double Hin; // inner edge scale height
    double RJhalf; // half angular momentum radius 
    double HRJhalf; // H/R at half angular momentum radius
    double dRindt,dRoutdt; // derivatives
    double PISM,RISM;
    double LX; // X-ray irradiation onto the disc
#ifdef NUCSYN
    double X[ISOTOPE_ARRAY_SIZE];
#endif//NUCSYN
    double Owen2012_norm;
    double Revap_in,Revap_out,Rshred,F_stripping_correction,Mdot_evap_whole_disc;
    double nextlog;
    double fRing;
#ifdef DISC_SAVE_EPSILONS
    double epstorquef;
    double epsilon[DISC_NUMBER_OF_CONSTRAINTS];
#endif //DISC_LOG
#ifdef DISC_LOG_POPSYN
    double lastlogtime;
#endif//DISC_LOG_POPSYN
    double t_m;
    double t_m_slow;
    double t_j;
    double t_e;
#ifdef DISC_EQUATION_CHECKS
    double equations_T_error_pc;
    double equations_mass_loss_term_pc;
#endif // DISC_EQUATION_CHECKS

    /* mass,ang mom and eccentricty transfer */
    struct disc_loss_t loss[DISC_LOSS_N];

    /* allow a maximum of 3 thermal zones */
    Disc_zone_counter n_thermal_zones;
    struct disc_thermal_zone_t thermal_zones[DISCS_MAX_N_ZONES+1];
    unsigned int converged;
    int vb;    
    int ndisc;
    int type;
    int delete_count;
    int solver;
    int guess;
    int iteration;
    int end_count;
    Boolean first;
    Boolean firstlog;
    Boolean append;
    Boolean suppress_viscous_inflow;
    Stellar_type donor_stellar_type;
};

#endif // DISCS
/*
 * Stellar derivative structure
 */
struct derivative_t {
    double mass;
    double eccentricity;
    double specific_angular_momentum;
    double other;
};

#ifdef BINT

struct bint_t {
    /*
     * Information for the BINT interpolation
     * scheme which should be in star_t.
     */
    double XHc; /* central hydrogen abundance */
    double XHec; /* central helium abundance */
    double XCc; /* central helium abundance */
    double XOc; /* central helium abundance */
};
    
#endif//BINT

/************************************************************/
/************************************************************/
/************************************************************/

/* the star struct contains the data for each star */
struct star_t {
#ifdef BINT
    struct bint_t bint;
#endif//BINT
    double derivative[Align(NUMBER_OF_STELLAR_DERIVATIVES)];
#ifdef BSE
    double * timescales, *luminosities, *GB;
#endif//BSE
#ifdef DISCS
    struct disc_t **discs;
#endif //DISCS
    struct new_supernova_t * new_supernova;
#if defined NUCSYN && defined NUCSYN_STRIP_AND_MIX
    double X[NUCSYN_STRIP_AND_MIX_NSHELLS_MAX][ISOTOPE_ARRAY_SIZE];
    double mshell[NUCSYN_STRIP_AND_MIX_NSHELLS_MAX];
#endif //NUCSYN && NUCSYN_STRIP_AND_MIX
    double mass; /* mass, in solar masses */
    double radius; /* radius, unknown units! */
    double effective_radius; /* Max(roche_radius,radius) */
    double roche_radius; /* roche lobe radius */
    double roche_radius_at_periastron; /* roche lobe radius at periastron */
    double rmin; /* minimum radius of RLOF accretion stream */
    double phase_start_mass; /* Mass at the beginning of this stage in the star's life */
    double phase_start_core_mass;/* ditto for the core mass */
    double age; /* stellar age */
    double stellar_type_tstart; /* age at the start of this stellar type */
    double epoch; /** the epoch of the star **/
    double core_mass; /* core mass of the star */
    double GB_core_mass; /* dummy core mass on the GB */
    double CO_core_mass; /* CO core mass on the AGB */
    double max_MS_core_mass; /* max core mass on the MS */
    double core_radius; /* core radius */
    double luminosity; /* total luminosity of the star */
    double accretion_luminosity; /* accretion luminosity */
    double omega; /* star's angular frequency, y^-1 */
    double omega_crit; /* critical angular frequency */
#ifdef OMEGA_CORE
    double omega_core; /* core angular frequency, y^-1 */
    double omega_core_crit; /* core critical angular frequency */
    double core_angular_momentum;
#endif//OMEGA_CORE
    double l_acc; /* specific angular momentum of accreted material (in RLOF) */
    double angular_momentum; /**  spin angular momentum **/
    double q; /** mass ratio **/
    double tbgb; /** giant branch time **/
    double tms; /** main sequence time **/
    double dM_in_timestep; /* mass change in a timestep */
    double vwind; /* wind velocity (km/s ?) */
    double mdot; /* wind mass loss rate */
    double mcxx; /* er... */

    /* RLOF interpolation variables */
    double rol0; /* roche lobe radius at the start of RLOF */
    double aj0; /* age at the start of RLOF */
    double mass_at_RLOF_start; /* used in RLOF interpolation */
    double rdot; /* abs(dr/dt) - dRL/dt */
    double drdt; /* (dr/dt) */
    double stellar_timestep; /* star's timestep */
    double tm,tn; /* Main sequence and nuclear timescales */
    Time tkh; /** Kelvin-Helmholtz timescale **/
    double max_EAGB_He_core_mass;
    double menv,renv,k2; // envelope mass, radius, gyration constant,tidal constant
#ifdef BINT
    double E2;
#endif//BINT
    double compact_core_mass; /* mass in a compact core */
    double effective_zams_mass; /* "main sequence" mass : can change by accretion */
    double pms_mass; /* the true initial (end of pre-main sequence) mass */
    double mcx_EAGB;//CO core mass during EAGB and it's initial value
    double rzams;
    double rtms;
    
#ifdef WIND_ENERGY_LOGGING
    double Ewind,Elum;
#endif//WIND_ENERGY_LOGGING

#if defined SELMA_FIX_ACCRETED_MASS_IN_REJUVENATION     \
    || defined SELMA_BETTER_TREATMENT_OF_MS_ACCRETORS
    double last_mass;
#endif// SELMA_FIX_ACCRETED_MASS_IN_REJUVENATION || SELMA_BETTER_TREATMENT_OF_MS_ACCRETORS

    double A0; // for Chen+Han 2008 qcrit prescription (ln(BGB radius)) 

#ifdef XRAY_LUMINOSITY 
    double Xray_luminosity; /* luminosity in Xrays */
#endif//XRAY_LUMINOSITY
    double vrot0; /* initial spin in km/s */
    /* 
     * the stellar velocity assuming it's a sphere,
     * the stellar equatorial velocity,
     * critical velocity assuming it's a sphere,
     * critical equatorial velocity.
     */ 
    double v_sph,v_eq,v_crit_sph,v_crit_eq;
    /* ratio of omega/omega_crit, and v_../v_crit_.. */
    double omega_ratio,v_sph_ratio,v_eq_ratio;

    double disc_mdot; /* mass lost from a disc by wind */
    double rotfac; /* rotationally enhanced wind factor */

#ifdef ADAPTIVE_RLOF
    double prev_r; // previous timestep radius
    double prev_dm; /* mass strip from previous call to RLOF */
    double roldot; /* d(Roche Radius)/dt */
    double dmdr; 
    double nth;
    double RLOF_tkh;
    double RLOF_starttime;
#endif//ADAPATIVE_RLOF
#ifdef MAIN_SEQUENCE_STRIP
    double main_sequence_radius; /* radius (stored while star is on the main sequence) */
    double tms_at_start_caseA;
#endif//MAIN_SEQUENCE_STRIP

    double num_thermal_pulses;
    double num_thermal_pulses_since_mcmin;
    double num_novae;
    double dntp;
    double menv_1tp;
    double Mc_prev_pulse;
    
    double dm_3dup;
    double core_mass_no_3dup; /* core mass in the absence of dredge up */

    double mc_bgb; /* core mass at the base of the GB */
    double initial_mcx_EAGB; /* initial CO core mass on the EAGB */
    double time_first_pulse;
    double time_prev_pulse;
    double time_next_pulse;
    double model_time_first_pulse;
    double interpulse_period;
    double mc_1tp; /* core mass at first pulse */
    double lambda_3dup;
    double dm_novaH;
    double nova_beta,nova_faml;

#ifdef RUNAWAY_STARS
    double v_Rwx,v_Rwy,v_Rwz,v_Rw;
#endif// RUNAWAY_STARS
    
    double spiky_luminosity; // L modulated by pulse rise/fall
    double prev_tagb;
    double dmacc; /* mass of accreted layer */
#ifdef NUCSYN
    /* Nucleosynthesis stuff */
    /* stuff you might want to log */
    double rho; /* HBB layer  density */
    double temp; /* HBB layer burning temperature */
    double mira; /* mira period */
    double start_HG_mass;
    // zero age helium star abundances
    double hezamsmetallicity; // metallicity at the start of the helium MS
    // time at which the star becomes a helium star
    double he_t,he_f; // and fraction of HeMS completed
    // HBB stuff
    double f_burn;
    double f_hbb;
    double temp_mult;
    double temp_rise_fac;
    double fmdupburn;
    double ftimeduphbb;
    double mixdepth,mixtime;
    double dmmix; /* mass of mixed region at the stellar surface */
    double conv_base; /* mass coord of surface convection zone (on MS) */
    double dm_companion_SN; /* mass change caused by companion supernova */

    double max_mix_depth;
    double prev_depth;

#ifdef KARAKAS2002_SMOOTH_AGB_RADIUS_TRANSITION
    double rTEAGB; // terminal AGB radius
#endif//KARAKAS2002_SMOOTH_AGB_RADIUS_TRANSITION
    
#ifdef NUCSYN_WR  
    double he_mcmax;
#endif //NUCSYN_WR
    double mconv,thickest_mconv;

#ifdef NUCSYN_STRIP_AND_MIX
    int topshell;
#endif//NUCSYN_STRIP_AND_MIX

    Abundance Xenv[(ISOTOPE_ARRAY_SIZE)]; /* stellar envelope abundances array */
    Abundance Xacc[(ISOTOPE_ARRAY_SIZE)];  /* accreted material layer */
    Abundance Xinit[(ISOTOPE_ARRAY_SIZE)]; /* "initial" abundances, can be defined by accretion */
    Abundance Xyield[(ISOTOPE_ARRAY_SIZE)];/* mass yielded as a function of isotope number */
    Abundance Xhbb[(ISOTOPE_ARRAY_SIZE)];

#ifdef NUCSYN_WR_ACCRETION
    Abundance XWR0[ISOTOPE_ARRAY_SIZE];
#endif //NUCSYN_WR_ACCRETION

    /* optional arrays */
#ifdef NUCSYN_ID_SOURCES
    Abundance Xsource[NUMBER_OF_SOURCES][ISOTOPE_ARRAY_SIZE]; /* yield by source */
#endif// NUCSYN_ID_SOURCES
    
#ifdef NUCSYN_LOG_BINARY_MPYIELDS
    Abundance mpyield[ISOTOPE_ARRAY_SIZE];
#endif// NUCSYN_LOG_BINARY_MPYIELDS
    
#ifdef NUCSYN_FIRST_DREDGE_UP_ACCRETION_CORRECTION_FROM_TAMS
    Abundance XTAMS[ISOTOPE_ARRAY_SIZE]; /* Terminal-age MS abundances */
#endif//NUCSYN_FIRST_DREDGE_UP_ACCRETION_CORRECTION_FROM_TAMS
    
#ifdef LOG_FINAL_TPAGB_ABUNDS
    Abundance final_tpagbX[ISOTOPE_ARRAY_SIZE];
#endif // LOG_FINAL_TPAGB_ABUNDS
    
#ifdef NUCSYN_FIRST_DREDGE_UP_ACCRETION_CORRECTION
    double MS_mass; /* save the (terminal) main sequence mass */
#endif// NUCSYN_FIRST_DREDGE_UP_ACCRETION_CORRECTION
    
#ifndef NUCSYN_WR_TABLES
    double prevHeaj;
#endif//NUCSYN_WR_TABLES

#ifdef NUCSYN_LOG
    double prevlambda,prevr; 
#endif //NUCSYN_LOG

#ifdef NUCSYN_FIRST_DREDGE_UP_PHASE_IN
    double mc_gb_was; /* previous GB core mass */
#endif//NUCSYN_FIRST_DREDGE_UP_PHASE_IN

#ifdef  NS_BH_AIC_LOG
    double prev_luminosity,prev_radius,prev_mass,prev_core_mass;
#endif // NS_BH_AIC_LOG

#ifdef LOG_COMENV_RSTARS
    double r_star_postvrot;
    double r_star_postvrot2;
    double r_star_postvrot3;
    double r_star_postomega;
    double r_star_postvcrit;
    double r_star_postjspin;
    double r_star_prejorb;
    double r_star_prejtot;
    double r_star_precomenv_m1;
    double r_star_precomenv_m2;
    double r_star_precomenv_mc1;
    double r_star_precomenv_mc2;
    double r_star_precomenv_l1;
    double r_star_precomenv_l2;
    double r_star_postcomenv_l;
    double r_star_postcomenv_m;
    double r_star_postcomenv_mc;
    double r_star_comenv_time;
#endif // LOG_COMENV_RSTARS

#endif /* NUCSYN */

#ifdef LOG_SUPERNOVAE
    double sn_v,sn_rel_v;
#endif//LOG_SUPERNOVAE

#ifdef STELLAR_COLOURS
    double stellar_colour[NUMBER_OF_STELLAR_MAGNITUDES];
#endif//STELLAR_COLOURS
    
#ifdef ANTI_TZ
    double TZ_mass;
    double TZ_NS_mass;
#endif//ANTI_TZ
    
#ifdef FABIAN_COSMOLOGY
    double final_carbon_core_mass;
    double final_helium_core_mass;
    double final_nuclear_burning_mass;
    double nuclear_burning_lifetime;
#endif// FABIAN_COSMOLOGY

    Stellar_type stellar_type; /* stellar type */
    Stellar_type detached_stellar_type; /* stellar type when detached */
    Star_number starnum; // set to 0 for primary, 1 for secondary. useful for logging
    
#ifdef DISCS
    int ndiscs;
#endif//DISCS
    
    int dtlimiter;
    Supernova_type SN_type,was_SN; // 0 if no SN this timestep, otherwise SN number (see supernovae/sn.h)
    int prev_kick_pulse_number;
#ifdef ANTI_TZ
    int TZ_channel;
#endif//ANTI_TZ
    
#ifdef NUCSYN
    int sn_last_time; /* true if star went SN in last timestep */

#ifdef LOG_COMENV_RSTARS
    Stellar_type r_star_postcomenv_stellar_type1;
    Stellar_type r_star_postcomenv_stellar_type2;
    Stellar_type r_star_precomenv_stellar_type1;
    Stellar_type r_star_precomenv_stellar_type2;
#endif //LOG_COMENV_RSTARS

#ifdef  NS_BH_AIC_LOG
    Stellar_type prev_stellar_type;
#endif //NS_BH_AIC_LOG

#endif//NUCSYN
    
    Reject_index reject;
    Stellar_type compact_core_type;
    Nova_state nova;
    
    Boolean hybrid_HeCOWD;
#ifdef WD_KICKS
    /* flags to force kick of a star */
    Boolean kick_WD,already_kicked_WD;
#endif//WD_KICKS
#ifdef LOG_SUPERNOVAE
    Boolean supernova;
#endif//LOG_SUPERNOAVE

#ifdef NUCSYN
    Boolean rstar; /* true if star is R type */
    Boolean first_dredge_up; /* stores whether we've had first dredge up */
    Boolean second_dredge_up; /* stores whether we've had second dredge up */
    Boolean newhestar; // TRUE if never been a He star, FALSE if we have

#ifdef NUCSYN_ANGELOU_LITHIUM
    Boolean angelou_lithium_boost_this_timestep;
#endif// NUCSYN_ANGELOU_LITHIUM

#ifdef NUCSYN_CEMP_LOGGING
    Boolean cemp,nemp,xemp;
#endif //NUCSYN_CEMP_LOGGING

#ifdef LOG_COMENV_RSTARS
    Boolean r_star_progenitor;
#endif

#ifdef NUCSYN_FIRST_DREDGE_UP_PHASE_IN
    Boolean first_dup_phase_in_firsttime; 
#endif// NUCSYN_FIRST_DREDGE_UP_PHASE_IN

#endif  //NUCSYN

    Boolean blue_straggler;

#ifdef ANTI_TZ
    Boolean started_EAGB;
    Boolean TZ_object;
#endif//ANTI_TZ
    
#ifdef PRE_MAIN_SEQUENCE
    Boolean PMS;
#endif//PRE_MAIN_SEQUENCE
    
#ifdef NUCSYN

#ifdef CN_THICK_DISC
    Boolean was_blue_straggler;
#endif//CN_THICK_DISC
    
#ifdef NUCSYN_STRIP_AND_MIX
    Boolean strip_and_mix_disabled;
#endif//NUCSYN_STRIP_AND_MIX

#endif//NUCSYN
    Boolean tide_spin_lock;
};

/* the model struct contains data about the model run */
/* e.g. run-time parameters such as star types,       */
/* evolution time etc. and parameters to be read in   */
/* from a config file                                 */
struct model_t {

    /* fixed timestep algorithm settings */
    struct binary_c_fixed_timestep_t fixed_timesteps[NUMBER_OF_FIXED_TIMESTEPS];
    
#ifdef NUCSYN

#if defined NUCSYN_YIELD_COMPRESSION || defined NUCSYN_LOG_BINARY_DX_YIELDS
    Abundance oldyields[ISOTOPE_ARRAY_SIZE];

#ifdef NUCSYN_ID_SOURCES
    Abundance oldyieldsources[NUMBER_OF_STARS][NUMBER_OF_SOURCES][ISOTOPE_ARRAY_SIZE];
#endif //NUCSYN_ID_SOURCES

#endif // NUCSYN_YIELD_COMPRESSION || NUCSYN_LOG_BINARY_DX_YIELDS

#ifdef NUCSYN_STELLAR_POPULATIONS_ENSEMBLE
    double ensemble_store[NUMBER_OF_STARS][NUCSYN_ENSEMBLE_N];
#endif // NUCSYN_STELLAR_POPULATIONS_ENSEMBLE
#endif // NUCSYN

    /* file pointers */
#ifdef FILE_LOG
    FILE *log_fp;
#endif //FILE_LOG
#ifdef BINARY_C_API
    FILE *api_log_fp;
#endif //BINARY_C_API

    double derivative[NUMBER_OF_SYSTEM_DERIVATIVES];
    double probability; /* the probability of the current model run */
    double time; /* the  time, was tphys in the fortran version */
    double max_evolution_time; /* Maximum evolution time, in Myr */ 
    double dt,dtm,true_dtm,time_remaining,dtmwas; /* timestepping */
    double dt_zoomfac,RLOF_recommended_timestep,nova_timeout;
    double prev_log_t;
#ifdef FABIAN_IMF_LOG
    double next_fabian_imf_log_time;
    double fabian_imf_log_timestep;
#endif //FABIAN_IMF_LOG
#if defined NUCSYN && defined NUCSYN_STELLAR_POPULATIONS_ENSEMBLE
    double lastensembleouttime;
    double gce_prevt;
#endif // NUCSYN && NUCSYN_STELLAR_POPULATIONS_ENSEMBLE

#ifdef HRDIAG
    double hrdiag_dt_guess;
#endif

    /* Variables for RLOF interpolation */
    double tphys0,tphys00,dtm0;

#ifdef PHASE_VOLUME
    double phasevol; /* grid phase volume */
#endif//PHASE_VOLUME
    
#ifdef HRDIAG
    double next_hrdiag_log_time;
    double prev_hrdiag_log_time;
    double hrdiag_log_dt;
#endif //HRDIAG

#ifdef NUCSYN
#ifdef NUCSYN_YIELDS
    double next_yield_out,prev_yield_out;
#endif

#ifdef NUCSYN_GIANT_ABUNDS_LOG
    double giant_prevt,giant_dt;
#endif
#ifdef LOG_JJE
    double log_jje_tprev;
#endif
#ifdef NUCSYN_LOG_JL
    double log_jl_tprev;
#endif
#ifdef NUCSYN_CEMP_LOGGING
    double cemp_log_prevt;
#endif
#ifdef LOG_RSTARS
    double rstar_prevtime;
#endif // LOG_RSTARS
#endif // NUCSYN

    char logflagstrings[NLOGFLAGS][STRING_LENGTH];
    int logstack[NLOGFLAGS]; 
    
    Reject_index reject;
    unsigned int coalesce;   


#ifdef LOG_REPEAT_NUMBER
    int repeat_number;
#endif // LOG_REPEAT_NUMBER

    int intpol,iter; // interpolation counter
    int comenv_type; // non-zero if common envelope occurred.
    int current_solver;
    int solver_step;
    int model_number;

#ifdef COUNT_COMENVS
    /* number of common envelope evolutions this star has gone through */
    int comenv_count;
#endif //COUNT_COMENVS

#ifdef NO_IMMEDIATE_MERGERS
    int evolution_number;
#endif //NO_IMMEDIATE_MERGERS

#ifdef BINARY_C_API
    /* id number, for use in multi-star systems */
    int id_number;
#endif //BINARY_C_API

#ifdef RLOF_ABC
    int rlof_type,rlof_stability,rlof_count;
#endif //RLOF_ABC
    Star_number ndonor,naccretor;
#ifdef ZW2019_SNIA_LOG
    Star_number ZW2019_Hestar;
    Star_number ZW2019_COWD;
#endif// ZW2019_SNIA_LOG    

    Boolean RLOF_start,RLOF_end;
    Boolean supernova,merged,inttry;
    Boolean sgl; /* True if the star is not a binary, false if it is */
    Boolean prec; /* precision exceeded */
    Boolean com; /* contact/comenv system */
    Boolean supedd; /* are we super-eddington? */
    Boolean restart_run[NUMBER_OF_STARS];
    Boolean rerun;
    Boolean exit_after_end;
    Boolean in_RLOF; // use this to check for whether we're in RLOF phase
    Boolean intermediate_step;
    Boolean deny_new_events;
    Boolean fixed_timestep_triggered;
    Boolean logflags[NLOGFLAGS];

#ifdef SYSTEM_LOGGING
    Boolean syslog_header_printed;
#endif // SYSTEM_LOGGING
    
#ifdef RLOF_ABC
    Boolean do_rlof_log;
#endif //RLOF_ABC

    Boolean hachisu;
#if defined NUCSYN_NOVAE && defined FILE_LOG
    Boolean novalogged;
#endif //NUCSYN_NOVAE && FILE_LOG
    
#ifdef EVOLUTION_SPLITTING
    Boolean doingsplit;
    Boolean split_last_time;
#endif // EVOLUTION_SPLITTING


    double nova_aggression_factor;
};

struct orbit_t {
    double period; /* Orbital period in years */
    double angular_frequency; /* Orbital angular frequency, y^-1 */
    double angular_momentum; /* Orbital angular momentum, code units */ 
    double eccentricity; /* Orbital eccentricity */
    double separation; /* Orbital separtaion in Rsun */
    double tcirc; // circularisation timescale (years)
};

/*
 * The common struct contains data common to both stars.
 *
 * There should be no dynamically allocated memory, i.e. 
 * no pointers, in the common struct. 
 */
struct common_t {

    /* events stack */
    struct binary_c_event_t ** events;
    struct binary_c_event_t * current_event;

    /* orbital information */
    struct orbit_t orbit;

    /* stats for logging */

    struct diffstats_t Aligned diffstats[2];
#ifdef NEW_DIFFLOG
    struct diffstats_t * diffstats_now;
    struct diffstats_t * diffstats_prev;
#endif //NEW_DIFFLOG

#ifdef DISCS
    struct disc_t discs[NDISCS];
#endif //DISCS
    
#ifdef MEMOIZE
    struct memoize_hash_t * memo;
#endif //MEMOIZE
    struct binary_c_random_buffer_t random_buffer;
#if defined NUCSYN && defined NUCSYN_STRIP_AND_MIX
    struct data_table_t strip_and_mix_table;
#endif // NUCSYN && NUCSYN_STRIP_AND_MIX
 
#ifdef FILE_LOG
    char file_log_prevtype[20];
#endif // FILE_LOG
#ifdef BSE
    double Aligned main_sequence_parameters[Align(MAIN_SEQUENCE_PARAMETERS_SIZE)];
    double Aligned giant_branch_parameters[Align(GIANT_BRANCH_PARAMETERS_SIZE)];
    double Aligned metallicity_parameters[Align(NUMBER_OF_METALLICITY_PARAMETERS)];
#endif//BSE
#ifdef NUCSYN//NUCSYN
    Abundance Aligned XZAMS[ISOTOPE_ARRAY_SIZE]; // ZAMS abundances
    Abundance Aligned Xsolar[ISOTOPE_ARRAY_SIZE]; // Solar (Z=0.02) abundances
    double Aligned dtguess[NUMBER_OF_REACTION_NETWORKS];
#ifdef NUCSYN_STRIP_AND_MIX
    double strip_and_mix_table_data[TAMS_NDOUBLES];
#endif//NUCSYN_STRIP_AND_MIX
#endif//NUCSYN
    
    Random_buffer random_systems_buffer;
    Random_seed random_seed,init_random_seed,random_systems_seed;
    char ** argv;
#ifdef BSE
    double parameters_metallicity;
#endif//BSE
#ifdef HRDIAG
    double hrdiag_prevlog,hrdiag_filltot,hrdiag_prevbintb;
#endif//HRDIAG
    double test; // remove me after testing
#ifdef LOG_SUPERNOVAE
    double double_sn_prob;
    FILE *snfp;
#endif//LOG_SUPERNOVAE
#ifdef DETAILED_LOG
    FILE *detailed_log_fp;
#endif//DETAILED_LOG
#ifdef FILE_LOG
    double file_log_prev_rlof_exit;
    char *file_log_prevstring;
#endif//FILE_LOG
    Abundance metallicity; /* The metallicity, Z, range 0-1 */
    Abundance effective_metallicity;
    double RLOF_speed_up_factor; // used in RLOF interpolation
    double max_mass_for_second_dredgeup;
    double zams_period;
    double zams_separation;
    double zams_eccentricity;
    double mdot_RLOF;
    double prevt_mdot_RLOF;
#ifdef ADAPTIVE_RLOF
    /* RLOF */
    double mdot_RLOF_adaptive;
    double mdot_RLOF_BSE;
    double suggested_timestep; /* years */
    double RLOF_rwas, RLOF_rolwas;
#ifdef ADAPTIVE_RLOF_LOG
    double RLOF_log_m1was;
#endif// ADAPTIVE_RLOF_LOG
#endif//ADAPTIVE_RLOF
    double monte_carlo_kick_normfac;

#ifdef NUCSYN
    Abundance nucsyn_metallicity; // Z to pass to SNe routines for GCE

#ifdef LOG_BARIUM_STARS
    double barium_prevt;
#endif//LOG_BARIUM_STARS

#ifdef NUCSYN_R_STAR_LOG
    double lastcallrlog;
#endif//NUCSYN_R_STAR_LOG

#ifdef NUCSYN_LONG_LOG
    double tpagbtime;
#endif//NUCSYN_LONG_LOG

#endif //NUCSYN

#ifdef DETAILED_COMPACT_LOG
    double detailed_compact_log_count
#endif//DETAILED_COMPACT_LOG

#ifdef GALACTIC_MODEL
    double galatic_coords[3];
    double distance;
#endif//GALACTIC_MODEL
    
#ifdef PHASE_VOLUME
    double phase_volume; // do we still need this?
#endif//PHASE_VOLUME
    
#ifdef CIRCUMBINARY_DISK_DERMINE
    double m_circumbinary_disk;
#endif//CIRCUMBINARY_DISK_DERMINE
    
#ifdef COMENV_LECTURE1
    double minrad,maxrad;
#endif//COMENV_LECTURE1

#ifdef GAIAHRD
    double gaia_Teff,gaia_L;
#endif//GAIAHRD
    
    int n_events;
#ifdef DISCS
    int ndiscs;
#endif//DISCS
    
#ifdef ADAPTIVE_RLOF_LOG
    int used_rate,runaway_rlof,thermal_cap;
#endif//ADAPTIVE_RLOF_LOG
    
#ifdef LOG_SUPERNOVAE
    int sn_number,sn_count,sn_last_time_type[NUMBER_OF_STARS];
#endif//LOG_SUPERNOVAE
    
#ifdef DETAILED_LOG
    int detailed_log_count;
#endif//DETAILED_LOG

#ifdef FILE_LOG
    int file_log_n_rlof;
#endif//FILE_LOG

#ifdef NUCSYN
    
#ifdef NUCSYN_LONG_LOG
    int tpagbcount;
#endif//NUCSYN_LONG_LOG

#ifdef NUCSYN_NETWORK_STATS
    int nucsyn_network_total_success_count,
        nucsyn_network_total_failure_count;
#endif// NUCSYN_NETWORK_STATS
    
    int nucsyn_log_count;
    int nucsyn_short_log_count;
#endif//NUCSYN
    
    int argc;
    
    Boolean prevflags[NLOG_LABELS];
    Boolean lockflags[NUMBER_OF_STARS][NLOCKFLAGS+1];
    Boolean interpolate_debug;
    Boolean diffstats_set;
    Boolean logflag;
    
    Boolean had_event;
#ifdef SINGLE_STAR_LIFETIMES
    Boolean done_single_star_lifetime;
#endif//SINGLE_STAR_LIFETIMES
    
#ifdef CANBERRA_PROJECT
    Boolean canberra_done_first_timestep;
#endif//CANBERRA_PROJECT
    
#ifdef FABIAN_IMF_LOG
    Boolean fabian_logged_zero;
#endif// FABIAN_IMF_LOG
    
#ifdef PRE_MAIN_SEQUENCE
    Boolean pms[NUMBER_OF_STARS];
#endif//PRE_MAIN_SEQUENCE
    
#ifdef NS_NS_BIRTH_LOG
    Boolean nsns;
#endif//NS_NS_BIRTH_LOG
    
#ifdef COMENV_LECTURE1
    Boolean star1_agb;
#endif//COMENV_LECTURE1

#ifdef HRDIAG
    Boolean hrdiag_done_zams,hrdiag_use2;
#endif //HRDIAG
    
#ifdef VISCOUS_RLOF_TRIGGER_SMALLER_TIMESTEP
    Boolean viscous_RLOF_wants_smaller_timestep;
#endif//VISCOUS_RLOF_TRIGGER_SMALLER_TIMESTEP
    
#ifdef LOG_SUPERNOVAE
    Boolean gone_sn[NUMBER_OF_STARS];
#endif//LOG_SUPERNOVAE
    
    Boolean sn_sc_header;
#ifdef FILE_LOG
    Boolean file_log_cached;    
#endif//FILE_LOG

#if defined NUCSYN && defined NUCSYN_STRIP_AND_MIX
    Boolean strip_and_mix_is_setup ;
#endif//NUCSYN && NUCSYN_STRIP_AND_MIX
};

/* The stardata struct contains the data we're interested in */
struct stardata_t {
    struct common_t common;
    struct star_t star[NUMBER_OF_STARS];
    struct model_t model; 
    struct preferences_t * preferences;
    struct store_t *store;
    struct tmpstore_t *tmpstore;
    struct stardata_t * previous_stardata;
    struct stardata_t ** previous_stardatas;
    struct stardata_t ** stardata_stack;
#ifdef CODESTATS
    struct codestats_t * codestats;
#endif//CODESTATS
#ifdef BATCHMODE
    jmp_buf batchmode_setjmp_buf;
#endif//BATCHMODE
    double warmup_timer_offset;
    unsigned int n_previous_stardatas;
    unsigned int n_stardata_stack;
    Boolean cpu_is_warm;
    Boolean evolving;
};
#define __HAVE_STARDATA_T


struct RLOF_orbit_t {
    /* 
     * RLOF mass transfer in one orbit.
     *
     * dM_RLOF_lose (was dm1 in BSE) is the mass that is lost from star 1
     * during an orbit. This number is negative (mass is lost).
     *
     * dM_RLOF_transfer (was dm2 in BSE) is the mass transferred in RLOF 
     * in an orbit, i.e. this is what the accreting star tries
     * to accrete. This number is positive.
     *
     * dM_RLOF_accrete (was dm22) is the mass actually accreted 
     * during RLOF in an orbit, which is not the same as
     * dM_RLOF_transfer if there are, e.g., novae.
     * This number is positive.
     *
     * Usually dm_RLOF_transfer == dm_RLOF_accrete
     */
    double dM_RLOF_lose,dM_RLOF_transfer,dM_RLOF_accrete;
    
    /*
     * Also required are the other mass losses during an orbit,
     * e.g. wind loss,
     * although these are generally small compared to the RLOF rate.
     *
     * NB These are negative in the case of (wind) loss.
     */
    double dM_other[NUMBER_OF_STARS];
};



#ifdef DISCS
struct binary_system_t {
    double m1;// greater of the masses (grams)
    double m2;// lesser of the masses (grams)
    double mtot; // total mass (grams)
    double reduced_mass; // grams
    double q; // m2/m1
    double separation; // orbital semi-major axis, cm

    /* NB distances are relative to the centre of mass */
    double aL1; // L1 radius, cm
    double aL2; // L2 radius, cm
    double aL3; // L3 radius, cm
    double a1; // a1 = position of star 1
    double a2; // a2 = position of star 2
    double Jorb; // cgs
    double eccentricity; // no units 
    double L; // erg/s
    double flux; // erg / s / cm^2
    double LFUV; // FUV luminosity, erg/s
    double LEUV; // EUV luminosity, erg/s
    double LX; // X-ray luminosity, erg/s
    double omega; // angular frequency (rad/s)
    double orbital_period;
    double Teff[NUMBER_OF_STARS];
    double luminosity[NUMBER_OF_STARS];
    double Rstar;
    double torqueF;
    Boolean RLOF;
};
#endif//DISCS


struct coordinate_t {
    double x;
    double y;
    double z;
};


struct kick_system_t {
    /* separation at the moment of explosion */
    double separation;
    
    /* eccentric and mean anomalies */
    double eccentric_anomaly;
    double mean_anomaly;

    /* relative stellar velocity : magntiude and square */
    double orbital_speed;
    double orbital_speed_squared;    
    
    /* beta is the angle between r and v */
    double sinbeta;
    double cosbeta;

    /* kick speed and squared */
    double kick_speed;
    double kick_speed_squared;
    
    /* phi is the angle between the kick and the orbital plane */
    double phi;
    double sinphi;
    double cosphi;

    /*
     * theta is the angle perpendicular to the angle
     * between the kick and the line between the stars.
     * NB in Hurley+2002 this is the angle omega.
     */
    double omega;
    double sinomega;
    double cosomega;

    /* new orbital speed */
    double new_orbital_speed;
    double new_orbital_speed_squared;

    /* new specific angular momentum */
    double hn;
    double hn_squared;

    /* bound before explosion? */
    Boolean bound_before_explosion;
};

struct opacity_t {
    double temperature;
    double density;
    double Z;
    double Fe;
    double H;
    double He;
    double C;
    double N;
    double O;
    double alpha;
};

struct equation_of_state_t {
    double error;

    double X; // hydrogen mass fraction
    double Y; // helium mass fraction
    double Z; // metallicity
    double temperature;
    double density;
    double lnf;
    double P; // pressure (cgs)
    double Pgas; // gas pressure (cgs)
    double Prad; // radiation pressure (cgs)
     
    /* ionisation fractions */
    double xh1;
    double xhe1;
    double xhe2;

    /* number of densities of species */
    double nH2; // hydrogen molecules
    double nHI; // neutral hydrogen
    double nHII; // ionized hydrogen
    double nHeI; // neutral helium
    double nHeII; // ionized helium 
    double nHeIII; // doubly-ionized helium
    double ne; // free electrons
    double nt; // total number of particles

    /* temperature gradients */
    double gradad; // dlnT/dlnP at const S
    double gradrad;

    /* adiabatic sound speed */
    double cs_ad;

    /* Cp, Cv : specific heats */
    double Cp; // dU/dt const P
    double Cv; // dU/dT const rho (or volume)

    /* internal energy */
    double U;

    /* thermodynamic derivatives */
    double dP_dT_rho; // dP/dT const rho (or volume)
    double dP_drho_T;// dP/drho const T
    double dlnrho_dlnT_P; // d(ln rho)/d(ln T) const P

    int include_radiation_in_ionization_region;
};



struct envelope_shell_t {
    double m; /* M(r) */
    double dm; /* dM */
    double r;
    double tau;
    double temperature;
    double density;
    double pressure;
    double grad;
    double gradad;
    double gradrad;
    double xion_h1;
    double xion_he1;
    double xion_he2;
    double X;
    double Y;
    double Z;
};

struct envelope_t {
    struct envelope_shell_t * shells;
    double logl;
    double logt0;
    double logteff;
    double m;
    double fm;
    double x;
    double y;
    double z;
    double alpha;
    double surface_density;
    double surface_tau;
    double tmax;
    double tauf;
    double E_bind,E1,E2,E3;
    double lambda_bind;
    double moment_of_inertia;
    int nshells;
};

struct stardata_dump_t
{
    int dump_format;
    int svn_revision; 
    char git_revision[STRING_LENGTH];
    char versionstring[50];
    char versioninfo[MEGABYTE];
    size_t sizeof_stardata_t;
    size_t sizeof_preferences_t;
    struct preferences_t preferences;
    struct stardata_t stardata;
    struct store_t store;
    struct tmpstore_t tmpstore;
};


struct GSL_args_t
{
    va_list args;
    brent_function func;
    int error;
    Boolean uselog;
};

#include "binary_c_event_structures.h"

    
#endif /*BINARY_STRUCTURES_H*/