source: CIVL/examples/accuracy/diffusion.cvl@ bb03188

main test-branch
Last change on this file since bb03188 was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 2.3 KB
Line 
1/* 1-dimension diffusion equation solver with constant boundaries.
2 * Accuracy is first-order in time and second order in space.
3 * To verify with CIVL, type:
4 * civl verify diffusion.cvl
5 */
6
7$input int n; // number of discrete spatial points
8$assume(n >= 1);
9$input double dx; // distance between two consecutive points
10$assume(0<dx && dx<1);
11$input double dt; // duration of one time step
12$assume(0<dt && dt<1);
13$input double k; // diffusivity constant
14$assume(k > 0);
15$input double u_init[n]; // initial temperatures
16// assume u:R^2->R has 4 continuous derivatives in [-1,1]x[0,100]:
17$abstract $differentiable(4, [-1,1][0,100]) $real u($real x, $real t);
18$input int step; // some arbitrary time step
19$assume(step >= 0);
20double v[n]; // values at this time step
21double v_new[n]; // values at next time step
22
23/* Updates the array v. The new values of v are computed from the old
24 * values of v, and the constants dt, dx, and k.
25 */
26void update() {
27 // compute the new values in v_new:
28 /*@ loop invariant 1<=i && i<=n-1;
29 @ loop invariant $forall (int j:1..i-1)
30 @ v_new[j] == v[j] + dt*k*(v[j+1] - 2*v[j] + v[j-1])/(dx*dx);
31 @ loop assigns i, v_new[1..n-2];
32 @*/
33 for (int i=1; i<n-1; i++) {
34 v_new[i] = v[i] + dt*k*(v[i+1] - 2*v[i] + v[i-1])/(dx*dx);
35 }
36 // copy v_new back to v:
37 /*@ loop invariant 1<=i && i<=n-1;
38 @ loop invariant $forall (int j:1..i-1) v[j] == v_new[j];
39 @ loop assigns i, v[1..n-2];
40 @*/
41 for (int i=1; i<n-1; i++) {
42 v[i] = v_new[i];
43 }
44}
45
46/* This main function is the driver.
47 * The annotations assume v[i] is exactly u(i*dx,step*dt) just before
48 * updating, and claim that the new v[i] is a very good approximation to
49 * u(i*dx,(step+1)*dt). Specifically, the approximation is
50 * O(dt)+O(dx^2) accurate in the interior spatial region. (The endpoints
51 * are held constant.)
52 */
53void main() {
54 /*@ loop invariant 0<=i && i<=n;
55 @ loop invariant $forall (int j:0..i-1) v[j] == u_init[j];
56 @ loop assigns i, v[0..n-1];
57 @*/
58 for (int i = 0; i < n; i++) {
59 v[i] = u_init[i];
60 }
61 $assume(n*dx < 1);
62 $assume(step*dt < 100);
63 $assume($forall (int i=0..n-1) v[i] == u(i*dx, step*dt));
64 update();
65 $assert($uniform (int i=1..n-2)
66 (u(i*dx, (step+1)*dt) - v[i])/dt - $D[u,{t,1}](i*dx, step*dt) + k*$D[u,{x,2}](i*dx, step*dt)
67 == $O(dt) + $O(dx*dx));
68}
Note: See TracBrowser for help on using the repository browser.