-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmass_spring.hpp
87 lines (68 loc) · 2.39 KB
/
mass_spring.hpp
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
/**
* @file mass_spring.hpp
* Implementation of mass-spring system using Graph
*/
#include <fstream>
#include <chrono>
#include <thread>
#include "CME212/Util.hpp"
#include "CME212/Color.hpp"
#include "CME212/Point.hpp"
#include "Graph.hpp"
// Gravity in meters/sec^2
static constexpr double grav = 9.81;
/** Custom structure of data to store with Nodes */
struct NodeData {
Point vel; //< Node velocity
double mass; //< Node mass
NodeData() : vel(0), mass(1) {}
};
// Define the Graph type
using GraphType = Graph<NodeData>;
using Node = typename GraphType::node_type;
using Edge = typename GraphType::edge_type;
/** Change a graph's nodes according to a step of the symplectic Euler
* method with the given node force.
* @param[in,out] g Graph
* @param[in] t The current time (useful for time-dependent forces)
* @param[in] dt The time step
* @param[in] force Function object defining the force per node
* @return the next time step (usually @a t + @a dt)
*
* @tparam G::node_value_type supports ???????? YOU CHOOSE
* @tparam F is a function object called as @a force(n, @a t),
* where n is a node of the graph and @a t is the current time.
* @a force must return a Point representing the force vector on
* Node n at time @a t.
*/
template <typename G, typename F>
double symp_euler_step(G& g, double t, double dt, F force) {
// Compute the t+dt position
for (auto it = g.node_begin(); it != g.node_end(); ++it) {
auto n = *it;
// Update the position of the node according to its velocity
// x^{n+1} = x^{n} + v^{n} * dt
n.position() += n.value().vel * dt;
}
// Compute the t+dt velocity
for (auto it = g.node_begin(); it != g.node_end(); ++it) {
auto n = *it;
// v^{n+1} = v^{n} + F(x^{n+1},t) * dt / m
n.value().vel += force(n, t) * (dt / n.value().mass);
}
return t + dt;
}
/** Force function object for HW2 #1. */
struct Problem1Force {
/** Return the force applying to @a n at time @a t.
*
* For HW2 #1, this is a combination of mass-spring force and gravity,
* except that points at (0, 0, 0) and (1, 0, 0) never move. We can
* model that by returning a zero-valued force. */
template <typename NODE>
Point operator()(NODE n, double t) {
// HW2 #1: YOUR CODE HERE
(void) n; (void) t; (void) grav; // silence compiler warnings
return Point(0);
}
};