/ proof-of-concept / plate-mechanics-sim
Sign in
proof-of-concept / plate-mechanics-sim
plate-mechanics-sim / packages / core / src / m / plate_fd_plan.m
42 lines · 2.0 KBBlameHistoryRaw
1function plan = plate_fd_plan(params)
2% PLATE_FD_PLAN Grid, time step and cost of the explicit finite-difference scheme.
3%
4% plan = plate_fd_plan(params) returns
5% plan.nx, plan.ny, plan.dx, plan.dy grid (nodes include the edges)
6% plan.dt_max largest stable time step [s]
7% plan.dt step actually used, params.fd.cfl * dt_max
8% plan.nsteps, plan.ncells, plan.cell_steps problem size
9%
10% Stability. Von Neumann analysis of the scheme in plate_fd for a Fourier
11% mode on which the discrete Laplacian has eigenvalue -lambda gives the
12% amplification polynomial
13% (1 + sigma0 dt) z^2 - (2 - dt^2 kappa^2 lambda^2 - 2 sigma1 dt lambda) z
14% + (1 - sigma0 dt - 2 sigma1 dt lambda) = 0.
15% Both roots stay inside the unit circle for every lambda up to the largest
16% eigenvalue of the five-point Laplacian, lambda_max = 4/dx^2 + 4/dy^2, iff
17% dt <= 2 / ( lambda_max (sigma1 + sqrt(kappa^2 + sigma1^2)) ),
18% which for a square grid without sigma1 is the familiar dt <= dx^2 / (4 kappa).
19% Because dt scales with dx^2, halving the grid spacing costs eight times
20% as many cell updates for the same simulated time.
22% The same bound serves the free plate: the largest eigenvalue of its
23% energy-method operator M \ K (plate_matrices) lies just below lambda_max^2
24% (about 0.97 to 0.99 of it on the grids used here), so the step is safe and
25% slightly conservative there.
27P = plate_setup(params);
28plan.nx = P.fd.nx;
29plan.ny = P.fd.ny;
30if plan.nx < 5 || plan.ny < 5
31 error('plate_fd_plan: the grid needs at least 5 nodes in each direction');
32end
33plan.dx = P.plate.Lx / (plan.nx - 1);
34plan.dy = P.plate.Ly / (plan.ny - 1);
35lambda_max = 4 / plan.dx^2 + 4 / plan.dy^2;
36s1 = P.damping.sigma1;
37plan.dt_max = 2 / (lambda_max * (s1 + sqrt(P.kappa^2 + s1^2)));
38plan.dt = P.fd.cfl * plan.dt_max;
39plan.nsteps = ceil(P.fd.duration / plan.dt);
40plan.ncells = plan.nx * plan.ny;
41plan.cell_steps = plan.ncells * plan.nsteps;
42end
↑↓ move↵openescclose