changeset 21:4c5bac1f2612

Testing Euler's method
author Jordi Gutiérrez Hermoso <jordigh@gmail.com>
date Fri, 12 Sep 2008 11:13:18 -0500
parents 9cd42f1be76e
children 532145a38fa2
files Makefile data/sw_eqs_init.m main-sw-rk4.cpp main.cpp results/plotresults.m results/plotresults_vtk.m
diffstat 6 files changed, 214 insertions(+), 225 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,9 @@
 CPP = g++
-LINKING = -lgsl -lgslcblas  
+LINKING = -lgsl -lgslcblas -static
 CFLAGS = -O3
 OPTIONS = -Wall -pedantic  -W -Werror -Wconversion -Wshadow \
 	  -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings  \
-	  -fshort-enums -fno-common -Wfatal-errors 
+	  -fshort-enums -fno-common -Wfatal-errors -static
 OBJECTFILES = interpolator.o linalg.o error.o utils.o rbf.o bvp.o \
 	      diff_op.o ddm.o func.o main.o interp_values.o
 HEADERFILES = include/linalg.hpp include/error.hpp include/utils.hpp \
--- a/data/sw_eqs_init.m
+++ b/data/sw_eqs_init.m
@@ -1,5 +1,5 @@
-n = 15
-m = 12;
+n = 20
+m = 6;
 r = linspace(0,1,n);
 
 rrintr = 0;
--- a/main-sw-rk4.cpp
+++ b/main-sw-rk4.cpp
@@ -3,7 +3,7 @@
 #include <map>
 #include <set>
 #include <sstream>
-
+ 
 #include <boost/shared_ptr.hpp>
 
 #include "include/linalg.hpp"
@@ -35,8 +35,10 @@
 
 const double g = 9.8; // m/s^2
 
+const double pi = 3.141592653589793238462643383279502;
+
 template<typename RBF>
-class Fgen : public realfunc{
+class Fgen {
 public:
   void set_interps(const interpolator<RBF>& u0, 
 		   const interpolator<RBF>& v0,
@@ -59,7 +61,7 @@
   using Fgen<RBF>::h;
   using Fgen<RBF>::dt;
 public:
-  double at(const point& p) const;
+  bvp::interp_values at() const;
 };
 
 template<typename RBF>
@@ -69,7 +71,7 @@
   using Fgen<RBF>::h;
   using Fgen<RBF>::dt;
 public:
-  double at(const point& p) const;
+  bvp::interp_values at() const;
 };
 
 template<typename RBF>
@@ -79,32 +81,7 @@
   using Fgen<RBF>::h;
   using Fgen<RBF>::dt;
 public:
-  double at(const point& p) const;
-};
-
-class iter_neumann : public bdry_diff_op{
-public:
-  //If this is u's, set 1, for v, set 2.
-  iter_neumann(size_t u_or_v_in);
-  double at(const realfunc &f, const point &p, const vector &n) const;
-private:
-  size_t u_or_v;
-  double at(const realfunc &f, const point &p) const {return f(p);};
-};
-
-template<typename RBF>
-class Gu_or_v : public realfunc{
-public:
-  //specify the OTHER, whether u or v.
-  Gu_or_v(size_t u_or_v_in, 
-	  const shared_ptr<domain> Omega_in) : u_or_v(u_or_v_in),
-					       Omega(Omega_in) {};
-  double at(const point& p) const;
-  void set_other(const interpolator<RBF>& other_in){other = other_in;};
-private:
-  size_t u_or_v;
-  const shared_ptr<domain> Omega;
-  interpolator<RBF> other;
+  bvp::interp_values at() const;
 };
 
 class zero_func : public realfunc{
@@ -120,8 +97,7 @@
 		 size_t n, string which_interp);
 
 template<typename RBF>
-void bdry_iter(interpolator<RBF> &u, interpolator<RBF> &v, 
-	       const boost::shared_ptr<domain> Omega);
+void set_bdry_conds(interpolator<RBF> &u, interpolator<RBF> &v);
 
 
 //********************** Main ******************************************
