Mercurial > hg > kwantix
view src/bvp.cpp @ 34:7f31f9e2d196
Rename kwantxi to kwantix
author | Jordi Gutiérrez Hermoso <jordigh@gmail.com> |
---|---|
date | Thu, 04 Feb 2010 21:55:30 -0600 |
parents | d22bce6382d7 |
children | e32da6c38b59 |
line wrap: on
line source
#include <map> #include <set> #include <utility> #include <fstream> #include <boost/shared_ptr.hpp> #include "include/bvp.hpp" #include "include/error.hpp" #include "include/utils.hpp" #include "include/func.hpp" namespace kwantix{ using std::pair; using std::make_pair; //******************** domain stuff ************************************ domain::domain(size_t dimension){ dim = dimension; } domain::domain(size_t dimension, set<point> intr, set<point> bdry, map<point, vector> ns){ dim = dimension; add_to_interior(intr); add_to_boundary(bdry); add_to_normals(ns); } domain::domain(string intr, string bdry, string ns){ bool intr_empty, bdry_empty; matrix intr_m ; try{ intr_m = read_matrix(intr); intr_empty = false; } catch(endOfFile){ intr_empty = true; } matrix bdry_m; try{ bdry_m = read_matrix(bdry); bdry_empty = false; } catch(endOfFile){ bdry_empty = true; } matrix ns_m; try{ ns_m = read_matrix(ns); } catch(endOfFile& exc){ if(!bdry_empty){ exc.reason = "Boundary is not empty, so normals cannot be either."; throw exc; } } dim = intr_m.cols(); if( bdry_m.cols() != dim and !bdry_empty ){ badArgument exc; exc.reason = "Wrong parameters for domain from filename. \n" "Dimension of boundary (columns) must equal dimension of interior."; exc.line = __LINE__; exc.file = __FILE__; throw exc; } if( ns_m.cols() != 2*dim and !bdry_empty){ badArgument exc; exc.reason = "Wrong parameters for domain from filename. \n" "Dimension of normals (columns) must equal twice the \n" "dimension of the interior and the boundary."; exc.line = __LINE__; exc.file = __FILE__; throw exc; } slice s(1,dim), s1(1,dim), s2(dim+1,2*dim); if(!intr_empty) for(size_t i = 1; i <= intr_m.rows(); i++) add_to_interior( intr_m(i,s) ); if(!bdry_empty){ for(size_t i = 1; i <= bdry_m.rows(); i++) add_to_boundary( bdry_m(i,s) ); for(size_t i = 1; i <= ns_m.rows(); i++) add_to_normals(ns_m(i,s1), ns_m(i, s2)); } } domain::~domain(){ //Nothing! } //This clears any data already in the domain and sets the dimension. void domain::set_dimension(size_t dimension){ dim = dimension; interior.clear(); boundary.clear(); normals.clear(); } //Add information to the domain void domain::add_to_interior(const set<point> &intr){ for(set<point>::const_iterator I = intr.begin(); I != intr.end(); I++){ if(I -> size() != dim){ badArgument exc; exc.reason = "Cannot assign to domain's interior: inconformant dimensions."; exc.line = __LINE__; exc.file = __FILE__; throw exc; } interior.insert(*I); } } void domain::add_to_interior(const point &intr){ if(intr.size() != dim){ badArgument exc; exc.reason = "Cannot assign to domain's interior: inconformant dimensions."; exc.line = __LINE__; exc.file = __FILE__; throw exc; } interior.insert(intr); } void domain::add_to_boundary(const set<point> &bdry){ for(set<point>::const_iterator I = bdry.begin(); I != bdry.end(); I++){ if(I -> size() != dim){ badArgument exc; exc.reason = "Cannot assign to domain's boundary: inconformant dimensions."; exc.line = __LINE__; exc.file = __FILE__; throw exc; } boundary.insert(*I); } } void domain::add_to_boundary(const point &bdry){ if(bdry.size() != dim){ badArgument exc; exc.reason = "Cannot assign to domain's boundary: inconformant dimensions."; exc.line = __LINE__; exc.file = __FILE__; throw exc; } boundary.insert(bdry); } void domain::add_to_normals(const map<point, vector> &ns){ for(map<point, vector>::const_iterator I = ns.begin(); I != ns.end(); I++){ if (!kwantix::contains(boundary, I->first)){ badArgument exc; exc.reason = "Bad normal given: must match a point on the boundary."; exc.line = __LINE__; exc.file = __FILE__; throw exc; } if(I->first.size() != dim or I->second.size() != dim){ badArgument exc; exc.reason = "Bad normal given: inconformant dimensions."; exc.line = __LINE__; exc.file = __FILE__; throw exc; } normals.insert(*I); } } void domain::add_to_normals(const point &bdry, const vector &n){ if (!kwantix::contains(boundary, bdry)){ badArgument exc; exc.reason = "Bad normal given: must match a point on the boundary."; exc.line = __LINE__; exc.file = __FILE__; throw exc; } if(bdry.size() != dim or n.size() != dim){ badArgument exc; exc.reason = "Bad normal given: inconformant dimensions."; exc.line = __LINE__; exc.file = __FILE__; throw exc; } pair<point, vector> pn = make_pair(bdry,n); normals.insert(pn); } //Read that information size_t domain::get_dimension() const{ return dim; } const set<point>& domain::get_interior() const{ return interior; } const set<point>& domain::get_boundary() const{ return boundary; } const map<point, vector>& domain::get_normals() const{ return normals; } //Is point in this domain, whether interior or boundary? bool domain::contains(const point& p) const{ if(kwantix::contains(interior, p)) return true; if(kwantix::contains(boundary, p)) return true; return false; } //**************** BVP stuff ********************************* //FIXME: Try to templatise this later BVP::BVP(shared_ptr<const domain> O, shared_ptr<const diff_op> L_in, shared_ptr<const bdry_diff_op> B_in, const realfunc& f_in, const realfunc& g_in){ Omega = O; L = L_in; B = B_in; set_f(f_in); set_g(g_in); } BVP::BVP(shared_ptr<const domain> O, shared_ptr<const diff_op> L_in, shared_ptr<const bdry_diff_op> B_in, const realfunc& f_in, const map<point,double>& g_in){ Omega = O; L = L_in; B = B_in; set_f(f_in); set_g(g_in); } BVP::BVP(shared_ptr<const domain> O, shared_ptr<const diff_op> L_in, shared_ptr<const bdry_diff_op> B_in, const map<point,double>& f_in, const realfunc& g_in){ Omega = O; L = L_in; B = B_in; set_f(f_in); set_g(g_in); } BVP::BVP(shared_ptr<const domain> O, shared_ptr<const diff_op> L_in, shared_ptr<const bdry_diff_op> B_in, const map<point,double>& f_in, const map<point,double>& g_in){ Omega = O; L = L_in; B = B_in; set_f(f_in); set_g(g_in); } shared_ptr<const domain> BVP::get_domain() const{ return Omega; } shared_ptr<const diff_op> BVP::get_diff_op() const{ return L; } shared_ptr<const bdry_diff_op> BVP::get_bdry_diff_op() const{ return B; } const map<point, double>& BVP::get_f() const{ return f; } const map<point, double>& BVP::get_g() const{ return g; } void BVP::set_f(const map<point, double>& f_in){ for( map<point,double>::const_iterator I = f_in.begin(); I != f_in.end(); I++){ if( !contains(Omega->get_interior(), I->first ) ){ badArgument exc; exc.reason = "Bad specification of f in BVP: " "gave a point not in the interior."; exc.line = __LINE__; exc.file = __FILE__; throw exc; } f[I->first] = I->second; } } void BVP::set_g(const map<point, double>& g_in){ for( map<point,double>::const_iterator I = g_in.begin(); I != g_in.end(); I++){ if( !contains(Omega->get_boundary(), I->first ) ){ badArgument exc; exc.reason = "Bad specification of g in BVP: " "gave a point not on the boundary."; exc.line = __LINE__; exc.file = __FILE__; throw exc; } g[I->first] = I -> second; } } void BVP::set_f(const realfunc &f_in){ for(set<point>::iterator I = Omega->get_interior().begin(); I != Omega->get_interior().end(); I++) f[*I] = f_in(*I); } void BVP::set_g(const realfunc &g_in){ for(set<point>::iterator I = Omega->get_boundary().begin(); I != Omega->get_boundary().end(); I++) g[*I] = g_in(*I); } shared_ptr<const linear_diff_op2> linear_BVP2::get_linear_diff_op2() const{ return boost:: dynamic_pointer_cast<const linear_diff_op2>(BVP::get_diff_op()); } }