mirror of
https://github.com/nasa/trick.git
synced 2025-01-18 02:40:08 +00:00
Add copy-constructors, assignment operators, insertion operators to SAIntegrator classes. #1091
This commit is contained in:
parent
939b3002d1
commit
870e7e9a41
@ -13,6 +13,7 @@
|
|||||||
* [class RK2Integrator](#class-RK2Integrator)
|
* [class RK2Integrator](#class-RK2Integrator)
|
||||||
* [class RK4Integrator](#class-RK4Integrator)
|
* [class RK4Integrator](#class-RK4Integrator)
|
||||||
* [class RK3_8Integrator](#class-RK3_8Integrator)
|
* [class RK3_8Integrator](#class-RK3_8Integrator)
|
||||||
|
* [typedef Derivs2Func](#typedef-Derivs2Func)
|
||||||
* [class EulerCromerIntegrator](#class-EulerCromerIntegrator)
|
* [class EulerCromerIntegrator](#class-EulerCromerIntegrator)
|
||||||
* [class ABM2Integrator](#class-ABM2Integrator)
|
* [class ABM2Integrator](#class-ABM2Integrator)
|
||||||
* [class ABM4Integrator](#class-ABM4Integrator)
|
* [class ABM4Integrator](#class-ABM4Integrator)
|
||||||
@ -53,10 +54,13 @@ This base-class represents a numerical **integrator**.
|
|||||||
|h |```double```| Default integration step-size |
|
|h |```double```| Default integration step-size |
|
||||||
|udata |```void*``` | A pointer to user defined data that will be passed to user-defined functions when called by the Integrator. |
|
|udata |```void*``` | A pointer to user defined data that will be passed to user-defined functions when called by the Integrator. |
|
||||||
|
|
||||||
|
|
||||||
### Destructor
|
### Destructor
|
||||||
|
|
||||||
#### ```virtual ~Integrator() {}```
|
#### ```virtual ~Integrator() {}```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Public Member Functions
|
### Public Member Functions
|
||||||
|
|
||||||
<a id=method-Integrator::step></a>
|
<a id=method-Integrator::step></a>
|
||||||
@ -172,6 +176,15 @@ where:
|
|||||||
| derivs_func |[```DerivsFunc```](#typedef-DerivsFunc)| Function thats generates the function (the derivatives) to be integrated. |
|
| derivs_func |[```DerivsFunc```](#typedef-DerivsFunc)| Function thats generates the function (the derivatives) to be integrated. |
|
||||||
|user_data |```void*``` | A pointer to user defined data that will be passed to a DerivsFunc when called by the Integrator. |
|
|user_data |```void*``` | A pointer to user defined data that will be passed to a DerivsFunc when called by the Integrator. |
|
||||||
|
|
||||||
|
In addition to the above constructor, this class provides:
|
||||||
|
|
||||||
|
* a copy constructor,
|
||||||
|
* a destructor,
|
||||||
|
* an assignment operator,
|
||||||
|
* an insertion operator,
|
||||||
|
* the public member functions inherited from [class Integrator](#class-Integrator),
|
||||||
|
* and the following public member functions:
|
||||||
|
|
||||||
### Public Member Functions
|
### Public Member Functions
|
||||||
|
|
||||||
<a id=method-FirstOrderODEIntegrator::load></a>
|
<a id=method-FirstOrderODEIntegrator::load></a>
|
||||||
@ -307,6 +320,25 @@ Those inherited from [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator) p
|
|||||||
|
|
||||||
### Constructor
|
### Constructor
|
||||||
|
|
||||||
|
```
|
||||||
|
FirstOrderODEVariableStepIntegrator( double h,
|
||||||
|
unsigned int N,
|
||||||
|
double* in_vars[],
|
||||||
|
double* out_vars[],
|
||||||
|
DerivsFunc dfunc,
|
||||||
|
void* udata);
|
||||||
|
```
|
||||||
|
[Constructor Parameters](#FOODEConstructorParameters) are those of [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
||||||
|
|
||||||
|
In addition to the above constructor, this class provides:
|
||||||
|
|
||||||
|
* a copy constructor,
|
||||||
|
* a destructor,
|
||||||
|
* an assignment operator,
|
||||||
|
* an insertion operator,
|
||||||
|
* the public member functions inherited from [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator),
|
||||||
|
* and the following public member functions:
|
||||||
|
|
||||||
<a id=FirstOrderODEVariableStepIntegrator::publicMemberFunctions></a>
|
<a id=FirstOrderODEVariableStepIntegrator::publicMemberFunctions></a>
|
||||||
### Public Member Functions
|
### Public Member Functions
|
||||||
|
|
||||||
@ -401,6 +433,15 @@ EulerIntegrator( double h,
|
|||||||
```
|
```
|
||||||
Constructor Parameters are those of [FirstOrderODEVariableStepIntegrator](#class-FirstOrderODEVariableStepIntegrator).
|
Constructor Parameters are those of [FirstOrderODEVariableStepIntegrator](#class-FirstOrderODEVariableStepIntegrator).
|
||||||
|
|
||||||
|
In addition to the above constructor, this class provides:
|
||||||
|
|
||||||
|
* a copy constructor,
|
||||||
|
* a destructor,
|
||||||
|
* an assignment operator,
|
||||||
|
* an insertion operator,
|
||||||
|
* the public member functions inherited from [FirstOrderODEVariableStepIntegrator](#class-FirstOrderODEVariableStepIntegrator),
|
||||||
|
* and the following public member functions:
|
||||||
|
|
||||||
### Public Member Functions
|
### Public Member Functions
|
||||||
|
|
||||||
* All of the [Public Member Functions of FirstOrderODEVariableStepIntegrator](#FirstOrderODEVariableStepIntegrator::publicMemberFunctions), plus :
|
* All of the [Public Member Functions of FirstOrderODEVariableStepIntegrator](#FirstOrderODEVariableStepIntegrator::publicMemberFunctions), plus :
|
||||||
@ -434,6 +475,15 @@ HeunsMethod( double h,
|
|||||||
```
|
```
|
||||||
[Constructor Parameters](#FOODEConstructorParameters) are those of [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
[Constructor Parameters](#FOODEConstructorParameters) are those of [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
||||||
|
|
||||||
|
In addition to the above constructor, this class provides:
|
||||||
|
|
||||||
|
* a copy constructor,
|
||||||
|
* a destructor,
|
||||||
|
* an assignment operator,
|
||||||
|
* an insertion operator,
|
||||||
|
* the public member functions inherited from [FirstOrderODEVariableStepIntegrator](#class-FirstOrderODEVariableStepIntegrator),
|
||||||
|
* and the following public member functions:
|
||||||
|
|
||||||
### Public Member Functions
|
### Public Member Functions
|
||||||
|
|
||||||
* All of the [Public Member Functions of FirstOrderODEVariableStepIntegrator](#FirstOrderODEVariableStepIntegrator::publicMemberFunctions).
|
* All of the [Public Member Functions of FirstOrderODEVariableStepIntegrator](#FirstOrderODEVariableStepIntegrator::publicMemberFunctions).
|
||||||
@ -463,10 +513,19 @@ RK2Integrator( double h,
|
|||||||
double* in_vars[],
|
double* in_vars[],
|
||||||
double* out_vars[],
|
double* out_vars[],
|
||||||
DerivsFunc func,
|
DerivsFunc func,
|
||||||
void* user_data)
|
void* user_data)
|
||||||
```
|
```
|
||||||
[Constructor Parameters](#FOODEConstructorParameters) are those of [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
[Constructor Parameters](#FOODEConstructorParameters) are those of [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
||||||
|
|
||||||
|
In addition to the above constructor, this class provides:
|
||||||
|
|
||||||
|
* a copy constructor,
|
||||||
|
* a destructor,
|
||||||
|
* an assignment operator,
|
||||||
|
* an insertion operator,
|
||||||
|
* the public member functions inherited from [FirstOrderODEVariableStepIntegrator](#class-FirstOrderODEVariableStepIntegrator),
|
||||||
|
* and the following public member functions:
|
||||||
|
|
||||||
### Public Member Functions
|
### Public Member Functions
|
||||||
|
|
||||||
* All of the [Public Member Functions of FirstOrderODEVariableStepIntegrator](#FirstOrderODEVariableStepIntegrator::publicMemberFunctions).
|
* All of the [Public Member Functions of FirstOrderODEVariableStepIntegrator](#FirstOrderODEVariableStepIntegrator::publicMemberFunctions).
|
||||||
@ -501,6 +560,15 @@ RK4Integrator( double h,
|
|||||||
```
|
```
|
||||||
[Constructor Parameters](#FOODEConstructorParameters) are those of [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
[Constructor Parameters](#FOODEConstructorParameters) are those of [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
||||||
|
|
||||||
|
In addition to the above constructor, this class provides:
|
||||||
|
|
||||||
|
* a copy constructor,
|
||||||
|
* a destructor,
|
||||||
|
* an assignment operator,
|
||||||
|
* an insertion operator,
|
||||||
|
* the public member functions inherited from [FirstOrderODEVariableStepIntegrator](#class-FirstOrderODEVariableStepIntegrator),
|
||||||
|
* and the following public member functions:
|
||||||
|
|
||||||
### Public Member Functions
|
### Public Member Functions
|
||||||
|
|
||||||
* All of the [Public Member Functions of FirstOrderODEVariableStepIntegrator](#FirstOrderODEVariableStepIntegrator::publicMemberFunctions).
|
* All of the [Public Member Functions of FirstOrderODEVariableStepIntegrator](#FirstOrderODEVariableStepIntegrator::publicMemberFunctions).
|
||||||
@ -535,6 +603,15 @@ RK3_8Integrator( double h,
|
|||||||
[Constructor Parameters](#FOODEConstructorParameters) are those of
|
[Constructor Parameters](#FOODEConstructorParameters) are those of
|
||||||
[FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
[FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
||||||
|
|
||||||
|
In addition to the above constructor, this class provides:
|
||||||
|
|
||||||
|
* a copy constructor,
|
||||||
|
* a destructor,
|
||||||
|
* an assignment operator,
|
||||||
|
* an insertion operator,
|
||||||
|
* the public member functions inherited from [FirstOrderODEVariableStepIntegrator](#class-FirstOrderODEVariableStepIntegrator),
|
||||||
|
* and the following public member functions:
|
||||||
|
|
||||||
### Public Member Functions
|
### Public Member Functions
|
||||||
|
|
||||||
* All of the [Public Member Functions of FirstOrderODEVariableStepIntegrator](#FirstOrderODEVariableStepIntegrator::publicMemberFunctions).
|
* All of the [Public Member Functions of FirstOrderODEVariableStepIntegrator](#FirstOrderODEVariableStepIntegrator::publicMemberFunctions).
|
||||||
@ -567,6 +644,14 @@ ABM2Integrator ( double h,
|
|||||||
```
|
```
|
||||||
[Constructor Parameters](#FOODEConstructorParameters) are those of [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
[Constructor Parameters](#FOODEConstructorParameters) are those of [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
||||||
|
|
||||||
|
In addition to the above constructor, this class provides:
|
||||||
|
|
||||||
|
* a copy constructor,
|
||||||
|
* a destructor,
|
||||||
|
* an assignment operator,
|
||||||
|
* an insertion operator,
|
||||||
|
* the public member functions inherited from [[FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
||||||
|
|
||||||
<a id=class-ABM4Integrator></a>
|
<a id=class-ABM4Integrator></a>
|
||||||
## class ABM4Integrator
|
## class ABM4Integrator
|
||||||
Derived from [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
Derived from [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
||||||
@ -589,6 +674,44 @@ ABM4Integrator ( double h,
|
|||||||
|
|
||||||
[Constructor Parameters](#FOODEConstructorParameters) are those of [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
[Constructor Parameters](#FOODEConstructorParameters) are those of [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
||||||
|
|
||||||
|
In addition to the above constructor, this class provides:
|
||||||
|
|
||||||
|
* a copy constructor,
|
||||||
|
* a destructor,
|
||||||
|
* an assignment operator,
|
||||||
|
* an insertion operator,
|
||||||
|
* the public member functions inherited from [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
||||||
|
|
||||||
|
|
||||||
|
<a id=typedef-Derivs2Func></a>
|
||||||
|
## typedef Derivs2Func
|
||||||
|
|
||||||
|
### Description
|
||||||
|
This typedef defines a type of C/C++ function whose purpose is to populate
|
||||||
|
an array of accelerations, given velocities and positions.
|
||||||
|
|
||||||
|
```
|
||||||
|
typedef void (*Derivs2Func)( double t, double x[], double v[], double a[], void* udata);
|
||||||
|
```
|
||||||
|
where:
|
||||||
|
|
||||||
|
|Parameter|Type |Direction|Description|
|
||||||
|
|---------|-------------|---------|-----------|
|
||||||
|
|t |```double``` |IN |Independent variable.|
|
||||||
|
|x |```double*```|IN |Array of position values.|
|
||||||
|
|v |```double*```|IN |Array of velocity values.|
|
||||||
|
|a |```double*```|OUT |Array into which accelerations are to be returned.|
|
||||||
|
|udata |```void*``` |IN |Pointer to user_data.|
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
```
|
||||||
|
void G( double t, double x[], double v[], double g_out[], void* udata) {
|
||||||
|
MassSpringDamper* msd = (MassSpringDamper*)udata;
|
||||||
|
g_out[0] = -(msd->k/msd->mass) * x[0]
|
||||||
|
-(msd->c/msd->mass) * v[0];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
<a id=class-EulerCromerIntegrator></a>
|
<a id=class-EulerCromerIntegrator></a>
|
||||||
## class EulerCromerIntegrator
|
## class EulerCromerIntegrator
|
||||||
Derived from [Integrator](#class-Integrator).
|
Derived from [Integrator](#class-Integrator).
|
||||||
@ -596,6 +719,12 @@ Derived from [Integrator](#class-Integrator).
|
|||||||
### Description
|
### Description
|
||||||
EulerCromer is integration method that conserves energy in oscillatory systems better than Runge-Kutta. So, it's good for mass-spring-damper systems, and orbital systems.
|
EulerCromer is integration method that conserves energy in oscillatory systems better than Runge-Kutta. So, it's good for mass-spring-damper systems, and orbital systems.
|
||||||
|
|
||||||
|
It calculates the next state, from the current state as follows:
|
||||||
|
|
||||||
|
![EulerCromerEqs](images/EulerCromerEqs.png)
|
||||||
|
|
||||||
|
**a(v(n), x(n), t)** [above] is the function of type [```Derivs2Func```](#typedef-Derivs2Func) below.
|
||||||
|
|
||||||
### Data Members
|
### Data Members
|
||||||
Those inherited from [Integrator](#class-Integrator) plus:
|
Those inherited from [Integrator](#class-Integrator) plus:
|
||||||
|
|
||||||
@ -609,9 +738,9 @@ Those inherited from [Integrator](#class-Integrator) plus:
|
|||||||
| pos_out |```double*``` |Protected|Position output array.|
|
| pos_out |```double*``` |Protected|Position output array.|
|
||||||
| vel_out |```double*``` |Protected|Velocity output array.|
|
| vel_out |```double*``` |Protected|Velocity output array.|
|
||||||
| g_out |```double*``` |Protected|Array of accelerations returned from gderivs.|
|
| g_out |```double*``` |Protected|Array of accelerations returned from gderivs.|
|
||||||
| f_out |```double*``` |Protected|Array of velocities returned from fderivs.|
|
| gderivs |[```Derivs2Func```](#typedef-Derivs2Func)|Protected|A function that returns accelerations.|
|
||||||
| gderivs |[```DerivsFunc```](#typedef-DerivsFunc)|Protected|A function that returns accelerations.|
|
| last_h |```double```|Value of h used in the last integration step.|
|
||||||
| fderivs |[```DerivsFunc```](#typedef-DerivsFunc)|Protected|A function that returns velocities.|
|
|
||||||
|
|
||||||
### Constructor
|
### Constructor
|
||||||
```
|
```
|
||||||
@ -619,8 +748,7 @@ EulerCromerIntegrator(double dt,
|
|||||||
int N,
|
int N,
|
||||||
double* xp[],
|
double* xp[],
|
||||||
double* vp[],
|
double* vp[],
|
||||||
DerivsFunc gfunc,
|
Derivs2Func gfunc,
|
||||||
DerivsFunc ffunc,
|
|
||||||
void* user_data)
|
void* user_data)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -630,10 +758,17 @@ EulerCromerIntegrator(double dt,
|
|||||||
| N |```int``` |Sets nDimensions above.|
|
| N |```int``` |Sets nDimensions above.|
|
||||||
| xp |```double*```|Sets pos_p above.|
|
| xp |```double*```|Sets pos_p above.|
|
||||||
| vp |```double*```|Sets vel_p above.|
|
| vp |```double*```|Sets vel_p above.|
|
||||||
| gfunc |[```DerivsFunc```](#typedef-DerivsFunc)| Sets gderivs above. |
|
| gfunc |[```Derivs2Func```](#typedef-Derivs2Func)| Sets gderivs above. |
|
||||||
| ffunc |[```DerivsFunc```](#typedef-DerivsFunc)| Sets fderivs above. |
|
|
||||||
|user_data |```void*``` | Sets Integrator::user_data. |
|
|user_data |```void*``` | Sets Integrator::user_data. |
|
||||||
|
|
||||||
|
In addition to the above constructor, this class provides:
|
||||||
|
|
||||||
|
* a copy constructor,
|
||||||
|
* a destructor,
|
||||||
|
* an assignment operator,
|
||||||
|
* an insertion operator,
|
||||||
|
* the public member functions inherited from [Integrator](#class-Integrator).
|
||||||
|
|
||||||
### Public Member Functions
|
### Public Member Functions
|
||||||
|
|
||||||
#### ```void step( double dt)```
|
#### ```void step( double dt)```
|
||||||
|
@ -48,10 +48,7 @@ int main ( int argc, char* argv[]) {
|
|||||||
double dt = 0.01;
|
double dt = 0.01;
|
||||||
double t = 0.0;
|
double t = 0.0;
|
||||||
SA::RK2Integrator integ(dt, 6, state_var_p, state_var_p, calc_derivs, NULL);
|
SA::RK2Integrator integ(dt, 6, state_var_p, state_var_p, calc_derivs, NULL);
|
||||||
|
integ.add_Rootfinder(0.00000000001, Negative, &impact);
|
||||||
RootFinder root_finder(0.00000000001, Negative);
|
|
||||||
integ.add_Rootfinder(&root_finder, &impact);
|
|
||||||
|
|
||||||
init_state(cannon);
|
init_state(cannon);
|
||||||
print_header();
|
print_header();
|
||||||
print_state( t, cannon);
|
print_state( t, cannon);
|
||||||
|
@ -13,7 +13,7 @@ void init_state ( MassSpringDamper& msd ) {
|
|||||||
msd.pos = 2.0;
|
msd.pos = 2.0;
|
||||||
msd.vel = 0.0;
|
msd.vel = 0.0;
|
||||||
msd.k = 1.0;
|
msd.k = 1.0;
|
||||||
msd.c = 0.0;
|
msd.c = 0.2;
|
||||||
msd.mass = 5.0;
|
msd.mass = 5.0;
|
||||||
}
|
}
|
||||||
void print_header() {
|
void print_header() {
|
||||||
@ -22,31 +22,24 @@ void print_header() {
|
|||||||
void print_state( double t, MassSpringDamper& msd ) {
|
void print_state( double t, MassSpringDamper& msd ) {
|
||||||
printf ("%10.10f, %10.10f, %10.10f\n", t, msd.pos, msd.vel);
|
printf ("%10.10f, %10.10f, %10.10f\n", t, msd.pos, msd.vel);
|
||||||
}
|
}
|
||||||
void G( double t, double x[], double g_out[], void* udata) {
|
void G( double t, double x[], double v[], double g_out[], void* udata) {
|
||||||
MassSpringDamper* msd = (MassSpringDamper*)udata;
|
MassSpringDamper* msd = (MassSpringDamper*)udata;
|
||||||
g_out[0] = -(msd->k/msd->mass) * x[0];
|
g_out[0] = -(msd->k/msd->mass) * x[0]
|
||||||
}
|
-(msd->c/msd->mass) * v[0];
|
||||||
void F( double t, double v[], double f_out[], void* udata) {
|
|
||||||
f_out[0] = v[0];
|
|
||||||
f_out[1] = v[1];
|
|
||||||
}
|
}
|
||||||
int main ( int argc, char* argv[]) {
|
int main ( int argc, char* argv[]) {
|
||||||
MassSpringDamper msd;
|
MassSpringDamper msd;
|
||||||
|
double time = 0.0;
|
||||||
double* x_p[N_DIMENSIONS] = { &msd.pos };
|
double* x_p[N_DIMENSIONS] = { &msd.pos };
|
||||||
double* v_p[N_DIMENSIONS] = { &msd.vel };
|
double* v_p[N_DIMENSIONS] = { &msd.vel };
|
||||||
unsigned count = 0;
|
|
||||||
double dt = 0.001;
|
double dt = 0.001;
|
||||||
double time = count * dt;
|
|
||||||
init_state(msd);
|
init_state(msd);
|
||||||
print_header();
|
print_header();
|
||||||
print_state(time, msd);
|
print_state(time, msd);
|
||||||
SA::EulerCromerIntegrator integ(dt, N_DIMENSIONS, x_p, v_p, G, F, &msd);
|
SA::EulerCromerIntegrator integ(dt, N_DIMENSIONS, x_p, v_p, G, &msd);
|
||||||
while (time < 50) {
|
while (time < 50) {
|
||||||
integ.load();
|
integ.integrate();
|
||||||
integ.step();
|
time = integ.getIndyVar();
|
||||||
integ.unload();
|
|
||||||
count ++;
|
|
||||||
time = count * dt;
|
|
||||||
print_state(time, msd);
|
print_state(time, msd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
0
trick_source/trick_utils/SAIntegrator/examples/MassSpringDamper/plot_position.py
Normal file → Executable file
0
trick_source/trick_utils/SAIntegrator/examples/MassSpringDamper/plot_position.py
Normal file → Executable file
@ -25,33 +25,25 @@ void print_state( double t, Orbit& orbit ) {
|
|||||||
printf ("%10.10f, %10.10f, %10.10f, %10.10f, %10.10f\n",
|
printf ("%10.10f, %10.10f, %10.10f, %10.10f, %10.10f\n",
|
||||||
t, orbit.pos[0], orbit.pos[1], orbit.vel[0], orbit.vel[1]);
|
t, orbit.pos[0], orbit.pos[1], orbit.vel[0], orbit.vel[1]);
|
||||||
}
|
}
|
||||||
void G( double t, double x[], double g_out[], void* udata) {
|
void G( double t, double pos[], double vel[], double acc_out[], void* udata) {
|
||||||
Orbit* orbit = (Orbit*)udata;
|
Orbit* orbit = (Orbit*)udata;
|
||||||
double d = sqrt( x[0]*x[0] + x[1]*x[1]);
|
double d = sqrt( pos[0]*pos[0] + pos[1]*pos[1]);
|
||||||
g_out[0] = -x[0] * GRAVITATIONAL_CONSTANT * orbit->planet_mass / (d*d*d);
|
acc_out[0] = -pos[0] * GRAVITATIONAL_CONSTANT * orbit->planet_mass / (d*d*d);
|
||||||
g_out[1] = -x[1] * GRAVITATIONAL_CONSTANT * orbit->planet_mass / (d*d*d);
|
acc_out[1] = -pos[1] * GRAVITATIONAL_CONSTANT * orbit->planet_mass / (d*d*d);
|
||||||
}
|
|
||||||
void F( double t, double v[], double f_out[], void* udata) {
|
|
||||||
f_out[0] = v[0];
|
|
||||||
f_out[1] = v[1];
|
|
||||||
}
|
}
|
||||||
int main ( int argc, char* argv[]) {
|
int main ( int argc, char* argv[]) {
|
||||||
Orbit orbit;
|
Orbit orbit;
|
||||||
|
double time = 0.0;
|
||||||
double* x_p[2] = { &orbit.pos[0], &orbit.pos[1] };
|
double* x_p[2] = { &orbit.pos[0], &orbit.pos[1] };
|
||||||
double* v_p[2] = { &orbit.vel[0], &orbit.vel[1] };
|
double* v_p[2] = { &orbit.vel[0], &orbit.vel[1] };
|
||||||
unsigned count = 0;
|
|
||||||
double dt = 0.1;
|
double dt = 0.1;
|
||||||
double time = count * dt;
|
|
||||||
init_state(orbit);
|
init_state(orbit);
|
||||||
print_header();
|
print_header();
|
||||||
print_state(time, orbit);
|
print_state(time, orbit);
|
||||||
SA::EulerCromerIntegrator integ(dt, 2, x_p, v_p, G, F, &orbit);
|
SA::EulerCromerIntegrator integ(dt, 2, x_p, v_p, G, &orbit);
|
||||||
while (time < 6000) {
|
while (time < 5600) {
|
||||||
integ.load();
|
integ.integrate();
|
||||||
integ.step();
|
time = integ.getIndyVar();
|
||||||
integ.unload();
|
|
||||||
count ++;
|
|
||||||
time = count * dt;
|
|
||||||
print_state(time, orbit);
|
print_state(time, orbit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
trick_source/trick_utils/SAIntegrator/images/EulerCromerEqs.png
Normal file
BIN
trick_source/trick_utils/SAIntegrator/images/EulerCromerEqs.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
@ -1,3 +1,4 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
Negative = -1,
|
Negative = -1,
|
||||||
@ -12,6 +13,7 @@ class RootFinder {
|
|||||||
RootFinder();
|
RootFinder();
|
||||||
RootFinder (double tolerance, SlopeConstraint constraint);
|
RootFinder (double tolerance, SlopeConstraint constraint);
|
||||||
double find_roots( double x, double f_error );
|
double find_roots( double x, double f_error );
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const RootFinder& rf);
|
||||||
private:
|
private:
|
||||||
double f_upper;
|
double f_upper;
|
||||||
double x_upper;
|
double x_upper;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include "Rootfinder.hh"
|
#include "Rootfinder.hh"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace SA {
|
namespace SA {
|
||||||
|
|
||||||
class Integrator {
|
class Integrator {
|
||||||
@ -9,7 +11,8 @@ namespace SA {
|
|||||||
void* user_data; // User data
|
void* user_data; // User data
|
||||||
void advanceIndyVar();
|
void advanceIndyVar();
|
||||||
public:
|
public:
|
||||||
Integrator(double h, void* udata): X_in(0.0), X_out(0.0), default_h(h), user_data(udata) {};
|
Integrator();
|
||||||
|
Integrator(double h, void* udata);
|
||||||
virtual ~Integrator() {}
|
virtual ~Integrator() {}
|
||||||
virtual void load();
|
virtual void load();
|
||||||
virtual void unload();
|
virtual void unload();
|
||||||
@ -18,8 +21,11 @@ namespace SA {
|
|||||||
virtual double undo_integrate();
|
virtual double undo_integrate();
|
||||||
double getIndyVar();
|
double getIndyVar();
|
||||||
void setIndyVar(double v);
|
void setIndyVar(double v);
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const SA::Integrator& I);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const Integrator& I);
|
||||||
|
|
||||||
typedef void (*DerivsFunc)( double x, double state[], double derivs[], void* udata);
|
typedef void (*DerivsFunc)( double x, double state[], double derivs[], void* udata);
|
||||||
|
|
||||||
class FirstOrderODEIntegrator : public Integrator {
|
class FirstOrderODEIntegrator : public Integrator {
|
||||||
@ -30,21 +36,23 @@ namespace SA {
|
|||||||
double** inVars; // Array of pointers to the variables whose values comprise the input state vector.
|
double** inVars; // Array of pointers to the variables whose values comprise the input state vector.
|
||||||
double** outVars; // Array of pointers to the variables to which the output state vector values are to be disseminated.
|
double** outVars; // Array of pointers to the variables to which the output state vector values are to be disseminated.
|
||||||
DerivsFunc derivs_func; // Pointer to the function that calculates the derivatives to be integrated.
|
DerivsFunc derivs_func; // Pointer to the function that calculates the derivatives to be integrated.
|
||||||
// void advanceIndyVar(); // Inherited from Integrator::advanceIndyVar()
|
|
||||||
public:
|
public:
|
||||||
FirstOrderODEIntegrator( double h, int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
FirstOrderODEIntegrator();
|
||||||
|
FirstOrderODEIntegrator( double h, unsigned int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
||||||
|
FirstOrderODEIntegrator(const FirstOrderODEIntegrator& other);
|
||||||
|
FirstOrderODEIntegrator& operator=( const FirstOrderODEIntegrator& other);
|
||||||
virtual ~FirstOrderODEIntegrator();
|
virtual ~FirstOrderODEIntegrator();
|
||||||
void load(); // Overrides Integrator::load(), Final
|
void load(); // Overrides Integrator::load(), Final
|
||||||
void unload(); // Overrides Integrator::unload(), Final
|
void unload(); // Overrides Integrator::unload(), Final
|
||||||
virtual void step(); // Overrides Integrator::step(). Virtual
|
virtual void step(); // Overrides Integrator::step(). Virtual
|
||||||
// integrate(); Inherited from Integrator::integrate(), Final
|
|
||||||
virtual double undo_integrate(); // Overrides Integrator::undo_integrate(), Virtual
|
virtual double undo_integrate(); // Overrides Integrator::undo_integrate(), Virtual
|
||||||
void load_from_outState(); // New, Final
|
void load_from_outState(); // New, Final
|
||||||
double** set_in_vars( double* in_vars[]); // New, Final
|
double** set_in_vars( double* in_vars[]); // New, Final
|
||||||
double** set_out_vars( double* out_vars[]);// New, Final
|
double** set_out_vars( double* out_vars[]);// New, Final
|
||||||
// double getIndyVar();
|
|
||||||
// void setIndyVar(double v);
|
friend std::ostream& operator<<(std::ostream& os, const SA::FirstOrderODEIntegrator& I);
|
||||||
};
|
};
|
||||||
|
std::ostream& operator<<(std::ostream& os, const FirstOrderODEIntegrator& I);
|
||||||
|
|
||||||
typedef double (*RootErrorFunc)( double x, double state[], RootFinder* root_finder, void* udata);
|
typedef double (*RootErrorFunc)( double x, double state[], RootFinder* root_finder, void* udata);
|
||||||
|
|
||||||
@ -54,82 +62,96 @@ namespace SA {
|
|||||||
RootErrorFunc root_error_func;
|
RootErrorFunc root_error_func;
|
||||||
protected:
|
protected:
|
||||||
double last_h;
|
double last_h;
|
||||||
// void advanceIndyVar(); // Inherited from Integrator::advanceIndyVar(), Final
|
|
||||||
void advanceIndyVar( double h);
|
void advanceIndyVar( double h);
|
||||||
public:
|
public:
|
||||||
FirstOrderODEVariableStepIntegrator( double h, int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
FirstOrderODEVariableStepIntegrator();
|
||||||
|
FirstOrderODEVariableStepIntegrator( double h, unsigned int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
||||||
|
FirstOrderODEVariableStepIntegrator( const FirstOrderODEVariableStepIntegrator& other);
|
||||||
|
FirstOrderODEVariableStepIntegrator& operator=( const FirstOrderODEVariableStepIntegrator& rhs);
|
||||||
~FirstOrderODEVariableStepIntegrator();
|
~FirstOrderODEVariableStepIntegrator();
|
||||||
// load(); Inherited from FirstOrderODEIntegrator, Final
|
|
||||||
// unload(); Inherited from FirstOrderODEIntegrator, Final
|
|
||||||
void step(); // Overrides FirstOrderODEIntegrator::step(), Final
|
void step(); // Overrides FirstOrderODEIntegrator::step(), Final
|
||||||
// integrate(); // Inherited from Integrator
|
|
||||||
double undo_integrate(); // Overrides FirstOrderODEIntegrator::undo_integrate(), Final
|
double undo_integrate(); // Overrides FirstOrderODEIntegrator::undo_integrate(), Final
|
||||||
// load_from_outState(); // Inherited from FirstOrderODEIntegrator, Final
|
|
||||||
// set_in_vars(); // Inherited from FirstOrderODEIntegrator, Final
|
|
||||||
// set_out_vars(); // Inherited from FirstOrderODEIntegrator, Final
|
|
||||||
virtual void variable_step( double h); // New, Should be overridden in derived classes, Virtual
|
virtual void variable_step( double h); // New, Should be overridden in derived classes, Virtual
|
||||||
void add_Rootfinder( RootFinder* root_finder, RootErrorFunc rfunc); // New, Final
|
void add_Rootfinder( double tolerance, SlopeConstraint constraint, RootErrorFunc rfunc);
|
||||||
// double getIndyVar(); // Inherited from Integrator
|
friend std::ostream& operator<<(std::ostream& os, const SA::FirstOrderODEVariableStepIntegrator& I);
|
||||||
// void setIndyVar(double v); // Inherited from Integrator
|
|
||||||
private:
|
private:
|
||||||
void find_roots(double h, unsigned int depth);
|
void find_roots(double h, unsigned int depth);
|
||||||
};
|
};
|
||||||
|
std::ostream& operator<<(std::ostream& os, const FirstOrderODEVariableStepIntegrator& I);
|
||||||
|
|
||||||
class EulerIntegrator : public FirstOrderODEVariableStepIntegrator {
|
class EulerIntegrator : public FirstOrderODEVariableStepIntegrator {
|
||||||
public:
|
public:
|
||||||
double *derivs;
|
double *derivs;
|
||||||
EulerIntegrator( double h, int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
EulerIntegrator();
|
||||||
|
EulerIntegrator( double h, unsigned int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
||||||
|
EulerIntegrator(const EulerIntegrator& other);
|
||||||
|
EulerIntegrator& operator=( const EulerIntegrator& rhs);
|
||||||
~EulerIntegrator();
|
~EulerIntegrator();
|
||||||
// load(); Inherited from FirstOrderODEIntegrator
|
void variable_step( double h);
|
||||||
// unload(); Inherited from FirstOrderODEIntegrator
|
friend std::ostream& operator<<(std::ostream& os, const SA::EulerIntegrator& I);
|
||||||
// void step(); Inherited from FirstOrderODEVariableStepIntegrator
|
|
||||||
// void integrate() Inherited from FirstOrderODEVariableStepIntegrator
|
|
||||||
// double undo_integrate(); Inherited from FirstOrderODEVariableStepIntegrator
|
|
||||||
// load_from_outState(); Inherited from FirstOrderODEIntegrator
|
|
||||||
// set_in_vars(); Inherited from FirstOrderODEIntegrator
|
|
||||||
// set_out_vars(); Inherited from FirstOrderODEIntegrator
|
|
||||||
void variable_step( double h); // Overrides FirstOrderODEVariableStepIntegrator::variable_step()
|
|
||||||
// void integrate(double h) Inherited from FirstOrderODEVariableStepIntegrator
|
|
||||||
// void add_Rootfinder( RootFinder* root_finder, RootErrorFunc rfunc); Inherited from FirstOrderODEVariableStepIntegrator
|
|
||||||
// double getIndyVar(); Inherited from Integrator
|
|
||||||
// void setIndyVar(double v); Inherited from Integrator
|
|
||||||
};
|
};
|
||||||
|
std::ostream& operator<<(std::ostream& os, const EulerIntegrator& I);
|
||||||
|
|
||||||
class HeunsMethod : public FirstOrderODEVariableStepIntegrator {
|
class HeunsMethod : public FirstOrderODEVariableStepIntegrator {
|
||||||
public:
|
public:
|
||||||
double *wstate;
|
double *wstate;
|
||||||
double *derivs[2];
|
double *derivs[2];
|
||||||
HeunsMethod( double h, int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
HeunsMethod();
|
||||||
|
HeunsMethod( double h, unsigned int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
||||||
|
HeunsMethod(const HeunsMethod& other);
|
||||||
|
HeunsMethod& operator=( const HeunsMethod& rhs);
|
||||||
~HeunsMethod();
|
~HeunsMethod();
|
||||||
void variable_step( double h); // Overrides FirstOrderODEVariableStepIntegrator::variable_step()
|
void variable_step( double h);
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const SA::HeunsMethod& I);
|
||||||
};
|
};
|
||||||
|
std::ostream& operator<<(std::ostream& os, const HeunsMethod& I);
|
||||||
|
|
||||||
class RK2Integrator : public FirstOrderODEVariableStepIntegrator {
|
class RK2Integrator : public FirstOrderODEVariableStepIntegrator {
|
||||||
public:
|
public:
|
||||||
double *wstate;
|
double *wstate;
|
||||||
double *derivs[2];
|
double *derivs[2];
|
||||||
RK2Integrator( double h, int N, double* in_vars[], double* out_vars[], DerivsFunc derivs_func, void* udata);
|
RK2Integrator();
|
||||||
|
RK2Integrator( double h, unsigned int N, double* in_vars[], double* out_vars[], DerivsFunc derivs_func, void* udata);
|
||||||
|
RK2Integrator(const RK2Integrator& other);
|
||||||
|
RK2Integrator& operator=( const RK2Integrator& rhs);
|
||||||
~RK2Integrator();
|
~RK2Integrator();
|
||||||
void variable_step( double h); // Overrides FirstOrderODEVariableStepIntegrator::variable_step()
|
void variable_step( double h);
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const SA::RK2Integrator& I);
|
||||||
};
|
};
|
||||||
|
std::ostream& operator<<(std::ostream& os, const RK2Integrator& I);
|
||||||
|
|
||||||
class RK4Integrator : public FirstOrderODEVariableStepIntegrator {
|
class RK4Integrator : public FirstOrderODEVariableStepIntegrator {
|
||||||
public:
|
public:
|
||||||
double *wstate[3];
|
double *wstate[3];
|
||||||
double *derivs[4];
|
double *derivs[4];
|
||||||
RK4Integrator( double h, int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
|
||||||
|
RK4Integrator();
|
||||||
|
RK4Integrator( double h, unsigned int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
||||||
|
RK4Integrator(const RK4Integrator& other);
|
||||||
|
RK4Integrator& operator=( const RK4Integrator& rhs);
|
||||||
~RK4Integrator();
|
~RK4Integrator();
|
||||||
void variable_step( double h); // Overrides FirstOrderODEVariableStepIntegrator::variable_step()
|
void variable_step( double h);
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const SA::RK4Integrator& I);
|
||||||
};
|
};
|
||||||
|
std::ostream& operator<<(std::ostream& os, const RK4Integrator& I);
|
||||||
|
|
||||||
class RK3_8Integrator : public FirstOrderODEVariableStepIntegrator {
|
class RK3_8Integrator : public FirstOrderODEVariableStepIntegrator {
|
||||||
public:
|
public:
|
||||||
double *wstate[4];
|
double *wstate[3];
|
||||||
double *derivs[4];
|
double *derivs[4];
|
||||||
RK3_8Integrator( double h, int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
|
||||||
|
RK3_8Integrator();
|
||||||
|
RK3_8Integrator( double h, unsigned int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
||||||
|
RK3_8Integrator(const RK3_8Integrator& other);
|
||||||
|
RK3_8Integrator& operator=( const RK3_8Integrator& rhs);
|
||||||
~RK3_8Integrator();
|
~RK3_8Integrator();
|
||||||
void variable_step( double h); // Overrides FirstOrderODEVariableStepIntegrator::variable_step()
|
void variable_step( double h);
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const SA::RK3_8Integrator& I);
|
||||||
};
|
};
|
||||||
|
std::ostream& operator<<(std::ostream& os, const RK3_8Integrator& I);
|
||||||
|
|
||||||
|
typedef void (*Derivs2Func)( double t, double x[], double v[], double derivs[], void* udata);
|
||||||
|
|
||||||
class EulerCromerIntegrator : public Integrator {
|
class EulerCromerIntegrator : public Integrator {
|
||||||
protected:
|
protected:
|
||||||
@ -141,19 +163,24 @@ namespace SA {
|
|||||||
double* pos_out;
|
double* pos_out;
|
||||||
double* vel_out;
|
double* vel_out;
|
||||||
double* g_out;
|
double* g_out;
|
||||||
double* f_out;
|
double last_h;
|
||||||
DerivsFunc gderivs;
|
Derivs2Func gderivs;
|
||||||
DerivsFunc fderivs;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EulerCromerIntegrator(double dt, int N, double* xp[], double* vp[], DerivsFunc g, DerivsFunc f , void* udata);
|
EulerCromerIntegrator();
|
||||||
|
EulerCromerIntegrator(double dt, unsigned int N, double* xp[], double* vp[], Derivs2Func g, void* udata);
|
||||||
|
EulerCromerIntegrator(const EulerCromerIntegrator& other);
|
||||||
|
EulerCromerIntegrator& operator=( const EulerCromerIntegrator& rhs);
|
||||||
~EulerCromerIntegrator();
|
~EulerCromerIntegrator();
|
||||||
|
void advanceIndyVar(double h);
|
||||||
void step( double dt);
|
void step( double dt);
|
||||||
void step();
|
void step();
|
||||||
void load();
|
void load();
|
||||||
void unload();
|
void unload();
|
||||||
double undo_integrate();
|
double undo_integrate();
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const SA::EulerCromerIntegrator& I);
|
||||||
};
|
};
|
||||||
|
std::ostream& operator<<(std::ostream& os, const EulerCromerIntegrator& I);
|
||||||
|
|
||||||
// AdamsBashforthMoulton Self Priming
|
// AdamsBashforthMoulton Self Priming
|
||||||
class ABMIntegrator : public FirstOrderODEIntegrator {
|
class ABMIntegrator : public FirstOrderODEIntegrator {
|
||||||
@ -165,11 +192,15 @@ namespace SA {
|
|||||||
unsigned int hix;
|
unsigned int hix;
|
||||||
unsigned int currentHistorySize;
|
unsigned int currentHistorySize;
|
||||||
public:
|
public:
|
||||||
ABMIntegrator(int history_size, double h, int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
ABMIntegrator(unsigned int history_size, double h, unsigned int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
||||||
|
ABMIntegrator(const ABMIntegrator& other);
|
||||||
|
ABMIntegrator& operator=( const ABMIntegrator& rhs);
|
||||||
~ABMIntegrator();
|
~ABMIntegrator();
|
||||||
void step();
|
void step();
|
||||||
double undo_integrate();
|
double undo_integrate();
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const ABMIntegrator& I);
|
||||||
};
|
};
|
||||||
|
std::ostream& operator<<(std::ostream& os, const ABMIntegrator& I);
|
||||||
|
|
||||||
// AdamsBashforthMoulton 2 with RK2 Priming
|
// AdamsBashforthMoulton 2 with RK2 Priming
|
||||||
class ABM2Integrator : public FirstOrderODEIntegrator {
|
class ABM2Integrator : public FirstOrderODEIntegrator {
|
||||||
@ -179,13 +210,17 @@ namespace SA {
|
|||||||
unsigned int bufferSize;
|
unsigned int bufferSize;
|
||||||
unsigned int hix;
|
unsigned int hix;
|
||||||
unsigned int currentHistorySize;
|
unsigned int currentHistorySize;
|
||||||
FirstOrderODEVariableStepIntegrator* priming_integrator;
|
RK2Integrator* priming_integrator;
|
||||||
public:
|
public:
|
||||||
ABM2Integrator( double h, int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
ABM2Integrator( double h, unsigned int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
||||||
|
ABM2Integrator(const ABM2Integrator& other);
|
||||||
|
ABM2Integrator& operator=( const ABM2Integrator& rhs);
|
||||||
~ABM2Integrator();
|
~ABM2Integrator();
|
||||||
void step();
|
void step();
|
||||||
double undo_integrate();
|
double undo_integrate();
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const ABM2Integrator& I);
|
||||||
};
|
};
|
||||||
|
std::ostream& operator<<(std::ostream& os, const ABM2Integrator& I);
|
||||||
|
|
||||||
// AdamsBashforthMoulton 4 with RK4 Priming
|
// AdamsBashforthMoulton 4 with RK4 Priming
|
||||||
class ABM4Integrator : public FirstOrderODEIntegrator {
|
class ABM4Integrator : public FirstOrderODEIntegrator {
|
||||||
@ -195,11 +230,15 @@ namespace SA {
|
|||||||
unsigned int bufferSize;
|
unsigned int bufferSize;
|
||||||
unsigned int hix;
|
unsigned int hix;
|
||||||
unsigned int currentHistorySize;
|
unsigned int currentHistorySize;
|
||||||
FirstOrderODEVariableStepIntegrator* priming_integrator;
|
RK4Integrator* priming_integrator;
|
||||||
public:
|
public:
|
||||||
ABM4Integrator( double h, int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
ABM4Integrator( double h, unsigned int N, double* in_vars[], double* out_vars[], DerivsFunc dfunc, void* udata);
|
||||||
|
ABM4Integrator(const ABM4Integrator& other);
|
||||||
|
ABM4Integrator& operator=( const ABM4Integrator& rhs);
|
||||||
~ABM4Integrator();
|
~ABM4Integrator();
|
||||||
void step();
|
void step();
|
||||||
double undo_integrate();
|
double undo_integrate();
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const ABM4Integrator& I);
|
||||||
};
|
};
|
||||||
|
std::ostream& operator<<(std::ostream& os, const ABM4Integrator& I);
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,18 @@ void RootFinder::init( double tolerance, SlopeConstraint constraint) {
|
|||||||
void RootFinder::init() {
|
void RootFinder::init() {
|
||||||
init(0.00000000001, Unconstrained);
|
init(0.00000000001, Unconstrained);
|
||||||
}
|
}
|
||||||
RootFinder::RootFinder (double tolerance, SlopeConstraint constraint) {
|
// Default Constructor
|
||||||
init(tolerance, constraint);
|
|
||||||
}
|
|
||||||
RootFinder::RootFinder () {
|
RootFinder::RootFinder () {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
// Constructor
|
||||||
|
RootFinder::RootFinder (double tolerance, SlopeConstraint constraint) {
|
||||||
|
init(tolerance, constraint);
|
||||||
|
}
|
||||||
|
// Copy Constructor: The default copy_constructor should suffice.
|
||||||
|
// Assignment Operator: The default assignment operator should suffice.
|
||||||
|
// Destructor: The default destructor should suffice.
|
||||||
|
|
||||||
// Given the values of the independent variable, and the function,
|
// Given the values of the independent variable, and the function,
|
||||||
// estimate the distance of the independent variable from functions root.
|
// estimate the distance of the independent variable from functions root.
|
||||||
double RootFinder::find_roots( double x, double f_error ) {
|
double RootFinder::find_roots( double x, double f_error ) {
|
||||||
@ -86,3 +92,15 @@ double RootFinder::find_roots( double x, double f_error ) {
|
|||||||
iterations = 0;
|
iterations = 0;
|
||||||
return (DBL_MAX);
|
return (DBL_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const RootFinder& rf) {
|
||||||
|
os << "\n--- RootFinder ---";
|
||||||
|
os << "\nupper: {" << rf.f_upper << ',' << rf.x_upper << ',' << rf.upper_set << "}";
|
||||||
|
os << "\nlower: {" << rf.f_lower << ',' << rf.x_lower << ',' << rf.lower_set << "}";
|
||||||
|
os << "\nprev_f_error: " << rf.prev_f_error;
|
||||||
|
os << "\nf_error_tol:" << rf.prev_f_error;
|
||||||
|
os << "\niterations:" << rf.prev_f_error;
|
||||||
|
os << "\nslope_constraint:" << rf.slope_constraint;
|
||||||
|
os << "\nf_slope:" << rf.f_slope;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,86 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include "SAIntegrator.hh"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
void deriv1( double t __attribute__((unused)),
|
||||||
|
double state[] __attribute__((unused)),
|
||||||
|
double derivs[],
|
||||||
|
void* udata __attribute__((unused))) {
|
||||||
|
derivs[0] = 4.0;
|
||||||
|
derivs[1] = -4.0;
|
||||||
|
derivs[2] = M_PI;
|
||||||
|
derivs[3] = -M_PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXCEPTABLE_ERROR 0.00000000001
|
||||||
|
|
||||||
|
TEST(EulerIntegrator_unittest, EulerIntegrator_1) {
|
||||||
|
|
||||||
|
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
||||||
|
double* state_var_p[4] = { &(state[0]), &(state[1]), &(state[2]), &(state[3])};
|
||||||
|
double dt = 0.01;
|
||||||
|
unsigned int count = 0;
|
||||||
|
double t = count * dt;
|
||||||
|
SA::EulerIntegrator integ(dt, 4, state_var_p, state_var_p, deriv1, NULL);
|
||||||
|
while (t < 2.0) {
|
||||||
|
integ.load();
|
||||||
|
integ.step();
|
||||||
|
integ.unload();
|
||||||
|
count ++;
|
||||||
|
t = count * dt;
|
||||||
|
}
|
||||||
|
EXPECT_NEAR(state[0], 8.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[1], -8.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[2], (2*M_PI), EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[3], (-2*M_PI), EXCEPTABLE_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FirstOrderODEVariableStepIntegrator_unittest, EulerIntegrator_undo_integrate) {
|
||||||
|
|
||||||
|
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
||||||
|
double* state_var_p[4] = { &(state[0]), &(state[1]), &(state[2]), &(state[3])};
|
||||||
|
double dx = 0.1;
|
||||||
|
double x;
|
||||||
|
|
||||||
|
SA::EulerIntegrator integ(dx, 4, state_var_p, state_var_p, deriv1, NULL);
|
||||||
|
integ.load();
|
||||||
|
integ.step();
|
||||||
|
integ.unload();
|
||||||
|
|
||||||
|
x = integ.getIndyVar();
|
||||||
|
EXPECT_NEAR(state[0], (4.0/10.0), EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[1], (-4.0/10.0), EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[2], (M_PI/10.0), EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[3], (-M_PI/10.0), EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(x, 0.1, EXCEPTABLE_ERROR);
|
||||||
|
|
||||||
|
integ.undo_integrate();
|
||||||
|
|
||||||
|
x = integ.getIndyVar();
|
||||||
|
EXPECT_NEAR(state[0], 0.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[1], 0.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[2], 0.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[3], 0.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(x, 0.0, EXCEPTABLE_ERROR);
|
||||||
|
|
||||||
|
integ.undo_integrate();
|
||||||
|
|
||||||
|
x = integ.getIndyVar();
|
||||||
|
EXPECT_NEAR(state[0], 0.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[1], 0.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[2], 0.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[3], 0.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(x, 0.0, EXCEPTABLE_ERROR);
|
||||||
|
|
||||||
|
integ.load();
|
||||||
|
integ.step();
|
||||||
|
integ.unload();
|
||||||
|
|
||||||
|
x = integ.getIndyVar();
|
||||||
|
EXPECT_NEAR(state[0], (4.0/10.0), EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[1], (-4.0/10.0), EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[2], (M_PI/10.0), EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[3], (-M_PI/10.0), EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(x, 0.1, EXCEPTABLE_ERROR);
|
||||||
|
}
|
@ -156,4 +156,65 @@ TEST(FirstOrderODEIntegrator_unittest, test_4) {
|
|||||||
|
|
||||||
double x = integ.getIndyVar();
|
double x = integ.getIndyVar();
|
||||||
EXPECT_NEAR(x, 0.6, EXCEPTABLE_ERROR);
|
EXPECT_NEAR(x, 0.6, EXCEPTABLE_ERROR);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FirstOrderODEIntegrator_unittest, test_copy_constructor) {
|
||||||
|
double h = 0.1;
|
||||||
|
unsigned int N = 4;
|
||||||
|
double vars[4] = {1.0, 2.0, 3.0, 4.0} ;
|
||||||
|
double* varptrs[4] = {&vars[0], &vars[1], &vars[2], &vars[3]};
|
||||||
|
|
||||||
|
SA::FirstOrderODEIntegrator integ1( h, N, varptrs, varptrs, calc_derivs, NULL);
|
||||||
|
|
||||||
|
// Do an integration step to change array values to non-zero.
|
||||||
|
integ1.integrate();
|
||||||
|
|
||||||
|
// Use the copy-constructor to create create a duplicate FirstOrderODEIntegrator.
|
||||||
|
SA::FirstOrderODEIntegrator integ2(integ1);
|
||||||
|
|
||||||
|
// We don't want to unload integ1 here because it will then effect integ2,
|
||||||
|
// since both are pointing to the same input/output arrays.
|
||||||
|
integ1.load(); integ1.step();
|
||||||
|
integ2.load(); integ2.step();
|
||||||
|
|
||||||
|
// Create a text representation for each of the FirstOrderODEIntegrators.
|
||||||
|
std::stringstream ss1;
|
||||||
|
std::stringstream ss2;
|
||||||
|
ss1 << integ1 << std::endl;
|
||||||
|
ss2 << integ2 << std::endl;
|
||||||
|
|
||||||
|
// Compare the text representations. They should be identical.
|
||||||
|
int result = ss1.str().compare(ss2.str());
|
||||||
|
EXPECT_EQ(result, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FirstOrderODEIntegrator_unittest, test_assignment_operator) {
|
||||||
|
double h = 0.1;
|
||||||
|
unsigned int N = 4;
|
||||||
|
double vars[4] = {1.0, 2.0, 3.0, 4.0} ;
|
||||||
|
double* varptrs[4] = {&vars[0], &vars[1], &vars[2], &vars[3]};
|
||||||
|
|
||||||
|
SA::FirstOrderODEIntegrator integ1( h, N, varptrs, varptrs, calc_derivs, NULL);
|
||||||
|
|
||||||
|
// Do an integration step to change array values to non-zero.
|
||||||
|
integ1.integrate();
|
||||||
|
|
||||||
|
// Use the assignment-operator to create a duplicate FirstOrderODEIntegrator.
|
||||||
|
SA::FirstOrderODEIntegrator integ2 = integ1;
|
||||||
|
|
||||||
|
// We don't want to unload integ1 here because it will then effect integ2,
|
||||||
|
// since both are pointing to the same input/output arrays.
|
||||||
|
integ1.load(); integ1.step();
|
||||||
|
integ2.load(); integ2.step();
|
||||||
|
|
||||||
|
// Create a text representation for each of the FirstOrderODEIntegrators.
|
||||||
|
std::stringstream ss1;
|
||||||
|
std::stringstream ss2;
|
||||||
|
ss1 << integ1 << std::endl;
|
||||||
|
ss2 << integ2 << std::endl;
|
||||||
|
|
||||||
|
// Compare the text representations. They should be identical.
|
||||||
|
int result = ss1.str().compare(ss2.str());
|
||||||
|
EXPECT_EQ(result, 0);
|
||||||
}
|
}
|
||||||
|
@ -38,69 +38,6 @@ void deriv1( double t __attribute__((unused)),
|
|||||||
|
|
||||||
#define EXCEPTABLE_ERROR 0.00000000001
|
#define EXCEPTABLE_ERROR 0.00000000001
|
||||||
|
|
||||||
TEST(FirstOrderODEVariableStepIntegrator_unittest, EulerIntegrator_1) {
|
|
||||||
|
|
||||||
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
|
||||||
double* state_var_p[4] = { &(state[0]), &(state[1]), &(state[2]), &(state[3])};
|
|
||||||
double dt = 0.01;
|
|
||||||
unsigned int count = 0;
|
|
||||||
double t = count * dt;
|
|
||||||
SA::EulerIntegrator integ(dt, 4, state_var_p, state_var_p, deriv1, NULL);
|
|
||||||
while (t < 2.0) {
|
|
||||||
integ.load();
|
|
||||||
integ.step();
|
|
||||||
integ.unload();
|
|
||||||
count ++;
|
|
||||||
t = count * dt;
|
|
||||||
}
|
|
||||||
EXPECT_NEAR(state[0], 8.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[1], -8.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[2], (2*M_PI), EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[3], (-2*M_PI), EXCEPTABLE_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FirstOrderODEVariableStepIntegrator_unittest, RungeKutta2_1) {
|
|
||||||
|
|
||||||
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
|
||||||
double* state_var_p[4] = { &(state[0]), &(state[1]), &(state[2]), &(state[3]) };
|
|
||||||
double dt = 0.01;
|
|
||||||
unsigned int count = 0;
|
|
||||||
double t = count * dt;
|
|
||||||
SA::RK2Integrator integ(dt, 4, state_var_p, state_var_p, deriv2, NULL);
|
|
||||||
while (t < 2.0) {
|
|
||||||
integ.load();
|
|
||||||
integ.step();
|
|
||||||
integ.unload();
|
|
||||||
count ++;
|
|
||||||
t = count * dt;
|
|
||||||
}
|
|
||||||
EXPECT_NEAR(state[0], 2.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[1], 18.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[2], 0.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[3], 18.0, EXCEPTABLE_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FirstOrderODEVariableStepIntegrator_unittest, RungeKutta4_1) {
|
|
||||||
|
|
||||||
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
|
||||||
double* state_var_p[4] = { &(state[0]), &(state[1]), &(state[2]), &(state[3]) };
|
|
||||||
double dt = 0.01;
|
|
||||||
unsigned int count = 0;
|
|
||||||
double t = count * dt;
|
|
||||||
SA::RK4Integrator integ(dt, 4, state_var_p, state_var_p, deriv4, NULL);
|
|
||||||
while (t < 2.0) {
|
|
||||||
integ.load();
|
|
||||||
integ.step();
|
|
||||||
integ.unload();
|
|
||||||
count ++;
|
|
||||||
t = count * dt;
|
|
||||||
}
|
|
||||||
EXPECT_NEAR(state[0], 6.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[1], (14.0+2/3.0), EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[2], (24+2/3.0), EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[3], 20.0, EXCEPTABLE_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FirstOrderODEVariableStepIntegrator_unittest, RungeKutta38_1) {
|
TEST(FirstOrderODEVariableStepIntegrator_unittest, RungeKutta38_1) {
|
||||||
|
|
||||||
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
||||||
@ -108,11 +45,11 @@ TEST(FirstOrderODEVariableStepIntegrator_unittest, RungeKutta38_1) {
|
|||||||
double dt = 0.01;
|
double dt = 0.01;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
double t = count * dt;
|
double t = count * dt;
|
||||||
SA::RK3_8Integrator integ(dt, 4, state_var_p, state_var_p, deriv4, NULL);
|
SA::RK3_8Integrator integ1(dt, 4, state_var_p, state_var_p, deriv4, NULL);
|
||||||
while (t < 2.0) {
|
while (t < 2.0) {
|
||||||
integ.load();
|
integ1.load();
|
||||||
integ.step();
|
integ1.step();
|
||||||
integ.unload();
|
integ1.unload();
|
||||||
count ++;
|
count ++;
|
||||||
t = count * dt;
|
t = count * dt;
|
||||||
}
|
}
|
||||||
@ -120,53 +57,17 @@ TEST(FirstOrderODEVariableStepIntegrator_unittest, RungeKutta38_1) {
|
|||||||
EXPECT_NEAR(state[1], (14.0+2/3.0), EXCEPTABLE_ERROR);
|
EXPECT_NEAR(state[1], (14.0+2/3.0), EXCEPTABLE_ERROR);
|
||||||
EXPECT_NEAR(state[2], (24+2/3.0), EXCEPTABLE_ERROR);
|
EXPECT_NEAR(state[2], (24+2/3.0), EXCEPTABLE_ERROR);
|
||||||
EXPECT_NEAR(state[3], 20.0, EXCEPTABLE_ERROR);
|
EXPECT_NEAR(state[3], 20.0, EXCEPTABLE_ERROR);
|
||||||
}
|
|
||||||
|
// Use the copy-constructor to create create a duplicate RK3_8Integrator.
|
||||||
TEST(FirstOrderODEVariableStepIntegrator_unittest, EulerIntegrator_undo_integrate) {
|
SA::RK3_8Integrator integ2(integ1);
|
||||||
|
|
||||||
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
// Create a text representation for each of the RK3_8Integrator.
|
||||||
double* state_var_p[4] = { &(state[0]), &(state[1]), &(state[2]), &(state[3])};
|
std::stringstream ss1;
|
||||||
double dx = 0.1;
|
std::stringstream ss2;
|
||||||
double x;
|
ss1 << integ1 << std::endl;
|
||||||
|
ss2 << integ2 << std::endl;
|
||||||
SA::EulerIntegrator integ(dx, 4, state_var_p, state_var_p, deriv1, NULL);
|
|
||||||
integ.load();
|
// Compare the text representations. They should be identical.
|
||||||
integ.step();
|
int result = ss1.str().compare(ss2.str());
|
||||||
integ.unload();
|
EXPECT_EQ(result, 0);
|
||||||
|
|
||||||
x = integ.getIndyVar();
|
|
||||||
EXPECT_NEAR(state[0], (4.0/10.0), EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[1], (-4.0/10.0), EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[2], (M_PI/10.0), EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[3], (-M_PI/10.0), EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(x, 0.1, EXCEPTABLE_ERROR);
|
|
||||||
|
|
||||||
integ.undo_integrate();
|
|
||||||
|
|
||||||
x = integ.getIndyVar();
|
|
||||||
EXPECT_NEAR(state[0], 0.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[1], 0.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[2], 0.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[3], 0.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(x, 0.0, EXCEPTABLE_ERROR);
|
|
||||||
|
|
||||||
integ.undo_integrate();
|
|
||||||
|
|
||||||
x = integ.getIndyVar();
|
|
||||||
EXPECT_NEAR(state[0], 0.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[1], 0.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[2], 0.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[3], 0.0, EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(x, 0.0, EXCEPTABLE_ERROR);
|
|
||||||
|
|
||||||
integ.load();
|
|
||||||
integ.step();
|
|
||||||
integ.unload();
|
|
||||||
|
|
||||||
x = integ.getIndyVar();
|
|
||||||
EXPECT_NEAR(state[0], (4.0/10.0), EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[1], (-4.0/10.0), EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[2], (M_PI/10.0), EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(state[3], (-M_PI/10.0), EXCEPTABLE_ERROR);
|
|
||||||
EXPECT_NEAR(x, 0.1, EXCEPTABLE_ERROR);
|
|
||||||
}
|
}
|
||||||
|
@ -13,12 +13,25 @@ SAI_LIBOBJS = ${SAI_OBJDIR}/Integrator.o
|
|||||||
|
|
||||||
LIBDIRS = -L${SAI_LIBDIR} -L${GTEST_HOME}/lib64 -L${GTEST_HOME}/lib
|
LIBDIRS = -L${SAI_LIBDIR} -L${GTEST_HOME}/lib64 -L${GTEST_HOME}/lib
|
||||||
|
|
||||||
|
TEST_PROGRAMS = SAIntegrator_unittest\
|
||||||
|
FirstOrderODEIntegrator_unittest\
|
||||||
|
FirstOrderODEVariableStepIntegrator_unittest\
|
||||||
|
EulerIntegrator_unittest\
|
||||||
|
RK2Integrator_unittest\
|
||||||
|
RK4Integrator_unittest\
|
||||||
|
RK3_8Integrator_unittest\
|
||||||
|
RootFinder_unittest
|
||||||
|
|
||||||
all: test
|
all: test
|
||||||
|
|
||||||
test: SAIntegrator_unittest FirstOrderODEIntegrator_unittest FirstOrderODEVariableStepIntegrator_unittest RootFinder_unittest
|
test: $(TEST_PROGRAMS)
|
||||||
./SAIntegrator_unittest --gtest_output=xml:${TRICK_HOME}/trick_test/SAIntegrator_unittest.xml
|
./SAIntegrator_unittest --gtest_output=xml:${TRICK_HOME}/trick_test/SAIntegrator_unittest.xml
|
||||||
./FirstOrderODEIntegrator_unittest --gtest_output=xml:${TRICK_HOME}/trick_test/FirstOrderODEIntegrator_unittest.xml
|
./FirstOrderODEIntegrator_unittest --gtest_output=xml:${TRICK_HOME}/trick_test/FirstOrderODEIntegrator_unittest.xml
|
||||||
./FirstOrderODEVariableStepIntegrator_unittest --gtest_output=xml:${TRICK_HOME}/trick_test/FirstOrderODEVariableStepIntegrator_unittest.xml
|
./FirstOrderODEVariableStepIntegrator_unittest --gtest_output=xml:${TRICK_HOME}/trick_test/FirstOrderODEVariableStepIntegrator_unittest.xml
|
||||||
|
./EulerIntegrator_unittest --gtest_output=xml:${TRICK_HOME}/trick_test/EulerIntegrator_unittest.xml
|
||||||
|
./RK2Integrator_unittest --gtest_output=xml:${TRICK_HOME}/trick_test/RK2Integrator_unittest.xml
|
||||||
|
./RK4Integrator_unittest --gtest_output=xml:${TRICK_HOME}/trick_test/RK4Integrator_unittest.xml
|
||||||
|
./RK3_8Integrator_unittest --gtest_output=xml:${TRICK_HOME}/trick_test/RK3_8Integrator_unittest.xml
|
||||||
./RootFinder_unittest --gtest_output=xml:${TRICK_HOME}/trick_test/RootFinder_unittest.xml
|
./RootFinder_unittest --gtest_output=xml:${TRICK_HOME}/trick_test/RootFinder_unittest.xml
|
||||||
|
|
||||||
SAIntegrator_unittest.o : SAIntegrator_unittest.cc
|
SAIntegrator_unittest.o : SAIntegrator_unittest.cc
|
||||||
@ -38,7 +51,31 @@ FirstOrderODEVariableStepIntegrator_unittest.o : FirstOrderODEVariableStepIntegr
|
|||||||
|
|
||||||
FirstOrderODEVariableStepIntegrator_unittest : ${SAI_LIBDIR}/${SAI_LIBNAME} FirstOrderODEVariableStepIntegrator_unittest.o
|
FirstOrderODEVariableStepIntegrator_unittest : ${SAI_LIBDIR}/${SAI_LIBNAME} FirstOrderODEVariableStepIntegrator_unittest.o
|
||||||
$(TRICK_CXX) $(TRICK_CPPFLAGS) -o $@ $^ ${LIBDIRS} -lSAInteg -lgtest -lgtest_main -lpthread
|
$(TRICK_CXX) $(TRICK_CPPFLAGS) -o $@ $^ ${LIBDIRS} -lSAInteg -lgtest -lgtest_main -lpthread
|
||||||
|
# ====
|
||||||
|
EulerIntegrator_unittest.o : EulerIntegrator_unittest.cc
|
||||||
|
$(TRICK_CXX) $(TRICK_CPPFLAGS) $(INCLUDE_DIRS) -c $<
|
||||||
|
|
||||||
|
EulerIntegrator_unittest : ${SAI_LIBDIR}/${SAI_LIBNAME} EulerIntegrator_unittest.o
|
||||||
|
$(TRICK_CXX) $(TRICK_CPPFLAGS) -o $@ $^ ${LIBDIRS} -lSAInteg -lgtest -lgtest_main -lpthread
|
||||||
|
# ====
|
||||||
|
RK2Integrator_unittest.o : RK2Integrator_unittest.cc
|
||||||
|
$(TRICK_CXX) $(TRICK_CPPFLAGS) $(INCLUDE_DIRS) -c $<
|
||||||
|
|
||||||
|
RK2Integrator_unittest : ${SAI_LIBDIR}/${SAI_LIBNAME} RK2Integrator_unittest.o
|
||||||
|
$(TRICK_CXX) $(TRICK_CPPFLAGS) -o $@ $^ ${LIBDIRS} -lSAInteg -lgtest -lgtest_main -lpthread
|
||||||
|
# ====
|
||||||
|
RK4Integrator_unittest.o : RK4Integrator_unittest.cc
|
||||||
|
$(TRICK_CXX) $(TRICK_CPPFLAGS) $(INCLUDE_DIRS) -c $<
|
||||||
|
|
||||||
|
RK4Integrator_unittest : ${SAI_LIBDIR}/${SAI_LIBNAME} RK4Integrator_unittest.o
|
||||||
|
$(TRICK_CXX) $(TRICK_CPPFLAGS) -o $@ $^ ${LIBDIRS} -lSAInteg -lgtest -lgtest_main -lpthread
|
||||||
|
# ====
|
||||||
|
RK3_8Integrator_unittest.o : RK3_8Integrator_unittest.cc
|
||||||
|
$(TRICK_CXX) $(TRICK_CPPFLAGS) $(INCLUDE_DIRS) -c $<
|
||||||
|
|
||||||
|
RK3_8Integrator_unittest : ${SAI_LIBDIR}/${SAI_LIBNAME} RK3_8Integrator_unittest.o
|
||||||
|
$(TRICK_CXX) $(TRICK_CPPFLAGS) -o $@ $^ ${LIBDIRS} -lSAInteg -lgtest -lgtest_main -lpthread
|
||||||
|
# ====
|
||||||
RootFinder_unittest.o : RootFinder_unittest.cc
|
RootFinder_unittest.o : RootFinder_unittest.cc
|
||||||
$(TRICK_CXX) $(TRICK_CPPFLAGS) $(INCLUDE_DIRS) -c $<
|
$(TRICK_CXX) $(TRICK_CPPFLAGS) $(INCLUDE_DIRS) -c $<
|
||||||
|
|
||||||
@ -52,4 +89,11 @@ clean:
|
|||||||
${RM} *.o
|
${RM} *.o
|
||||||
|
|
||||||
spotless: clean
|
spotless: clean
|
||||||
|
${RM} SAIntegrator_unittest
|
||||||
|
${RM} FirstOrderODEIntegrator_unittest
|
||||||
${RM} FirstOrderODEVariableStepIntegrator_unittest
|
${RM} FirstOrderODEVariableStepIntegrator_unittest
|
||||||
|
${RM} EulerIntegrator_unittest
|
||||||
|
${RM} RK2Integrator_unittest
|
||||||
|
${RM} RK4Integrator_unittest
|
||||||
|
${RM} RK3_8Integrator_unittest
|
||||||
|
${RM} RootFinder_unittest
|
||||||
|
@ -0,0 +1,116 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include "SAIntegrator.hh"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
void deriv2( double t,
|
||||||
|
double state[] __attribute__((unused)),
|
||||||
|
double derivs[],
|
||||||
|
void* udata __attribute__((unused))) {
|
||||||
|
|
||||||
|
derivs[0] = -2.0*t + 3.0;
|
||||||
|
derivs[1] = 5.0*t + 4.0;
|
||||||
|
derivs[2] = 3.0*t - 3.0;
|
||||||
|
derivs[3] = 5.0*t + 4.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXCEPTABLE_ERROR 0.00000000001
|
||||||
|
|
||||||
|
TEST(RK2Integrator_unittest, test_load_step_unload) {
|
||||||
|
|
||||||
|
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
||||||
|
double* state_var_p[4] = { &(state[0]), &(state[1]), &(state[2]), &(state[3]) };
|
||||||
|
double dt = 0.01;
|
||||||
|
unsigned int count = 0;
|
||||||
|
double t = count * dt;
|
||||||
|
SA::RK2Integrator integ1(dt, 4, state_var_p, state_var_p, deriv2, NULL);
|
||||||
|
while (t < 2.0) {
|
||||||
|
integ1.load();
|
||||||
|
integ1.step();
|
||||||
|
integ1.unload();
|
||||||
|
count ++;
|
||||||
|
t = count * dt;
|
||||||
|
}
|
||||||
|
EXPECT_NEAR(state[0], 2.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[1], 18.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[2], 0.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[3], 18.0, EXCEPTABLE_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RK2Integrator_unittest, test_integrate) {
|
||||||
|
|
||||||
|
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
||||||
|
double* state_var_p[4] = { &(state[0]), &(state[1]), &(state[2]), &(state[3]) };
|
||||||
|
double dt = 0.01;
|
||||||
|
unsigned int count = 0;
|
||||||
|
double t = count * dt;
|
||||||
|
SA::RK2Integrator integ1(dt, 4, state_var_p, state_var_p, deriv2, NULL);
|
||||||
|
while (t < 2.0) {
|
||||||
|
integ1.integrate();
|
||||||
|
count ++;
|
||||||
|
t = count * dt;
|
||||||
|
}
|
||||||
|
EXPECT_NEAR(state[0], 2.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[1], 18.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[2], 0.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[3], 18.0, EXCEPTABLE_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(RK2Integrator_unittest, copy_constructor) {
|
||||||
|
|
||||||
|
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
||||||
|
double* state_var_p[4] = { &(state[0]), &(state[1]), &(state[2]), &(state[3]) };
|
||||||
|
double dt = 0.01;
|
||||||
|
unsigned int count = 0;
|
||||||
|
double t = count * dt;
|
||||||
|
SA::RK2Integrator integ1(dt, 4, state_var_p, state_var_p, deriv2, NULL);
|
||||||
|
while (t < 2.0) {
|
||||||
|
integ1.integrate();
|
||||||
|
count ++;
|
||||||
|
t = count * dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the copy-constructor to create create a duplicate RK2Integrator.
|
||||||
|
SA::RK2Integrator integ2(integ1);
|
||||||
|
|
||||||
|
// Create a text representation for each of the RK2Integrators.
|
||||||
|
std::stringstream ss1;
|
||||||
|
std::stringstream ss2;
|
||||||
|
ss1 << integ1 << std::endl;
|
||||||
|
ss2 << integ2 << std::endl;
|
||||||
|
|
||||||
|
// Compare the text representations. They should be identical.
|
||||||
|
int result = ss1.str().compare(ss2.str());
|
||||||
|
EXPECT_EQ(result, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RK2Integrator_unittest, assignment_operator) {
|
||||||
|
|
||||||
|
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
||||||
|
double* state_var_p[4] = { &(state[0]), &(state[1]), &(state[2]), &(state[3]) };
|
||||||
|
double dt = 0.01;
|
||||||
|
unsigned int count = 0;
|
||||||
|
double t = count * dt;
|
||||||
|
SA::RK2Integrator integ1(dt, 4, state_var_p, state_var_p, deriv2, NULL);
|
||||||
|
while (t < 2.0) {
|
||||||
|
integ1.integrate();
|
||||||
|
count ++;
|
||||||
|
t = count * dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the assignment operator to create create a duplicate RK2Integrator.
|
||||||
|
SA::RK2Integrator integ2;
|
||||||
|
integ2 = integ1;
|
||||||
|
|
||||||
|
// Create a text representation for each of the RK2Integrators.
|
||||||
|
std::stringstream ss1;
|
||||||
|
std::stringstream ss2;
|
||||||
|
ss1 << integ1 << std::endl;
|
||||||
|
ss2 << integ2 << std::endl;
|
||||||
|
|
||||||
|
// Compare the text representations. They should be identical.
|
||||||
|
int result = ss1.str().compare(ss2.str());
|
||||||
|
EXPECT_EQ(result, 0);
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include "SAIntegrator.hh"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
void deriv4( double t,
|
||||||
|
double state[] __attribute__((unused)),
|
||||||
|
double derivs[],
|
||||||
|
void* udata __attribute__((unused))) {
|
||||||
|
double t2 = t*t;
|
||||||
|
double t3 = t2*t;
|
||||||
|
derivs[0] = 3.0*t3 - 3.0*t2 - 3.0*t + 4.0;
|
||||||
|
derivs[1] = 2.0*t3 + 1.0*t2 - 5.0*t + 7.0;
|
||||||
|
derivs[2] = t3 + t2 + 5.0*t + 4.0;
|
||||||
|
derivs[3] = t3 - 6.0*t2 + 4.0*t + 12.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXCEPTABLE_ERROR 0.00000000001
|
||||||
|
|
||||||
|
TEST(FirstOrderODEVariableStepIntegrator_unittest, RungeKutta38_1) {
|
||||||
|
|
||||||
|
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
||||||
|
double* state_var_p[4] = { &(state[0]), &(state[1]), &(state[2]), &(state[3]) };
|
||||||
|
double dt = 0.01;
|
||||||
|
unsigned int count = 0;
|
||||||
|
double t = count * dt;
|
||||||
|
SA::RK3_8Integrator integ1(dt, 4, state_var_p, state_var_p, deriv4, NULL);
|
||||||
|
while (t < 2.0) {
|
||||||
|
integ1.load();
|
||||||
|
integ1.step();
|
||||||
|
integ1.unload();
|
||||||
|
count ++;
|
||||||
|
t = count * dt;
|
||||||
|
}
|
||||||
|
EXPECT_NEAR(state[0], 6.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[1], (14.0+2/3.0), EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[2], (24+2/3.0), EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[3], 20.0, EXCEPTABLE_ERROR);
|
||||||
|
|
||||||
|
// Use the copy-constructor to create create a duplicate RK3_8Integrator.
|
||||||
|
SA::RK3_8Integrator integ2(integ1);
|
||||||
|
|
||||||
|
// Create a text representation for each of the RK3_8Integrator.
|
||||||
|
std::stringstream ss1;
|
||||||
|
std::stringstream ss2;
|
||||||
|
ss1 << integ1 << std::endl;
|
||||||
|
ss2 << integ2 << std::endl;
|
||||||
|
|
||||||
|
// Compare the text representations. They should be identical.
|
||||||
|
int result = ss1.str().compare(ss2.str());
|
||||||
|
EXPECT_EQ(result, 0);
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include "SAIntegrator.hh"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
void deriv4( double t,
|
||||||
|
double state[] __attribute__((unused)),
|
||||||
|
double derivs[],
|
||||||
|
void* udata __attribute__((unused))) {
|
||||||
|
double t2 = t*t;
|
||||||
|
double t3 = t2*t;
|
||||||
|
derivs[0] = 3.0*t3 - 3.0*t2 - 3.0*t + 4.0;
|
||||||
|
derivs[1] = 2.0*t3 + 1.0*t2 - 5.0*t + 7.0;
|
||||||
|
derivs[2] = t3 + t2 + 5.0*t + 4.0;
|
||||||
|
derivs[3] = t3 - 6.0*t2 + 4.0*t + 12.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXCEPTABLE_ERROR 0.00000000001
|
||||||
|
|
||||||
|
TEST(FirstOrderODEVariableStepIntegrator_unittest, RungeKutta4_1) {
|
||||||
|
|
||||||
|
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
||||||
|
double* state_var_p[4] = { &(state[0]), &(state[1]), &(state[2]), &(state[3]) };
|
||||||
|
double dt = 0.01;
|
||||||
|
unsigned int count = 0;
|
||||||
|
double t = count * dt;
|
||||||
|
SA::RK4Integrator integ1(dt, 4, state_var_p, state_var_p, deriv4, NULL);
|
||||||
|
while (t < 2.0) {
|
||||||
|
integ1.load();
|
||||||
|
integ1.step();
|
||||||
|
integ1.unload();
|
||||||
|
count ++;
|
||||||
|
t = count * dt;
|
||||||
|
}
|
||||||
|
EXPECT_NEAR(state[0], 6.0, EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[1], (14.0+2/3.0), EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[2], (24+2/3.0), EXCEPTABLE_ERROR);
|
||||||
|
EXPECT_NEAR(state[3], 20.0, EXCEPTABLE_ERROR);
|
||||||
|
|
||||||
|
// Use the copy-constructor to create create a duplicate RK4Integrator.
|
||||||
|
SA::RK4Integrator integ2(integ1);
|
||||||
|
|
||||||
|
// Create a text representation for each of the RK4Integrator.
|
||||||
|
std::stringstream ss1;
|
||||||
|
std::stringstream ss2;
|
||||||
|
ss1 << integ1 << std::endl;
|
||||||
|
ss2 << integ2 << std::endl;
|
||||||
|
|
||||||
|
// Compare the text representations. They should be identical.
|
||||||
|
int result = ss1.str().compare(ss2.str());
|
||||||
|
EXPECT_EQ(result, 0);
|
||||||
|
}
|
@ -78,3 +78,12 @@ TEST(RootFinder_unittest, Negative_constraint_with_positive_slope_function) {
|
|||||||
root_error = root_finder->find_roots(9, func_positive_slope(9));
|
root_error = root_finder->find_roots(9, func_positive_slope(9));
|
||||||
EXPECT_NEAR(root_error, DBL_MAX, EXCEPTABLE_ERROR);
|
EXPECT_NEAR(root_error, DBL_MAX, EXCEPTABLE_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(RootFinder_unittest, serialize) {
|
||||||
|
RootFinder* root_finder = new RootFinder ( 0.00000000001, Negative );
|
||||||
|
double root_error;
|
||||||
|
root_error = root_finder->find_roots(8, func_positive_slope(8));
|
||||||
|
EXPECT_NEAR(root_error, DBL_MAX, EXCEPTABLE_ERROR);
|
||||||
|
root_error = root_finder->find_roots(9, func_positive_slope(9));
|
||||||
|
EXPECT_NEAR(root_error, DBL_MAX, EXCEPTABLE_ERROR);
|
||||||
|
}
|
||||||
|
@ -72,3 +72,35 @@ TEST(Integrator, test_undo_integrate) {
|
|||||||
x = integ.getIndyVar();
|
x = integ.getIndyVar();
|
||||||
EXPECT_NEAR(x, 4.0, EXCEPTABLE_ERROR);
|
EXPECT_NEAR(x, 4.0, EXCEPTABLE_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Integrator, test_copy_constructor) {
|
||||||
|
std::stringstream ss1;
|
||||||
|
std::stringstream ss2;
|
||||||
|
double h = 0.1;
|
||||||
|
void* udata = NULL;
|
||||||
|
SA::Integrator integ( h, udata);
|
||||||
|
integ.setIndyVar(4.0);
|
||||||
|
integ.integrate();
|
||||||
|
// Test Copy Constructor
|
||||||
|
SA::Integrator integ2(integ);
|
||||||
|
ss1 << integ << std::endl;
|
||||||
|
ss2 << integ2 << std::endl;
|
||||||
|
int result = ss1.str().compare(ss2.str());
|
||||||
|
EXPECT_EQ(result, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Integrator, test_assignment_operator) {
|
||||||
|
std::stringstream ss1;
|
||||||
|
std::stringstream ss2;
|
||||||
|
double h = 0.1;
|
||||||
|
void* udata = NULL;
|
||||||
|
SA::Integrator integ( h, udata);
|
||||||
|
integ.setIndyVar(4.0);
|
||||||
|
integ.integrate();
|
||||||
|
// Test Copy Constructor
|
||||||
|
SA::Integrator integ2 = integ;
|
||||||
|
ss1 << integ << std::endl;
|
||||||
|
ss2 << integ2 << std::endl;
|
||||||
|
int result = ss1.str().compare(ss2.str());
|
||||||
|
EXPECT_EQ(result, 0);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user