Assignment 2
Table of Contents
- 1 Compute the deformation gradient \(\mathbf{F}\)
- 2 Compute the first Piola-Kirchhoff stress tensor \(\mathbf{P}(\mathbf{F})\)
- 3 Compute forces
- 4 Compute symplectic Euler time integration
- 5 Testing your implementation
- 6 Optional extras
- 7 Submission
In this assignment, you will implement a simulator for a 2D deformable Gingerman, with three types of constitutive models.
You are provided with a GUI system, with the following modes and controls already implemented. Make sure you play with the starter code to get familiar with these controls.
Run python3 fem_starter.py
and you should see an interface, with a Gingerman displayed at the center.
By default, the GUI window is set to size 600 by 600. Do NOT resize the window if you are using a Mac, since this will mess up the mouse cursor detection in Taichi GGUI, due to potential clamping of the window display on the screen. However, window resizing is fine on Ubuntu. We have not tested on Windows machines, so please let us know if it works.
The system has two modes, namely, the Edit Mode and the Simulation Mode.
In the Edit Mode, you use mouse clicks to toggle the vertices to be pinned in the simulation. A mouse click either adds the closest vertex to the list of pinned vertices, or removes it from the list if it is pinned.
In the Simulation Mode, you use mouse drags to create spring-like forces on the vertices of the object, which result in deformations of the object. The mouse drag only exerts a spring force on a single vertex that is closest to the starting cursor position of the mouse drag, and the strength of the force should be proportional to the distance between the starting and ending cursor positions of the drag. Once a mouse drag is initiated, a red arrow is displayed to indicate the vertex to be acted upon, as well as the magnitude and direction of the drag, and the arrow disappears upon releasing the mouse. The spring force persists throughout the mouse drag motion, and vanishes upon releasing the mouse.
The key/mouse controls are as follows:
- ‘C’/‘V’/‘N’: Switch between different constitute models (Corotated linear/St. Venant-Kirchhoff/Neo-Hookean). Note that switching to a different constitutive model would re-initialize the positions and velocities of the object (i.e. reset to initial state).
- ‘M’: Switch between edit mode and simulation mode (default is edit mode)
- ‘R’: When pressed in edit mode, removes all pins; in simulation mode, re-initialize the positions and velocities of the object
- ‘D’: Toggle damping (default is no damping)
- ‘SPACE’: Toggle simulation state. By default, the simulation is paused, i.e. no time integration function is called.
- Left mouse button down (in edit mode): Adds/Removes pin on the vertex that is closest to the cursor position
- Left mouse button down and drag (in simulation mode): Creates a spring force along the mouse drag direction with magnitude proportional to the amount of mouse drag that exerts on a single vertex closest to the cursor position when the left mouse button pressed. Only one spring force is active at a time, i.e. the previous force is removed when a new force is created on an arbitrary vertex.
Now go ahead and make the gingerman move!
1 Compute the deformation gradient \(\mathbf{F}\)
The first step is simple: Use the formula from class to compute the deformation gradient. You are already provided with a vector x that contains the vertex positions, and a vector of triangles (finite elements) where each entry is a tuple containing the indices of the three vertices composing a face. Simply write two functions, one that computes the \(\mathbf{D}\) (or \(\mathbf{D}_0\), when called by the initial state) of each element, the other computes \(\mathbf{F}\) using the formula from class. Note that everything is in 2D, as what has been illustrated in class.
2 Compute the first Piola-Kirchhoff stress tensor \(\mathbf{P}(\mathbf{F})\)
Now you will compute \(\mathbf{P}(\mathbf{F})=\frac{\partial\psi(\mathbf{F})}{\partial \mathbf{F}}\) for three constitutive models, namely, the corotated linear model, the St. Venant-Kirchhoff (StVK) model, and the Neo-Hookean model. The value of ModelSelector[None]=0/1/2
tracks the current model being used.
The first two calculations are provided in the course notes.
We provide the first Piola-Kirchhoff tensor for the Neo-Hookean model, so you do not need to derive the chain rule by hand:
\[\mathbf{P}(\mathbf{F}) = \mu*(\mathbf{F}-\mathbf{F}^{-T})+\lambda*\ln{(\det(\mathbf{F}))}*\mathbf{F}^{-T}\]
Additionally, you will need to create fields for the Lame parameters \(\lambda\) and \(\mu\), and compute them from the Young’s Modulus and Poisson’s Ratio.
3 Compute forces
Now you will compute the forces exerted on each element/triangle (denoted by \(e\)), and map to forces exerted on the three vertices of the element.
\[\mathbf{f}_i=-\frac{\partial U}{\partial\mathbf{x}_i}=-\sum_e A_e\frac{\partial\psi(\mathbf{F}_e)}{\partial \mathbf{F}_e}\frac{\partial\mathbf{F}_e}{\partial\mathbf{x}_i}=-\sum_e A_e\mathbf{P}(\mathbf{F}_e)\frac{\partial\mathbf{F}_e}{\partial\mathbf{x}_i}\]
There are two parts that you need to figure out, in addition to transcribing the formula (both are very easy to derive from previous steps!)
- What is \(\frac{\partial\mathbf{F}_e}{\partial\mathbf{x}_i}\)?
- What is \(A_e\)?
4 Compute symplectic Euler time integration
This part is very similar to the cloth simulation in PA1. In addition to the forces computed from the previous step, you will need to account for the vertices with pinned positions, as well as the vertex where spring force is applied. In addition, the object movement is bounded by the four edges of the GUI, i.e. at every time step, you should detect if any vertex goes beyond the boundary, and project it onto the boundary.
The damping is simple: At each time step, multiply the velocity by a scaling factor close to 1 (e.g. 0.99).
This video shows the target behavior of the simulator, with time steps of 0.167 milliseconds. Note that your simulation result might not exactly match the video, due to different scaling parameters causing the magnitudes in the forces to differ. The behavior should agree though, i.e. a handle-based force should exhibit in the mouse drag direction.
Once you finish implementing the simulator, you should switch between the three different constitutive models, observe their differences, and report your findings. You are also encouraged to create sliders for the Young’s modulus and Poisson’s ratio (with appropriate ranges) and play with different values of these parameters. Note that for the changes in parameters to take effect, you should also update the Lame coefficients correspondingly.
5 Testing your implementation
To test your implementation, we provide a simple test scenario of stretching/compressing a rectangle in the alternate starter code fem_test_starter.py
. Here, the vertices of the rest shape are stored in x_rest
, and the vertices of the compressed/stretched shapes are stored in x_compress
and x_stretch
, which get assigned to the field storing the deformed vertex positions x
. The top and bottom edges are pinned, i.e. in the compressed mode, the top edge are fixed at 0.6 times the rectangle’s original height, and in the stretched mode, twice the original height. For calculating \(F\), you will need \(D_0\) from the rest shape \(x_rest\) and \(D\) from the deformed shape \(x\). If you plug your implementation into this starter code, you will be able to see a clear difference in the three models under the stretched/compressed settings that should match this video. Pressing the UP/DOWN arrow keys switches between the stretched/compressed shapes.
6 Optional extras
For a modest amount of extra credit, do something cool with this system that we didn’t specify! Some ideas:
- Self-collision of the object
- Extend to 3D
- More complex models and interesting behaviors
7 Submission
You need to include two things in your submission:
- A pdf file including a link to the chosen commit for your submission, as well as your observation of the different constitutive models and model parameters.
- A demo video demonstrating the functionalities of your simulators (please make sure that we can easily run your code and generate similar results shown in the demo).