blob: 34fe12c424c232083c631655a93f4bf8d554a67d [file] [log] [blame]
Brian Silverman7c33ab22018-08-04 17:14:51 -07001/*
2 [auto_generated]
3 libs/numeric/odeint/examples/heun.cpp
4
5 [begin_description]
6 Examplary implementation of the method of Heun.
7 [end_description]
8
9 Copyright 2012 Karsten Ahnert
10 Copyright 2012 Mario Mulansky
11
12 Distributed under the Boost Software License, Version 1.0.
13 (See accompanying file LICENSE_1_0.txt or
14 copy at http://www.boost.org/LICENSE_1_0.txt)
15 */
16
17#include <iostream>
18
19
20#include <boost/fusion/container/vector.hpp>
21#include <boost/fusion/container/generation/make_vector.hpp>
22
23#include <boost/array.hpp>
24
25#include <boost/numeric/odeint.hpp>
26
27
28
29
30
31
32namespace fusion = boost::fusion;
33
34//[ heun_define_coefficients
35template< class Value = double >
36struct heun_a1 : boost::array< Value , 1 > {
37 heun_a1( void )
38 {
39 (*this)[0] = static_cast< Value >( 1 ) / static_cast< Value >( 3 );
40 }
41};
42
43template< class Value = double >
44struct heun_a2 : boost::array< Value , 2 >
45{
46 heun_a2( void )
47 {
48 (*this)[0] = static_cast< Value >( 0 );
49 (*this)[1] = static_cast< Value >( 2 ) / static_cast< Value >( 3 );
50 }
51};
52
53
54template< class Value = double >
55struct heun_b : boost::array< Value , 3 >
56{
57 heun_b( void )
58 {
59 (*this)[0] = static_cast<Value>( 1 ) / static_cast<Value>( 4 );
60 (*this)[1] = static_cast<Value>( 0 );
61 (*this)[2] = static_cast<Value>( 3 ) / static_cast<Value>( 4 );
62 }
63};
64
65template< class Value = double >
66struct heun_c : boost::array< Value , 3 >
67{
68 heun_c( void )
69 {
70 (*this)[0] = static_cast< Value >( 0 );
71 (*this)[1] = static_cast< Value >( 1 ) / static_cast< Value >( 3 );
72 (*this)[2] = static_cast< Value >( 2 ) / static_cast< Value >( 3 );
73 }
74};
75//]
76
77
78//[ heun_stepper_definition
79template<
80 class State ,
81 class Value = double ,
82 class Deriv = State ,
83 class Time = Value ,
84 class Algebra = boost::numeric::odeint::range_algebra ,
85 class Operations = boost::numeric::odeint::default_operations ,
86 class Resizer = boost::numeric::odeint::initially_resizer
87>
88class heun : public
89boost::numeric::odeint::explicit_generic_rk< 3 , 3 , State , Value , Deriv , Time ,
90 Algebra , Operations , Resizer >
91{
92
93public:
94
95 typedef boost::numeric::odeint::explicit_generic_rk< 3 , 3 , State , Value , Deriv , Time ,
96 Algebra , Operations , Resizer > stepper_base_type;
97
98 typedef typename stepper_base_type::state_type state_type;
99 typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
100 typedef typename stepper_base_type::value_type value_type;
101 typedef typename stepper_base_type::deriv_type deriv_type;
102 typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
103 typedef typename stepper_base_type::time_type time_type;
104 typedef typename stepper_base_type::algebra_type algebra_type;
105 typedef typename stepper_base_type::operations_type operations_type;
106 typedef typename stepper_base_type::resizer_type resizer_type;
107 typedef typename stepper_base_type::stepper_type stepper_type;
108
109 heun( const algebra_type &algebra = algebra_type() )
110 : stepper_base_type(
111 fusion::make_vector(
112 heun_a1<Value>() ,
113 heun_a2<Value>() ) ,
114 heun_b<Value>() , heun_c<Value>() , algebra )
115 { }
116};
117//]
118
119
120const double sigma = 10.0;
121const double R = 28.0;
122const double b = 8.0 / 3.0;
123
124struct lorenz
125{
126 template< class State , class Deriv >
127 void operator()( const State &x_ , Deriv &dxdt_ , double t ) const
128 {
129 typename boost::range_iterator< const State >::type x = boost::begin( x_ );
130 typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ );
131
132 dxdt[0] = sigma * ( x[1] - x[0] );
133 dxdt[1] = R * x[0] - x[1] - x[0] * x[2];
134 dxdt[2] = -b * x[2] + x[0] * x[1];
135 }
136};
137
138struct streaming_observer
139{
140 std::ostream &m_out;
141 streaming_observer( std::ostream &out ) : m_out( out ) { }
142 template< typename State , typename Value >
143 void operator()( const State &x , Value t ) const
144 {
145 m_out << t;
146 for( size_t i=0 ; i<x.size() ; ++i ) m_out << "\t" << x[i];
147 m_out << "\n";
148 }
149};
150
151
152
153int main( int argc , char **argv )
154{
155 using namespace std;
156 using namespace boost::numeric::odeint;
157
158
159 //[ heun_example
160 typedef boost::array< double , 3 > state_type;
161 heun< state_type > h;
162 state_type x = {{ 10.0 , 10.0 , 10.0 }};
163
164 integrate_const( h , lorenz() , x , 0.0 , 100.0 , 0.01 ,
165 streaming_observer( std::cout ) );
166
167 //]
168
169 return 0;
170}