Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
D
dynamic
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
MostafaMollaali
dynamic
Commits
ac3bab86
Commit
ac3bab86
authored
8 years ago
by
Christoph Lehmann
Committed by
Dmitri Naumov
8 years ago
Browse files
Options
Downloads
Patches
Plain Diff
[T] check results are within tolerances
parent
8cd48810
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
Tests/MathLib/TestCVode.cpp
+97
-51
97 additions, 51 deletions
Tests/MathLib/TestCVode.cpp
with
97 additions
and
51 deletions
Tests/MathLib/TestCVode.cpp
+
97
−
51
View file @
ac3bab86
...
@@ -7,15 +7,14 @@
...
@@ -7,15 +7,14 @@
*
*
*/
*/
#ifdef CVODE_FOUND
#include
<gtest/gtest.h>
#include
<gtest/gtest.h>
#include
<logog/include/logog.hpp>
#include
<logog/include/logog.hpp>
#include
"MathLib/ODE/CVodeSolver.h"
#include
"MathLib/ODE/OdeSolver.h"
#include
"MathLib/ODE/ConcreteOdeSolver.h"
#include
"MathLib/ODE/ConcreteOdeSolver.h"
const
double
abs_tol
=
1e-8
;
const
double
rel_tol
=
1e-8
;
bool
f
(
const
double
,
bool
f
(
const
double
,
MathLib
::
MappedConstVector
<
1
>
const
y
,
MathLib
::
MappedConstVector
<
1
>
const
y
,
MathLib
::
MappedVector
<
1
>
ydot
)
MathLib
::
MappedVector
<
1
>
ydot
)
...
@@ -39,7 +38,7 @@ bool df(const double /*t*/,
...
@@ -39,7 +38,7 @@ bool df(const double /*t*/,
struct
ExtraData
struct
ExtraData
{
{
double
value
=
1
5.0
;
double
value
=
1
2.5
;
};
};
bool
f_extra
(
const
double
,
bool
f_extra
(
const
double
,
...
@@ -53,6 +52,53 @@ bool f_extra(const double,
...
@@ -53,6 +52,53 @@ bool f_extra(const double,
return
true
;
return
true
;
}
}
bool
any_ode_solver_libs_available
()
{
#ifdef CVODE_FOUND
return
true
;
#else
return
false
;
#endif // CVODE_FOUND
}
template
<
unsigned
NumEquations
>
std
::
unique_ptr
<
MathLib
::
OdeSolver
<
NumEquations
>>
make_ode_solver
(
boost
::
property_tree
::
ptree
const
&
conf
)
{
BaseLib
::
ConfigTree
config
(
conf
,
""
,
BaseLib
::
ConfigTree
::
onerror
,
BaseLib
::
ConfigTree
::
onwarning
);
return
MathLib
::
createOdeSolver
<
NumEquations
>
(
config
);
}
// There is no definition of this function in order to prevent passing temporary
// property trees! There will be linker errors if you do so anyway.
template
<
unsigned
NumEquations
>
std
::
unique_ptr
<
MathLib
::
OdeSolver
<
NumEquations
>>
make_ode_solver
(
boost
::
property_tree
::
ptree
&&
);
void
check
(
const
double
time_reached
,
const
double
y
,
const
double
y_dot
,
const
double
time
,
const
double
y_ana
,
const
double
y_dot_ana
)
{
DBUG
(
"t: %14.7g, y: %14.7g, diff: %14.7g, y_dot: %14.7g, diff: %14.7g"
,
time_reached
,
y
,
y
-
y_ana
,
y_dot
,
y_dot
-
y_dot_ana
);
(
void
)
y_dot_ana
;
// Avoid unused variable warning when DBUG output is
// disabled.
EXPECT_NEAR
(
time
,
time_reached
,
std
::
numeric_limits
<
double
>::
epsilon
());
auto
const
abs_err
=
std
::
abs
(
y
-
y_ana
);
auto
const
rel_err
=
abs_err
/
std
::
abs
(
y_ana
);
EXPECT_GT
(
10.0
*
abs_tol
,
abs_err
);
// relative errors are not checked.
// EXPECT_GT(10.0*rel_tol, rel_err);
// make sure that the relative error of the derivative is not much bigger
// than the one of the solution y.
auto
const
dot_rel_err
=
std
::
abs
(
y_dot
/
y_ana
-
1.0
);
EXPECT_LT
(
10.0
*
rel_err
,
dot_rel_err
);
}
TEST
(
MathLibCVodeTest
,
Exponential
)
TEST
(
MathLibCVodeTest
,
Exponential
)
{
{
// initial values
// initial values
...
@@ -60,12 +106,14 @@ TEST(MathLibCVodeTest, Exponential)
...
@@ -60,12 +106,14 @@ TEST(MathLibCVodeTest, Exponential)
const
double
t0
=
0.0
;
const
double
t0
=
0.0
;
auto
tree
=
boost
::
property_tree
::
ptree
{};
auto
tree
=
boost
::
property_tree
::
ptree
{};
BaseLib
::
ConfigTree
config
(
tree
,
""
,
BaseLib
::
ConfigTree
::
onerror
,
auto
ode_solver
=
make_ode_solver
<
1
>
(
tree
);
BaseLib
::
ConfigTree
::
onwarning
);
auto
ode_solver
=
MathLib
::
createOdeSolver
<
1
>
(
config
);
ASSERT_EQ
(
any_ode_solver_libs_available
(),
!!
ode_solver
);
// Don't run the test if the ODE solver could not be constructed.
if
(
!
ode_solver
)
return
;
ode_solver
->
setFunction
(
f
,
nullptr
);
ode_solver
->
setFunction
(
f
,
nullptr
);
ode_solver
->
setTolerance
(
1e-8
,
1e-6
);
ode_solver
->
setTolerance
(
abs_tol
,
rel_tol
);
ode_solver
->
setIC
(
t0
,
{
y0
});
ode_solver
->
setIC
(
t0
,
{
y0
});
...
@@ -80,14 +128,13 @@ TEST(MathLibCVodeTest, Exponential)
...
@@ -80,14 +128,13 @@ TEST(MathLibCVodeTest, Exponential)
ASSERT_TRUE
(
ode_solver
->
solve
(
time
));
ASSERT_TRUE
(
ode_solver
->
solve
(
time
));
auto
const
y
=
ode_solver
->
getSolution
();
auto
const
y
=
ode_solver
->
getSolution
();
double
time_reached
=
ode_solver
->
getTime
();
auto
const
time_reached
=
ode_solver
->
getTime
();
auto
const
y_dot
=
ode_solver
->
getYDot
(
time_reached
,
y
);
auto
const
y_dot
=
ode_solver
->
getYDot
(
time_reached
,
y
);
DBUG
(
"t: %14.7g, y: %14.7g, diff: %14.7g, y_dot: %14.7g, diff: %14.7g"
,
auto
const
y_ana
=
exp
(
-
15.0
*
time
);
time_reached
,
y
[
0
],
y
[
0
]
-
exp
(
-
15.0
*
time_reached
),
y_dot
[
0
],
auto
const
y_dot_ana
=
-
15.0
*
exp
(
-
15.0
*
time
);
y_dot
[
0
]
+
15.0
*
exp
(
-
15.0
*
time_reached
));
EXPECT_NEAR
(
time
,
time_reached
,
std
::
numeric_limits
<
double
>::
epsilon
()
);
check
(
time_reached
,
y
[
0
],
y_dot
[
0
],
time
,
y_ana
,
y_dot_ana
);
}
}
}
}
...
@@ -98,9 +145,11 @@ TEST(MathLibCVodeTest, ExponentialExtraData)
...
@@ -98,9 +145,11 @@ TEST(MathLibCVodeTest, ExponentialExtraData)
const
double
t0
=
0.0
;
const
double
t0
=
0.0
;
auto
tree
=
boost
::
property_tree
::
ptree
{};
auto
tree
=
boost
::
property_tree
::
ptree
{};
BaseLib
::
ConfigTree
config
(
tree
,
""
,
BaseLib
::
ConfigTree
::
onerror
,
auto
ode_solver
=
make_ode_solver
<
1
>
(
tree
);
BaseLib
::
ConfigTree
::
onwarning
);
auto
ode_solver
=
MathLib
::
createOdeSolver
<
1
>
(
config
);
ASSERT_EQ
(
any_ode_solver_libs_available
(),
!!
ode_solver
);
// Don't run the test if the ODE solver could not be constructed.
if
(
!
ode_solver
)
return
;
ExtraData
data
;
ExtraData
data
;
auto
f_lambda
=
[
&
](
double
t
,
auto
f_lambda
=
[
&
](
double
t
,
...
@@ -111,7 +160,7 @@ TEST(MathLibCVodeTest, ExponentialExtraData)
...
@@ -111,7 +160,7 @@ TEST(MathLibCVodeTest, ExponentialExtraData)
};
};
ode_solver
->
setFunction
(
f_lambda
,
nullptr
);
ode_solver
->
setFunction
(
f_lambda
,
nullptr
);
ode_solver
->
setTolerance
(
1e-8
,
1e-6
);
ode_solver
->
setTolerance
(
abs_tol
,
rel_tol
);
ode_solver
->
setIC
(
t0
,
{
y0
});
ode_solver
->
setIC
(
t0
,
{
y0
});
ode_solver
->
preSolve
();
ode_solver
->
preSolve
();
...
@@ -125,14 +174,13 @@ TEST(MathLibCVodeTest, ExponentialExtraData)
...
@@ -125,14 +174,13 @@ TEST(MathLibCVodeTest, ExponentialExtraData)
ASSERT_TRUE
(
ode_solver
->
solve
(
time
));
ASSERT_TRUE
(
ode_solver
->
solve
(
time
));
auto
const
y
=
ode_solver
->
getSolution
();
auto
const
y
=
ode_solver
->
getSolution
();
double
time_reached
=
ode_solver
->
getTime
();
auto
const
time_reached
=
ode_solver
->
getTime
();
auto
const
y_dot
=
ode_solver
->
getYDot
(
time_reached
,
y
);
auto
const
y_dot
=
ode_solver
->
getYDot
(
time_reached
,
y
);
DBUG
(
"t: %14.7g, y: %14.7g, diff: %14.7g, y_dot: %14.7g, diff: %14.7g"
,
auto
const
y_ana
=
exp
(
-
data
.
value
*
time
);
time_reached
,
y
[
0
],
y
[
0
]
-
exp
(
-
15.0
*
time_reached
),
y_dot
[
0
],
auto
const
y_dot_ana
=
-
data
.
value
*
exp
(
-
data
.
value
*
time
);
y_dot
[
0
]
+
15.0
*
exp
(
-
15.0
*
time_reached
));
EXPECT_NEAR
(
time
,
time_reached
,
std
::
numeric_limits
<
double
>::
epsilon
()
);
check
(
time_reached
,
y
[
0
],
y_dot
[
0
],
time
,
y_ana
,
y_dot_ana
);
}
}
ode_solver
->
setFunction
(
f_lambda
,
nullptr
);
ode_solver
->
setFunction
(
f_lambda
,
nullptr
);
...
@@ -144,14 +192,13 @@ TEST(MathLibCVodeTest, ExponentialExtraData)
...
@@ -144,14 +192,13 @@ TEST(MathLibCVodeTest, ExponentialExtraData)
ASSERT_TRUE
(
ode_solver
->
solve
(
time
));
ASSERT_TRUE
(
ode_solver
->
solve
(
time
));
auto
const
y
=
ode_solver
->
getSolution
();
auto
const
y
=
ode_solver
->
getSolution
();
double
time_reached
=
ode_solver
->
getTime
();
auto
const
time_reached
=
ode_solver
->
getTime
();
auto
const
y_dot
=
ode_solver
->
getYDot
(
time_reached
,
y
);
auto
const
y_dot
=
ode_solver
->
getYDot
(
time_reached
,
y
);
DBUG
(
"t: %14.7g, y: %14.7g, diff: %14.7g, y_dot: %14.7g, diff: %14.7g"
,
auto
const
y_ana
=
exp
(
-
data
.
value
*
time
);
time_reached
,
y
[
0
],
y
[
0
]
-
exp
(
-
15.0
*
time_reached
),
y_dot
[
0
],
auto
const
y_dot_ana
=
-
data
.
value
*
exp
(
-
data
.
value
*
time
);
y_dot
[
0
]
+
15.0
*
exp
(
-
15.0
*
time_reached
));
EXPECT_NEAR
(
time
,
time_reached
,
std
::
numeric_limits
<
double
>::
epsilon
()
);
check
(
time_reached
,
y
[
0
],
y_dot
[
0
],
time
,
y_ana
,
y_dot_ana
);
}
}
}
}
...
@@ -162,12 +209,14 @@ TEST(MathLibCVodeTest, ExponentialWithJacobian)
...
@@ -162,12 +209,14 @@ TEST(MathLibCVodeTest, ExponentialWithJacobian)
const
double
t0
=
0.0
;
const
double
t0
=
0.0
;
auto
tree
=
boost
::
property_tree
::
ptree
{};
auto
tree
=
boost
::
property_tree
::
ptree
{};
BaseLib
::
ConfigTree
config
(
tree
,
""
,
BaseLib
::
ConfigTree
::
onerror
,
auto
ode_solver
=
make_ode_solver
<
1
>
(
tree
);
BaseLib
::
ConfigTree
::
onwarning
);
auto
ode_solver
=
MathLib
::
createOdeSolver
<
1
>
(
config
);
ASSERT_EQ
(
any_ode_solver_libs_available
(),
!!
ode_solver
);
// Don't run the test if the ODE solver could not be constructed.
if
(
!
ode_solver
)
return
;
ode_solver
->
setFunction
(
f
,
df
);
ode_solver
->
setFunction
(
f
,
df
);
ode_solver
->
setTolerance
(
1e-10
,
1e-8
);
ode_solver
->
setTolerance
(
abs_tol
,
rel_tol
);
ode_solver
->
setIC
(
t0
,
{
y0
});
ode_solver
->
setIC
(
t0
,
{
y0
});
...
@@ -182,14 +231,13 @@ TEST(MathLibCVodeTest, ExponentialWithJacobian)
...
@@ -182,14 +231,13 @@ TEST(MathLibCVodeTest, ExponentialWithJacobian)
ASSERT_TRUE
(
ode_solver
->
solve
(
time
));
ASSERT_TRUE
(
ode_solver
->
solve
(
time
));
auto
const
y
=
ode_solver
->
getSolution
();
auto
const
y
=
ode_solver
->
getSolution
();
double
time_reached
=
ode_solver
->
getTime
();
auto
const
time_reached
=
ode_solver
->
getTime
();
auto
const
y_dot
=
ode_solver
->
getYDot
(
time_reached
,
y
);
auto
const
y_dot
=
ode_solver
->
getYDot
(
time_reached
,
y
);
DBUG
(
"t: %14.7g, y: %14.7g, diff: %14.7g, y_dot: %14.7g, diff: %14.7g"
,
auto
const
y_ana
=
exp
(
-
15.0
*
time
);
time_reached
,
y
[
0
],
y
[
0
]
-
exp
(
-
15.0
*
time_reached
),
y_dot
[
0
],
auto
const
y_dot_ana
=
-
15.0
*
exp
(
-
15.0
*
time
);
y_dot
[
0
]
+
15.0
*
exp
(
-
15.0
*
time_reached
));
EXPECT_NEAR
(
time
,
time_reached
,
std
::
numeric_limits
<
double
>::
epsilon
()
);
check
(
time_reached
,
y
[
0
],
y_dot
[
0
],
time
,
y_ana
,
y_dot_ana
);
}
}
}
}
...
@@ -199,16 +247,17 @@ TEST(MathLibCVodeTest, ExponentialWithJacobianNewton)
...
@@ -199,16 +247,17 @@ TEST(MathLibCVodeTest, ExponentialWithJacobianNewton)
const
double
y0
=
1.0
;
const
double
y0
=
1.0
;
const
double
t0
=
0.0
;
const
double
t0
=
0.0
;
boost
::
property_tree
::
ptree
conf
;
boost
::
property_tree
::
ptree
tree
;
conf
.
put
(
"linear_multistep_method"
,
"BDF"
);
tree
.
put
(
"linear_multistep_method"
,
"BDF"
);
conf
.
put
(
"nonlinear_solver_iteration"
,
"Newton"
);
tree
.
put
(
"nonlinear_solver_iteration"
,
"Newton"
);
BaseLib
::
ConfigTree
config
(
conf
,
""
,
BaseLib
::
ConfigTree
::
onerror
,
auto
ode_solver
=
make_ode_solver
<
1
>
(
tree
);
BaseLib
::
ConfigTree
::
onwarning
);
auto
ode_solver
=
MathLib
::
createOdeSolver
<
1
>
(
config
);
ASSERT_EQ
(
any_ode_solver_libs_available
(),
!!
ode_solver
);
// Don't run the test if the ODE solver could not be constructed.
if
(
!
ode_solver
)
return
;
ode_solver
->
setFunction
(
f
,
df
);
ode_solver
->
setFunction
(
f
,
df
);
ode_solver
->
setTolerance
(
1e-6
,
1e-6
);
ode_solver
->
setTolerance
(
abs_tol
,
rel_tol
);
ode_solver
->
setIC
(
t0
,
{
y0
});
ode_solver
->
setIC
(
t0
,
{
y0
});
...
@@ -223,15 +272,12 @@ TEST(MathLibCVodeTest, ExponentialWithJacobianNewton)
...
@@ -223,15 +272,12 @@ TEST(MathLibCVodeTest, ExponentialWithJacobianNewton)
ASSERT_TRUE
(
ode_solver
->
solve
(
time
));
ASSERT_TRUE
(
ode_solver
->
solve
(
time
));
auto
const
y
=
ode_solver
->
getSolution
();
auto
const
y
=
ode_solver
->
getSolution
();
double
time_reached
=
ode_solver
->
getTime
();
auto
const
time_reached
=
ode_solver
->
getTime
();
auto
const
y_dot
=
ode_solver
->
getYDot
(
time_reached
,
y
);
auto
const
y_dot
=
ode_solver
->
getYDot
(
time_reached
,
y
);
DBUG
(
"t: %14.7g, y: %14.7g, diff: %14.7g, y_dot: %14.7g, diff: %14.7g"
,
auto
const
y_ana
=
exp
(
-
15.0
*
time
);
time_reached
,
y
[
0
],
y
[
0
]
-
exp
(
-
15.0
*
time_reached
),
y_dot
[
0
],
auto
const
y_dot_ana
=
-
15.0
*
exp
(
-
15.0
*
time
);
y_dot
[
0
]
+
15.0
*
exp
(
-
15.0
*
time_reached
));
EXPECT_NEAR
(
time
,
time_reached
,
std
::
numeric_limits
<
double
>::
epsilon
()
);
check
(
time_reached
,
y
[
0
],
y_dot
[
0
],
time
,
y_ana
,
y_dot_ana
);
}
}
}
}
#endif // CVODE_FOUND
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment