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 RK4Integrator](#class-RK4Integrator)
|
||||
* [class RK3_8Integrator](#class-RK3_8Integrator)
|
||||
* [typedef Derivs2Func](#typedef-Derivs2Func)
|
||||
* [class EulerCromerIntegrator](#class-EulerCromerIntegrator)
|
||||
* [class ABM2Integrator](#class-ABM2Integrator)
|
||||
* [class ABM4Integrator](#class-ABM4Integrator)
|
||||
@ -53,10 +54,13 @@ This base-class represents a numerical **integrator**.
|
||||
|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. |
|
||||
|
||||
|
||||
### Destructor
|
||||
|
||||
#### ```virtual ~Integrator() {}```
|
||||
|
||||
|
||||
|
||||
### Public Member Functions
|
||||
|
||||
<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. |
|
||||
|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
|
||||
|
||||
<a id=method-FirstOrderODEIntegrator::load></a>
|
||||
@ -307,6 +320,25 @@ Those inherited from [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator) p
|
||||
|
||||
### 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>
|
||||
### Public Member Functions
|
||||
|
||||
@ -401,6 +433,15 @@ EulerIntegrator( double h,
|
||||
```
|
||||
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
|
||||
|
||||
* 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).
|
||||
|
||||
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
|
||||
|
||||
* All of the [Public Member Functions of FirstOrderODEVariableStepIntegrator](#FirstOrderODEVariableStepIntegrator::publicMemberFunctions).
|
||||
@ -463,10 +513,19 @@ RK2Integrator( double h,
|
||||
double* in_vars[],
|
||||
double* out_vars[],
|
||||
DerivsFunc func,
|
||||
void* user_data)
|
||||
void* user_data)
|
||||
```
|
||||
[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
|
||||
|
||||
* 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).
|
||||
|
||||
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
|
||||
|
||||
* All of the [Public Member Functions of FirstOrderODEVariableStepIntegrator](#FirstOrderODEVariableStepIntegrator::publicMemberFunctions).
|
||||
@ -535,6 +603,15 @@ RK3_8Integrator( double h,
|
||||
[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
|
||||
|
||||
* 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).
|
||||
|
||||
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>
|
||||
## class ABM4Integrator
|
||||
Derived from [FirstOrderODEIntegrator](#class-FirstOrderODEIntegrator).
|
||||
@ -589,6 +674,44 @@ ABM4Integrator ( double h,
|
||||
|
||||
[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>
|
||||
## class EulerCromerIntegrator
|
||||
Derived from [Integrator](#class-Integrator).
|
||||
@ -596,6 +719,12 @@ Derived from [Integrator](#class-Integrator).
|
||||
### 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.
|
||||
|
||||
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
|
||||
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.|
|
||||
| vel_out |```double*``` |Protected|Velocity output array.|
|
||||
| g_out |```double*``` |Protected|Array of accelerations returned from gderivs.|
|
||||
| f_out |```double*``` |Protected|Array of velocities returned from fderivs.|
|
||||
| gderivs |[```DerivsFunc```](#typedef-DerivsFunc)|Protected|A function that returns accelerations.|
|
||||
| fderivs |[```DerivsFunc```](#typedef-DerivsFunc)|Protected|A function that returns velocities.|
|
||||
| gderivs |[```Derivs2Func```](#typedef-Derivs2Func)|Protected|A function that returns accelerations.|
|
||||
| last_h |```double```|Value of h used in the last integration step.|
|
||||
|
||||
|
||||
### Constructor
|
||||
```
|
||||
@ -619,8 +748,7 @@ EulerCromerIntegrator(double dt,
|
||||
int N,
|
||||
double* xp[],
|
||||
double* vp[],
|
||||
DerivsFunc gfunc,
|
||||
DerivsFunc ffunc,
|
||||
Derivs2Func gfunc,
|
||||
void* user_data)
|
||||
```
|
||||
|
||||
@ -630,10 +758,17 @@ EulerCromerIntegrator(double dt,
|
||||
| N |```int``` |Sets nDimensions above.|
|
||||
| xp |```double*```|Sets pos_p above.|
|
||||
| vp |```double*```|Sets vel_p above.|
|
||||
| gfunc |[```DerivsFunc```](#typedef-DerivsFunc)| Sets gderivs above. |
|
||||
| ffunc |[```DerivsFunc```](#typedef-DerivsFunc)| Sets fderivs above. |
|
||||
| gfunc |[```Derivs2Func```](#typedef-Derivs2Func)| Sets gderivs above. |
|
||||
|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
|
||||
|
||||
#### ```void step( double dt)```
|
||||
|
@ -48,10 +48,7 @@ int main ( int argc, char* argv[]) {
|
||||
double dt = 0.01;
|
||||
double t = 0.0;
|
||||
SA::RK2Integrator integ(dt, 6, state_var_p, state_var_p, calc_derivs, NULL);
|
||||
|
||||
RootFinder root_finder(0.00000000001, Negative);
|
||||
integ.add_Rootfinder(&root_finder, &impact);
|
||||
|
||||
integ.add_Rootfinder(0.00000000001, Negative, &impact);
|
||||
init_state(cannon);
|
||||
print_header();
|
||||
print_state( t, cannon);
|
||||
|
@ -13,7 +13,7 @@ void init_state ( MassSpringDamper& msd ) {
|
||||
msd.pos = 2.0;
|
||||
msd.vel = 0.0;
|
||||
msd.k = 1.0;
|
||||
msd.c = 0.0;
|
||||
msd.c = 0.2;
|
||||
msd.mass = 5.0;
|
||||
}
|
||||
void print_header() {
|
||||
@ -22,31 +22,24 @@ void print_header() {
|
||||
void print_state( double t, MassSpringDamper& msd ) {
|
||||
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;
|
||||
g_out[0] = -(msd->k/msd->mass) * x[0];
|
||||
}
|
||||
void F( double t, double v[], double f_out[], void* udata) {
|
||||
f_out[0] = v[0];
|
||||
f_out[1] = v[1];
|
||||
g_out[0] = -(msd->k/msd->mass) * x[0]
|
||||
-(msd->c/msd->mass) * v[0];
|
||||
}
|
||||
int main ( int argc, char* argv[]) {
|
||||
MassSpringDamper msd;
|
||||
double time = 0.0;
|
||||
double* x_p[N_DIMENSIONS] = { &msd.pos };
|
||||
double* v_p[N_DIMENSIONS] = { &msd.vel };
|
||||
unsigned count = 0;
|
||||
double dt = 0.001;
|
||||
double time = count * dt;
|
||||
init_state(msd);
|
||||
print_header();
|
||||
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) {
|
||||
integ.load();
|
||||
integ.step();
|
||||
integ.unload();
|
||||
count ++;
|
||||
time = count * dt;
|
||||
integ.integrate();
|
||||
time = integ.getIndyVar();
|
||||
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",
|
||||
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;
|
||||
double d = sqrt( x[0]*x[0] + x[1]*x[1]);
|
||||
g_out[0] = -x[0] * GRAVITATIONAL_CONSTANT * orbit->planet_mass / (d*d*d);
|
||||
g_out[1] = -x[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];
|
||||
double d = sqrt( pos[0]*pos[0] + pos[1]*pos[1]);
|
||||
acc_out[0] = -pos[0] * GRAVITATIONAL_CONSTANT * orbit->planet_mass / (d*d*d);
|
||||
acc_out[1] = -pos[1] * GRAVITATIONAL_CONSTANT * orbit->planet_mass / (d*d*d);
|
||||
}
|
||||
int main ( int argc, char* argv[]) {
|
||||
Orbit orbit;
|
||||
double time = 0.0;
|
||||
double* x_p[2] = { &orbit.pos[0], &orbit.pos[1] };
|
||||
double* v_p[2] = { &orbit.vel[0], &orbit.vel[1] };
|
||||
unsigned count = 0;
|
||||
double dt = 0.1;
|
||||
double time = count * dt;
|
||||
init_state(orbit);
|
||||
print_header();
|
||||
print_state(time, orbit);
|
||||
SA::EulerCromerIntegrator integ(dt, 2, x_p, v_p, G, F, &orbit);
|
||||
while (time < 6000) {
|
||||
integ.load();
|
||||
integ.step();
|
||||
integ.unload();
|
||||
count ++;
|
||||
time = count * dt;
|
||||
SA::EulerCromerIntegrator integ(dt, 2, x_p, v_p, G, &orbit);
|
||||
while (time < 5600) {
|
||||
integ.integrate();
|
||||
time = integ.getIndyVar();
|
||||
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 {
|
||||
Negative = -1,
|
||||
@ -12,6 +13,7 @@ class RootFinder {
|
||||
RootFinder();
|
||||
RootFinder (double tolerance, SlopeConstraint constraint);
|
||||
double find_roots( double x, double f_error );
|
||||
friend std::ostream& operator<<(std::ostream& os, const RootFinder& rf);
|
||||
private:
|
||||
double f_upper;
|
||||
double x_upper;
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include "Rootfinder.hh"
|
||||
#include <iostream>
|
||||
|
||||
namespace SA {
|
||||
|
||||
class Integrator {
|
||||
@ -9,7 +11,8 @@ namespace SA {
|
||||
void* user_data; // User data
|
||||
void advanceIndyVar();
|
||||
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 void load();
|
||||
virtual void unload();
|
||||
@ -18,8 +21,11 @@ namespace SA {
|
||||
virtual double undo_integrate();
|
||||
double getIndyVar();
|
||||
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);
|
||||
|
||||
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** 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.
|
||||
// void advanceIndyVar(); // Inherited from Integrator::advanceIndyVar()
|
||||
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();
|
||||
void load(); // Overrides Integrator::load(), Final
|
||||
void unload(); // Overrides Integrator::unload(), Final
|
||||
virtual void step(); // Overrides Integrator::step(). Virtual
|
||||
// integrate(); Inherited from Integrator::integrate(), Final
|
||||
virtual double undo_integrate(); // Overrides Integrator::undo_integrate(), Virtual
|
||||
void load_from_outState(); // New, Final
|
||||
double** set_in_vars( double* in_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);
|
||||
|
||||
@ -54,82 +62,96 @@ namespace SA {
|
||||
RootErrorFunc root_error_func;
|
||||
protected:
|
||||
double last_h;
|
||||
// void advanceIndyVar(); // Inherited from Integrator::advanceIndyVar(), Final
|
||||
void advanceIndyVar( double h);
|
||||
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();
|
||||
// load(); Inherited from FirstOrderODEIntegrator, Final
|
||||
// unload(); Inherited from FirstOrderODEIntegrator, Final
|
||||
void step(); // Overrides FirstOrderODEIntegrator::step(), Final
|
||||
// integrate(); // Inherited from Integrator
|
||||
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
|
||||
void add_Rootfinder( RootFinder* root_finder, RootErrorFunc rfunc); // New, Final
|
||||
// double getIndyVar(); // Inherited from Integrator
|
||||
// void setIndyVar(double v); // Inherited from Integrator
|
||||
void add_Rootfinder( double tolerance, SlopeConstraint constraint, RootErrorFunc rfunc);
|
||||
friend std::ostream& operator<<(std::ostream& os, const SA::FirstOrderODEVariableStepIntegrator& I);
|
||||
private:
|
||||
void find_roots(double h, unsigned int depth);
|
||||
};
|
||||
std::ostream& operator<<(std::ostream& os, const FirstOrderODEVariableStepIntegrator& I);
|
||||
|
||||
class EulerIntegrator : public FirstOrderODEVariableStepIntegrator {
|
||||
public:
|
||||
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();
|
||||
// load(); Inherited from FirstOrderODEIntegrator
|
||||
// unload(); Inherited from FirstOrderODEIntegrator
|
||||
// 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
|
||||
void variable_step( double h);
|
||||
friend std::ostream& operator<<(std::ostream& os, const SA::EulerIntegrator& I);
|
||||
};
|
||||
std::ostream& operator<<(std::ostream& os, const EulerIntegrator& I);
|
||||
|
||||
class HeunsMethod : public FirstOrderODEVariableStepIntegrator {
|
||||
public:
|
||||
double *wstate;
|
||||
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();
|
||||
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 {
|
||||
public:
|
||||
double *wstate;
|
||||
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();
|
||||
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 {
|
||||
public:
|
||||
double *wstate[3];
|
||||
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();
|
||||
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 {
|
||||
public:
|
||||
double *wstate[4];
|
||||
double *wstate[3];
|
||||
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();
|
||||
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 {
|
||||
protected:
|
||||
@ -141,19 +163,24 @@ namespace SA {
|
||||
double* pos_out;
|
||||
double* vel_out;
|
||||
double* g_out;
|
||||
double* f_out;
|
||||
DerivsFunc gderivs;
|
||||
DerivsFunc fderivs;
|
||||
double last_h;
|
||||
Derivs2Func gderivs;
|
||||
|
||||
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();
|
||||
void advanceIndyVar(double h);
|
||||
void step( double dt);
|
||||
void step();
|
||||
void load();
|
||||
void unload();
|
||||
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
|
||||
class ABMIntegrator : public FirstOrderODEIntegrator {
|
||||
@ -165,11 +192,15 @@ namespace SA {
|
||||
unsigned int hix;
|
||||
unsigned int currentHistorySize;
|
||||
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();
|
||||
void step();
|
||||
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
|
||||
class ABM2Integrator : public FirstOrderODEIntegrator {
|
||||
@ -179,13 +210,17 @@ namespace SA {
|
||||
unsigned int bufferSize;
|
||||
unsigned int hix;
|
||||
unsigned int currentHistorySize;
|
||||
FirstOrderODEVariableStepIntegrator* priming_integrator;
|
||||
RK2Integrator* priming_integrator;
|
||||
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();
|
||||
void step();
|
||||
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
|
||||
class ABM4Integrator : public FirstOrderODEIntegrator {
|
||||
@ -195,11 +230,15 @@ namespace SA {
|
||||
unsigned int bufferSize;
|
||||
unsigned int hix;
|
||||
unsigned int currentHistorySize;
|
||||
FirstOrderODEVariableStepIntegrator* priming_integrator;
|
||||
RK4Integrator* priming_integrator;
|
||||
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();
|
||||
void step();
|
||||
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() {
|
||||
init(0.00000000001, Unconstrained);
|
||||
}
|
||||
RootFinder::RootFinder (double tolerance, SlopeConstraint constraint) {
|
||||
init(tolerance, constraint);
|
||||
}
|
||||
// Default Constructor
|
||||
RootFinder::RootFinder () {
|
||||
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,
|
||||
// estimate the distance of the independent variable from functions root.
|
||||
double RootFinder::find_roots( double x, double f_error ) {
|
||||
@ -86,3 +92,15 @@ double RootFinder::find_roots( double x, double f_error ) {
|
||||
iterations = 0;
|
||||
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();
|
||||
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
|
||||
|
||||
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) {
|
||||
|
||||
double state[4] = {0.0, 0.0, 0.0, 0.0};
|
||||
@ -108,11 +45,11 @@ TEST(FirstOrderODEVariableStepIntegrator_unittest, RungeKutta38_1) {
|
||||
double dt = 0.01;
|
||||
unsigned int count = 0;
|
||||
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) {
|
||||
integ.load();
|
||||
integ.step();
|
||||
integ.unload();
|
||||
integ1.load();
|
||||
integ1.step();
|
||||
integ1.unload();
|
||||
count ++;
|
||||
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[2], (24+2/3.0), EXCEPTABLE_ERROR);
|
||||
EXPECT_NEAR(state[3], 20.0, 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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
@ -13,12 +13,25 @@ SAI_LIBOBJS = ${SAI_OBJDIR}/Integrator.o
|
||||
|
||||
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
|
||||
|
||||
test: SAIntegrator_unittest FirstOrderODEIntegrator_unittest FirstOrderODEVariableStepIntegrator_unittest RootFinder_unittest
|
||||
test: $(TEST_PROGRAMS)
|
||||
./SAIntegrator_unittest --gtest_output=xml:${TRICK_HOME}/trick_test/SAIntegrator_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
|
||||
./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
|
||||
|
||||
SAIntegrator_unittest.o : SAIntegrator_unittest.cc
|
||||
@ -38,7 +51,31 @@ FirstOrderODEVariableStepIntegrator_unittest.o : FirstOrderODEVariableStepIntegr
|
||||
|
||||
FirstOrderODEVariableStepIntegrator_unittest : ${SAI_LIBDIR}/${SAI_LIBNAME} FirstOrderODEVariableStepIntegrator_unittest.o
|
||||
$(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
|
||||
$(TRICK_CXX) $(TRICK_CPPFLAGS) $(INCLUDE_DIRS) -c $<
|
||||
|
||||
@ -52,4 +89,11 @@ clean:
|
||||
${RM} *.o
|
||||
|
||||
spotless: clean
|
||||
${RM} SAIntegrator_unittest
|
||||
${RM} FirstOrderODEIntegrator_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));
|
||||
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();
|
||||
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