Planetary Orbital Evolution due to Tides
Orbital evolution of two objects experiencing tides
PolynomialEvolution.h
1 #ifndef __POLYNOMIAL_EVOLUTION_H
2 #define __POLYNOMIAL_EVOLUTION_H
3 
4 #include "../Core/Functions.h"
5 #include "../StellarEvolution/EvolvingStellarQuantity.h"
6 #include "../StellarEvolution/Interpolator.h"
7 
8 #include "Common.h"
9 //#include "../StellarSystem.h"
10 //#include "../Star.h"
11 //#include "../Planet.h"
12 //#include "../OrbitSolver.h"
13 #include <valarray>
14 #include <gsl/gsl_roots.h>
15 //#include "YRECIO.h"
16 #include <fstream>
17 #include <boost/archive/text_oarchive.hpp>
18 #include <boost/archive/text_iarchive.hpp>
19 
20 namespace StellarEvolution {
21 
30  private:
32  std::valarray<double> __poly_coef;
33 
34  double
38 
41  __xmax;
42 
44  mutable double __deriv_x;
45 
47  std::vector<double> __empty_vector;
48 
49  public:
54  const std::valarray<double> &coefficients,
55 
57  double range_low,
58 
60  double range_high,
61 
63  double derivative_x=NaN
64  ) :
65  __poly_coef(coefficients),
66  __xmin(range_low),
67  __xmax(range_high),
68  __deriv_x(derivative_x)
69  {}
70 
71  void select_interpolation_region(double) const {}
72 
77  double operator()(double x) const {__deriv_x = x; return order(0);}
78 
80  double range_low() const {return __xmin;}
81 
83  double range_high() const {return __xmax;}
84 
86  virtual const std::vector<double> &discontinuities() const
87  {return __empty_vector;}
88 
91  virtual double previous_discontinuity() const {return __xmin;}
92 
95  virtual double next_discontinuity() const {return __xmax;}
96 
99  virtual void enable_next_interpolation_region() const
100  {assert(false);}
101 
103  const Core::FunctionDerivatives *deriv(double x) const
104  {return new PolynomialEvolutionQuantity(__poly_coef,
105  __xmin,
106  __xmax,
107  x);}
108 
110  double order(unsigned deriv_order = 1) const;
111 
113  friend std::ostream &operator<<(
114  std::ostream &os,
115  const PolynomialEvolutionQuantity &track
116  );
117 
119  std::string kind() const {return "PolynomialEvolutionQuantity";}
120  };//End PolynomialEvolutionQuantity class.
121 
127  private:
128  std::valarray< std::valarray<double> >
131  __R,
132 
135  __Iconv,
136 
139  __Irad,
140 
143  __Itot,
144 
147  __Rcore,
148 
151  __Mcore,
152 
155  __Menv,
156 
159  __Lum;
160 
163  public:
170  double core_formation_age = Core::NaN,
171 
174  const std::valarray< std::valarray<double> > &
175  R = std::valarray< std::valarray<double> >(),
176 
179  const std::valarray< std::valarray<double> > &
180  Iconv = std::valarray< std::valarray<double> >(),
181 
184  const std::valarray< std::valarray<double> > &
185  Irad = std::valarray< std::valarray<double> >(),
186 
189  const std::valarray< std::valarray<double> > &
190  Rcore = std::valarray< std::valarray<double> >(),
191 
194  const std::valarray< std::valarray<double> > &
195  Mcore = std::valarray< std::valarray<double> >(),
196 
199  const std::valarray< std::valarray<double> > &
200  Lum = std::valarray< std::valarray<double> >()
201  );
202 
205  double mass,
206  double feh) const;
207 
209  double core_formation_age() const {return __core_formation_age;}
210  };
211 
212  MockStellarEvolution *make_no_evolution(double Rstar = 1.0,
213  double Iconv = 1.0);
214 
215  MockStellarEvolution *make_linear_I_evolution();
216 
217 }//End StellarEvolution namespace.
218 
219 #if 0
220  class StarData {
224  private:
225  unsigned __num_stars_created;
226  public:
227  double mass,
228  feh,
229  radius,
230  age,
231  conv_spin,
232  rad_spin,
233  tidal_Q,
234  wind_strength,
235  wind_sat_freq,
236  coupling_timescale,
237  Q_trans_width,
238  disk_lock_w,
239  disk_lock_time;
240 
241  PolynomialEvolutionTrack *Lrad_track,
242  *Lconv_track;
243 
244  std::valarray<double> evolution_masses,
245  evolution_ages,
246  Lrad,
247  Lconv,
248  Iconv,
249  Irad,
250  Mrad_deriv,
251  Lconv_deriv,
252  Lrad_deriv,
253  Rrad,
254  all_radii;
255 
256  std::valarray< std::valarray<double> > r_coef,
257  Iconv_coef,
258  Irad_coef,
259  Mrad_coef,
260  Rcore_coef;
261 
262  StarData();
263 
266  void create_random_star(Star::EvolvingStar **star);
267 
270  ~StarData();
271  };
272 
273 
277 class PlanetData {
278 public:
279  Star* star;
280  StarData* sdata;
281  double mass, radius;
282  std::valarray<double> ages;
283  std::valarray<double> semis;
284  PlanetData() : star(NULL) {
285  sdata = new StarData();
286  sdata->create_random_star(&star);
287  };
288  void create_random_planet(Planet** planet);
289  double get_semi(double age);
290 
292  ~PlanetData();
293 };
294 
298 class SystemData {
299 public:
300  Star* star;
301  Planet* planet;
302  StarData* sdata;
303  PlanetData* pdata;
304  SystemData() {
305  //exit(-1);
306  pdata = new PlanetData();
307  pdata->create_random_planet(&planet);
308  star = pdata->star;
309  sdata = pdata->sdata;
310  }
311  void create_random_system(StellarSystem** system) {
312 /* double min_age = sdata->evolution_ages[0];
313  double precision = 0.01;
314  double max_age = star->get_lifetime();
315  OrbitSolver orb(min_age, max_age, precision,
316  stellar_system_diff_eq, stellar_system_jacobian);*/
317  *system = new StellarSystem(*star, *planet, "");
318  }
319 };
320 #endif
321 
322 namespace StellarEvolution {
323 
326  PolynomialEvolutionQuantity *exact_track(
329  const std::valarray< std::valarray<double> > &poly_coef,
330 
332  double mass,
333 
335  double low_mass_age_scaling = 0,
336 
338  double high_mass_age_scaling = 0,
339 
341  double scale_mass = NaN
342  );
343 
344 } //End StellarEvolution namespace.
345 
346 #if 0
347 class PolynomialStellarEvolution : public StellarEvolution {
352 public:
353  PolynomialStellarEvolution(
356  const std::valarray<double> &masses,
357 
360  const std::valarray<double> &ages,
361 
364  const std::valarray< std::valarray<double> > &r_coef,
365 
368  const std::valarray< std::valarray<double> > &Iconv_coef,
369 
372  const std::valarray< std::valarray<double> > &Itot_coef,
373 
376  const std::valarray< std::valarray<double> > &Mrad_coef,
377 
380  const std::valarray< std::valarray<double> > &Rcore_coef,
381 
383  double low_mass_age_scaling,
384 
386  double high_mass_age_scaling);
387 };
388 #endif
389 
396 {
397 private:
398  double __scale, __rate, __deriv_x;
400 public:
403  double scale,
404  double rate,
405  double deriv_x = Core::NaN) :
406  __scale(scale),
407  __rate(rate),
408  __deriv_x(deriv_x),
409  __offset(offset)
410  {}
411 
413  double operator()(double x) const
414  {return (*__offset)(x) + __scale * std::exp(__rate * x);}
415 
417  const Core::FunctionDerivatives *deriv(double x) const
418  {return new ExponentialPlusFunc(__offset, __scale, __rate, x);}
419 
422  double order(unsigned deriv_order = 1) const;
423 
425  double range_high() const {return __offset->range_high();}
426 
428  double range_low() const {return __offset->range_low();}
429 
432  {return Core::InterpSolutionIterator();}
433 };
434 
440 private:
441  const OneArgumentDiffFunction *__f1, *__f2;
442  double __deriv_x;
443 public:
445  FuncPlusFunc(const OneArgumentDiffFunction *f1,
446  const OneArgumentDiffFunction *f2,
447  double deriv_x = Core::NaN) :
448  __f1(f1), __f2(f2), __deriv_x(deriv_x)
449  {}
450 
452  double operator()(double x) const {return (*__f1)(x) + (*__f2)(x);}
453 
455  const FunctionDerivatives *deriv(double x) const
456  {return new FuncPlusFunc(__f1, __f2, x);}
457 
459  double order(unsigned deriv_order = 1) const;
460 
462  double range_high() const
463  {return std::min(__f1->range_high(), __f2->range_high());}
464 
466  double range_low() const
467  {return std::max(__f1->range_low(), __f2->range_low());}
468 
471  {return Core::InterpSolutionIterator();}
472 };
473 
479 private:
480  double __deriv_x, __range_low, __range_high;
481  std::list<const OneArgumentDiffFunction *> __pieces;
482 public:
484  PiecewiseFunction(const std::list<const OneArgumentDiffFunction *>
485  &pieces = std::list<const OneArgumentDiffFunction *>(),
486  double deriv_x = Core::NaN);
487 
490  void add_piece(const OneArgumentDiffFunction *piece);
491 
493  double operator()(double x) const;
494 
496  const FunctionDerivatives *deriv(double x) const
497  {return new PiecewiseFunction(__pieces, x);}
498 
500  double order(unsigned deriv_order=1) const;
501 
503  double range_high() const {return __range_high;}
504 
506  double range_low() const {return __range_low;}
507 
511  {return Core::InterpSolutionIterator();}
512 };
513 
519 private:
520  double __deriv_x;
521  const OneArgumentDiffFunction *__f1, *__f2;
522 public:
524  FunctionRatio(const OneArgumentDiffFunction *f1,
525  const OneArgumentDiffFunction *f2,
526  double deriv_x = Core::NaN) :
527  __deriv_x(deriv_x), __f1(f1), __f2(f2) {}
528 
530  double operator()(double x) const {return (*__f1)(x) / (*__f2)(x);}
531 
533  const FunctionDerivatives *deriv(double x) const
534  {return new FunctionRatio(__f1, __f2, x);}
535 
537  double order(unsigned deriv_order=1) const;
538 
540  double range_high() const
541  {return std::min(__f1->range_high(), __f2->range_high());}
542 
544  double range_low() const
545  {return std::max(__f1->range_low(), __f2->range_low());}
546 
550  {return Core::InterpSolutionIterator();}
551 };
552 
558 private:
559  const OneArgumentDiffFunction *__f;
560  double __power, __deriv_x;
561 public:
563  FunctionToPower(const OneArgumentDiffFunction *f,
564  double power,
565  double deriv_x = Core::NaN) :
566  __f(f), __power(power), __deriv_x(deriv_x) {}
567 
569  double operator()(double x) const
570  {return std::pow((*__f)(x), __power);}
571 
573  const FunctionDerivatives *deriv(double x) const
574  {return new FunctionToPower(__f, __power, x);}
575 
577  double order(unsigned deriv_order=1) const;
578 
580  double range_high() const {return __f->range_high();}
581 
583  double range_low() const {return __f->range_low();}
584 
588  {return Core::InterpSolutionIterator();}
589 };
590 
596 private:
597  const OneArgumentDiffFunction *__f;
598  double __scale, __deriv_x;
599 public:
601  ScaledFunction(const OneArgumentDiffFunction *f,
602  double scale,
603  double deriv_x = Core::NaN) :
604  __f(f), __scale(scale), __deriv_x(deriv_x) {}
605 
607  double operator()(double x) const
608  {return __scale*(*__f)(x);}
609 
611  const FunctionDerivatives *deriv(double x) const
612  {return new ScaledFunction(__f, __scale, x);}
613 
615  double order(unsigned deriv_order=1) const;
616 
618  double range_high() const {return __f->range_high();}
619 
621  double range_low() const {return __f->range_low();}
622 
626  {return Core::InterpSolutionIterator();}
627 };
628 
634 private:
635  const OneArgumentDiffFunction *__f;
636  double __deriv_x;
637 public:
639  LogFunction(const OneArgumentDiffFunction *f,
640  double deriv_x = Core::NaN) :
641  __f(f), __deriv_x(deriv_x) {}
642 
644  double operator()(double x) const {return std::log((*__f)(x));}
645 
647  const FunctionDerivatives *deriv(double x) const
648  {return new LogFunction(__f, x);}
649 
651  double order(unsigned deriv_order=1) const;
652 
654  double range_high() const {return __f->range_high();}
655 
657  double range_low() const {return __f->range_low();}
658 
662  {return Core::InterpSolutionIterator();}
663 };
664 
670 private:
671  const OneArgumentDiffFunction *__f;
672  double __deriv_x;
673 public:
675  CosFunction(const OneArgumentDiffFunction *f,
676  double deriv_x = Core::NaN) :
677  __f(f), __deriv_x(deriv_x) {}
678 
680  double operator()(double x) const {return std::cos((*__f)(x));}
681 
683  const FunctionDerivatives *deriv(double x) const
684  {return new CosFunction(__f, x);}
685 
687  double order(unsigned deriv_order=1) const;
688 
690  double range_high() const {return __f->range_high();}
691 
693  double range_low() const {return __f->range_low();}
694 
698  {return Core::InterpSolutionIterator();}
699 };
700 
701 
702 #if 0
703 std::valarray<double> tabulate_track(PolynomialEvolutionTrack *track,
705  std::valarray<double> ages, unsigned deriv_order=0);
706 
709 double eval_poly(const std::valarray< std::valarray<double> > &poly_coef,
710  double mass, double age, double low_mass_age_scaling=0,
711  double high_mass_age_scaling=0, double scale_mass=NaN);
712 #endif
713 
715 double solve(double guess_x,
716  double abs_precision,
717  double rel_precision,
718  double (*f)(double x, void *params),
719  double (*df) (double x, void *params),
720  void (*fdf) (double x, void *params, double *f, double *df),
721  void *params);
722 
723 #endif
const Core::FunctionDerivatives * deriv(double x) const
Returns the derivatives at the given x.
Core::InterpSolutionIterator crossings(double) const
An iterator over the x values where the function takes the given value.
Implements a StellarEvolution based on polynomial evolution quantities.
double range_high() const
The upper end of the range where the function is defined.
const FunctionDerivatives * deriv(double x) const
Returns the derivatives at the given x.
double operator()(double x) const
Evaluates the function at the given x.
CosFunction(const OneArgumentDiffFunction *f, double deriv_x=Core::NaN)
Create the function.
double core_formation_age(const EvolvingStar *star)
The age at which the core of a star forms.
Definition: CInterface.cpp:126
double operator()(double x) const
Evaluates the function at the given x.
double operator()(double x) const
Evaluates the function at the given x.
double range_high() const
The upper end of the range over which the function is defined.
Functions and classes of general use for all unit tests.
Core::InterpSolutionIterator crossings(double) const
Iterator over the points at which the function takes the given value.
virtual double previous_discontinuity() const
See StellarEvolution::EvolvingStellarQuantity::prevous_discontinuity()
double range_high() const
The upper end of the range over which the function is defined.
A function scaled by some constant.
virtual void enable_next_interpolation_region() const
Set up the interpolation over the next interpolation region (between consecutive discontinuities.)
std::vector< double > __empty_vector
An empty vector to serve as the list of discontinuities.
double range_high() const
The upper end of the range over which the function is defined.
friend std::ostream & operator<<(std::ostream &os, const PolynomialEvolutionQuantity &track)
Prints an expression of the polynomial that this track represents.
double operator()(double x) const
Evaluates the function at the given x.
double range_high() const
The upper end of the range over which the function is defined.
Core::InterpSolutionIterator crossings(double) const
An iterator over the x values where the function takes the given value.
double core_formation_age() const
The age in Gyr at which the core forms.
FuncPlusFunc(const OneArgumentDiffFunction *f1, const OneArgumentDiffFunction *f2, double deriv_x=Core::NaN)
Creates the function.
Core::InterpSolutionIterator crossings(double) const
An iterator over the x values where the function takes the given value.
Core::InterpSolutionIterator crossings(double) const
An iterator over the x values where the function takes the given value.
A class representing a once differentiable function of a single argument.
Definition: Functions.h:104
const FunctionDerivatives * deriv(double x) const
Returns the derivatives at the given x.
double operator()(double x) const
Evaluate the function at the given x.
const Core::FunctionDerivatives * deriv(double x) const
The derivatives.
ScaledFunction(const OneArgumentDiffFunction *f, double scale, double deriv_x=Core::NaN)
Create the function.
double __core_formation_age
The age in Gyr at which the core forms.
A class for stellar properties that depend on age.
An iterator over a set of solutions to an interpolating function.
const FunctionDerivatives * deriv(double x) const
Returns the derivatives at the given x.
A class that interpolates among stellar evolution tracks.
Definition: Interpolator.h:42
Represents the sum of two functions and the derivative.
double range_high() const
The upper end of the range over which the function is defined.
FunctionToPower(const OneArgumentDiffFunction *f, double power, double deriv_x=Core::NaN)
Create the function.
The cosine of a function.
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.
The natural logarithm of a function.
double range_low() const
The lower end of the range over which the function is defined.
double order(unsigned deriv_order=1) const
The order-th derivative.
double range_low() const
The lower end of the range over which the function is defined.
std::valarray< std::valarray< double > > __Rcore
The polynomial coefficients of the core radius dependence on stellar mass and age.
A class representing arbitrary order derivatives of a function.
Definition: Functions.h:66
const FunctionDerivatives * deriv(double x) const
Returns the derivatives at the given x.
double range_low() const
The lower end of the range over which the function is defined.
double operator()(double x) const
Evaluates the polynomial at the given age.
double range_low() const
The lower end of the range over which the function is defined.
const FunctionDerivatives * deriv(double x) const
Returns the derivatives at the given x.
virtual const std::vector< double > & discontinuities() const
The ages at which the quantity may be discontinuous.
const FunctionDerivatives * deriv(double x) const
Returns the derivatives at the given x.
LogFunction(const OneArgumentDiffFunction *f, double deriv_x=Core::NaN)
Create the function.
virtual double next_discontinuity() const
See StellarEvolution::EvolvingStellarQuantity::next_discontinuity()
double __xmin
The lower limit of the age at which this quantity can be evaluated.
Core::InterpSolutionIterator crossings(double) const
Iterator over the x values where the function takes the given value.
std::valarray< double > __poly_coef
The coefficients of the polynomial giving the evolution.
double range_low() const
The lower end of the range where the function is defined.
Several functions stiched together.
double operator()(double x) const
Evaluates the function at the given x.
Core::InterpSolutionIterator crossings(double) const
An iterator over the x values where the function takes the given value.
QuantityID
Defines the quantities tracked by stellar evolution and their order.
double range_low() const
The lower end of the range where the function is defined.
double range_low() const
The lower end of the range over which the function is defined.
Represents a function of the form offset + scale*exp(rate*x) as well as its derivative.
double range_low() const
The lower end of the range over which the function is defined.
const FunctionDerivatives * deriv(double x) const
Returns the derivative.
double operator()(double x) const
Evaluates the function at the given x.
Definition: Planet.h:15
A function raised to some power.
std::string kind() const
A string identifying the type of quantity this is.
double range_high() const
The upper end of the range over which the function is defined.
Core::InterpSolutionIterator crossings(double) const
An iterator over the x values where the function takes the given value.
The ratio of two functions;.
PolynomialEvolutionQuantity(const std::valarray< double > &coefficients, double range_low, double range_high, double derivative_x=NaN)
Create an evolving quantity or its derivative.
ExponentialPlusFunc(Core::OneArgumentDiffFunction *offset, double scale, double rate, double deriv_x=Core::NaN)
Create the function with the given parameters.
double range_high() const
The upper end of the range where the function is defined.
virtual InputDataType range_high() const =0
The lower end of the range over which the function is defined.
double __deriv_x
The location at which the derivative has been requested.
double range_low() const
The lower end of the range over which the function is defined.
double range_high() const
The upper end of the range over which the function is defined.
virtual InputDataType range_low() const =0
The upper end of the range over which the function is defined.
struct LIB_PUBLIC EvolvingStar
Opaque struct to cast to/from Star::InterpolatedEvolutionStar.
Definition: CInterface.h:30
FunctionRatio(const OneArgumentDiffFunction *f1, const OneArgumentDiffFunction *f2, double deriv_x=Core::NaN)
Create the function.