Project

General

Profile

Statistics
| Branch: | Revision:

root / src / layout / forcedirectedparametersbase.h @ 8aeaaccc

History | View | Annotate | Download (8.88 KB)

1
//=========================================================================
2
//  FORCEDIRECTEDPARAMETERSBASE.H - part of
3
//                  OMNeT++/OMNEST
4
//           Discrete System Simulation in C++
5
//
6
//  Author: Levente Meszaros
7
//
8
//=========================================================================
9

    
10
/*--------------------------------------------------------------*
11
  Copyright (C) 2006-2008 OpenSim Ltd.
12

13
  This file is distributed WITHOUT ANY WARRANTY. See the file
14
  `license' for details on this and other legal matters.
15
*--------------------------------------------------------------*/
16

    
17
#ifndef __FORCEDIRECTEDPARAMETERSBASE_H_
18
#define __FORCEDIRECTEDPARAMETERSBASE_H_
19

    
20
#include <math.h>
21
#include "geometry.h"
22

    
23
NAMESPACE_BEGIN
24

    
25
class ForceDirectedEmbedding;
26

    
27
/**
28
 * Various parameters driving the algorithm.
29
 */
30
struct ForceDirectedParameters
31
{
32
    /**
33
     * For bodies not initialized with a particular size.
34
     */
35
    Rs defaultBodySize;
36

    
37
    /**
38
     * For bodies not initialized with a particular mass.
39
     */
40
    double defaultBodyMass;
41

    
42
    /**
43
     * For bodies not initialized with a particular charge.
44
     */
45
    double defaultBodyCharge;
46

    
47
    /**
48
     * For springs not initialized with a particular coefficient.
49
     */
50
    double defaultSpringCoefficient;
51

    
52
    /**
53
     * Default spring repose length.
54
     */
55
    double defaultSpringReposeLength;
56

    
57
    /**
58
     * Electric repulsion force coefficient.
59
     */
60
    double electricRepulsionCoefficient;
61

    
62
    /**
63
     * For electric repulsions not initialized with a linearity distance.
64
     */
65
    double defaultElectricRepulsionLinearityDistance;
66

    
67
    /**
68
     * For electric repulsions not initialized with a particular max distance.
69
     */
70
    double defaultElectricRepulsionMaxDistance;
71

    
72
    /**
73
     * Friction reduces the energy of the system. The friction force points in the opposite direction of the current velocity.
74
     */
75
    double frictionCoefficient;
76

    
77
    /**
78
     * For force providers not initialized with a particular slippery flag.
79
     */
80
    bool defaultSlippery;
81

    
82
    /**
83
     * For force providers not initialized with a particular point like distance flag.
84
     */
85
    bool defaultPointLikeDistance;
86

    
87
    /**
88
     * The default time step used when solution starts.
89
     */
90
    double timeStep;
91

    
92
    /**
93
     * Lower limit for the updated time step.
94
     */
95
    double minTimeStep;
96

    
97
    /**
98
     * Lower limit for the updated time step.
99
     */
100
    double maxTimeStep;
101

    
102
    /**
103
     * Multiplier used to update the time step.
104
     */
105
    double timeStepMultiplier;
106

    
107
    /**
108
     * Relative lwer limit of acceleration approximation difference (between a1, a2, a3 and a4 in RK-4).
109
     * During updating the time step this is the lower limit to accept the current time step.
110
     */
111
    double minAccelerationError;
112

    
113
    /**
114
     * Relative upper limit of acceleration approximation difference (between a1, a2, a3 and a4 in RK-4).
115
     */
116
    double maxAccelerationError;
117

    
118
    /**
119
     * Velocity limit during the solution.
120
     * When all bodies has lower velocity than this limit then the algorithm may be stopped.
121
     */
122
    double velocityRelaxLimit;
123

    
124
    /**
125
     * Acceleration limit during the solution.
126
     * When all bodies has lower acceleration than this limit then the algorithm may be stopped.
127
     */
128
    double accelerationRelaxLimit;
129

    
130
    /**
131
     * For force providers not initialized with a particular maximum force.
132
     */
133
    double defaultMaxForce;
134

    
135
    /**
136
     * Maximim velocity that a body may have.
137
     */
138
    double maxVelocity;
139

    
140
    /**
141
     * Maximum number of calculation cycles to run.
142
     */
143
    int maxCycle;
144

    
145
    /**
146
     * Maximum time to be spent on the calculation in milliseconds.
147
     * The algorithm will return after this time has been elapsed.
148
     */
149
    double maxCalculationTime;
150
};
151

    
152
/**
153
 * A variable used in the differential equation.
154
 * The actual value of the variable is the position, the first derivative is the velocity
155
 * and the second derivative is the acceleration.
156
 */
