Planetary Orbital Evolution due to Tides
Orbital evolution of two objects experiencing tides
PolynomialEvolution.cpp
1 #include "PolynomialEvolution.h"
2 
3 namespace StellarEvolution {
4 
5  double PolynomialEvolutionQuantity::order(unsigned deriv_order) const
6  {
7  if(__deriv_x < __xmin || __deriv_x > __xmax) {
8  std::ostringstream msg;
9  msg << ("Attempt to evaluate a PolynomialEvolutionQuantity "
10  "defined over ")
11  << __xmin << " < x < " << __xmax << " at x=" << __deriv_x
12  << ", polynomial coefficients:" << __poly_coef;
13  std::cout << msg.str() << std::endl;
14 // *static_cast<int*>(NULL) = 0;
15  throw Core::Error::Runtime(msg.str());
16  }
17  double xn = 1, result = 0;
18  for(size_t n = deriv_order; n < __poly_coef.size(); ++n) {
19  double coef_mod = 1;
20  for(size_t i = 0; i < deriv_order; ++i) coef_mod *= (n-i);
21  result += coef_mod * __poly_coef[n] * xn;
22  xn *= __deriv_x;
23  }
24  return result;
25  }
26 
28  double core_formation_age,
29  const std::valarray< std::valarray<double> > &R,
30  const std::valarray< std::valarray<double> > &Iconv,
31  const std::valarray< std::valarray<double> > &Irad,
32  const std::valarray< std::valarray<double> > &Rcore,
33  const std::valarray< std::valarray<double> > &Mcore,
34  const std::valarray< std::valarray<double> > &Lum
35  ) :
36  __R(R),
37  __Iconv(Iconv),
38  __Irad(Irad),
39  __Rcore(Rcore),
40  __Mcore(Mcore),
41  __Lum(Lum),
42  __core_formation_age(core_formation_age)
43  {
44  if(std::isnan(__core_formation_age))
46  if(__R.size() == 0) rand_poly_coef(__R);
47  if(__Iconv.size()==0) rand_poly_coef(__Iconv);
48  if(__Irad.size()==0) rand_poly_coef(__Irad);
49  if(__Rcore.size()==0) rand_poly_coef(__Rcore);
50  if(__Mcore.size()==0) rand_poly_coef(__Mcore);
51  if(__Lum.size()==0) rand_poly_coef(__Lum);
52  if(core_formation_age > 0) {
53  __Irad[0] = 0;
54  __Rcore[0] = 0;
55  __Mcore[0] = 0;
56  __Irad = offset_age(Irad, core_formation_age);
57  __Rcore = offset_age(Rcore, core_formation_age);
58  __Mcore = offset_age(Mcore, core_formation_age);
59  }
60  __Menv.resize(
61  __Mcore.size(),
62  std::valarray<double>(0.0,
63  std::max(__Mcore[0].size(), size_t(2)))
64  );
65  __Itot.resize(__Iconv.size(),
66  std::valarray<double>(__Iconv[0].size()));
67  __Itot = __Iconv + __Irad;
68  for(size_t mass_i = 0; mass_i < __Mcore.size(); ++mass_i)
69  for(size_t age_i = 0; age_i < __Mcore[mass_i].size(); ++age_i)
70  __Menv[mass_i][age_i] = -__Mcore[mass_i][age_i];
71  __Menv[0][1] += 1;
72  }
73 
75  QuantityID quantity,
76  double mass,
77  double
78  ) const
79  {
80  switch(quantity) {
81  case RADIUS: return exact_track(__R, mass);
82  case ICONV: return exact_track(__Iconv, mass);
83  case LUM: return exact_track(__Lum, mass);
84  case IRAD: return exact_track(__Irad, mass);
85  case MRAD: return exact_track(__Mcore, mass);
86  case RRAD: return exact_track(__Rcore, mass);
87  default: throw Core::Error::BadFunctionArguments(
88  "Unknown quantity ID"
89  );
90  };
91  }
92 
93  MockStellarEvolution *make_no_evolution(double Rstar, double Iconv)
94  {
96  0.0,
97  std::valarray< std::valarray<double> >(//R
98  std::valarray<double>(Rstar, 1),
99  1
100  ),
101  std::valarray< std::valarray<double> >(//Iconv
102  std::valarray<double>(Iconv, 1),
103  1
104  ),
105  std::valarray< std::valarray<double> >(//Irad
106  std::valarray<double>(1.0, 1),
107  1
108  ),
109  std::valarray< std::valarray<double> >(//Rcore
110  std::valarray<double>(1.0, 1),
111  1
112  ),
113  std::valarray< std::valarray<double> >(//Mcore
114  std::valarray<double>(1.0, 1),
115  1
116  ),
117  std::valarray< std::valarray<double> >(//Lum
118  std::valarray<double>(1.0, 1),
119  1
120  )
121  );
122  }
123 
124  MockStellarEvolution *make_linear_I_evolution()
125  {
127  0.0,
128  std::valarray< std::valarray<double> >(//R
129  std::valarray<double>(1.0, 1),
130  1
131  ),
132  std::valarray< std::valarray<double> >(//Iconv
133  std::valarray<double>(1.0, 1),
134  2
135  ),
136  std::valarray< std::valarray<double> >(//Irad
137  std::valarray<double>(1.0, 1),
138  2
139  ),
140  std::valarray< std::valarray<double> >(//Rcore
141  std::valarray<double>(1.0, 1),
142  1
143  ),
144  std::valarray< std::valarray<double> >(//Mcore
145  std::valarray<double>(1.0, 1),
146  1
147  ),
148  std::valarray< std::valarray<double> >(//Lum
149  std::valarray<double>(1.0, 1),
150  1
151  )
152  );
153  }
154 
155 }//End StellarEvolution namespace.
156 
157 #if 0
158  StarData::StarData() :
159  num_stars_created(0),
160  Lrad_track(NULL),
161  Lconv_track(NULL),
162  evolution_masses(100),
163  evolution_ages(100),
164  r_coef(rand_poly_coef()),
165  Iconv_coef(rand_poly_coef()),
166  Irad_coef(rand_poly_coef()),
167  Mrad_coef(rand_poly_coef()),
168  Rcore_coef(rand_poly_coef())
169  {
170  for (size_t age_ind=0; age_ind < evolution_ages.size(); age_ind++) {
171  evolution_ages[age_ind] = (
172  MIN_AGE
173  +
174  age_ind * (max_age - MIN_AGE) / evolution_ages.size()
175  );
176  }
177 
178  for (
179  size_t mass_ind = 0;
180  mass_ind < evolution_masses.size();
181  ++mass_ind
182  ) {
183  evolution_masses[mass_ind] = (
184  min_stellar_mass
185  +
186  mass_ind
187  *
188  (max_stellar_mass - min_stellar_mass)
189  /
190  evolution_masses.size()
191  );
192  }
193  }
194 
195 
196  StarData::~StarData()
197  {
198  if(Lrad_track) delete Lrad_track;
199  if(Lconv_track) delete Lconv_track;
200  }
201 
202  void StarData::create_random_star(Star::InterpolatedEvolutionStar **star)
203  {
204  mass = rand_value(min_stellar_mass, max_stellar_mass);
205  feh = rand_value(-1.0, 0.5);
206  age = rand_value(MIN_AGE, 2.1);
207  radius = (rand_value(0.9, 1.1)) * eval_poly(r_coef, mass, age);
208  conv_spin = rand_value(0.0, 1.0);
209  rad_spin = rand_value(0.0, 1.0);
210  tidal_Q = std::pow(10.0, rand_value(5.0,10.0));
211  wind_strength = rand_value(0.0, 1.0);
212  wind_sat_freq = rand_value(0.0, 1.0);
213  disk_lock_w = rand_value(0.0, wind_sat_freq);
214  disk_lock_time = evolution_ages[rand_value(0, evolution_ages.size()-1)];
215  coupling_timescale = rand_value(0.0, 1.0);
216  Q_trans_width = 0;
217 
218  MockStellarEvolution evol(Core::NaN,
219  r_coef,
220  Iconv_coef,
221  Irad_coef,
222  Rcore_coef,
223  Mcore_coef);
224  (*star) = new Star(mass,
225  feh,
226  wind_strength,
227  wind_sat_freq,
228  coupling_timescale,
229  evol);
230 
231  Lconv_track=exact_track(rand_poly_coef(), mass);
232  Lrad_track=exact_track(rand_poly_coef(), mass);
233  Lconv.resize(evolution_ages.size());
234  Lconv = tabulate_track(Lconv_track, evolution_ages);
235  Lrad.resize(evolution_ages.size());
236  Lrad = tabulate_track(Lrad_track, evolution_ages);
237  Iconv.resize(evolution_ages.size());
238  Iconv = tabulate_track(exact_track(Iconv_coef, mass), evolution_ages);
239  std::valarray<double> Itot =
240  tabulate_track(exact_track(Itot_coef, mass), evolution_ages);
241 
242  std::list<double> Irad_list;
243  for (size_t i=0; i < evolution_ages.size(); i++)
244  Irad_list.push_back(Itot[i]-Iconv[i]);
245  Irad = list_to_valarray(Irad_list);
246 
247  Mrad_deriv = tabulate_track(exact_track(Mrad_coef, mass),
248  evolution_ages, 1);
249  Lconv_deriv = tabulate_track(Lconv_track, evolution_ages, 1);
250  Lrad_deriv = tabulate_track(Lrad_track, evolution_ages, 1);
251  Rrad = tabulate_track(exact_track(Rcore_coef, mass), evolution_ages);
252  all_radii = tabulate_track(exact_track(r_coef, mass), evolution_ages);
253 
254  std::valarray<double> fake_derivs;
255  (*star)->set_angular_momentum_evolution(evolution_ages,
256  tabulate_track(Lrad_track, evolution_ages),
257  tabulate_track(Lrad_track, evolution_ages, 1), radiative);
258  (*star)->set_angular_momentum_evolution(evolution_ages,
259  tabulate_track(Lconv_track, evolution_ages),
260  tabulate_track(Lconv_track, evolution_ages, 1), convective);
261  num_stars_created++;
262  }
263 
264 void PlanetData::create_random_planet(Planet** planet)
265 {
266  mass = rand_value(min_planet_mass, max_planet_mass);
267  radius = rand_value(min_planet_radius, max_planet_radius);
268 
269  std::list<double> semis;
270  std::list<double> ages;
271  for (double age=0; age < 3; age += 0.1) {
272  ages.push_back(age);
273  semis.push_back(get_semi(age));
274  }
275  this->ages.resize(ages.size());
276  this->ages = list_to_valarray(ages);
277  this->semis.resize(semis.size());
278  this->semis = list_to_valarray(semis);
279 
280  std::valarray<double> fakeDerivs;
281  double curr_semi = get_semi(star->age());
282  (*planet) = new Planet(*star, mass, radius, curr_semi);
283  (*planet)->set_semimajor_evolution(this->ages,
284  this->semis, fakeDerivs);
285 }
286 
287 double PlanetData::get_semi(double age)
288 {
289  return (-age*age*age + 1.5*age*age + 2*age + 3)/50;
290 }
291 
292 PlanetData::~PlanetData()
293 {
294  delete sdata;
295  if(star) delete star;
296 }
297 
298 std::ostream &operator<<(std::ostream &os,
299  const PolynomialEvolutionTrack &track)
300 {
301 
302  for(size_t p=0; p<track.poly_coef.size(); p++) {
303  os << track.poly_coef[p];
304  if(p) os << "x";
305  if(p>1) os << "^" << p;
306  if(p<track.poly_coef.size()-1) os << " + ";
307  }
308  os << ", " << track.xmin << " < x < " << track.xmax;
309  return os;
310 }
311 #endif
312 
313 namespace StellarEvolution {
314 
315  PolynomialEvolutionQuantity *exact_track(
316  const std::valarray< std::valarray<double> > &poly_coef,
317  double mass,
318  double low_mass_age_scaling,
319  double high_mass_age_scaling,
320  double scale_mass
321  )
322  {
323  if(std::isnan(scale_mass)) scale_mass=mass;
324  std::valarray<double> age_poly_coeff(poly_coef.size());
325  double age_scaling=(mass <= MAX_LOW_MASS ? low_mass_age_scaling
326  : high_mass_age_scaling);
327  for(size_t age_i = 0; age_i < poly_coef.size(); ++age_i) {
328  double mass_pow=1.0;
329  age_poly_coeff[age_i]=0.0;
330  for(size_t mass_i=0; mass_i<poly_coef[age_i].size(); mass_i++) {
331  age_poly_coeff[age_i]+=mass_pow*poly_coef[age_i][mass_i];
332  mass_pow*=mass;
333  }
334  age_poly_coeff[age_i]*=std::pow(scale_mass, age_scaling*age_i);
335  }
336  return new PolynomialEvolutionQuantity(
337  age_poly_coeff,
338  MIN_AGE,
339  std::numeric_limits<double>::max()
340  );
341  }
342 
343 }//End StellarEvolution namespace.
344 
345 #if 0
346 double eval_poly(const std::valarray< std::valarray<double> > &poly_coef,
347  double mass, double age, double low_mass_age_scaling,
348  double high_mass_age_scaling, double scale_mass)
349 {
350  if(std::isnan(scale_mass)) scale_mass=mass;
351  double age_scaling=(mass<=max_low_mass ? low_mass_age_scaling :
352  high_mass_age_scaling), result=0.0, age_pow=1.0;
353  for(size_t age_i=0; age_i<poly_coef.size(); age_i++) {
354  double mass_pow=1.0, mass_result=0.0;
355  for(size_t mass_i=0; mass_i<poly_coef[age_i].size(); mass_i++) {
356  mass_result+=mass_pow*poly_coef[age_i][mass_i];
357  mass_pow*=mass;
358  }
359  result+=mass_result*age_pow*std::pow(scale_mass, age_scaling*age_i);
360  age_pow*=age;
361  }
362  return result;
363 }
364 
365 std::valarray<double> tabulate_track(PolynomialEvolutionQuantity *track,
366  std::valarray<double> ages, unsigned deriv_order)
367 {
368  std::valarray<double> data(ages.size());
369  for(unsigned a=0; a<ages.size(); a++) {
370  (*track)(ages[a]);
371  data[a]=track->order(deriv_order);
372  }
373  return data;
374 }
375 
376 PolynomialStellarEvolution::PolynomialStellarEvolution(
377  const std::valarray<double> &masses,
378  const std::valarray<double> &ages,
379  const std::valarray< std::valarray<double> > &r_coef,
380  const std::valarray< std::valarray<double> > &Iconv_coef,
381  const std::valarray< std::valarray<double> > &Itot_coef,
382  const std::valarray< std::valarray<double> > &Mrad_coef,
383  const std::valarray< std::valarray<double> > &Rcore_coef,
384  double low_mass_age_scaling, double high_mass_age_scaling)
385 {
386  std::list< std::valarray<double> > r_data, Iconv_data, Irad_data,
387  Mrad_data, Rcore_data;
389  for(unsigned i=0; i<masses.size(); i++) {
390  track=exact_track(r_coef, masses[i], low_mass_age_scaling,
391  high_mass_age_scaling);
392  r_data.push_back(tabulate_track(track, ages));
393  delete track;
394  track=exact_track(Iconv_coef, masses[i],
395  low_mass_age_scaling, high_mass_age_scaling);
396  Iconv_data.push_back(tabulate_track(track, ages));
397  delete track;
398  track=exact_track(Itot_coef-Iconv_coef, masses[i],
399  low_mass_age_scaling, high_mass_age_scaling);
400  Irad_data.push_back(tabulate_track(track, ages));
401  delete track;
402  track=exact_track(Mrad_coef, masses[i],
403  low_mass_age_scaling, high_mass_age_scaling);
404  Mrad_data.push_back(tabulate_track(track, ages));
405  delete track;
406  track=exact_track(Rcore_coef, masses[i],
407  low_mass_age_scaling, high_mass_age_scaling);
408  Rcore_data.push_back(tabulate_track(track, ages));
409  delete track;
410  };
411  interpolate_from(masses,
412  std::list< std::valarray<double> >(masses.size(), ages),
413  r_data, Iconv_data, Irad_data, Mrad_data, Rcore_data, NaN, NaN,
414  NaN, NaN, NaN, 0, 0, 0, 0, 0,
415  std::list< std::valarray<double> >(), 0,
416  max_low_mass, low_mass_age_scaling, high_mass_age_scaling);
417 }
418 #endif
419 
420 double ExponentialPlusFunc::order(unsigned deriv_order) const
421 {
422  if(deriv_order == 0) return (*this)(__deriv_x);
423  const Core::FunctionDerivatives *offset_deriv = __offset->deriv(__deriv_x);
424  double result = (__scale
425  *
426  std::pow(__rate, static_cast<int>(deriv_order))
427  *
428  std::exp(__rate * __deriv_x)
429  +
430  offset_deriv->order(deriv_order));
431  delete offset_deriv;
432  return result;
433 }
434 
435 double FuncPlusFunc::order(unsigned deriv_order) const
436 {
437  if(deriv_order == 0) return (*this)(__deriv_x);
438  const FunctionDerivatives *f1_deriv = __f1->deriv(__deriv_x),
439  *f2_deriv = __f2->deriv(__deriv_x);
440  double result = (f1_deriv->order(deriv_order)
441  +
442  f2_deriv->order(deriv_order));
443  delete f1_deriv;
444  delete f2_deriv;
445  return result;
446 }
447 
448 
450  const std::list<const OneArgumentDiffFunction *> &pieces,
451  double deriv_x
452 ) :
453  __deriv_x(deriv_x),
454  __range_low(Core::Inf),
455  __range_high(-Core::Inf),
456  __pieces(pieces)
457 {
458  for(
459  std::list<const OneArgumentDiffFunction *>::const_iterator
460  piece_i = __pieces.begin();
461  piece_i!=__pieces.end();
462  piece_i++
463  ) {
464  if((*piece_i)->range_low() < __range_low)
465  __range_low = (*piece_i)->range_low();
466  if((*piece_i)->range_high()>__range_high)
467  __range_high = (*piece_i)->range_high();
468  }
469 }
470 
471 void PiecewiseFunction::add_piece(const OneArgumentDiffFunction *piece)
472 {
473  __pieces.push_back(piece);
474  if(piece->range_low() < __range_low)
475  __range_low = piece->range_low();
476  if(piece->range_high() > __range_high)
477  __range_high = piece->range_high();
478 }
479 
480 double PiecewiseFunction::operator()(double x) const
481 {
482  double deriv_x = __deriv_x;
483  const_cast<PiecewiseFunction*>(this)->__deriv_x = x;
484  double result = order(0);
485  const_cast<PiecewiseFunction*>(this)->__deriv_x = deriv_x;
486  return result;
487 }
488 
489 double PiecewiseFunction::order(unsigned deriv_order) const
490 {
491  unsigned index = 0;
492  if(std::isnan(__deriv_x)) return Core::NaN;
493  for(
494  std::list<const OneArgumentDiffFunction *>::const_iterator
495  fi = __pieces.begin();
496  fi != __pieces.end();
497  ++fi
498  ) {
499  if(
500  __deriv_x >= (*fi)->range_low()
501  &&
502  __deriv_x < (*fi)->range_high()
503  ) {
504  if(deriv_order == 0) return (**fi)(__deriv_x);
505  const FunctionDerivatives *df = (*fi)->deriv(__deriv_x);
506  double result = df->order(deriv_order);
507  delete df;
508  return result;
509  }
510  ++index;
511  }
512  if(__deriv_x == __pieces.back()->range_high()) {
513  if(deriv_order == 0) return (*(__pieces.back()))(__deriv_x);
514  const FunctionDerivatives *df = __pieces.back()->deriv(__deriv_x);
515  double result = df->order(deriv_order);
516  delete df;
517  return result;
518  }
519  std::ostringstream msg;
520  msg << "Requested derivative or function value at age="
521  << __deriv_x
522  << ", outside the range of any piece in PiecewiseFunction::order.";
523  throw Core::Error::BadFunctionArguments(msg.str());
524 }
525 
526 double FunctionRatio::order(unsigned deriv_order) const
527 {
528  if(deriv_order == 0)
529  return (*this)(__deriv_x);
530  else {
531  const FunctionDerivatives *df1 = __f1->deriv(__deriv_x),
532  *df2 = __f2->deriv(__deriv_x);
533  double result;
534  if(deriv_order == 1)
535  result = (
536  df1->order(1) / df2->order(0)
537  -
538  df1->order(0) * df2->order(1) / std::pow(df2->order(0), 2)
539  );
540  else if(deriv_order == 2)
541  result = (
542  df1->order(2) / df2->order(0)
543  -
544  (
545  2.0 * df1->order(1) * df2->order(1)
546  /
547  std::pow(df2->order(0), 2)
548  )
549  -
550  df1->order(0) * df2->order(2) / std::pow(df2->order(0), 2)
551  +
552  (
553  df1->order(0) * std::pow(df2->order(1), 2)
554  /
555  std::pow(df2->order(0), 3)
556  )
557  );
558  else
560  "Function ratio derivatives are only implemneted up to and "
561  "including order 2."
562  );
563  delete df1;
564  delete df2;
565  return result;
566  }
567 }
568 
569 double FunctionToPower::order(unsigned deriv_order) const
570 {
571  if(deriv_order == 0)
572  return (*this)(__deriv_x);
573  else {
574  const FunctionDerivatives *df = __f->deriv(__deriv_x);
575  double result;
576  if(deriv_order == 1)
577  result = (__power
578  *
579  std::pow(df->order(0), __power-1)
580  *
581  df->order(1));
582  else if(deriv_order == 2)
583  result = (
584  __power
585  *
586  (
587  (__power-1)
588  *
589  std::pow(df->order(0), __power-2)
590  *
591  std::pow(df->order(1), 2)
592  +
593  std::pow(df->order(0), __power - 1) * df->order(2)
594  )
595  );
596  else
598  "Function to power derivatives are only implemneted up to "
599  "and including order 2."
600  );
601  delete df;
602  return result;
603  }
604 }
605 
606 double ScaledFunction::order(unsigned deriv_order) const
607 {
608  if(deriv_order == 0) return (*this)(__deriv_x);
609  const FunctionDerivatives *f_deriv = __f->deriv(__deriv_x);
610  double result = __scale*f_deriv->order(deriv_order);
611  delete f_deriv;
612  return result;
613 }
614 
615 double LogFunction::order(unsigned deriv_order) const
616 {
617  if(deriv_order == 0) return (*this)(__deriv_x);
618  else {
619  const FunctionDerivatives *f_deriv=__f->deriv(__deriv_x);
620  double result;
621  if(deriv_order == 1)
622  result = f_deriv->order(1) / f_deriv->order(0);
623  else if(deriv_order == 2)
624  result = (f_deriv->order(2) / f_deriv->order(0)
625  -
626  std::pow(f_deriv->order(1) / f_deriv->order(0), 2));
627  else
629  "Log(Function) derivatives are only implemneted up to and "
630  "including order 2."
631  );
632  delete f_deriv;
633  return result;
634  }
635 }
636 
637 double CosFunction::order(unsigned deriv_order) const
638 {
639  if(deriv_order == 0) return (*this)(__deriv_x);
640  else {
641  const FunctionDerivatives *f_deriv=__f->deriv(__deriv_x);
642  double result;
643  if(deriv_order == 1)
644  result = - std::sin(f_deriv->order(0)) * f_deriv->order(1);
645  else if(deriv_order == 2)
646  result = - (
647  std::cos(f_deriv->order(0)) * std::pow(f_deriv->order(1), 2)
648  +
649  std::sin(f_deriv->order(1)) * f_deriv->order(2)
650  );
651  else
653  "Cos(Function) derivatives are only implemneted up to and "
654  "including order 2."
655  );
656  delete f_deriv;
657  return result;
658  }
659 }
660 
661 double solve(double guess_x,
662  double abs_precision,
663  double rel_precision,
664  double (*f)(double x, void *params),
665  double (*df) (double x, void *params),
666  void (*fdf) (double x, void *params, double *f, double *df),
667  void *params)
668 {
669  int status;
670  int iter = 0;
671  const gsl_root_fdfsolver_type *T;
672  gsl_root_fdfsolver *s;
673  double x0, x = guess_x;
674  gsl_function_fdf FDF;
675 
676  FDF.f = f;
677  FDF.df = df;
678  FDF.fdf = fdf;
679  FDF.params = params;
680 
681  T = gsl_root_fdfsolver_newton;
682  s = gsl_root_fdfsolver_alloc (T);
683  gsl_root_fdfsolver_set (s, &FDF, x);
684 
685  do {
686  iter++;
687  status = gsl_root_fdfsolver_iterate (s);
688  x0 = x;
689  x = gsl_root_fdfsolver_root (s);
690  status = gsl_root_test_delta (x, x0, abs_precision, rel_precision);
691  } while (status == GSL_CONTINUE);
692 
693  gsl_root_fdfsolver_free (s);
694  return x;
695 }
Implements a StellarEvolution based on polynomial evolution quantities.
const double MIN_AGE
Most tests start at this age in Gyr.
Definition: Common.h:54
std::valarray< std::valarray< double > > __Irad
The polynomial coefficients of the radiative zone moment of inertia dependence on stellar mass and ag...
std::valarray< std::valarray< double > > __Lum
The polynomial coefficients of the luminosity dependence on stellar mass and age. ...
const double MAX_LOW_MASS
The boundary between high and low mass stars in .
Definition: Common.h:48
Function arguments do not satisfy some requirement.
Definition: Error.h:73
RADIUS
The derivative w.r.t. the radius of the body in .
double core_formation_age(const EvolvingStar *star)
The age at which the core of a star forms.
Definition: CInterface.cpp:126
std::valarray< std::valarray< double > > __Menv
The polynomial coefficients of the envelope mass dependence on stellar mass and age.
double order(unsigned deriv_order=1) const
For a derivative object returns the derivative of the given order.
double operator()(double x) const
Evaluates the function at the given x.
double rand_value(double min, double max)
A uniform random real value in the given range.
Definition: Common.cpp:61
std::valarray< std::valarray< double > > __Iconv
The polynomial coefficients of the convective zone moment of inertia dependence on stellar mass and a...
const int LUM
Identifier for the stellar luminosity as an interpolation quantity.
Definition: CInterface.cpp:13
double order(unsigned deriv_order=1) const
For a derivative object returns the derivative of the given order.
double order(unsigned deriv_order=1) const
For a derivative object returns the derivative of the given order.
double order(unsigned deriv_order=1) const
For a derivative object returns the derivative of the given order.
Any runtime error.
Definition: Error.h:61
double __core_formation_age
The age in Gyr at which the core forms.
A class for stellar properties that depend on age.
virtual double order(unsigned deriv_order=1) const =0
Derivative of the given order of the function with respect to its argument.
MockStellarEvolution(double core_formation_age=Core::NaN, const std::valarray< std::valarray< double > > &R=std::valarray< std::valarray< double > >(), const std::valarray< std::valarray< double > > &Iconv=std::valarray< std::valarray< double > >(), const std::valarray< std::valarray< double > > &Irad=std::valarray< std::valarray< double > >(), const std::valarray< std::valarray< double > > &Rcore=std::valarray< std::valarray< double > >(), const std::valarray< std::valarray< double > > &Mcore=std::valarray< std::valarray< double > >(), const std::valarray< std::valarray< double > > &Lum=std::valarray< std::valarray< double > >())
Uses the given values and polynomials for the quantities.
void rand_poly_coef(std::valarray< std::valarray< double > > &poly_coef, double max_mass=-1)
Fills the given valarray with a random set of polynomial coefficients.
Definition: Common.cpp:90
double order(unsigned deriv_order=1) const
Return the given order-th derivative at x set by previous call to deriv().
An EvolvingStellar quantity that uses a polynomial instead of interpolating.
double __xmax
The upper limit of the age at which this quantity can be evaluated.
double order(unsigned deriv_order=1) const
The order-th derivative.
std::valarray< std::valarray< double > > __Itot
The polynomial coefficients of total stellar moment of inertia dependence on stellar mass and age...
std::valarray< std::valarray< double > > __Rcore
The polynomial coefficients of the core radius dependence on stellar mass and age.
double order(unsigned deriv_order=1) const
For a derivative object returns the derivative of the given order.
A class representing arbitrary order derivatives of a function.
Definition: Functions.h:66
EvolvingStellarQuantity * operator()(QuantityID quantity, double mass, double feh) const
See StellarEvolutino::Interpolator::operator()()
Moment of inertia of the radiative zone of the star (low mass stars only) in .
Definition: IOColumns.h:114
std::valarray< std::valarray< double > > __R
The polynomial coefficients of the radius dependence on mass and age.
double __xmin
The lower limit of the age at which this quantity can be evaluated.
std::valarray< double > __poly_coef
The coefficients of the polynomial giving the evolution.
std::valarray< std::valarray< double > > __Mcore
The polynomial coefficients of the core mass dependence on stellar mass and age.
Moment of inertia of the convective zone of the star (low mass stars only) in .
Definition: IOColumns.h:110
Several functions stiched together.
QuantityID
Defines the quantities tracked by stellar evolution and their order.
PiecewiseFunction(const std::list< const OneArgumentDiffFunction *> &pieces=std::list< const OneArgumentDiffFunction *>(), double deriv_x=Core::NaN)
Create the function.
Radius of the stellar core in (low mass stars only).
Definition: IOColumns.h:123
Definition: Planet.h:15
std::valarray< std::valarray< double > > offset_age(const std::valarray< std::valarray< double > > &poly_coef, double age_offset)
Returns new polynomial coefficienst such that output polynomial(mass, age+age_offset)=input polynomia...
Definition: Common.cpp:115
void add_piece(const OneArgumentDiffFunction *piece)
Adds another piece of the function, where it applies is defined by its range.
double order(unsigned deriv_order=1) const
For a derivative returns the given order.
Mass of the stellar core in (low mass stars only).
Definition: IOColumns.h:126
double __deriv_x
The location at which the derivative has been requested.
double order(unsigned deriv_order=1) const
For a derivative object returns the derivative of the given order.