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.
22P = plate_setup(params);
23plan.nx = P.fd.nx;
24plan.ny = P.fd.ny;
25if plan.nx < 5 || plan.ny < 5
26 error('plate_fd_plan: the grid needs at least 5 nodes in each direction');
27end
28plan.dx = P.plate.Lx / (plan.nx - 1);
29plan.dy = P.plate.Ly / (plan.ny - 1);
30lambda_max = 4 / plan.dx^2 + 4 / plan.dy^2;
31s1 = P.damping.sigma1;
32plan.dt_max = 2 / (lambda_max * (s1 + sqrt(P.kappa^2 + s1^2)));
33plan.dt = P.fd.cfl * plan.dt_max;
34plan.nsteps = ceil(P.fd.duration / plan.dt);
35plan.ncells = plan.nx * plan.ny;
36plan.cell_steps = plan.ncells * plan.nsteps;
37end