Program Listing for File Interpolator.cpp¶
↰ Return to documentation for file (/home/kpenev/projects/git/poet/poet_src/StellarEvolution/Interpolator.cpp)
#define BUILDING_LIBRARY
#include "Interpolator.h"
#include "SumQuantity.h"
#include "../Core/Functions.h"
namespace StellarEvolution {
int Interpolator::find_first_core_index(
const std::valarray<double> &core_mass
) const
{
int first_core_index = 0;
while(
first_core_index < static_cast<int>(core_mass.size())
&&
core_mass[first_core_index] == 0
) ++first_core_index;
return first_core_index;
}
void Interpolator::perform_queued_interpolations(
InterpolationQueue &interpolation_queue,
unsigned num_threads
)
{
for(
interpolation_queue.calculate(num_threads);
interpolation_queue;
interpolation_queue.pop_front()
) {
__interpolated_quantities[
interpolation_queue.quantity_id()
][
interpolation_queue.grid_index()
] = interpolation_queue.result();
}
}
void Interpolator::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
)
{
__track_masses = tabulated_masses;
__track_feh = tabulated_feh;
__core_formation = Core::Inf;
__vs_log_age = vs_log_age;
__log_quantity = log_quantity;
size_t num_tracks = (tabulated_masses.size()
*
tabulated_feh.size());
assert(tabulated_ages.size() == num_tracks);
assert(tabulated_quantities.size() == NUM_QUANTITIES);
assert(nodes.size() == NUM_QUANTITIES);
assert(smoothing.size() == NUM_QUANTITIES);
assert(vs_log_age.size() == NUM_QUANTITIES);
assert(log_quantity.size() == NUM_QUANTITIES);
typedef std::list< std::valarray<double> >::const_iterator
track_quantity_iter;
track_quantity_iter ages_iter=tabulated_ages.begin();
std::vector< track_quantity_iter > track_iter(NUM_QUANTITIES);
std::list< std::valarray<double> > log_ages;
for(
int quantity_index = 0;
quantity_index < NUM_QUANTITIES;
++quantity_index
) {
assert(tabulated_quantities[quantity_index].size()
==
num_tracks);
__interpolated_quantities[quantity_index].resize(num_tracks);
track_iter[quantity_index] =
tabulated_quantities[quantity_index].begin();
}
std::list<const std::valarray<double> *> to_delete;
InterpolationQueue interpolation_queue;
for(size_t grid_index = 0; grid_index < num_tracks; ++grid_index) {
std::clog << "Grid point " << grid_index
<< ": M = "
<< tabulated_masses[grid_index % tabulated_masses.size()]
<< ", [Fe/H] = "
<< tabulated_feh[grid_index
/
tabulated_masses.size()]
<< std::endl;
int first_core_index = (
tabulated_quantities[MRAD].empty()
? 0
: find_first_core_index(*(track_iter[MRAD]))
);
bool no_core = (
first_core_index == static_cast<int>(
track_iter[MRAD]->size()
)
||
(*(track_iter[MRAD]))[first_core_index] == 0
);
if(!no_core)
__core_formation = std::min(
__core_formation,
(*ages_iter)[std::max(0, first_core_index - 1)]
);
log_ages.push_back(std::log(*ages_iter));
for(
int quantity_index = 0;
quantity_index < NUM_QUANTITIES;
++quantity_index
) {
if(quantity_index >= FIRST_CORE_QUANTITY && no_core) {
__interpolated_quantities[quantity_index][grid_index] =
new Core::ZeroFunction();
__vs_log_age[quantity_index] = false;
__log_quantity[quantity_index] = false;
continue;
}
int first_interp_index;
const std::valarray<double> *interp_quantity;
if(log_quantity[quantity_index]) {
interp_quantity = new std::valarray<double>(
std::log(*(track_iter[quantity_index]))
);
to_delete.push_back(interp_quantity);
} else
interp_quantity = &(*(track_iter[quantity_index]));
if(quantity_index < FIRST_CORE_QUANTITY)
first_interp_index = 0;
else if(log_quantity[quantity_index])
first_interp_index = first_core_index;
else
first_interp_index = std::max(0, first_core_index - 1);
interpolation_queue.push_back(
(
vs_log_age[quantity_index]
? &(log_ages.back()[first_interp_index])
: &((*ages_iter)[first_interp_index])
),
&((*interp_quantity)[first_interp_index]),
ages_iter->size() - first_interp_index,
nodes[quantity_index],
smoothing[quantity_index],
quantity_index,
grid_index
);
}
++ages_iter;
for(
size_t quantity_index = 0;
quantity_index < NUM_QUANTITIES;
++quantity_index
)
++track_iter[quantity_index];
}
perform_queued_interpolations(interpolation_queue, num_threads);
for(
std::list<const std::valarray<double> *>::iterator
del_iter = to_delete.begin();
del_iter != to_delete.end();
++del_iter
)
delete *del_iter;
}
EvolvingStellarQuantity *Interpolator::operator()(
QuantityID quantity,
double mass,
double feh
) const
{
return new EvolvingStellarQuantity(
mass,
feh,
__track_masses,
__track_feh,
__interpolated_quantities[quantity],
__vs_log_age[quantity],
__log_quantity[quantity],
quantity >= FIRST_CORE_QUANTITY
);
}
void Interpolator::delete_tracks()
{
for(
std::vector<
std::vector<const OneArgumentDiffFunction*>
>::iterator quantity_tracks = __interpolated_quantities.begin();
quantity_tracks != __interpolated_quantities.end();
++quantity_tracks
)
for(
std::vector<const OneArgumentDiffFunction*>::iterator
track = quantity_tracks->begin();
track != quantity_tracks->end();
++track
)
if(*track) delete *track;
}
#ifndef NO_SERIALIZE
void Interpolator::load_state(const std::string &filename)
{
#ifndef NDEBUG
std::cerr << "Loading interpolator from " << filename << std::endl;
#endif
__interpolated_quantities.clear();
std::ifstream ifs(filename.c_str());
boost::archive::text_iarchive ia(ifs);
ia >> (*this);
ifs.close();
}
void Interpolator::save_state(const std::string &filename) const
{
#ifndef NDEBUG
std::cerr << "Saving interpolator to " << filename << std::endl;
#endif
std::ofstream ofs(filename.c_str());
boost::archive::text_oarchive oa(ofs);
oa << (*this);
}
#endif
} //End StellarEvolution namespace.