Mercurial > hg > kwantix
changeset 23:acefa48d4b4d
Not compiling, added .hgignore
author | Jordi Gutiérrez Hermoso <jordigh@gmail.com> |
---|---|
date | Sun, 12 Apr 2009 12:28:49 -0500 |
parents | 532145a38fa2 |
children | ad9e3d28ce9b |
files | .hgignore Makefile data/linear_wave.m include/interp_values.hpp include/interpolator.hpp include/linalg.hpp interp_values.cpp interpolator.cpp main-sw-rk4.cpp main.cpp results/showvecs.m |
diffstat | 11 files changed, 310 insertions(+), 449 deletions(-) [+] |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/.hgignore @@ -0,0 +1,7 @@ +syntax: glob +html/* +*.ogg +*.ogv +*.matrix +*.map +*.o
--- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CPP = g++ LINKING = -lgsl -lgslcblas -CFLAGS = -ggdb3 +CFLAGS = -O3 OPTIONS = -Wall -pedantic -W -Werror -Wconversion -Wshadow \ -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings \ -fshort-enums -fno-common -Wfatal-errors
new file mode 100644 --- /dev/null +++ b/data/linear_wave.m @@ -0,0 +1,64 @@ +n = 20 +m = 6; +r = linspace(0,1,n); + +rrintr = 0; +ththintr = 0; +for k = 2:n-1 + c = (k-1)*m; + th = [0:2*pi/c:2*pi*(1-1/c)]; + for j = 1:c + rrintr(end+1) = r(k); + ththintr(end+1) = th(j); + endfor +endfor +#Remove one in order to get a nice non-prime number. +#rrintr = rrintr(2:end); +#ththintr = ththintr(2:end); + +r=1; +c = (n-1)*m; +th = [0:2*pi/c:2*pi*(1-1/c)]; +rrbdry = 1; +ththbdry = 0; +for j = 2:c + rrbdry(end+1) = r; + ththbdry(end+1) = th(j); +endfor +[xxintr,yyintr] = pol2cart(ththintr, rrintr); +[xxbdry,yybdry] = pol2cart(ththbdry, rrbdry); +intr = [xxintr',yyintr']; +bdry = [xxbdry',yybdry']; + +##gotta avoid zero coordinates, so shift the boundary slightly +bdry = ([cos(pi/200), sin(pi/200); -sin(pi/200) cos(pi/200)]*bdry')'; +nrml = [bdry, bdry]; +save "circ_intr.matrix" intr; +save "circ_bdry.matrix" bdry; +save "circ_nrml.matrix" nrml; + +xxbdry = bdry(:,1)'; +yybdry = bdry(:,2)'; + +##radial +##u0 = (1-(xxintr.^2 + yyintr.^2)')/2; + +##nonradial +h0 = []; + for i = 1:columns(xxintr) + h0(i) = fr( (xxintr(i)-0.25)^2 + yyintr(i)^2, 0.025); + endfor + h0 = 4*h0(:)+0.1; + +h0 = [h0]; + +h_init = [xxintr', yyintr', h0]; + +save "wave_init.map" h_init; + + +hold off; +plot(intr(:,1),intr(:,2),'xr'); + hold on; +plot(bdry(:,1),bdry(:,2),'xb'); +size([intr;bdry])
--- a/include/interp_values.hpp +++ b/include/interp_values.hpp @@ -15,8 +15,8 @@ class normals{ public: /** \brief Return the kth coordinate of all normals along the - * boundary as interp values - */ + * boundary as interp values + */ bdry_values operator()(size_t k) const; /*! \name comparisons @@ -32,7 +32,7 @@ template<typename RBF> friend class interpolator; ///Only constructor available for interpolator class normals(size_t rbfs_hash_in, const map<point, linalg::vector>& - normals_in, size_t n_in); + normals_in, size_t n_in); ///Does nothing normals(){}; ///Exception builder @@ -89,7 +89,7 @@ protected: /// Interpolator creates interp_values with this interp_values(const linalg::vector& v_in, size_t rbfs_hash_in, - size_t n_in, size_t m_in) + size_t n_in, size_t m_in) : v(v_in), rbfs_hash(rbfs_hash_in), n(n_in), m(m_in) {}; /// No construction! @@ -124,10 +124,26 @@ friend class normals; ///Same as for parent class bdry_values(const linalg::vector& v_in, size_t rbfs_hash_in, - size_t n_in, size_t m_in) + size_t n_in, size_t m_in) : interp_values(v_in, rbfs_hash_in, n_in, m_in) {}; }; + /// For referring to values purely on the interior of an interpolator. + class intr_values : public interp_values{ + public: + ///Empty initialisation + intr_values(){}; + ///Initialise the interior values with interp_values + intr_values(const interp_values& v_in); + private: + ///Same as for parent class + intr_values(const linalg::vector& v_in, size_t rbfs_hash_in, + size_t n_in, size_t m_in) + : interp_values(v_in, rbfs_hash_in, n_in, m_in) {}; + }; + + + /*! \name Arithmetic operators
--- a/include/interpolator.hpp +++ b/include/interpolator.hpp @@ -95,7 +95,6 @@ void interpolate(const interp_values& values); //@} - /** @name Pointwise evaluation and derivatives */ //@{ @@ -122,7 +121,6 @@ interp_values d2(size_t k1, size_t k2) const; //@} - /** @name Precomputation of RBFs * * The following functions will precompute upon request all the @@ -146,6 +144,8 @@ * and for other methods. They do not factor a matrix again. */ //@{ + void set_f(const intr_values &f); + void set_g(const bdry_values &g); void set_f(const realfunc &f); void set_g(const realfunc &g); void set_f(const map<point, double>& f); @@ -183,9 +183,18 @@ */ normals get_normals() const; + /** \brief This will put into an ostream a linalg::matrix where + * the first \f$n-1\f$ columns will be all the points where the + * interpolator is defined and the \f$n^{th}\f$ column is the + * values that the interpolator takes on that point. + */ + friend + template<typename RBF> + linalg::matrix& operator<< (ostream& os, + private: ///Once the matrix is defined, this function inverts it. - void computecoeffs(); + void computecoeffs(bool rhs_defined = false); ///Perform the actual interpolation. void init(shared_ptr<linear_BVP2> bvp); @@ -207,6 +216,7 @@ ///Is the interpolator ready for use? bool initted; + /** @name Exception builders */ //@{
--- a/include/linalg.hpp +++ b/include/linalg.hpp @@ -18,6 +18,8 @@ #include <gsl/gsl_permutation.h> #include "error.hpp" +#include <boost/operators.hpp> + /// Linear algebra namespace namespace linalg{ using namespace error_handling;
--- a/interp_values.cpp +++ b/interp_values.cpp @@ -79,7 +79,7 @@ //*************** bdry_vals stuff ************************************ bdry_values::bdry_values(const interp_values& v_in) - : interp_values(v_in) + : interp_values(v_in) { if(v.size() == m+n){ //Lower part of the vector contains the boundary @@ -88,23 +88,37 @@ } else if(v.size() != m){ throw badArgument("Cannot initialise bdry_values from given " - "interp_values", __FILE__,__LINE__); + "interp_values", __FILE__,__LINE__); } // Else, we're initting with interp_values that are the right size // and there's no need to do anything, since they're bona fide // boundary values (parent copy ctor does the work). + } - //debug - using namespace std; - cout << "The boundary vector: " << endl - << v << endl; + //*************** intr_vals stuff ***************************** + + intr_values::intr_values(const interp_values& v_in) + : interp_values(v_in) + { + if(v.size() == m+n){ + //Upper part of the vector contains the boundary + linalg::slice s(1,n); + v = v(s); + } + else if(v.size() != n){ + throw badArgument("Cannot initialise intr_values from given " + "interp_values", __FILE__,__LINE__); + } + // Else, we're initting with interp_values that are the right size + // and there's no need to do anything, since they're bona fide + // boundary values (parent copy ctor does the work). } //*************** normals stuff ************************************* normals::normals(size_t rbfs_hash_in, - const map<point, linalg::vector>& normals_in, - size_t n_in) : rbfs_hash(rbfs_hash_in), n(n_in) + const map<point, linalg::vector>& normals_in, + size_t n_in) : rbfs_hash(rbfs_hash_in), n(n_in) { map<point, linalg::vector>::const_iterator I; size_t rows = normals_in.size();
--- a/interpolator.cpp +++ b/interpolator.cpp @@ -33,20 +33,20 @@ template<typename RBF> interpolator<RBF>::interpolator(shared_ptr<domain> Omega, - const map<point, double>& Xi) + const map<point, double>& Xi) { //Check that Xi matches the domain in size size_t Omega_size = Omega -> get_interior().size() - + Omega -> get_boundary().size(); + + Omega -> get_boundary().size(); if(Xi.size() != Omega_size) { badArgument exc; if(Xi.size() < Omega_size) - exc.reason = "Did not provide enough interpolation data for every " - "point in the given domain."; + exc.reason = "Did not provide enough interpolation data for every " + "point in the given domain."; else - exc.reason = "Provided more interpolation data than points in the " - "given domain."; + exc.reason = "Provided more interpolation data than points in the " + "given domain."; exc.line = __LINE__; exc.file = __FILE__; throw exc; @@ -59,19 +59,19 @@ //Extract f and g from given information for(map<point, double>::const_iterator I = Xi.begin(); - I != Xi.end(); I++) + I != Xi.end(); I++) { if(utils::contains(Omega -> get_interior(), I -> first)) - f[I -> first] = I -> second; + f[I -> first] = I -> second; else if(utils::contains(Omega -> get_boundary(), I -> first)) - g[I -> first] = I -> second; + g[I -> first] = I -> second; else { - badArgument exc; - exc.reason = "The interpolation data contains points not in the given domain."; - exc.line = __LINE__; - exc.file = __FILE__; - throw exc; + badArgument exc; + exc.reason = "The interpolation data contains points not in the given domain."; + exc.line = __LINE__; + exc.file = __FILE__; + throw exc; } } @@ -110,15 +110,15 @@ size_t dimension = 0; for(map<point,double>::const_iterator i = Xi.begin(); i != Xi.end(); i++){ if(!dim_set){ - dimension = (i -> first).size(); - dim_set = true; + dimension = (i -> first).size(); + dim_set = true; } else if(dimension != (i -> first).size()){ - badArgument exc; - exc.reason = "Inconformant dimensions in interpolation data."; - exc.line = __LINE__; - exc.file = __FILE__; - throw exc; + badArgument exc; + exc.reason = "Inconformant dimensions in interpolation data."; + exc.line = __LINE__; + exc.file = __FILE__; + throw exc; } intr.insert( i->first); } @@ -140,7 +140,7 @@ if(!initted){ badArgument exc; exc.reason = "Cannot interpolate with other interpolator's " - "values without defining the domain."; + "values without defining the domain."; exc.line = __LINE__; exc.file = __FILE__; throw exc; @@ -148,7 +148,7 @@ if(rbfs_hash != values.rbfs_hash){ badArgument exc; exc.reason = "Cannot interpolate with values from incompatible " - "interpolator." ; + "interpolator." ; exc.line = __LINE__; exc.file = __FILE__; throw exc; @@ -202,7 +202,7 @@ I = interior.begin(); for(size_t i = 1; i <= n; i++){ for(size_t j = 1; j <= n+m; j++) - M(i,j) = L -> at(rbfs[j-1], *I); + M(i,j) = L -> at(rbfs[j-1], *I); I++; } @@ -210,7 +210,7 @@ J = normals.begin(); for(size_t i = n+1; i <= n+m; i++){ for(size_t j = 1; j <= n+m; j++) - M(i,j) = B -> at(rbfs[j-1], J->first, J->second); + M(i,j) = B -> at(rbfs[j-1], J->first, J->second); J++; } @@ -258,14 +258,14 @@ set<point>::iterator I; size_t i; for(I = thebvp -> get_domain () -> get_interior().begin(), i = 1; - i <= n; i++, I++) - for(size_t j = 0; j < n+m; j++) - phis(i,j+1) = rbfs[j].at(*I); + i <= n; i++, I++) + for(size_t j = 0; j < n+m; j++) + phis(i,j+1) = rbfs[j].at(*I); for(I = thebvp -> get_domain() -> get_boundary().begin(), i=n+1; - i <= n+m; i++, I++) - for(size_t j = 0; j < n+m; j++) - phis(i,j+1) = rbfs[j].at(*I); + i <= n+m; i++, I++) + for(size_t j = 0; j < n+m; j++) + phis(i,j+1) = rbfs[j].at(*I); precomp_rbfs[alpha] = phis; computecoeffs(); @@ -286,25 +286,25 @@ //No, so precompute the RBFs first derivatives at all points of //the domain. for(size_t k = 1; k <= thebvp -> get_domain() -> get_dimension(); - k++){ - std::vector<size_t> alpha(k); alpha[k-1]++; - matrix phis(n+m,n+m); - { - set<point>::iterator I; - size_t i; - for(I = thebvp -> get_domain() -> get_interior().begin(), - i = 1; i <= n; i++, I++) - for(size_t j = 0; j < n+m; j++) - phis(i,j+1) = rbfs[j].d(*I,k); + k++){ + std::vector<size_t> alpha(k); alpha[k-1]++; + matrix phis(n+m,n+m); + { + set<point>::iterator I; + size_t i; + for(I = thebvp -> get_domain() -> get_interior().begin(), + i = 1; i <= n; i++, I++) + for(size_t j = 0; j < n+m; j++) + phis(i,j+1) = rbfs[j].d(*I,k); - for(I = thebvp -> get_domain() -> get_boundary().begin(), - i=n+1; i <= n+m; i++, I++) - for(size_t j = 0; j < n+m; j++) - phis(i,j+1) = rbfs[j].d(*I,k); - } + for(I = thebvp -> get_domain() -> get_boundary().begin(), + i=n+1; i <= n+m; i++, I++) + for(size_t j = 0; j < n+m; j++) + phis(i,j+1) = rbfs[j].d(*I,k); + } - precomp_rbfs[alpha] = phis; - computecoeffs(); + precomp_rbfs[alpha] = phis; + computecoeffs(); } } d1_precomp = true; @@ -319,24 +319,24 @@ size_t dim = thebvp -> get_domain() -> get_dimension(); //precompute all second derivatives for(size_t k1 = 1; k1 <= dim; k1++){ - for(size_t k2 = k1; k2 <= dim; k2++){ - std::vector<size_t> alpha(k1>k2?k1:k2); alpha[k1-1]++; alpha[k2-1]++; - matrix phis(n+m,n+m); - set<point>::iterator I; - size_t i; - for(I = thebvp -> get_domain () -> get_interior().begin(), i = 1; - i <= n; i++, I++) - for(size_t j = 0; j < n+m; j++) - phis(i,j+1) = rbfs[j].d2(*I,k1,k2); + for(size_t k2 = k1; k2 <= dim; k2++){ + std::vector<size_t> alpha(k1>k2?k1:k2); alpha[k1-1]++; alpha[k2-1]++; + matrix phis(n+m,n+m); + set<point>::iterator I; + size_t i; + for(I = thebvp -> get_domain () -> get_interior().begin(), i = 1; + i <= n; i++, I++) + for(size_t j = 0; j < n+m; j++) + phis(i,j+1) = rbfs[j].d2(*I,k1,k2); - for(I = thebvp -> get_domain() -> get_boundary().begin(), i=n+1; - i <= n+m; i++, I++) - for(size_t j = 0; j < n+m; j++) - phis(i,j+1) = rbfs[j].d2(*I,k1,k2); + for(I = thebvp -> get_domain() -> get_boundary().begin(), i=n+1; + i <= n+m; i++, I++) + for(size_t j = 0; j < n+m; j++) + phis(i,j+1) = rbfs[j].d2(*I,k1,k2); - precomp_rbfs[alpha] = phis; - computecoeffs(); - } + precomp_rbfs[alpha] = phis; + computecoeffs(); + } } } d2_precomp = true; @@ -470,7 +470,7 @@ if(this -> rbfs_hash != u.rbfs_hash){ badArgument exc; exc.reason = - "Cannot add interpolators on different domains (interior and boundary must match)."; + "Cannot add interpolators on different domains (interior and boundary must match)."; exc.line = __LINE__; exc.file = __FILE__; throw exc; @@ -490,7 +490,7 @@ if(this -> rbfs_hash != u.rbfs_hash){ badArgument exc; exc.reason = - "Cannot subtract interpolators on different domains (interior and boundary must match)."; + "Cannot subtract interpolators on different domains (interior and boundary must match)."; exc.line = __LINE__; exc.file = __FILE__; throw exc; @@ -525,7 +525,7 @@ normals interpolator<RBF>::get_normals() const{ if(!initted){ throw badArgument("Interpolator not initialised, so there are " - "no normals!",__FILE__,__LINE__); + "no normals!",__FILE__,__LINE__); } return nrmls; } @@ -533,6 +533,34 @@ //******************* data manipulation ************************** template<typename RBF> + void interpolator<RBF>::set_f(const intr_values& f){ + if(!initted){ + throw not_initted(__LINE__, __FILE__); + } + + std::vector<size_t> alpha; + slice s(1,n); + precomp_values_vec[alpha](s) = f.v; + //precomp_values[alpha] = valsvec2map(precomp_values_vec[alpha]); + + computecoeffs(true); + } + + template<typename RBF> + void interpolator<RBF>::set_g(const bdry_values& g){ + if(!initted){ + throw not_initted(__LINE__, __FILE__); + } + + std::vector<size_t> alpha; + slice s(n+1,n+m); + precomp_values_vec[alpha](s) = g.v; + //precomp_values[alpha] = valsvec2map(precomp_values_vec[alpha]); + + computecoeffs(true); + } + + template<typename RBF> void interpolator<RBF>::set_f(const realfunc& f){ if(!initted){ throw not_initted(__LINE__, __FILE__); @@ -611,23 +639,28 @@ } template<typename RBF> - void interpolator<RBF>::computecoeffs() + void interpolator<RBF>::computecoeffs(bool rhs_defined) { linalg::vector rhs(n+m); //Compute the RBF coefficients + if(rhs_defined){ + std::vector<size_t> alpha; + rhs = precomp_values_vec[alpha]; + } + else { map<point, double>::const_iterator I; I = (thebvp -> get_f()).begin(); for(size_t i = 1; i <= n; i++){ - rhs(i) = I->second; - I++; + rhs(i) = I->second; + I++; } I = (thebvp -> get_g()).begin(); for(size_t i = n+1; i <= n+m; i++){ - rhs(i) = I->second; - I++; + rhs(i) = I->second; + I++; } } coeffs = M.inv(rhs); @@ -638,9 +671,9 @@ typename map<std::vector<size_t>, matrix>::const_iterator I; for(I = precomp_rbfs.begin(); I != precomp_rbfs.end(); I++){ - linalg::vector vals = (I->second)*coeffs; - precomp_values_vec[I -> first] = vals; - precomp_values[I -> first] = valsvec2map(vals); + linalg::vector vals = (I->second)*coeffs; + precomp_values_vec[I -> first] = vals; + precomp_values[I -> first] = valsvec2map(vals); } } } @@ -654,12 +687,12 @@ set<point>::const_iterator I; size_t i; for(I = thebvp -> get_domain() -> get_interior().begin(), i = 1; - i <= n; I++, i++) - out[*I] = values(i); + i <= n; I++, i++) + out[*I] = values(i); for(I = thebvp -> get_domain() -> get_boundary().begin(), i = n+1; - i <= n+m; I++, i++) - out[*I] = values(i); + i <= n+m; I++, i++) + out[*I] = values(i); } return out; } @@ -680,11 +713,11 @@ /*! \mainpage Outline of the RBF-DDM code -Thank you for your interest in my code. Above you can browse the -structure of my code. You can also read here a technical design -document that also outlines certain difficulties I have been facing -with it: + Thank you for your interest in my code. Above you can browse the + structure of my code. You can also read here a technical design + document that also outlines certain difficulties I have been facing + with it: -http://inversethought.com/jordi/design.pdf + http://inversethought.com/jordi/design.pdf */
--- a/main-sw-rk4.cpp +++ b/main-sw-rk4.cpp @@ -1,4 +1,5 @@ #include <iostream> +#include <iomanip> #include <fstream> #include <map> #include <set> @@ -145,7 +146,10 @@ 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; @@ -159,13 +163,13 @@ f_h.set_dt(dt); //main loop, timestepping with RK4. - size_t maxiter = 5; + size_t maxiter = 1000; 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"); + if(i % 10 == 0){ + save_interp(Omega,u0,i,"u"); + save_interp(Omega,v0,i,"v"); + save_interp(Omega,h0,i,"h"); } //k1 @@ -180,10 +184,7 @@ 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)); f_v.set_interps(u0+(k1[0]/2), v0+(k1[1]/2), h0+(k1[2]/2)); @@ -301,25 +302,14 @@ const interpolator<RBF>& u, size_t n, string which_interp) { - - 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() + @@ -375,7 +365,9 @@ //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); } + +
--- a/main.cpp +++ b/main.cpp @@ -21,87 +21,25 @@ #define RBF_TYPE rbf::conical -//Will solve the system -// -// u_t = -u*u_x - v*u_y - g*h_x =: f1(u,v,h) -// -// v_t = -u*v_x - v*v_y - g*h_y =: f2(u,v,h) -// -// h_t = -u*h_x - h*u_x - v*h_y - h*v_y =: f3(u,v,h) -// -//where g is the acceleration due to gravity, u(x,y,0) = v(x,y,0) = 0, -//and h starts out as an undisturbed surface high with a small -//disturbance. We'll do this by RK4. - - -const double g = 9.8; // m/s^2 - const double pi = 3.141592653589793238462643383279502; -template<typename RBF> -class Fgen { +class wave_op : public linear_diff_op2{ public: - void set_interps(const interpolator<RBF>& u0, - const interpolator<RBF>& v0, - const interpolator<RBF>& h0); - void set_u(const interpolator<RBF>& u0); - void set_v(const interpolator<RBF>& v0); - void set_h(const interpolator<RBF>& h0); - void set_dt(double dt_in); -protected: - interpolator<RBF> u; - interpolator<RBF> v; - interpolator<RBF> h; - double dt; -}; - -template<typename RBF> -class Fu : public Fgen<RBF>{ - using Fgen<RBF>::u; - using Fgen<RBF>::v; - using Fgen<RBF>::h; - using Fgen<RBF>::dt; -public: - bvp::interp_values at() const; -}; - -template<typename RBF> -class Fv : public Fgen<RBF>{ - using Fgen<RBF>::u; - using Fgen<RBF>::v; - using Fgen<RBF>::h; - using Fgen<RBF>::dt; -public: - bvp::interp_values at() const; -}; - -template<typename RBF> -class Fh : public Fgen<RBF>{ - using Fgen<RBF>::u; - using Fgen<RBF>::v; - using Fgen<RBF>::h; - using Fgen<RBF>::dt; -public: - bvp::interp_values at() const; + wave_op(double dt_in): dt2(dt_in*dt_in){}; + double at(const realfunc& f, const point& p) const + { + return dt2*L(f,p) + f(p); + } +private: + Laplacian L; + double dt2; }; class zero_func : public realfunc{ public: - double at(const point& p) const{p.size(); return 0;}; + double at(const point&) const{return 0;}; }; -//************ Function declarations **************************** - -template<typename RBF> -void save_interp(const shared_ptr<domain> Omega, - const interpolator<RBF>& u, - size_t n, string which_interp); - -template<typename RBF> -void set_bdry_conds(interpolator<RBF> &u, interpolator<RBF> &v); - - -//********************** Main ****************************************** int main() { gsl_set_error_handler(&error_handling::errorHandler); @@ -110,137 +48,37 @@ using namespace std; using boost::shared_ptr; - map<point, double> h_init = utils::read_pd_map("data/h_init.map"); + map<point, double> u_init = utils::read_pd_map("data/wave_init.map"); shared_ptr<domain> Omega(new domain("data/circ_intr.matrix", - "data/circ_bdry.matrix", - "data/circ_nrml.matrix")); - - shared_ptr<Id_op> I(new Id_op); - 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, D, Z, Z)), - v_bvp_init(new linear_BVP2(Omega, I, D, Z, Z)); - + "data/circ_bdry.matrix", + "data/circ_nrml.matrix")); - //init the interps. - using namespace rbf; - 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> - 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(); + zero_func g; - //Intermediate interpolators for RK4 - std::vector<interpolator<RBF_TYPE> > - // FIXME: make the copy ctor for interps make different copies - // of the bvp. - 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; - - f_u.set_dt(dt); - f_v.set_dt(dt); - f_h.set_dt(dt); - - //main loop, timestepping with RK4. - size_t maxiter = 1000; - 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"); - } + //timestep + double dt=1e-2; + + shared_ptr<wave_op> W(new wave_op(dt) ); + shared_ptr<dirichlet_op> D(new dirichlet_op); + shared_ptr<linear_BVP2> the_bvp(new linear_BVP2(Omega, W, D, + u_init, g)); - //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()); - - //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)); - 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()); - - set_bdry_conds(k2[0],k2[1]); + rbf::conical::set_n(5); + interpolator<RBF_TYPE> u(the_bvp); + u.precompute_ev(); + interpolator<RBF_TYPE> u0 = u, u1 = u; - 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()); - - 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()); - - set_bdry_conds(k4[0],k4[1]); - - cout << "k4 done!" << endl; - - //Grand finale - 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); + //Main loop + size_t maxiter = 1000; + for(size_t n = 1; n <= maxiter; n++) + { + u0 = u1; + u1 = u; + cout << "Iteration: " << n << endl; + u.set_f( (u0 - 2*u1).at() ); } - return 0; } catch(error exc){ utils::show_exception(exc); @@ -249,133 +87,4 @@ } -//******************* Function definitions *************************** -template<typename RBF> -void Fgen<RBF>::set_interps(const interpolator<RBF>& u0, - const interpolator<RBF>& v0, - const interpolator<RBF>& h0){ - set_u(u0); - set_v(v0); - set_h(h0); -} - -template<typename RBF> -void Fgen<RBF>::set_u(const interpolator<RBF>& u0) -{ - u = u0; -} - -template<typename RBF> -void Fgen<RBF>::set_v(const interpolator<RBF>& v0) -{ - v = v0; -} - -template<typename RBF> -void Fgen<RBF>::set_h(const interpolator<RBF>& h0) -{ - h = h0; -} - -template<typename RBF> -void Fgen<RBF>::set_dt(double dt_in) -{ - dt = dt_in; -} - - -template<typename RBF> -interp_values Fu<RBF>::at() const -{ - return dt*(u()*u.d(1) + v()*u.d(2) + g*h.d(1)); -} - -template<typename RBF> -interp_values Fv<RBF>::at() const -{ - return dt*(u()*v.d(1) - + v()*v.d(2) - + g*h.d(2)); -} - -template<typename RBF> -interp_values Fh<RBF>::at() const -{ - 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; - stringstream ss; - ss << std::setw(5) << setfill('0') << n; - string n_string; - 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; - } - - - 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> -void set_bdry_conds(interpolator<RBF> & u, interpolator<RBF> & v) -{ - 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; - } - - //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); -} - -
new file mode 100644 --- /dev/null +++ b/results/showvecs.m @@ -0,0 +1,14 @@ +N = 21810; +skip = 10; + +for i = skip:skip:N + nameu = "u"; namev = "v"; + istr = sprintf("%05d",i); + filenameu = strcat(nameu,istr,".map"); + filenamev = strcat(namev,istr,".map"); + u = load(filenameu); + v = load(filenamev); + x = u(:,1); y = u(:,2); + u = u(:,3); v = v(:,3); + quiver(x,y,u,v,0.15); +endfor \ No newline at end of file