157
class Variable {
158
    protected:
159
        /**
160
         * Value of the variable.
161
         */
162
        Pt position;
163

    
164
        /**
165
         * First derivative.
166
         */
167
        Pt velocity;
168

    
169
        /**
170
         * Second derivative.
171
         */
172
        Pt acceleration;
173

    
174
        /**
175
         * Total applied force.
176
         */
177
        Pt force;
178

    
179
        /**
180
         * The list of all applied forces for debug purposes.
181
         */
182
        std::vector<Pt> forces;
183

    
184
        /**
185
         * Total mass of bodies appling forces to this variable.
186
         */
187
        double mass;
188

    
189
        ForceDirectedEmbedding *embedding;
190

    
191
    private:
192
        void constructor(const Pt& position, const Pt& velocity) {
193
            this->position = position;
194
            this->velocity = velocity;
195

    
196
            mass = 0;
197
            force = Pt::getZero();
198
        }
199

    
200
    public:
201
        Variable(const Pt& position) {
202
            constructor(position, Pt::getZero());
203
        }
204

    
205
        Variable(const Pt& position, const Pt& velocity) {
206
            constructor(position, velocity);
207
        }
208
        virtual ~Variable() {}
209

    
210
        virtual void reinitialize() {};
211

    
212
        void setForceDirectedEmbedding(ForceDirectedEmbedding *embedding) {
213
            this->embedding = embedding;
214
        }
215

    
216
        const Pt& getPosition() {
217
            return position;
218
        }
219

    
220
        virtual void assignPosition(const Pt& position) {
221
            this->position.assign(position);
222
        }
223

    
224
        const Pt& getVelocity() {
225
            return velocity;
226
        }
227

    
228
        virtual void assignVelocity(const Pt& velocity) {
229
            this->velocity.assign(velocity);
230
        }
231

    
232
        virtual const Pt& getAcceleration() {
233
            return acceleration.assign(force).divide(mass);
234
        }
235

    
236
        double getKineticEnergy() {
237
            double vlen = velocity.getLength();
238
            return 0.5 * mass * vlen * vlen;
239
        }
240

    
241
        void resetForce() {
242
            force = Pt::getZero();
243
        }
244

    
245
        double getMass() {
246
            return mass;
247
        }
248

    
249
        void setMass(double mass) {
250
            this->mass = mass;
251
        }
252

    
253
        Pt getForce() {
254
            return force;
255
        }
256

    
257
        void addForce(const Pt& f) {
258
            if (f.isFullySpecified()) {
259
                force.add(f);
260

    
261
// TODO:
262
//                if (embedding->inspected)
263
//                    forces.push_back(f);
264
            }
265
        }
266

    
267
        void subtractForce(const Pt& f) {
268
            if (f.isFullySpecified()) {
269
                force.subtract(f);
270

    
271
// TODO:
272
//                if (embedding->inspected)
273
//                    forces.push_back(f.multiply(-1));
274
            }
275
        }
276

    
277
        void resetForces() {
278
            forces.clear();
279
        }
280

    
281
        const std::vector<Pt>& getForces() {
282
            return forces;
283
        }
284
};
285

    
286
/**
287
 * A variable which has fix x and y coordinates but still has a free z coordinate.
288
 */
289
class PointConstrainedVariable : public Variable {
290
    public:
291
        PointConstrainedVariable(Pt position) : Variable(position) {
292
        }
293

    
294
        virtual void assignPosition(const Pt& position) {
295
            this->position.z = position.z;
296
        }
297

    
298
        virtual void assignVelocity(const Pt& velocity) {
299
            this->velocity.z = velocity.z;
300
        }
301

    
302
        virtual const Pt& getAcceleration() {
303
            return acceleration.assign(0, 0, force.z).divide(mass);
304
        }
305
};
306

    
307
/**
308
 * Interface class for bodies.
309
 */
310
class IBody {
311
    protected:
312
        ForceDirectedEmbedding *embedding;
313

    
314
    public:
315
        virtual ~IBody() {}
316

    
317
        virtual void reinitialize() {};
318

    
319
        virtual void setForceDirectedEmbedding(ForceDirectedEmbedding *embedding) {
320
            this->embedding = embedding;
321
        }
322

    
323
        virtual const Pt& getPosition() = 0;
324

    
325
        virtual const char *getClassName() = 0;
326

    
327
        virtual const Rs& getSize() = 0;
328

    
329
        virtual double getMass() = 0;
330

    
331
        virtual double getCharge() = 0;
332

    
333
        virtual Variable *getVariable() = 0;
334

    
335
        Pt getLeftTop() {
336
            return Pt(getLeft(), getTop(), getPosition().z);
337
        }
338

    
339
        double getLeft() {
340
            return getPosition().x - getSize().width / 2;
341
        }
342

    
343
        double getRight() {
344
            return getPosition().x + getSize().width / 2;
345
        }
346

    
347
        double getTop() {
348
            return getPosition().y - getSize().height / 2;
349
        }
350

    
351
        double getBottom() {
352
            return getPosition().y + getSize().height / 2;
353
        }
354
};
355

    
356
/**
357
 * Interface class used by the force directed embedding to generate forces among bodies.
358
 */
359
class IForceProvider {
360
    protected:
361
        ForceDirectedEmbedding *embedding;
362

    
363
    public:
364
        virtual ~IForceProvider() {}
365

    
366
        virtual void reinitialize() {};
367

    
368
        virtual void setForceDirectedEmbedding(ForceDirectedEmbedding *embedding) {
369
            this->embedding = embedding;
370
        }
371

    
372
        virtual const char *getClassName() = 0;
373

    
374
        virtual void applyForces() = 0;
375

    
376
        virtual double getPotentialEnergy() = 0;
377
};
378

    
379
NAMESPACE_END
380

    
381

    
382
#endif