1 #define BUILDING_LIBRARY 4 std::ostream &operator<<(std::ostream &os,
36 (
Xprotosun + scaling * std::pow(10.0, feh))
47 (1.0 -
Yprimordial - scaling * std::pow(10.0, metallicity))
129 const std::string &filename,
130 unsigned &line_number)
133 for(;line==
""; ++line_number) {
135 std::ostringstream msg;
136 msg <<
"Failed to extract line " << line_number
137 <<
" from " << filename <<
".";
140 std::getline(track, line);
143 std::istringstream line_parser(line);
144 std::string column_name;
146 int column_number = 0;
150 std::getline(line_parser, column_name,
',');
151 int colname_index = 0;
172 unsigned line_number=0;
205 std::ostringstream message;
207 <<
"' on line " << line_number <<
" of " << filename
228 for(
size_t i=0; i<quantity_iter.size(); ++i) ++quantity_iter[i];
235 assert(__mass_list.size() == __feh_list.size());
236 std::list<double>::const_iterator
237 mass_iter = __mass_list.begin(),
238 feh_iter = __feh_list.begin();
240 std::list< std::valarray<double> >::const_iterator
241 age_iter = __track_ages.begin();
242 while(mass_iter != __mass_list.end()) {
243 assert(feh_iter != __feh_list.end());
244 assert(age_iter != __track_ages.end());
255 std::istringstream fname_stream(filename);
256 if(fname_stream.get() !=
'M' || !fname_stream.good())
260 fname_stream >> mass;
261 if(!fname_stream.good() || mass <= 0)
return false;
263 if(fname_stream.get() !=
'_' || !fname_stream.good())
265 if(fname_stream.get() !=
'Z' || !fname_stream.good())
268 double metallicity = 0;
269 fname_stream >> metallicity;
270 if(!fname_stream.good() || metallicity <= 0)
return false;
272 __feh_list.push_back(
281 __mass_list.push_back(std::round(PRECISION * mass) / PRECISION);
288 const std::valarray<double> __ages;
290 CompareAges(
const std::valarray<double> &ages) : __ages(ages) {}
292 bool operator()(
size_t i1,
size_t i2)
293 {
return __ages[i1] < __ages[i2];}
299 std::is_sorted(std::begin(__track_ages.back()),
300 std::end(__track_ages.back()))
304 std::valarray<size_t> age_sorting_indices(
305 __track_ages.back().size()
307 for(
size_t i = 0; i < __track_ages.back().size(); ++i)
308 age_sorting_indices[i] = i;
309 std::sort(std::begin(age_sorting_indices),
310 std::end(age_sorting_indices),
313 __track_ages.back() = std::valarray<double>(
314 __track_ages.back()[age_sorting_indices]
317 std::is_sorted(std::begin(__track_ages.back()),
318 std::end(__track_ages.back()))
325 __track_quantities[quantity].back() = std::valarray<double>(
326 __track_quantities[quantity].back()[age_sorting_indices]
332 std::ifstream track(filename.c_str());
333 Header header(track, filename);
334 std::vector< std::list<double> > track_columns = parse_columns(
336 header.get_all_columns()
342 assert(__mass_list.back()
346 __track_ages.push_back(
347 Core::list_to_valarray(track_columns[
MESA::AGE]) * 1e-9
350 <<
"Model: M = " << __mass_list.back()
351 <<
", [Fe/H] = " << __feh_list.back()
353 << __track_ages.back()[__track_ages.back().size() - 1]
356 QuantityID quantity = __column_to_quantity[column];
360 track_columns[column].empty()
364 __track_quantities[quantity].push_back(
367 Core::list_to_valarray(track_columns[column])
371 __track_quantities[quantity].push_back(
372 Core::list_to_valarray(track_columns[column])
375 sort_last_track_by_age();
379 std::valarray<double> &masses,
380 std::valarray<double> &feh
383 assert(__mass_list.size() == __feh_list.size());
384 std::list<double>::const_iterator
385 mass_iter = __mass_list.begin(),
386 feh_iter = __feh_list.begin();
388 std::list< std::valarray<double> >::const_iterator
389 age_iter = __track_ages.begin();
391 size_t num_masses = 0;
393 double first_feh = *feh_iter;
394 *feh_iter == first_feh;
398 feh_iter = __feh_list.begin();
399 assert(__mass_list.size() % num_masses == 0);
400 size_t num_feh = __mass_list.size() / num_masses;
402 masses.resize(num_masses);
405 for(
size_t feh_index = 0; feh_index < num_feh; ++feh_index) {
407 size_t mass_index = 0;
408 mass_index < num_masses;
411 assert(mass_iter != __mass_list.end());
412 assert(feh_iter != __feh_list.end());
414 <<
"M = " << *mass_iter
415 <<
", [Fe/H] = " << *feh_iter
416 <<
", age range = " << (*age_iter)[0]
417 <<
" - " << (*age_iter)[age_iter->size() -1]
420 masses[mass_index] = *mass_iter;
421 else if(masses[mass_index] != *mass_iter)
423 "Input MESA tracks do not lie on a grid of " 428 feh[feh_index] = *feh_iter;
429 else if(feh[feh_index] != *feh_iter)
431 "Input MESA tracks do not lie on a grid of " 440 assert(feh_iter == __feh_list.end());
441 assert(mass_iter == __mass_list.end());
448 result.
feh_iter = __feh_list.begin();
449 result.
age_iter = __track_ages.begin();
452 __track_quantities[quantity].begin();
461 result.
age_iter = __track_ages.end();
464 __track_quantities[quantity].end();
484 __track_quantities[quantity].splice(
486 __track_quantities[quantity],
490 log_current_age_ranges();
497 double last_sorted_mass = *iter.
mass_iter,
499 while(iter != stop_iter) {
517 if(iter == stop_iter)
break;
536 unsigned num_threads,
537 const std::vector<double> &smoothing,
538 const std::vector<int> &nodes,
539 const std::vector<bool> &vs_log_age,
540 const std::vector<bool> &log_quantity) :
543 std::clog <<
"Reading tracks from " 546 DIR *dirstream = opendir(model_directory.c_str());
548 if(model_directory[model_directory.size()-1] ==
'/') join=
"";
550 if(dirstream == NULL)
552 "in MESA::Evolution constructor.",
555 struct dirent *entry;
556 while((entry = readdir(dirstream))) {
557 std::string fname(entry->d_name);
561 fname.substr(fname.size() - 4) ==
".csv" 567 << model_directory + join + fname
573 << model_directory + join + entry->d_name
577 "Failed to close directory stream tied to " 581 " in MESA::Evolution constructor." 584 std::valarray<double> masses, feh;
587 <<
"Done reading tracks." << std::endl
588 <<
"Starting interpolation" << std::endl;
599 std::cout <<
"Done with interpolation" << std::endl;
EvolutionIterator & operator=(const EvolutionIterator &rhs)
Copy rhs to *this.
The total number of interesting columns.
double metallicity_from_feh(double feh)
Return the metallicity interpolation parameter corresponding to the given [Fe/H] value.
const double Yprotosun
The Helium fraction with which the Sun formed.
Used as comparison when sorting quantities by age.
bool parse_model_file_name(const std::string &filename)
Parse the mass (in ) and [Fe/H] from a track filename.
RADIUS
The derivative w.r.t. the radius of the body in .
EvolutionIterator & operator++()
Advance all iterators to the next track.
std::list< std::valarray< double > >::iterator age_iter
Iterator over the array of ages of the tracks.
Mass of the radiative core in .
static const std::vector< bool > __default_log_quantity
The default selection of interpolation function (quantity vs log(quantity) for each quantity...
const double Yprimordial
The primordial Helium fraction of the universe.
const double scaling
A scaling constant used when transforming between different metallicity quantities.
Log10 of the luminosity of the star in .
const double Zprotosun
The metal fraction with which the Sun formed.
Log10 of the radius of the star in .
const int LUM
Identifier for the stellar luminosity as an interpolation quantity.
static const std::vector< bool > __default_vs_log_age
The default selection of interpolation argument (age vs log(age) for each quantity. See StellarEvolution::Interpolator::create_from.
const double Xprotosun
The hydrogen fraction with which the Sun formed.
The total mass of the star in .
void log_current_age_ranges() const
Output the current masses [Fe/H] and age ranges.
Exception indicating that a file or a directory was not found.
Column
Names for the interesting columns in a MESA track.
std::list< std::valarray< double > > __track_ages
The ages at which each track is tabulated.
Defines the classes for generating stellar evolution interpolators from the MESA tracks.
Moment of inertia of the convective envelope in .
The luminosity of the star in .
double feh_from_metallicity(double metallicity)
Return the [Fe/H] value corresponding to the given metallicity.
void read_model_file(const std::string &filename)
Reads a single evolution track file.
std::list< double >::iterator feh_iter
Iterator over the masses of the tracks.
std::vector< std::list< std::valarray< double > > > __track_quantities
A structure holding all interesting quantities from the MESA tracks except age.
static const std::vector< QuantityID > __column_to_quantity
The value at the indexed from Column is the StellarEvolution::QuantityID to which this column is conv...
EvolutionIterator end()
Returns an EvolutionIterator pointing to the end of all quantities.
Moment of inertia of the radiative zone of the star (low mass stars only) in .
void create_from(const std::valarray< double > &tabulated_masses, const std::valarray< double > &tabulated_feh, const std::list< std::valarray< double > > &tabulated_ages, const std::vector< std::list< std::valarray< double > > > &tabulated_quantities, const std::vector< double > &smoothing, const std::vector< int > &nodes, const std::vector< bool > &vs_log_age, const std::vector< bool > &log_quantity, unsigned num_threads)
Fully setup an object created by the default constructor.
const int NUM_QUANTITIES
The number of interpolation quantities currentyl supported.
Moment of inertia of the convective zone of the star (low mass stars only) in .
An iterator over the list of extracted tracks.
Radius of the radiative core in .
The radius of the star in .
std::list< double >::iterator mass_iter
Iterator over the masses of the tracks.
QuantityID
Defines the quantities tracked by stellar evolution and their order.
Radius of the stellar core in (low mass stars only).
std::vector< std::list< std::valarray< double > >::iterator > quantity_iter
Iterators over the arrays of the track quantities.
void get_mass_feh_grid(std::valarray< double > &masses, std::valarray< double > &feh)
Verify that the track masses and [Fe/H] form a grid and return the grid.
Moment of inertia of the radiative core in .
The number of significant figures require of the evolution.
EvolutionIterator begin()
Returns an EvolutionIterator pointing to the beginning of all quantities.
void sort_last_track_by_age()
Sorts the quantities read from the last track by age.
static const std::vector< int > __default_nodes
The default number of node to use for each quantity. See StellarEvolution::Interpolator::create_from...
void move(EvolutionIterator &dest, EvolutionIterator &source)
Moves source to right before destination.
Mass of the stellar core in (low mass stars only).
static const std::vector< double > __default_smoothing
The default amount of smoothing to use for each quantity. See StellarEvolution::Interpolator::create_...
void sort_tracks()
Sorts the data by mass and [Fe/H].