Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
N
nmm_2020_site
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Erik Strand
nmm_2020_site
Commits
28a512ad
Commit
28a512ad
authored
Mar 28, 2020
by
Erik Strand
Browse files
Options
Downloads
Patches
Plain Diff
Experiment with three particles
parent
9829b00f
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
_code/notes/diffsim/main.cpp
+59
-29
59 additions, 29 deletions
_code/notes/diffsim/main.cpp
with
59 additions
and
29 deletions
_code/notes/diffsim/main.cpp
+
59
−
29
View file @
28a512ad
...
@@ -16,6 +16,27 @@ Vector euler_step(F const& f, Scalar t, Vector const& x, Scalar delta_t) {
...
@@ -16,6 +16,27 @@ Vector euler_step(F const& f, Scalar t, Vector const& x, Scalar delta_t) {
return
x
+
delta_t
*
f
(
t
,
x
);
return
x
+
delta_t
*
f
(
t
,
x
);
}
}
//--------------------------------------------------------------------------------------------------
// A single step of fourth order Runge-Kutta
template
<
typename
F
,
typename
Vector
,
typename
Scalar
>
Vector
rk4_step
(
F
const
&
f
,
Scalar
t
,
Vector
const
&
x
,
Scalar
delta_t
)
{
Scalar
const
half_delta_t
=
static_cast
<
Scalar
>
(
0.5
)
*
delta_t
;
Vector
result
=
x
;
// k1
Vector
tmp
=
delta_t
*
f
(
t
,
x
);
result
+=
0.16666666666666
*
tmp
;
// k2
tmp
=
delta_t
*
f
(
half_delta_t
,
x
+
static_cast
<
Scalar
>
(
0.5
)
*
tmp
);
result
+=
0.33333333333333
*
tmp
;
// k3
tmp
=
delta_t
*
f
(
half_delta_t
,
x
+
static_cast
<
Scalar
>
(
0.5
)
*
tmp
);
result
+=
0.33333333333333
*
tmp
;
// k4
tmp
=
delta_t
*
f
(
t
+
delta_t
,
x
+
tmp
);
result
+=
0.16666666666666
*
tmp
;
return
result
;
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
// state vectors (i.e. phase space points) are packed as follows:
// state vectors (i.e. phase space points) are packed as follows:
// 0, ..., d - 1 give (up to) x, y, z for mass zero
// 0, ..., d - 1 give (up to) x, y, z for mass zero
...
@@ -30,45 +51,48 @@ Vector euler_step(F const& f, Scalar t, Vector const& x, Scalar delta_t) {
...
@@ -30,45 +51,48 @@ Vector euler_step(F const& f, Scalar t, Vector const& x, Scalar delta_t) {
// Functor that computes phase space derivatives
// Functor that computes phase space derivatives
class
NBodyLaw
{
class
NBodyLaw
{
public:
public:
NBodyLaw
();
NBodyLaw
()
{}
void
set_masses
(
VectorX
<
Scalar
>
const
&
m
)
{
m_
=
m
;
}
void
resize
(
uint32_t
n
);
void
set_masses
(
VectorX
<
Scalar
>
const
&
m
)
{
resize
(
m
.
size
());
m_
=
m
;
}
uint32_t
n
()
const
{
return
n_
;
}
// returns derivative of state for a give state
// returns derivative of state for a give state
VectorX
<
Scalar
>
const
&
operator
()(
VectorX
<
Scalar
>
const
&
state
);
VectorX
<
Scalar
>
const
&
operator
()(
VectorX
<
Scalar
>
const
&
state
);
static
constexpr
uint32_t
n
=
2
;
static
constexpr
uint32_t
d
=
2
;
static
constexpr
uint32_t
d
=
2
;
static
constexpr
Scalar
G
=
1e-
3
;
static
constexpr
Scalar
G
=
1e-
1
;
private
:
private
:
void
compute_force
();
void
compute_force
();
uint32_t
n_
;
VectorX
<
Scalar
>
m_
;
VectorX
<
Scalar
>
m_
;
// holds velocities and derivatives
// holds velocities and derivatives
VectorX
<
Scalar
>
d_state_
;
VectorX
<
Scalar
>
d_state_
;
};
};
//..................................................................................................
//..................................................................................................
NBodyLaw
::
NBodyLaw
()
{
void
NBodyLaw
::
resize
(
uint32_t
n
)
{
m_
.
resize
(
n
);
n_
=
n
;
d_state_
.
resize
(
2
*
n
*
d
);
m_
.
resize
(
n_
);
d_state_
.
resize
(
2
*
n_
*
d
);
}
}
//..................................................................................................
//..................................................................................................
VectorX
<
Scalar
>
const
&
NBodyLaw
::
operator
()(
VectorX
<
Scalar
>
const
&
state
)
{
VectorX
<
Scalar
>
const
&
NBodyLaw
::
operator
()(
VectorX
<
Scalar
>
const
&
state
)
{
// Copy in velocities
// Copy in velocities
d_state_
.
segment
<
n
*
d
>
(
0
)
=
state
.
segment
<
n
*
d
>
(
n
*
d
);
d_state_
.
segment
(
0
,
n_
*
d
)
=
state
.
segment
(
n_
*
d
,
n_
*
d
);
// Compute forces
// Compute forces
d_state_
.
segment
<
n
*
d
>
(
n
*
d
).
setZero
();
d_state_
.
segment
(
n_
*
d
,
n_
*
d
).
setZero
();
for
(
uint32_t
i
=
0
;
i
<
n
;
++
i
)
{
for
(
uint32_t
i
=
0
;
i
<
n
_
;
++
i
)
{
for
(
uint32_t
j
=
i
+
1
;
j
<
n
;
++
j
)
{
for
(
uint32_t
j
=
i
+
1
;
j
<
n
_
;
++
j
)
{
Eigen
::
Matrix
<
Scalar
,
d
,
1
>
force
=
state
.
segment
<
d
>
(
j
*
d
)
-
state
.
segment
<
d
>
(
i
*
d
);
Eigen
::
Matrix
<
Scalar
,
d
,
1
>
force
=
state
.
segment
<
d
>
(
j
*
d
)
-
state
.
segment
<
d
>
(
i
*
d
);
Scalar
const
distance_squared
=
force
.
squaredNorm
();
Scalar
const
distance_squared
=
force
.
squaredNorm
();
Scalar
const
distance
=
std
::
sqrt
(
distance_squared
);
Scalar
const
distance
=
std
::
sqrt
(
distance_squared
);
force
*=
G
/
(
distance_squared
*
distance
);
force
*=
G
/
(
distance_squared
*
distance
);
d_state_
.
segment
<
d
>
((
n
+
i
)
*
d
)
+=
m_
[
j
]
*
force
;
d_state_
.
segment
<
d
>
((
n
_
+
i
)
*
d
)
+=
m_
[
j
]
*
force
;
d_state_
.
segment
<
d
>
((
n
+
j
)
*
d
)
-=
m_
[
i
]
*
force
;
d_state_
.
segment
<
d
>
((
n
_
+
j
)
*
d
)
-=
m_
[
i
]
*
force
;
}
}
}
}
...
@@ -97,8 +121,8 @@ private:
...
@@ -97,8 +121,8 @@ private:
//..................................................................................................
//..................................................................................................
NBody
::
NBody
()
{
NBody
::
NBody
()
{
state_
.
resize
(
2
*
law_
.
n
*
law_
.
d
);
state_
.
resize
(
2
*
law_
.
n
()
*
law_
.
d
);
delta_t_
=
1e-
3
;
delta_t_
=
1e-
4
;
}
}
//..................................................................................................
//..................................................................................................
...
@@ -109,11 +133,11 @@ void NBody::initialize(
...
@@ -109,11 +133,11 @@ void NBody::initialize(
t_
=
0
;
t_
=
0
;
law_
.
set_masses
(
m
);
law_
.
set_masses
(
m
);
state_
=
state
;
state_
=
state
;
//state_.resize(2 * law_.n * law_.d);
//state_.resize(2 * law_.n
()
* law_.d);
//state_.segment(0, law_.n * law_.d) = x0;
//state_.segment(0, law_.n
()
* law_.d) = x0;
//state_.segment(law_.n * law_.d, law_.n * law_.d) = v0;
//state_.segment(law_.n
()
* law_.d, law_.n
()
* law_.d) = v0;
points_
.
resize
(
law_
.
n
*
law_
.
d
);
points_
.
resize
(
law_
.
n
()
*
law_
.
d
);
points_
=
state_
.
segment
(
0
,
law_
.
n
*
law_
.
d
);
points_
=
state_
.
segment
(
0
,
law_
.
n
()
*
law_
.
d
);
std
::
cout
<<
"state.size() = "
<<
state_
.
size
()
<<
'\n'
;
std
::
cout
<<
"state.size() = "
<<
state_
.
size
()
<<
'\n'
;
std
::
cout
<<
"points.size() = "
<<
points_
.
size
()
<<
'\n'
;
std
::
cout
<<
"points.size() = "
<<
points_
.
size
()
<<
'\n'
;
...
@@ -121,7 +145,7 @@ void NBody::initialize(
...
@@ -121,7 +145,7 @@ void NBody::initialize(
//..................................................................................................
//..................................................................................................
void
NBody
::
step
()
{
void
NBody
::
step
()
{
state_
=
euler
_step
(
state_
=
rk4
_step
(
[
this
](
Scalar
,
VectorX
<
Scalar
>
const
&
state
)
{
return
law_
(
state
);
},
[
this
](
Scalar
,
VectorX
<
Scalar
>
const
&
state
)
{
return
law_
(
state
);
},
t_
,
t_
,
state_
,
state_
,
...
@@ -130,21 +154,27 @@ void NBody::step() {
...
@@ -130,21 +154,27 @@ void NBody::step() {
t_
+=
delta_t_
;
t_
+=
delta_t_
;
// hack
// hack
points_
=
state_
.
segment
(
0
,
law_
.
n
*
law_
.
d
);
points_
=
state_
.
segment
(
0
,
law_
.
n
()
*
law_
.
d
);
}
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
int
main
()
{
int
main
()
{
VectorX
<
Scalar
>
masses
(
2
);
uint32_t
n_bodies
=
3
;
masses
[
0
]
=
1e3
;
// sun
VectorX
<
Scalar
>
masses
(
n_bodies
);
masses
[
0
]
=
1.5
;
// sun
masses
[
1
]
=
1
;
// earth
masses
[
1
]
=
1
;
// earth
VectorX
<
Scalar
>
initial_conditions
(
8
);
masses
[
2
]
=
0.2
;
// moon
Scalar
const
earth_v
=
-
1
;
VectorX
<
Scalar
>
initial_conditions
(
2
*
n_bodies
*
NBodyLaw
::
d
);
Scalar
const
sun_v
=
-
earth_v
*
masses
[
1
]
/
masses
[
0
];
Scalar
const
earth_v_y
=
-
0.3
;
Scalar
const
moon_v_x
=
0.3
;
Scalar
const
sun_v_y
=
-
earth_v_y
*
masses
[
1
]
/
masses
[
0
];
Scalar
const
sun_v_x
=
-
moon_v_x
*
masses
[
2
]
/
masses
[
0
];
initial_conditions
.
segment
<
2
>
(
0
)
=
Vector2
<
Scalar
>
(
0
,
0
);
// position of sun
initial_conditions
.
segment
<
2
>
(
0
)
=
Vector2
<
Scalar
>
(
0
,
0
);
// position of sun
initial_conditions
.
segment
<
2
>
(
2
)
=
Vector2
<
Scalar
>
(
1
,
0
);
// position of earth
initial_conditions
.
segment
<
2
>
(
2
)
=
Vector2
<
Scalar
>
(
1
,
0
);
// position of earth
initial_conditions
.
segment
<
2
>
(
4
)
=
Vector2
<
Scalar
>
(
0
,
sun_v
);
// velocity of sun
initial_conditions
.
segment
<
2
>
(
4
)
=
Vector2
<
Scalar
>
(
0
,
0.8
);
// position of moon
initial_conditions
.
segment
<
2
>
(
6
)
=
Vector2
<
Scalar
>
(
0
,
earth_v
);
// velocity of earth
initial_conditions
.
segment
<
2
>
(
6
)
=
Vector2
<
Scalar
>
(
sun_v_x
,
sun_v_y
);
// velocity of sun
initial_conditions
.
segment
<
2
>
(
8
)
=
Vector2
<
Scalar
>
(
0
,
earth_v_y
);
// velocity of earth
initial_conditions
.
segment
<
2
>
(
10
)
=
Vector2
<
Scalar
>
(
moon_v_x
,
0
);
// velocity of moon
NBody
nbody
;
NBody
nbody
;
nbody
.
initialize
(
masses
,
initial_conditions
);
nbody
.
initialize
(
masses
,
initial_conditions
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment