-
Notifications
You must be signed in to change notification settings - Fork 0
/
forces.cpp
154 lines (132 loc) · 3.92 KB
/
forces.cpp
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
#include "forces.h"
#include <GL/gl.h>
#include <GL/freeglut.h>
#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <stdio.h>
SystemGravityForce::SystemGravityForce(
caams::matrix g,
System &system):
g(g),
system(system)
{
}
void SystemGravityForce::Apply(caams::matrix &y_rhs)
{
for(auto body:system.bodies){
caams::matrix f(body->mass*g);
AccumulateForce(y_rhs,f,body->eqn_index);
}
}
BodyGravityForce::BodyGravityForce(
caams::matrix g,
Body *body):
g(g),
body(body){
}
void BodyGravityForce::Apply(caams::matrix &y_rhs)
{
caams::matrix f(body->mass*g);
AccumulateForce(y_rhs, f, body->eqn_index);
}
SystemNewtonianGravityForce::SystemNewtonianGravityForce(
double G_Newton,
System &system):
G_Newton(G_Newton),
system(system)
{
}
void SystemNewtonianGravityForce::Apply(caams::matrix &y_rhs)
{
long Nbodies = system.bodies.size();
if(Nbodies<=1)return;
for(long b1=0;b1<(Nbodies-1);b1++){
for(long b2=b1+1;b2<Nbodies;b2++){
GravityForcePair(
system.bodies[b1],
system.bodies[b2],
y_rhs);
}
}
}
void SystemNewtonianGravityForce::GravityForcePair(
Body *body1,
Body *body2,
caams::matrix &y_rhs)
{
caams::matrix r21(body2->rk_r - body1->rk_r);
double mag_r21 = caams::norm(r21);
caams::matrix r21n(1.0/mag_r21*r21);
double mag_F1 = body1->mass*body2->mass*G_Newton/(mag_r21*mag_r21);
caams::matrix F1(mag_F1*r21n);
AccumulateForce(y_rhs,F1,body1->eqn_index);
AccumulateForce(y_rhs,-F1,body2->eqn_index);
}
LinearSpringDamperForce::LinearSpringDamperForce(
Body *body1,
Body *body2,
caams::matrix s1_p,
caams::matrix s2_p,
double length,
double k_spring,
double k_damper):
body1(body1),
body2(body2),
s1_p(s1_p),
s2_p(s2_p),
length(length),
k_spring(k_spring),
k_damper(k_damper)
{
}
void LinearSpringDamperForce::Apply(caams::matrix &y_rhs)
{
caams::matrix A1(caams::Ap(body1->rk_p));
caams::matrix A2(caams::Ap(body2->rk_p));
caams::matrix s1(A1*s1_p);
caams::matrix s2(A2*s2_p);
caams::matrix r1(body1->rk_r + s1);
caams::matrix r2(body2->rk_r + s2);
caams::matrix r21(r2-r1);
double mag_r21 = caams::norm(r21);
//printf("mag_r21:%lf\n",mag_r21);
caams::matrix r21n(caams::normalize(r21));
caams::matrix omega1(2.0*caams::G(body1->rk_p)*body1->rk_p_dot);
caams::matrix omega2(2.0*caams::G(body2->rk_p)*body2->rk_p_dot);
caams::matrix v1(body1->rk_r_dot + caams::SS(omega1)*s1);
caams::matrix v2(body2->rk_r_dot + caams::SS(omega2)*s2);
caams::matrix v21(v2-v1);
caams::matrix v21_dot_r21n(~v21*r21n);
double mag_F1 = (mag_r21-length)*k_spring + v21_dot_r21n.data[0]*k_damper;
caams::matrix F1(mag_F1*r21n);
caams::matrix F2(-F1);
caams::matrix n1(caams::SS(s1)*F1);
caams::matrix n2(caams::SS(s2)*F2);
if(body1->eqn_index){
AccumulateForce(y_rhs,F1,body1->eqn_index);
AccumulateTorque(y_rhs,2.0*~caams::G(body1->rk_p)*n1,body1->eqn_index+3);
}
if(body2->eqn_index){
AccumulateForce(y_rhs,F2,body2->eqn_index);
AccumulateTorque(y_rhs,2.0*~caams::G(body2->rk_p)*n2,body2->eqn_index+3);
}
}
void LinearSpringDamperForce::Draw(void)
{
caams::matrix r1(body1->r + caams::Ap(body1->p)*s1_p);
caams::matrix r2(body2->r + caams::Ap(body2->p)*s2_p);
glBegin(GL_LINES);
glColor3f(0.5f,0.5f,0.5f);
glVertex3dv(body1->r.data);
glVertex3dv(r1.data);
glColor3f(0.75f,0.5f,0.0f);
glVertex3dv(r1.data);
glVertex3dv(r2.data);
glColor3f(0.5f,0.5f,0.5f);
glVertex3dv(r2.data);
glVertex3dv(body2->r.data);
glEnd();
}