ModelSpace
All Classes Namespaces Functions Variables Enumerations Pages
RK4Integrator.hpp
1/******************************************************************************
2* Copyright (c) ATTX LLC 2024. All Rights Reserved.
3*
4* This software and associated documentation (the "Software") are the
5* proprietary and confidential information of ATTX, LLC. The Software is
6* furnished under a license agreement between ATTX and the user organization
7* and may be used or copied only in accordance with the terms of the agreement.
8* Refer to 'license/attx_license.adoc' for standard license terms.
9*
10* EXPORT CONTROL NOTICE: THIS SOFTWARE MAY INCLUDE CONTENT CONTROLLED UNDER THE
11* INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) OR THE EXPORT ADMINISTRATION
12* REGULATIONS (EAR99). No part of the Software may be used, reproduced, or
13* transmitted in any form or by any means, for any purpose, without the express
14* written permission of ATTX, LLC.
15******************************************************************************/
16/*
17RK4 header file
18---------------
19
20
21Author: Alex Reynolds
22*/
23#ifndef RK4_HPP
24#define RK4_HPP
25
26#include <array>
27
28#include "Rates.hpp"
29#include "Integrator.hpp"
30
31namespace clockwerk {
32
33 template <typename T, unsigned int N>
34 class RK4Integrator : public Integrator<T, N> {
35 public:
36 RK4Integrator(Rates<T, N>& rate_calculator);
37
38 /// Function to take a full integrator step forward from time start to time end
39 /// @param start_time Start time for integration
40 /// @param end_time End time for integration
41 /// @param start_state State at start of integration
42 /// @param out_state Output state via implicit -- result of integration
43 void step(T start_time, T end_time, const std::array<T, N> &start_state, std::array<T, N> &out_state);
44
45 /// -------------------------------------------------------------------------
46 /// Functions for manual RK4 control -- calling these individually allows
47 /// a downstream user to manually control RK4 steps. Each is executed in order
48 /// for a full step
49 /// -------------------------------------------------------------------------
50 /// @brief Function to configure a full integration step
51 /// @param start_time Start time for the full integration step
52 /// @param end_time End time for the full integration step
53 /// @param start_state State at start of integration
54 void configureForStep(T start_time, T end_time, const std::array<T, N> &start_state);
55 /// @brief Function to calculate k1
56 /// @param state_for_k2 The integrated state to be used in the calculation of k2
57 void calculateK1(std::array<T, N> &state_for_k2);
58 /// @brief Function to calculate k2
59 /// @param state_in_k2 The state input to calculate k2
60 /// @param state_for_k3 The integrated state to be used in the calculation of k3
61 void calculateK2(const std::array<T, N> &state_in_k2, std::array<T, N> &state_for_k3);
62 /// @brief Function to calculate k3
63 /// @param state_in_k3 The state input to calculate k3
64 /// @param state_for_k4 The integrated state to be used in the calculation of k4
65 void calculateK3(const std::array<T, N> &state_in_k2, std::array<T, N> &state_for_k4);
66 /// @brief Function to calculate k4
67 /// @param state_in_k4 The state input to calculate k4
68 void calculateK4(const std::array<T, N> &state_in_k4);
69 /// @brief Calculation of final integrated step at the end of state
70 /// @param end_state State at the end of step
71 void getValueEndStep(std::array<T, N> &end_state);
72 protected:
73 /// Step size for integrator
75 T _half_step_size;
76 T _step_average;
77
78 /// Initial state tracking
80 T _end_time;
81 std::array<T, N> _start_state;
82
83 /// RK4 step rate values k1, k2, k3, k4 and var to calc average rate
84 std::array<T, N> _k1;
85 std::array<T, N> _k2;
86 std::array<T, N> _k3;
87 std::array<T, N> _k4;
88 };
89
90 template <typename T, unsigned int N>
91 RK4Integrator<T, N>::RK4Integrator(Rates<T, N>& rate_calculator)
92 : Integrator<T, N>(rate_calculator) {
93 /// Initialize steps and whatnot
94 _full_step_size = 0.0;
95 _half_step_size = 0.0;
96 _step_average = 0.0;
97 _start_time = 0.0;
98 _end_time = 0.0;
99
100 /// Initialize k values
101 for(unsigned int i = 0; i < N; i++) {
102 _start_state[i] = 0.0;
103 _k1[i] = 0.0;
104 _k2[i] = 0.0;
105 _k3[i] = 0.0;
106 _k4[i] = 0.0;
107 }
108 }
109
110 template <typename T, unsigned int N>
111 void RK4Integrator<T, N>::configureForStep(T start_time, T end_time,
112 const std::array<T, N> &start_state) {
113 /// Set up for step
114 _full_step_size = end_time - start_time;
115 _half_step_size = 0.5*_full_step_size;
116 _step_average = _full_step_size/6.0;
117 _start_time = start_time;
118 _end_time = end_time;
119 for(unsigned int i = 0; i < N; i++) {
120 _start_state[i] = start_state[i];
121 }
122 }
123
124 template <typename T, unsigned int N>
125 void RK4Integrator<T, N>::calculateK1(std::array<T, N> &state_for_k2) {
126 /// Calculate k1 from start state
127 Integrator<T, N>::_rate_calculator.calculateRates(_start_time, _start_state, _k1);
128
129 /// Calculate state for k2 calculation downstream
130 for(unsigned int i = 0; i < N; i++) {
131 state_for_k2[i] = _start_state[i] + _half_step_size*_k1[i];
132 }
133 }
134
135 template <typename T, unsigned int N>
136 void RK4Integrator<T, N>::calculateK2(const std::array<T, N> &state_in_k2,
137 std::array<T, N> &state_for_k3) {
138 /// Calculate k2 from start state
139 Integrator<T, N>::_rate_calculator.calculateRates(_start_time + _half_step_size, state_in_k2, _k2);
140
141 /// Calculate state for k3 calculation downstream
142 for(unsigned int i = 0; i < N; i++) {
143 state_for_k3[i] = _start_state[i] + _half_step_size*_k2[i];
144 }
145 }
146
147 template <typename T, unsigned int N>
148 void RK4Integrator<T, N>::calculateK3(const std::array<T, N> &state_in_k3,
149 std::array<T, N> &state_for_k4) {
150 /// Calculate k3 from start state
151 Integrator<T, N>::_rate_calculator.calculateRates(_start_time + _half_step_size, state_in_k3, _k3);
152
153 /// Calculate state for k4 calculation downstream
154 for(unsigned int i = 0; i < N; i++) {
155 state_for_k4[i] = _start_state[i] + _full_step_size*_k3[i];
156 }
157 }
158
159 template <typename T, unsigned int N>
160 void RK4Integrator<T, N>::calculateK4(const std::array<T, N> &state_in_k4) {
161 /// Calculate k4 from start state
162 Integrator<T, N>::_rate_calculator.calculateRates(_start_time + _full_step_size, state_in_k4, _k4);
163 }
164
165 template <typename T, unsigned int N>
166 void RK4Integrator<T, N>::getValueEndStep(std::array<T, N> &end_state) {
167 for(unsigned int i = 0; i < N; i++) {
168 end_state[i] = _start_state[i] + _step_average*(_k1[i] + 2.0*_k2[i] + 2.0*_k3[i] + _k4[i]);
169 }
170 }
171
172 template <typename T, unsigned int N>
173 void RK4Integrator<T, N>::step(T start_time, T end_time,
174 const std::array<T, N> &start_state,
175 std::array<T, N> &out_state) {
176 /// This is an RK4 integrator, so we need to execute each of our K steps
177 /// to execute our full integration. Go step by step, then sum total for
178 /// our out state. Call subfunctions for simplicity
179 configureForStep(start_time, end_time, start_state);
180 calculateK1(out_state);
181 calculateK2(out_state, out_state);
182 calculateK3(out_state, out_state);
183 calculateK4(out_state);
184 getValueEndStep(out_state);
185 }
186
187}
188
189#endif
This class is a base implementation of the integrator. It defines the basic functions and components ...
Definition Integrator.hpp:37
Definition RK4Integrator.hpp:34
void configureForStep(T start_time, T end_time, const std::array< T, N > &start_state)
Function to configure a full integration step.
Definition RK4Integrator.hpp:111
void getValueEndStep(std::array< T, N > &end_state)
Calculation of final integrated step at the end of state.
Definition RK4Integrator.hpp:166
void calculateK3(const std::array< T, N > &state_in_k2, std::array< T, N > &state_for_k4)
Function to calculate k3.
Definition RK4Integrator.hpp:148
T _start_time
Initial state tracking.
Definition RK4Integrator.hpp:79
void step(T start_time, T end_time, const std::array< T, N > &start_state, std::array< T, N > &out_state)
Function to take a full integrator step forward from time start to time end.
Definition RK4Integrator.hpp:173
void calculateK1(std::array< T, N > &state_for_k2)
Function to calculate k1.
Definition RK4Integrator.hpp:125
void calculateK4(const std::array< T, N > &state_in_k4)
Function to calculate k4.
Definition RK4Integrator.hpp:160
std::array< T, N > _k1
RK4 step rate values k1, k2, k3, k4 and var to calc average rate.
Definition RK4Integrator.hpp:84
T _full_step_size
Step size for integrator.
Definition RK4Integrator.hpp:74
void calculateK2(const std::array< T, N > &state_in_k2, std::array< T, N > &state_for_k3)
Function to calculate k2.
Definition RK4Integrator.hpp:136
Definition Rates.hpp:27