Planetary Orbital Evolution due to Tides
Orbital evolution of two objects experiencing tides
Interpolator.cpp
Go to the documentation of this file.
1 
8 #define BUILDING_LIBRARY
9 #include "Interpolator.h"
10 #include "SumQuantity.h"
11 #include "../Core/Functions.h"
12 
13 namespace StellarEvolution {
14 
16  const std::valarray<double> &core_mass
17  ) const
18  {
19  int first_core_index = 0;
20  while(
21  first_core_index < static_cast<int>(core_mass.size())
22  &&
23  core_mass[first_core_index] == 0
24  ) ++first_core_index;
25  return first_core_index;
26  }
27 
29  InterpolationQueue &interpolation_queue,
30  unsigned num_threads
31  )
32  {
33 
34  for(
35  interpolation_queue.calculate(num_threads);
36  interpolation_queue;
37  interpolation_queue.pop_front()
38  ) {
40  interpolation_queue.quantity_id()
41  ][
42  interpolation_queue.grid_index()
43  ] = interpolation_queue.result();
44  }
45  }
46 
48  const std::valarray<double> &tabulated_masses,
49  const std::valarray<double> &tabulated_feh,
50  const std::list< std::valarray<double> > &tabulated_ages,
51  const std::vector< std::list< std::valarray<double> > >
52  &tabulated_quantities,
53  const std::vector<double> &smoothing,
54  const std::vector<int> &nodes,
55  const std::vector<bool> &vs_log_age,
56  const std::vector<bool> &log_quantity,
57  unsigned num_threads
58  )
59  {
60  __track_masses = tabulated_masses;
61  __track_feh = tabulated_feh;
62  __core_formation = Core::Inf;
63  __vs_log_age = vs_log_age;
64  __log_quantity = log_quantity;
65 
66  size_t num_tracks = (tabulated_masses.size()
67  *
68  tabulated_feh.size());
69 
70  assert(tabulated_ages.size() == num_tracks);
71  assert(tabulated_quantities.size() == NUM_QUANTITIES);
72  assert(nodes.size() == NUM_QUANTITIES);
73  assert(smoothing.size() == NUM_QUANTITIES);
74  assert(vs_log_age.size() == NUM_QUANTITIES);
75  assert(log_quantity.size() == NUM_QUANTITIES);
76 
77  typedef std::list< std::valarray<double> >::const_iterator
78  track_quantity_iter;
79 
80  track_quantity_iter ages_iter=tabulated_ages.begin();
81 
82  std::vector< track_quantity_iter > track_iter(NUM_QUANTITIES);
83 
84  std::list< std::valarray<double> > log_ages;
85 
86  for(
87  int quantity_index = 0;
88  quantity_index < NUM_QUANTITIES;
89  ++quantity_index
90  ) {
91  assert(tabulated_quantities[quantity_index].size()
92  ==
93  num_tracks);
94  __interpolated_quantities[quantity_index].resize(num_tracks);
95  track_iter[quantity_index] =
96  tabulated_quantities[quantity_index].begin();
97  }
98 
99  std::list<const std::valarray<double> *> to_delete;
100 
101  InterpolationQueue interpolation_queue;
102 
103  for(size_t grid_index = 0; grid_index < num_tracks; ++grid_index) {
104 
105  std::clog << "Grid point " << grid_index
106  << ": M = "
107  << tabulated_masses[grid_index % tabulated_masses.size()]
108  << ", [Fe/H] = "
109  << tabulated_feh[grid_index
110  /
111  tabulated_masses.size()]
112  << std::endl;
113 
114  int first_core_index = (
115  tabulated_quantities[MRAD].empty()
116  ? 0
117  : find_first_core_index(*(track_iter[MRAD]))
118  );
119 
120  bool no_core = (
121  first_core_index == static_cast<int>(
122  track_iter[MRAD]->size()
123  )
124  ||
125  (*(track_iter[MRAD]))[first_core_index] == 0
126  );
127 
128  if(!no_core)
129  __core_formation = std::min(
131  (*ages_iter)[std::max(0, first_core_index - 1)]
132  );
133 
134  log_ages.push_back(std::log(*ages_iter));
135 
136  for(
137  int quantity_index = 0;
138  quantity_index < NUM_QUANTITIES;
139  ++quantity_index
140  ) {
141 
142  if(quantity_index >= FIRST_CORE_QUANTITY && no_core) {
143  __interpolated_quantities[quantity_index][grid_index] =
144  new Core::ZeroFunction();
145  __vs_log_age[quantity_index] = false;
146  __log_quantity[quantity_index] = false;
147  continue;
148  }
149 
150  int first_interp_index;
151  const std::valarray<double> *interp_quantity;
152  if(log_quantity[quantity_index]) {
153  interp_quantity = new std::valarray<double>(
154  std::log(*(track_iter[quantity_index]))
155  );
156  to_delete.push_back(interp_quantity);
157  } else
158  interp_quantity = &(*(track_iter[quantity_index]));
159  if(quantity_index < FIRST_CORE_QUANTITY)
160  first_interp_index = 0;
161  else if(log_quantity[quantity_index])
162  first_interp_index = first_core_index;
163  else
164  first_interp_index = std::max(0, first_core_index - 1);
165 
166  interpolation_queue.push_back(
167  (
168  vs_log_age[quantity_index]
169  ? &(log_ages.back()[first_interp_index])
170  : &((*ages_iter)[first_interp_index])
171  ),
172  &((*interp_quantity)[first_interp_index]),
173  ages_iter->size() - first_interp_index,
174  nodes[quantity_index],
175  smoothing[quantity_index],
176  quantity_index,
177  grid_index
178  );
179  }
180 
181  ++ages_iter;
182  for(
183  size_t quantity_index = 0;
184  quantity_index < NUM_QUANTITIES;
185  ++quantity_index
186  )
187  ++track_iter[quantity_index];
188  }
189  perform_queued_interpolations(interpolation_queue, num_threads);
190  for(
191  std::list<const std::valarray<double> *>::iterator
192  del_iter = to_delete.begin();
193  del_iter != to_delete.end();
194  ++del_iter
195  )
196  delete *del_iter;
197  }
198 
200  QuantityID quantity,
201  double mass,
202  double feh
203  ) const
204  {
205  return new EvolvingStellarQuantity(
206  mass,
207  feh,
209  __track_feh,
210  __interpolated_quantities[quantity],
211  __vs_log_age[quantity],
212  __log_quantity[quantity],
213  quantity >= FIRST_CORE_QUANTITY
214  );
215  }
216 
218  {
219  for(
220  std::vector<
221  std::vector<const OneArgumentDiffFunction*>
222  >::iterator quantity_tracks = __interpolated_quantities.begin();
223  quantity_tracks != __interpolated_quantities.end();
224  ++quantity_tracks
225  )
226  for(
227  std::vector<const OneArgumentDiffFunction*>::iterator
228  track = quantity_tracks->begin();
229  track != quantity_tracks->end();
230  ++track
231  )
232  if(*track) delete *track;
233  }
234 
235 #ifndef NO_SERIALIZE
236  void Interpolator::load_state(const std::string &filename)
237  {
238 #ifndef NDEBUG
239  std::cerr << "Loading interpolator from " << filename << std::endl;
240 #endif
242  std::ifstream ifs(filename.c_str());
243  boost::archive::text_iarchive ia(ifs);
244  ia >> (*this);
245  ifs.close();
246  }
247 
248  void Interpolator::save_state(const std::string &filename) const
249  {
250 #ifndef NDEBUG
251  std::cerr << "Saving interpolator to " << filename << std::endl;
252 #endif
253  std::ofstream ofs(filename.c_str());
254  boost::archive::text_oarchive oa(ofs);
255  oa << (*this);
256  }
257 #endif
258 
259 } //End StellarEvolution namespace.
std::valarray< double > __track_masses
Definition: Interpolator.h:58
The index of the first core quantity.
struct LIB_PUBLIC EvolvingStellarQuantity
Opaque struct to cast to/from StellarEvolution::EvolvingStellarQuantity pointers. ...
Definition: CInterface.h:47
std::vector< bool > __log_quantity
Was the interpolation of the log(corresponding quantity)?
Definition: Interpolator.h:75
Declare a class for a stellar evolution quantity which is the sum of two other quantities.
std::valarray< double > __track_feh
The stellar [Fe/H] values for which evolution tracks are available.
Definition: Interpolator.h:58
int grid_index() const
The grid index of the currently selected result.
Core::InterpolatingFunctionALGLIB * result() const
The currently selected interupolation result.
A class for stellar properties that depend on age.
int find_first_core_index(const std::valarray< double > &core_mass) const
Return the index of the first non-zero value in the argument.
std::vector< std::vector< const OneArgumentDiffFunction * > > __interpolated_quantities
The interpolated stellar evolution quantities for each track.
Definition: Interpolator.h:69
void push_back(const double *x, const double *y, size_t npoints, int nodes, double smoothing, int quantity_id, int grid_index)
Add an interpolation taks to the queue.
A class that handles a queue of interpolation tasks. Also functions as an iterator over the results...
virtual void save_state(const std::string &filename="../interp_state_data") const
Serializes the interpolation state to file.
double __core_formation
The age at which the core starts forming in Gyr.
Definition: Interpolator.h:78
int quantity_id() const
The quantity ID of the currently selected result.
void perform_queued_interpolations(InterpolationQueue &interpolation_queue, unsigned num_threads=1)
Perform all queued interpolations.
A class representing a function that is identically zero.
Definition: Functions.h:143
void pop_front()
Move to the next result in the queue (earlier results are no longer accessible.
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.
Definition: CInterface.cpp:17
virtual void load_state(const std::string &filename="../interp_state_data")
Loads data from serialization.
QuantityID
Defines the quantities tracked by stellar evolution and their order.
void delete_tracks()
Free all evolution tracks, rendering all created quantities unuseable!
virtual EvolvingStellarQuantity * operator()(QuantityID quantity, double mass, double feh) const
Return a single quantity interpolation to a given mass and [Fe/H].
std::vector< bool > __vs_log_age
Was the interpolation of the corresponding quantity vs. log(age)?
Definition: Interpolator.h:72
Mass of the stellar core in (low mass stars only).
Definition: IOColumns.h:126
Defines the StellarEvolution class needed for interpolating among stellar evolution tracks...