Discontinuous Galerkin Library
#include "dg/algorithm.h"
simpsons.h
Go to the documentation of this file.
1#pragma once
2
3#include <list>
5#include "blas1.h"
6
10namespace dg{
11
31template<class ContainerType>
33{
35 using container_type = ContainerType;
40 Simpsons( unsigned order = 3): m_counter(0), m_order(order), m_t0(0)
41 {
42 set_order(order);
43 }
45 void set_order( unsigned order){
46 m_order=order;
47 m_t.resize( order-1);
48 m_u.resize(order-1);
49 if( !(order == 2 || order == 3))
50 throw dg::Error(dg::Message()<<"Integration order must be either 2 or 3!");
51 }
53 unsigned get_order() const{return m_order;}
59 void init( value_type t0, const ContainerType& u0) {
60 m_integral = u0;
61 for( auto& u: m_u)
62 u = u0;
63 for( auto& t: m_t)
64 t = 0;
65 m_t.front() = t0;
66 flush();
67 m_t0 = t0;
68 }
71 void flush() {
72 m_counter = 0; //since the counter becomes zero we do not need to touch m_u and m_t since the next add triggers the Trapezoidal rule
73 dg::blas1::scal( m_integral, 0.);
74 m_t0 = m_t.front();
75 }
83 void add( value_type t_new, const ContainerType& u_new){
84 if( t_new < m_t.front())
85 throw dg::Error(dg::Message()<<"New time must be strictly larger than old time!");
86 auto pt0 = m_t.begin();
87 auto pt1 = std::next( pt0);
88 auto pu0 = m_u.begin();
89 auto pu1 = std::next( pu0);
90 value_type t0 = *pt1, t1 = *pt0, t2 = t_new;
91 if( m_counter % 2 == 0 || m_order == 2)
92 {
93 //Trapezoidal rule
94 dg::blas1::axpbypgz( 0.5*(t2 - t1), u_new,
95 0.5*(t2 - t1), *pu0 , 1., m_integral);
96 }
97 else
98 {
99 //Simpson's rule
100 value_type pre0 = (2.*t0-3.*t1+t2)*(t2-t0)/(6.*(t0-t1));
101 value_type pre1 = (t2-t0)*(t2-t0)*(t2-t0)/(6.*(t0-t1)*(t1-t2));
102 value_type pre2 = (t0-3.*t1+2.*t2)*(t0-t2)/(6.*(t1-t2));
103
104 dg::blas1::axpby( pre2, u_new, 1., m_integral);
106 pre1-0.5*(t1-t0), *pu0, //subtract last Trapezoidal step
107 pre0-0.5*(t1-t0), *pu1,
108 1., m_integral);
109 }
110 //splice does not copy or move anything, only the internal pointers of the list nodes are re-pointed
111 m_t.splice( pt0, m_t, pt1, m_t.end());//permute elements
112 m_u.splice( pu0, m_u, pu1, m_u.end());
113 m_t.front() = t_new; //and now remove zeroth element
114 dg::blas1::copy( u_new, m_u.front());
115 m_counter++;
116 }
117
121 const ContainerType& get_integral() const{
122 return m_integral;
123 }
129 std::array<value_type,2> get_boundaries() const{
130 std::array<value_type,2> times{ m_t0, m_t.front()};
131 return times;
132 }
133 private:
134 unsigned m_counter, m_order;
135 ContainerType m_integral;
136 //we use a list here to avoid explicitly calling the swap function
137 std::list<value_type> m_t;
138 std::list<ContainerType> m_u;
139 value_type m_t0;
140};
141
142}//namespace dg
class intended for the use in throw statements
Definition: exceptions.h:83
small class holding a stringstream
Definition: exceptions.h:29
Error classes or the dg library.
void copy(const ContainerTypeIn &source, ContainerTypeOut &target)
Definition: blas1.h:164
void axpbypgz(get_value_type< ContainerType > alpha, const ContainerType1 &x, get_value_type< ContainerType > beta, const ContainerType2 &y, get_value_type< ContainerType > gamma, ContainerType &z)
Definition: blas1.h:265
void axpby(get_value_type< ContainerType > alpha, const ContainerType1 &x, get_value_type< ContainerType > beta, ContainerType &y)
Definition: blas1.h:231
void scal(ContainerType &x, get_value_type< ContainerType > alpha)
Definition: blas1.h:185
typename TensorTraits< std::decay_t< Vector > >::value_type get_value_type
Definition: tensor_traits.h:38
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
Time integration based on Simpson's rule.
Definition: simpsons.h:33
unsigned get_order() const
Access current integration order.
Definition: simpsons.h:53
Simpsons(unsigned order=3)
Set integration order without initializing values.
Definition: simpsons.h:40
void init(value_type t0, const ContainerType &u0)
Initialize the left-side boundary of the integration.
Definition: simpsons.h:59
void flush()
Reset the integral to zero and the last (t,u) pair in the add function as the new left-side.
Definition: simpsons.h:71
void add(value_type t_new, const ContainerType &u_new)
Add a new (t,u) pair to the time integral.
Definition: simpsons.h:83
std::array< value_type, 2 > get_boundaries() const
Access the left and right boundary in time.
Definition: simpsons.h:129
ContainerType container_type
the type of the vector class in use
Definition: simpsons.h:35
const ContainerType & get_integral() const
Access the current value of the time integral.
Definition: simpsons.h:121
get_value_type< ContainerType > value_type
the value type of the time variable (float or double)
Definition: simpsons.h:34
void set_order(unsigned order)
Set integration order without initializing values.
Definition: simpsons.h:45