forked from Conedy/Conedy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
containerNode.h
240 lines (144 loc) · 5.21 KB
/
containerNode.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#ifndef containerNode_h
#define containerNode_h containerNode_h
//#include "node.h"
#include "params.h"
#include <boost/function.hpp>
//#include <gsl/gsl_errno.h>
//#include <gsl/gsl_matrix.h>
//#include <gsl/gsl_odeiv2.h>
#include "dynNode.h"
#include <list>
// nodes container number
// odeNode : 1
// mapNode : 2
// gslOdeNode: 3
// sdeNode : 4
namespace conedy
{
//! Container class, which puts nodes representing dynamical systems of the same kind (e.g. ODEs) into container. The second template is the container number. Nodes in the same container have consecutive memory for their state variables. Time evolution is handled by the first node in the container.
template <typename T, int N>
class containerNode : public dynNode
{
protected:
//! static pointer to the dynamical variables of all nodes in the container
static T * dynamicVariablesOfAllDynNodes;
//! the number of used indices, the smallest unused index
static unsigned int usedIndices;
//! the current size of the container
static unsigned int sizeOfArray;
//! a list of all nodes in the container
typedef list<containerNode<T,N> *> containerNodeList;
static containerNodeList nodeList;
params<T> p;
// Hilfsfunktionen für die GSL:
public:
unsigned int startPosGslOdeNodeArray;
virtual baseType getState (unsigned int component) { return dynamicVariablesOfAllDynNodes[ startPosGslOdeNodeArray + component ]; }
static unsigned int containerDimension () { return usedIndices;}
containerNode (networkElementType n ) : dynNode ( n), p ( _containerNode_ ) { };
containerNode (networkElementType n, unsigned int dim ) : dynNode ( n, dim), p ( _containerNode_ ) { };
virtual void dynamics() { throw "dynamics of containerNode called"; }
static void clear()
{
usedIndices = 0;
nodeList.clear();
}
virtual bool timeEvolution () // only the first element of the container will be called for time evolution.
{
if ( (*nodeList.begin()) == this)
return 1;
else
return 0;
}
containerNode ( const containerNode & c ) : dynNode ( c ), p ( _containerNode_ )
{
free( this->x);
//cout << "Copy-Konstruktor" << endl;
if ( usedIndices == 0 ) // first node in the container. Reserve memory according two gslOdeNode_arraySize
{
dynamicVariablesOfAllDynNodes = ( T* ) calloc ( p.getParams ( 0 ),sizeof ( T ) );
sizeOfArray = p.getParams(0);
}
while ( usedIndices + (&c)->dimension() > sizeOfArray ) // memory space is empty
{
realign(); // try to fill in the wholes in the array
if ( usedIndices + (&c)->dimension() > sizeOfArray ) // still not enough space in the array, so copy the array to a new location.
{
unsigned int newSize = (unsigned int) sizeOfArray * 1.5;
T* newArray = ( T* ) calloc ( newSize ,sizeof ( T ) );
sizeOfArray = newSize;
T* pointer = newArray;
usedIndices = 0;
typename containerNodeList::iterator it;
for (it = nodeList.begin(); it != nodeList.end(); it++)
{
for (unsigned int i = 0; i < (*it)->dimension(); i++)
pointer[i] = (*it)->x [i] ;
(*it)->x = pointer;
(*it)->startPosGslOdeNodeArray = usedIndices;
pointer = pointer + (*it)->dimension();
usedIndices = usedIndices + (*it)->dimension();
}
free (dynamicVariablesOfAllDynNodes);
dynamicVariablesOfAllDynNodes = newArray;
}
}
this->x = &dynamicVariablesOfAllDynNodes[usedIndices];
nodeList.push_back ( this );
startPosGslOdeNodeArray = usedIndices;
usedIndices += (&c)->dimension();
}
//! Lücken füllen und zusammenschieben
static void realign ()
{
typename containerNodeList::iterator it;
T* pointer = dynamicVariablesOfAllDynNodes;
unsigned int offset = 0;
usedIndices = 0;
for (it = nodeList.begin(); it != nodeList.end(); it++)
{
while (usedIndices + offset != (*it)->startPosGslOdeNodeArray)
offset++;
for (unsigned int i = 0; i < (*it)->dimension(); i++)
{
(*it)->x = pointer;
pointer[i] = pointer[i + offset];
usedIndices ++;
}
pointer = pointer + (*it)->dimension();
}
}
//! 1. und einizger Intergrationsschritt:
virtual ~containerNode()
{
typename containerNodeList::iterator it;
for (it = nodeList.begin(); it != nodeList.end(); it++)
if (*it == this)
{
nodeList.erase(it);
break;
}
}
//! clean: wird vor der Integration aufgerufen und initialisiert diverse GSL-Parameter (Art der Stufenfunktion, Schrittweite usw.)
virtual void clean ()
{
realign();
}
bool amIFirst() { return ( (*nodeList.begin()) == this); }
static void registerStandardValues()
{
params<T>::registerStandard ( _containerNode_,"containerNode_arraySize", 0,4096 );
}
};
template < class T, int N>
T*containerNode<T, N>::dynamicVariablesOfAllDynNodes;
template < class T, int N>
unsigned int containerNode<T,N>::usedIndices;
template < class T, int N>
std::list<containerNode<T,N>*> containerNode<T,N>::nodeList;
template < class T, int N>
unsigned int containerNode<T,N>::sizeOfArray;
//template < class T>
//double containerNode<T>::time;
}
#endif