@@ -132,7 +108,7 @@
   try{
     using namespace std;
     using boost::shared_ptr;
-    
+   
     map<point, double> h_init = utils::read_pd_map("data/h_init.map");
       
     shared_ptr<domain> Omega(new domain("data/circ_intr.matrix",
@@ -140,115 +116,119 @@
 					"data/circ_nrml.matrix"));
 
     shared_ptr<Id_op> I(new Id_op);
-    shared_ptr<iter_neumann> 
-      u_bdry_op(new iter_neumann(1)), 
-      v_bdry_op(new iter_neumann(2));
+    shared_ptr<dirichlet_op> D(new dirichlet_op);
     zero_func Z;
+    //FIXME: Turns this into a purely interpolating interpolator,
+    //without a BVP.
     shared_ptr<linear_BVP2> 
-      u_bvp_init(new linear_BVP2(Omega, I, u_bdry_op, Z, Z)),
-      v_bvp_init(new linear_BVP2(Omega, I, v_bdry_op, Z, Z));
+      u_bvp_init(new linear_BVP2(Omega, I, D, Z, Z)),
+      v_bvp_init(new linear_BVP2(Omega, I, D, Z, Z));
       
-   
-    double dt = 1e-2;
-
+    
     //init the interps.
     using namespace rbf;
-    conical::set_n(5); thin_plate_spline::set_n(6); 
+    conical::set_n(7); thin_plate_spline::set_n(6); 
     c_infty_rbf::set_epsilon(0.01);
 
     cout << "Initialising... please wait." << endl;
 
     interpolator<RBF_TYPE> 
-      u1, u0(u_bvp_init), 
-      v1, v0(v_bvp_init), 
-      h1, h0(Omega, h_init);
-    u1 = u0; v1 = v0; h1 = h0;
+      u0(u_bvp_init), 
+      v0(v_bvp_init), 
+      h0(Omega, h_init);
+
+    //Precompute some RBFs
+    u0.precompute_ev(); v0.precompute_ev(), h0.precompute_ev();
+    u0.precompute_d1(); v0.precompute_d1(), h0.precompute_d1();
 
     //Intermediate interpolators for RK4
     std::vector<interpolator<RBF_TYPE> >
-      k1(3,h0), k2(3,h0), k3(3,h0), k4(3,h0);
+      // FIXME: make the copy ctor for interps make different copies
+      // of the bvp.
+      k1(3,h0), k2(3,h0), k3(3,h0), k4(3,h0); 
 
     Fu<RBF_TYPE> f_u;
     Fv<RBF_TYPE> f_v;
     Fh<RBF_TYPE> f_h;
 
+    //Negative because of the way the F's below are written.
+    double dt = -0.01;
+
     f_u.set_dt(dt);
     f_v.set_dt(dt);
     f_h.set_dt(dt);
 
-    //main loop
-    size_t maxiter = 3;
+    //main loop, timestepping with RK4.
+    size_t maxiter = 5;
     for(size_t i = 1; i <= maxiter; i++){ 
       cout << "Now on iteration #" << i << endl;
       if(i % 1 == 0){
-	save_interp(Omega,u0,i,"u");
-	save_interp(Omega,v0,i,"v");
-	save_interp(Omega,h0,i,"h");
+ 	save_interp(Omega,u0,i,"u");
+ 	save_interp(Omega,v0,i,"v");
+ 	save_interp(Omega,h0,i,"h");
       }
 
       //k1 
       f_u.set_interps(u0,v0,h0);
       f_v.set_interps(u0,v0,h0);
       f_h.set_interps(u0,v0,h0);
+
+      k1[0].interpolate(f_u.at());
+      k1[1].interpolate(f_v.at());
+      k1[2].interpolate(f_h.at());
+
+      set_bdry_conds(k1[0],k1[1]);
       
-      //debug
-      k1[0].set_f(f_u);
-      cout << "Finished k1[0]" << endl;
-      k1[1].set_f(f_v);
-      cout << "Finished k1[1]" << endl;
-      k1[2].set_f(f_h);
-      cout << "Finished k1[2]" << endl;
+      cout << "k1 done!" << endl;
 
-      bdry_iter(k1[0],k1[1],Omega);
+      //debug Euler
+      u0 = k1[0]; v0 = k1[1]; h0 = k1[2]; continue;
            
       //k2
       f_u.set_interps(u0+(k1[0]/2), v0+(k1[1]/2), h0+(k1[2]/2));
       f_v.set_interps(u0+(k1[0]/2), v0+(k1[1]/2), h0+(k1[2]/2));
       f_h.set_interps(u0+(k1[0]/2), v0+(k1[1]/2), h0+(k1[2]/2));
+
+      k2[0].interpolate(f_u.at());
+      k2[1].interpolate(f_v.at());
+      k2[2].interpolate(f_h.at());
  
-      //debug
-      k2[0].set_f(f_u);
-      cout << "Finished k2[0]" << endl;
-      k2[1].set_f(f_v);
-      cout << "Finished k2[1]" << endl;
-      k2[2].set_f(f_h);
-      cout << "Finished k2[2]" << endl;
+      set_bdry_conds(k2[0],k2[1]);
 
-      bdry_iter(k2[0],k2[1],Omega);
+      cout << "k2 done!" << endl;
 
       //k3      
       f_u.set_interps(u0+(k2[0]/2), v0+(k2[1]/2), h0+(k2[2]/2));
       f_v.set_interps(u0+(k2[0]/2), v0+(k2[1]/2), h0+(k2[2]/2));
       f_h.set_interps(u0+(k2[0]/2), v0+(k2[1]/2), h0+(k2[2]/2));
+
+      k3[0].interpolate(f_u.at());
+      k3[1].interpolate(f_v.at());
+      k3[2].interpolate(f_h.at());
       
-      k3[0].set_f(f_u);
-      k3[1].set_f(f_v);
-      k3[2].set_f(f_h);
-
-      bdry_iter(k3[0],k3[1],Omega);
+      set_bdry_conds(k3[0],k3[1]);
+      
+      cout << "k3 done!" << endl;
 
       //k4
       f_u.set_interps(u0+k3[0], v0+k3[1], h0+k3[2]);
       f_v.set_interps(u0+k3[0], v0+k3[1], h0+k3[2]);
       f_h.set_interps(u0+k3[0], v0+k3[1], h0+k3[2]);
+
+      k4[0].interpolate(f_u.at());
+      k4[1].interpolate(f_v.at());
+      k4[2].interpolate(f_h.at());
       
-      k4[0].set_f(f_u);
-      k4[1].set_f(f_v);
-      k4[2].set_f(f_h);
+      set_bdry_conds(k4[0],k4[1]);
 
-      bdry_iter(k4[0],k4[1],Omega);
+      cout << "k4 done!" << endl;
      
       //Grand finale
-      u1.set_f(u0 + (k1[0] + 2*k2[0] + 2*k3[0] + k4[0])/6);
-      v1.set_f(v0 + (k1[1] + 2*k2[1] + 2*k3[1] + k4[1])/6);
-      h1.set_f(h0 + (k1[2] + 2*k2[2] + 2*k3[2] + k4[2])/6);
-     
-      //Enforce boundary conditions iteratively
-      bdry_iter(u1,v1,Omega);
-      
-      u0 = u1;
-      v0 = v1;
-      h0 = h1;
+      u0.interpolate((u0 + (k1[0] + 2*k2[0] + 2*k3[0] + k4[0])/6).at());
+      v0.interpolate((v0 + (k1[1] + 2*k2[1] + 2*k3[1] + k4[1])/6).at());
+      h0.interpolate((h0 + (k1[2] + 2*k2[2] + 2*k3[2] + k4[2])/6).at());
+
+      set_bdry_conds(u0,v0);
     }
 
     return 0;
@@ -297,54 +277,32 @@
 
 
 template<typename RBF>
-double Fu<RBF>::at(const point& p) const
+interp_values Fu<RBF>::at() const
 {
-  return   dt*(u(p)*u.d(p,1) +  v(p)*u.d(p,2) +  g*h.d(p,1));
-}
-
-template<typename RBF>
-double Fv<RBF>::at(const point& p) const
-{
-  return   dt*(u(p)*v.d(p,1) +  v(p)*v.d(p,2) +  g*h.d(p,2));
+  return   dt*(u()*u.d(1) +  v()*u.d(2) +  g*h.d(1));
 }
 
 template<typename RBF>
-double Fh<RBF>::at(const point& p) const
-{
-  return   dt*(u(p)*h.d(p,1) + h(p)*u.d(p,1) +   v(p)*h.d(p,2) + h(p)*v.d(p,2));
-}
-
-iter_neumann::iter_neumann(size_t u_or_v_in)
+interp_values Fv<RBF>::at() const
 {
-  if(u_or_v_in < 1 or u_or_v_in > 2){
-    error_handling::badArgument exc;
-    exc.reason = "Argument to iter_neumann constructor must be 1 or 2";
-    exc.line = __LINE__;
-    exc.file = __FILE__;
-    throw exc;
-  }
-  u_or_v = u_or_v_in;
-}
-
-double iter_neumann::at(const realfunc &f, const point &p, 
-			const vector &n) const
-{
-  return n(u_or_v)*f(p);
+  return   dt*(u()*v.d(1) 
+	       +  v()*v.d(2) 
+	       +  g*h.d(2));
 }
 
 template<typename RBF>
-double Gu_or_v<RBF>::at(const point& p) const
+interp_values Fh<RBF>::at() const
 {
-  point n = Omega -> get_normals().at(p);
-  return -n(u_or_v)*other(p);
+  return   dt*(u()*h.d(1) + h()*u.d(1) +   v()*h.d(2) + h()*v.d(2));
 }
-
-
+ 
 template<typename RBF>
 void save_interp(const shared_ptr<domain> Omega, 
 		 const interpolator<RBF>& u, 
 		 size_t n, string which_interp)
 {
+
+
   using namespace std;
   string filename = "results/" + which_interp;
   if(n < 10000)
@@ -361,63 +319,63 @@
   ss >> n_string;
   filename += n_string + ".map";
   ofstream ofs(filename.c_str());
+    
+  {
+    slice s(1,2);
+    matrix M(Omega -> get_interior().size() +
+	     Omega -> get_boundary().size(), 3);
+    size_t k = 1;
+    for(set<point>::const_iterator i = Omega -> get_interior().begin();
+	i != Omega -> get_interior().end(); i++){
+      M(k,s) = *i;
+      M(k,3) = u(*i);
+      k++;
+    }
+    for(set<point>::const_iterator i = Omega -> get_boundary().begin();
+	i != Omega -> get_boundary().end(); i++){
+      M(k,s) = *i;
+      M(k,3) = u(*i);
+      k++;
+    }
+    ofs << M;
+  }
 
-  slice s(1,2);
-  matrix M(Omega -> get_interior().size() +
-	   Omega -> get_boundary().size(), 3);
-  size_t k = 1;
-  for(set<point>::const_iterator i = Omega -> get_interior().begin();
-      i != Omega -> get_interior().end(); i++){
-    M(k,s) = *i;
-    M(k,3) = u(*i);
-    k++;
-  }
-  for(set<point>::const_iterator i = Omega -> get_boundary().begin();
-      i != Omega -> get_boundary().end(); i++){
-    M(k,s) = *i;
-    M(k,3) = u(*i);
-    k++;
-  }
-  ofs << M;
+
+  if(false){ //debug
+    double r, th, N, M;
+    N = 30; M  = 70;
+    linalg::matrix out(static_cast<size_t>(N),static_cast<size_t>(M));
+    size_t i,j;
+    for(r = 0, j=1;  j <= N; r += 1/(N-1),j++){
+      for(th = 0,i=1; i <= M; th += 2*pi/(M-1),i++){
+	linalg::vector p(2); 
+	p(1) = r*cos(th); 
+	p(2) = r*sin(th);
+	out(j,i) = u(p);
+      }
+    }
+  
+    ofs << out;
+  }//debug
 }
 
+
 template<typename RBF>
-linalg::vector at_bdry(const interpolator<RBF>& u,
-		       const boost::shared_ptr<domain> Omega)
+void set_bdry_conds(interpolator<RBF> & u, interpolator<RBF> & v)
 {
-  using namespace linalg;
-
-  vector out(Omega -> get_boundary().size());
-  std::set<point>::const_iterator I = Omega -> get_boundary().begin();
-
-  for(size_t i = 1; i <= out.size(); i++){
-    out(i) = u(*I);
-    I++;
+  bvp::bdry_values u_bdry(u.at()), v_bdry(v.at());
+  bvp::normals N=u.get_normals(), M=v.get_normals();
+  if(N != M){
+    failure exc;
+    exc.reason="u and v have incompatible domains. This should never"
+      " happen.";
+    exc.line=__LINE__; exc.file=__FILE__; throw exc;
   }
 
-  return out;
+  //Project the vector (u,v) onto the perp of (N(1),N(2)) = (-N(2),N(1)).
+  bvp::bdry_values u_bdry_new = u_bdry*N(2)*N(2) - v_bdry*N(1)*N(2);
+  bvp::bdry_values v_bdry_new = v_bdry*N(1)*N(1) - u_bdry*N(1)*N(2);
+  
+  u.set_bdry_values(u_bdry_new);
+  v.set_bdry_values(v_bdry_new);
 }
-
-template<typename RBF>
-void bdry_iter(interpolator<RBF> &u, interpolator<RBF> &v, 
-	       const boost::shared_ptr<domain> Omega)
-{
-  Gu_or_v<RBF_TYPE> gu(2, Omega), gv(1, Omega);
-  double err = 1;
-  do{    
-    linalg::vector u_old, u_new, v_old, v_new;
-    u_old = at_bdry(u,Omega);
-    gu.set_other(v);
-    u.set_g(gu);
-    u_new = at_bdry(u,Omega);
-
-    v_old = at_bdry(v,Omega);
-    gv.set_other(u);
-    v.set_g(gv);
-    v_new = at_bdry(v,Omega);
-    
-    double err_u = norm(u_new - u_old);
-    double err_v = norm(v_new - v_old);
-    err = (err_u > err_v? err_u : err_v);
-  }while(err > 1e-2);
-}
--- a/main.cpp
+++ b/main.cpp
@@ -1,4 +1,5 @@
 #include <iostream>
+#include <iomanip>
 #include <fstream>
 #include <map>
 #include <set>
@@ -18,7 +19,7 @@
 using namespace linalg;
 using namespace bvp;
 
-#define RBF_TYPE rbf::thin_plate_spline
+#define RBF_TYPE rbf::conical
 
 //Will solve the system
 //
@@ -35,6 +36,8 @@
 
 const double g = 9.8; // m/s^2
 
+const double pi = 3.141592653589793238462643383279502;
+
 template<typename RBF>
 class Fgen {
 public:
@@ -125,8 +128,8 @@
     
     //init the interps.
     using namespace rbf;
-    conical::set_n(5); thin_plate_spline::set_n(6); 
-    c_infty_rbf::set_epsilon(10);
+    conical::set_n(7); thin_plate_spline::set_n(6); 
+    c_infty_rbf::set_epsilon(0.01);
 
     cout << "Initialising... please wait." << endl;
 
@@ -143,27 +146,30 @@
     std::vector<interpolator<RBF_TYPE> >
       // FIXME: make the copy ctor for interps make different copies
       // of the bvp.
-      k1(3,h0), k2(3,h0), k3(3,h0), k4(3,h0); 
+      k1(3,u0), k2(3,u0), k3(3,u0), k4(3,u0); 
+
+    //debug
+    cout << "Size of interpolator is " << sizeof(k1[0]) << endl;
 
     Fu<RBF_TYPE> f_u;
     Fv<RBF_TYPE> f_v;
     Fh<RBF_TYPE> f_h;
 
     //Negative because of the way the F's below are written.
-    double dt = -0.01;
+    double dt = -0.0001;
 
     f_u.set_dt(dt);
     f_v.set_dt(dt);
     f_h.set_dt(dt);
 
     //main loop, timestepping with RK4.
-    size_t maxiter = 1000;
+    size_t maxiter = 5000;
     for(size_t i = 1; i <= maxiter; i++){ 
       cout << "Now on iteration #" << i << endl;
       if(i % 1 == 0){
-	save_interp(Omega,u0,i,"u");
-	save_interp(Omega,v0,i,"v");
-	save_interp(Omega,h0,i,"h");
+ 	save_interp(Omega,u0,i,"u");
+ 	save_interp(Omega,v0,i,"v");
+ 	save_interp(Omega,h0,i,"h");
       }
 
       //k1 
@@ -171,13 +177,21 @@
       f_v.set_interps(u0,v0,h0);
       f_h.set_interps(u0,v0,h0);
 
-      k1[0].interpolate(f_u.at());
-      k1[1].interpolate(f_v.at());
-      k1[2].interpolate(f_h.at());
+//       k1[0].interpolate(f_u.at());
+//       k1[1].interpolate(f_v.at());
+//       k1[2].interpolate(f_h.at());
+
+      //debug Euler
+      k1[0].interpolate(u0.at() + f_u.at());
+      k1[1].interpolate(v0.at() + f_v.at());
+      k1[2].interpolate(h0.at() + f_h.at());
 
       set_bdry_conds(k1[0],k1[1]);
       
       cout << "k1 done!" << endl;
+
+      //debug Euler
+      u0 = k1[0]; v0 = k1[1]; h0 = k1[2]; continue;
            
       //k2
       f_u.set_interps(u0+(k1[0]/2), v0+(k1[1]/2), h0+(k1[2]/2));
@@ -298,38 +312,49 @@
 {
   using namespace std;
   string filename = "results/" + which_interp;
-  if(n < 10000)
-    filename += "0";
-  if(n < 1000)
-    filename += "0";
-  if(n < 100)
-    filename += "0";
-  if(n < 10)
-    filename += "0";
   stringstream ss;
+  ss << std::setw(5) << setfill('0') << n;
   string n_string;
-  ss << n;
   ss >> n_string;
   filename += n_string + ".map";
-  ofstream ofs(filename.c_str());
+  ofstream ofs(filename.c_str());    
+  {
+    slice s(1,2);
+    matrix M(Omega -> get_interior().size() +
+	     Omega -> get_boundary().size(), 3);
+    size_t k = 1;
+    for(set<point>::const_iterator i = Omega -> get_interior().begin();
+	i != Omega -> get_interior().end(); i++){
+      M(k,s) = *i;
+      M(k,3) = u(*i);
+      k++;
+    }
+    for(set<point>::const_iterator i = Omega -> get_boundary().begin();
+	i != Omega -> get_boundary().end(); i++){
+      M(k,s) = *i;
+      M(k,3) = u(*i);
+      k++;
+    }
+    ofs << M;
+  }
 
-  slice s(1,2);
-  matrix M(Omega -> get_interior().size() +
-	   Omega -> get_boundary().size(), 3);
-  size_t k = 1;
-  for(set<point>::const_iterator i = Omega -> get_interior().begin();
-      i != Omega -> get_interior().end(); i++){
-    M(k,s) = *i;
-    M(k,3) = u(*i);
-    k++;
-  }
-  for(set<point>::const_iterator i = Omega -> get_boundary().begin();
-      i != Omega -> get_boundary().end(); i++){
-    M(k,s) = *i;
-    M(k,3) = u(*i);
-    k++;
-  }
-  ofs << M;
+
+  if(false){ //debug
+    double r, th, N, M;
+    N = 30; M  = 70;
+    linalg::matrix out(static_cast<size_t>(N),static_cast<size_t>(M));
+    size_t i,j;
+    for(r = 0, j=1;  j <= N; r += 1/(N-1),j++){
+      for(th = 0,i=1; i <= M; th += 2*pi/(M-1),i++){
+	linalg::vector p(2); 
+	p(1) = r*cos(th); 
+	p(2) = r*sin(th);
+	out(j,i) = u(p);
+      }
+    }
+  
+    ofs << out;
+  }//debug
 }
 
 
--- a/results/plotresults.m
+++ b/results/plotresults.m
@@ -1,9 +1,11 @@
-r = linspace(0,1,40);
-th = linspace(-pi,pi,60);
+r = linspace(0,1,80);
+th = linspace(0,2*pi,60);
 [rr,thth] = meshgrid(r,th);
 [xx,yy] = pol2cart(thth,rr);
 
-for i = 1:1:1000
+skip = 1;
+
+for i = skip:skip:1000
   name = "h";
   if(i < 10000);
     name = strcat(name, "0");
@@ -21,11 +23,14 @@
   filename = strcat(name,".map");
   load(filename);
   h = eval(name);
-  zz = griddata(h(:,1),h(:,2),h(:,3),xx,yy);
-  surf(xx,yy,zz);
-  xlim([-1,1]);
-  ylim([-1,1]);
-##  zlim([0,0.2]);
-  print(strcat(name,".png"),"-dpng");
+  x = h(:,1); y = h(:,2); z = h(:,3);
+  [xi,yi,zi] = griddata(x,y,z,xx,yy);
+  zi = zi(:,1:end-1);   xi = xi(:,1:end-1);  yi = yi(:,1:end-1);
+  vtk_clear;
+  vtk_surf(xi,yi,zi);
+  vtk_xlim([-1,1]);
+  vtk_ylim([-1,1]);
+  vtk_zlim([0,0.2]);
+  vtk_print(strcat(name,".png"),"-dpng");
   clear eval(name);
 endfor
--- a/results/plotresults_vtk.m
+++ b/results/plotresults_vtk.m
@@ -1,4 +1,5 @@
-for i = 1:100000
+skip = 5;
+for i = skip:skip:100000
   name = "h";
   if(i < 10000)
     name = strcat(name, "0");