9 #define BUILDING_LIBRARY 32 std::ostringstream msg;
34 msg <<
"Stellar mass: " 38 <<
" are outside the range of masses: " 46 <<
" covered by the stellar evolution grid.";
52 const std::valarray<double> &boundaries,
58 const double *first_ptr = &boundaries[0],
59 *last_ptr = first_ptr + boundaries.size(),
60 *above_ptr = std::lower_bound(first_ptr,
63 *below_ptr = above_ptr;
64 if(boundaries.size() == 1) {
65 below_index = above_index = 0;
69 if(above_ptr >= last_ptr )
70 std::cerr <<
"Value: " 72 <<
" out of bounds: [" 75 << boundaries[boundaries.size() - 1]
80 assert( above_ptr < last_ptr );
82 if( value < *below_ptr) --below_ptr;
84 if(*above_ptr < value)
85 std::cerr <<
"Value: " << value
86 <<
" not in [" << *below_ptr <<
", " << *above_ptr <<
"]" 89 assert(*above_ptr >= value);
90 assert(value >= *below_ptr);
91 below_index = below_ptr - first_ptr;
92 above_index = above_ptr - first_ptr;
110 double min_track_age =
115 min_track_age = std::exp(min_track_age);
116 max_track_age = std::exp(max_track_age);
129 std::cerr <<
"Track " 149 double track_argument = (
__log_age ? std::log(age) : age);
151 assert(std::abs(track_argument - track.
range_low())
153 1e-8 * std::abs(track_argument));
161 track.
deriv(track_argument),
164 return (*derivatives)->
order(0);
165 }
else return track(track_argument);
307 std::valarray<size_t> padding(4);
316 if(grow.
lighter() && padding[0] == padding.min()) {
320 padding[0] = std::numeric_limits<size_t>::max();
321 if(grow.
poorer() && padding[1] == padding.min()) {
325 padding[1] = std::numeric_limits<size_t>::max();
326 if(grow.
richer() && padding[2] == padding.min()) {
339 std::vector<double>::const_iterator
399 std::cerr <<
"Age: " << age
400 <<
" not in [" <<
__min_age <<
", " << __max_age <<
"]" 403 assert(
__min_age <= age && age <= __max_age);
406 std::vector<double>::const_iterator
413 size_t num_interp_tracks = (
418 alglib::real_1d_array track_values;
419 track_values.setlength(num_interp_tracks);
420 std::vector<const FunctionDerivatives *>
423 new std::vector<const FunctionDerivatives *>(num_interp_tracks);
424 size_t value_index = 0;
446 ? &((*track_derivatives)[value_index])
452 if(derivatives == NULL) {
458 delete track_derivatives;
471 return (*derivatives)->order(0);
482 double feh_factor = std::pow(10.0, -feh / 5.0);
486 (1.0 + age / 5.0 * std::pow(mass, 5) * feh_factor)
490 std::pow(feh_factor, 2)
500 double feh_factor = std::pow(10.0, -feh / 5.0),
501 c = (std::exp(interp_param)
505 std::pow(feh_factor, 2)),
506 a = 0.2 * std::pow(mass, 5) * feh_factor,
507 discr = 1.0 + 4.0 * a * c;
508 return (std::sqrt(discr) - 1.0) / (2.0 * a);
514 const std::valarray<double> &track_masses,
515 const std::valarray<double> &track_feh,
516 const std::vector<const OneArgumentDiffFunction *> &evolution_tracks,
533 std::cerr <<
"Creating quantity with mass: " << mass
534 <<
", [Fe/H]: " << feh << std::endl
535 <<
", with track masses: " << track_masses << std::endl
536 <<
" and track [Fe/H]: " << track_feh << std::endl
537 <<
" with " << evolution_tracks.size() <<
" tracks" 541 assert(evolution_tracks.size() == (track_masses.size()
627 std::cerr <<
"Finding interpolation region for age = " 629 <<
", grid change ages: " 632 std::vector<double>::const_iterator
637 std::cerr <<
"\t" << *change_age_i << std::endl;
641 std::vector<double>::const_iterator new_grid_change_age =
664 double EvolvingStellarQuantity::previous_discontinuity()
const 674 void EvolvingStellarQuantity::enable_next_interpolation_region()
const Derivative class for stellar quantities which are interpolated age, mass and [Fe/H].
std::valarray< double > __track_feh
The [Fe/H] of the evolution tracks.
bool poorer() const
Can grow toward lower [Fe/H]?
bool __initially_zero
Should the quantity be assumed zero below the minimum track age.
AllowedGridGrowth & block_heavier()
Disable growth to higher masses.
void check_grid_range() const
Verify that the stellar mass and [Fe/H] are within range of the evolution tracks. ...
Function arguments do not satisfy some requirement.
double __min_age
The minimum age for which this quantity is defined in Gyr.
std::vector< const OneArgumentDiffFunction * > __evolution_tracks
The model tracks for the evolution of the quantity on the grid defined by ::__track_masses and ::__tr...
size_t __feh_index_above
The index of the smallest track [Fe/H] not smaller than ::__feh.
AllowedGridGrowth & block_richer()
Disable growth to higher [Fe/H].
size_t __mass_index_below
The index of the largest track mass not exceeding ::__mass.
The derivatives of an identically zero quantity.
double evaluate_track(double age, const OneArgumentDiffFunction &track, const FunctionDerivatives **derivatives) const
Interpolate the quantity for the given track to the given age, returning NaN if out of age range...
size_t track_index(size_t mass_index, size_t feh_index) const
Return the index within ::__evolution_tracks for the given mass and [Fe/H] indices.
A class representing a once differentiable function of a single argument.
Declares a class implementing the intepolation of a single stellar quantity from stellar evolution tr...
size_t __max_interp_feh_index
The index within ::__track_feh of the highest [Fe/H] currently participating in the interpolation...
double __max_age
The maximum age for which this quantity is defined in Gyr.
bool lighter() const
Can grow toward lower masses?
std::vector< double >::const_iterator __next_grid_change_age
The entry in ::__interp_grid_change_ages up to which the current interpolation grid is valid...
size_t __min_interp_feh_index
The index within ::__track_feh of the lowest [Fe/H] currently participating in the interpolation...
size_t __min_interp_mass_index
The index within ::__track_masses of the lowest mass currently participating in the interpolation...
std::valarray< double > __track_masses
The masses of the evolution tracks.
size_t __feh_index_below
The index of the largest track [Fe/H] not exceeding ::__feh.
void update_interpolation_grid() const
Find the best sub-grid of tracks to interpolate on.
double interpolate(double age, const FunctionDerivatives **derivatives=NULL) const
Interpolate the quantity to the desired age.
void select_interpolation_region(const EvolvingStar *star, double age)
Prepare the zone quantities for interpolation around the given age.
double interp_param_to_age(double interp_param) const
Return the age for the given interpoltaion parameter for the current star.
A class representing arbitrary order derivatives of a function.
Return dy/dx given dy/dln(x), dln(y)/dx or dln(y)/dln(x).
std::valarray< double > __max_interp_ages
The maximum interpolation age for the current star to which each track can contribute.
Return the age derivative of the quantity at the given age in virtual Gyr const FunctionDerivatives * deriv(double age) const
Returns a pointer to the derivative of the function.
double __mass
The mass to which to interpolate in .
AllowedGridGrowth & block_lighter()
Disable growth to lower masses.
bool __log_age
Whether the tracks have log(age) instead of age as their argument.
bool heavier() const
Can grow toward higher masses?
double age_to_interp_param(double age) const
Return the interpoltaion parameter for the given age for the current star.
void check_grid_expansion_directions(AllowedGridGrowth &grow, double age) const
Figure out in which directions we can expand a mass-[Fe/H] interpolation grid, assuming a single dire...
bool __log_quantity
Whether the tracks are of log(quantity) instead of the quantity.
EvolvingStellarQuantity()
Default constructor (only useful for derived classes which do not use the interpolation).
size_t __mass_index_above
The index of the smallest track mass not smaller than ::__mass.
std::valarray< double > __min_interp_ages
The minimum interpolation age for the current star to which each track can contribute.
bool richer() const
Can grow toward higher [Fe/H]?
double order(unsigned deriv_order=1) const
Returns the deriv_order-th derivative of the quantity.
bool track_in_range(size_t track_i, double age) const
Answer if a given track can participate in interpolating to the given age.
size_t __max_interp_mass_index
The index within ::__track_masses of the highest mass currently participating in the interpolation...
void set_interp_age_ranges()
Fill the ::__min_interp_ages and ::__max_interp_ages members.
double __feh
The [Fe/H] to which to interpolate.
std::vector< double > __interp_grid_change_ages
The ages at which the interpolation grid needs to be re-determined.
alglib::real_1d_array __interp_feh
The current track [Fe/H] values participating in the interpolation.
bool expand_grid(const AllowedGridGrowth &grow, double age) const
Attempt to expand the current interpolation grid returning true on success.
AllowedGridGrowth & block_poorer()
Disable growth to lower [Fe/H].
virtual const FunctionDerivatives * deriv(double x) const =0
Returns a pointer to the derivative of the function.
alglib::real_1d_array __interp_masses
The current track masses participating in the interpolation.
void find_cell(const std::valarray< double > &boundaries, double value, size_t &below_index, size_t &above_index) const
The two indices within the given sorted array defining the closed internal containing value...
virtual InputDataType range_low() const =0
The upper end of the range over which the function is defined.