bvp::additive_schwarz_ddm< RBF > Class Template Reference

#include <ddm.hpp>

Inheritance diagram for bvp::additive_schwarz_ddm< RBF >:

Inheritance graph
[legend]
Collaboration diagram for bvp::additive_schwarz_ddm< RBF >:

Collaboration graph
[legend]

List of all members.

Public Member Functions

 additive_schwarz_ddm (const set< shared_ptr< const domain > > &, shared_ptr< const linear_BVP2 > bvp)
double at (const point &p) const

Private Member Functions

set< shared_ptr< const
interpolator< RBF > > > 
which_interps (const point &p) const
void solve ()
double avg_interp (set< shared_ptr< const interpolator< RBF > > > relevant_interpolators, const point &p) const
vector at_all_points () const

Private Attributes

map< shared_ptr< const
overlapping_domain >
, shared_ptr< interpolator
< RBF > > > 
phis

template<typename RBF>
class bvp::additive_schwarz_ddm< RBF >


Constructor & Destructor Documentation

template<typename RBF>
bvp::additive_schwarz_ddm< RBF >::additive_schwarz_ddm ( const set< shared_ptr< const domain > > &  ds,
shared_ptr< const linear_BVP2 bvp 
) [inline]

00112                                                                    : 
00113     ddm(ds,thebvp){
00114 
00115     shared_ptr<const linear_diff_op2> 
00116       L = dynamic_pointer_cast<
00117       const linear_diff_op2>(this -> bvp -> get_diff_op());
00118 
00119     shared_ptr<const bdry_diff_op> 
00120       B = this -> bvp -> get_bdry_diff_op();
00121     
00122     map<point, double> global_f = this -> bvp -> get_f();
00123     map<point, double> global_g = this -> bvp -> get_g();
00124     
00125     //Define a bvp for each domain and assign it an interpolator. 
00126     for(set<shared_ptr<const domain> >::iterator 
00127           i = this -> domains.begin(); i != this -> domains.end(); i++){
00128       shared_ptr<const overlapping_domain> this_domain =
00129         dynamic_pointer_cast<const overlapping_domain>(*i);
00130       
00131       //Define the interiors and f's
00132       set<point> this_intr = this_domain -> get_interior();
00133       map<point, double> this_f;
00134       for(set<point>::iterator spi = this_intr.begin(); 
00135           spi != this_intr.end(); spi++)
00136         this_f[*spi] = global_f[*spi];
00137 
00138       //Define the boundaries and g's
00139       set<point> this_bdry = this_domain -> get_boundary();
00140       map<point, double> this_g;
00141       set<point> interior_boundary_pts;
00142       for(set<point>::iterator spi = this_bdry.begin();
00143           spi != this_bdry.end(); spi++){
00144         if(this_domain -> which_domain(*spi).get() == 0){
00145           this_g[*spi] = global_g[*spi]; 
00146         }
00147         else{
00148           interior_boundary_pts.insert(*spi);
00149           this_g[*spi] = 0; //Init to zero artificial boundary conditions. 
00150         }
00151       }
00152 
00153       //Define the boundary operator, using Dirichlet for artificial
00154       //boundaries
00155       shared_ptr<dirichlet_op> D(new dirichlet_op);
00156       shared_ptr<ddm_bdry_diff_op> 
00157         this_B( new 
00158                 ddm_bdry_diff_op(B, D, interior_boundary_pts));
00159       
00160       //Put all this info into an interpolator.
00161       shared_ptr<linear_BVP2>
00162         this_bvp(new linear_BVP2(this_domain, L, this_B, this_f, this_g) );
00163       shared_ptr<interpolator<RBF> > 
00164         rbf_ptr( new interpolator<RBF>(this_bvp));
00165       phis[this_domain] = rbf_ptr;
00166     }
00167     
00168     //Apply actual additive Schwarz DDM algorithm here
00169     solve();
00170   }

Here is the call graph for this function:


Member Function Documentation

template<typename RBF>
double bvp::additive_schwarz_ddm< RBF >::at ( const point &  p  )  const [inline, virtual]

Implements bvp::ddm.

00173                                                           {
00174     //If p is one of the domain points, then it's used. If more than
00175     //one domain contains p, then the average is taken. If no domain
00176     //contains p, we exhaustively search for the closest point in the
00177     //domains and use the interpolator from that domain to evaluate.
00178    
00179     set<shared_ptr<const interpolator<RBF> > >
00180     relevant_interpolators = which_interps(p);
00181     
00182     if(relevant_interpolators.size() != 0)//p is in one of the
00183                                           //domains.
00184       return avg_interp(relevant_interpolators, p);
00185     
00186     
00187     //Else, p is not one of the grid points. Find closest grid point
00188     //and evaluate on the domain(s) that the point belongs to.
00189 
00190     
00191     //Uh, just begin with closest being some point in the whatever
00192     //domain. 
00193     point c = *(((*( this->domains.begin() )) 
00194                  -> get_interior()).begin() );
00195 
00196     //Search each domain's interior and boundary. Can't do better than
00197     //exhaustive search. 
00198     for(set<shared_ptr<const domain> >::iterator i = this -> domains.begin();
00199         i != this -> domains.end(); i++){
00200       for(set<point>::iterator j = (*i) -> get_interior().begin();
00201           j != (*i) -> get_interior().end(); j++)
00202         if( norm(*j - p) < norm(c - p))
00203           c = *j;
00204 
00205       for(set<point>::iterator j = (*i) -> get_boundary().begin();
00206           j != (*i) -> get_boundary().end(); j++)
00207         if( norm(*j - p) < norm(c - p))
00208           c = *j;
00209     }
00210     
00211     return avg_interp( which_interps(c), p);
00212     
00213   }

Here is the call graph for this function:

template<typename RBF>
set< shared_ptr< const interpolator< RBF > > > bvp::additive_schwarz_ddm< RBF >::which_interps ( const point &  p  )  const [inline, private]

00217                                      {
00218     set<shared_ptr<const interpolator<RBF> > > relevant_interpolators;
00219     for(set<shared_ptr<const domain> >::iterator i = this -> domains.begin();
00220         i != this -> domains.end(); i++){
00221       if( (*i) -> contains(p)){
00222         shared_ptr<const overlapping_domain> j = 
00223           dynamic_pointer_cast<const overlapping_domain>(*i);
00224         relevant_interpolators.insert(phis.at(j)); 
00225         //at is not in current STL standard; but it is necessary here
00226         //because operator[] can't be used here since this is a const
00227         //function. at is currently a GNU extension, and we're using
00228         //it.
00229       }
00230     }
00231     return relevant_interpolators;
00232   }

Here is the call graph for this function:

template<typename RBF>
void bvp::additive_schwarz_ddm< RBF >::solve (  )  [inline, private, virtual]

Implements bvp::ddm.

00250                                        {
00251     //Recap: each domain already has an interpolator associated to it
00252     //and all overlapping domain information has been defined. Just
00253     //need to iterate on the boundary conditions. Method converges
00254     //when 2-norm (Frobenius, if it were a matrix) of the artificial
00255     //boundary does not change by more than tolerance.
00256     using std::make_pair;
00257 
00258     vector newv = at_all_points();
00259     vector oldv(newv.size());
00260     double change;
00261     do{
00262       oldv = newv;
00263 
00264       //Each domain will have new g's.
00265       map<shared_ptr<const overlapping_domain>, map<point, double> > 
00266         new_bdry_assts;
00267       for(set<shared_ptr<const domain> >::iterator 
00268             i = this -> domains.begin(); i != this -> domains.end(); i++){
00269         shared_ptr<const overlapping_domain> d = 
00270           dynamic_pointer_cast<const overlapping_domain>(*i);
00271         for(set<point>::iterator j = (*i) -> get_boundary().begin();
00272             j != (*i) -> get_boundary().end(); j++)
00273           if( d -> which_domain(*j).get() != 0){
00274 
00275 
00276             new_bdry_assts[d].
00277               insert(make_pair(*j, 
00278                                phis[d -> which_domain(*j)] -> at(*j))
00279                      );
00280           }
00281       }
00282 
00283       //Now assign to each interpolator the modified boundary.
00284       for(typename map<shared_ptr<const overlapping_domain>,
00285             shared_ptr<interpolator<RBF> > >::
00286             iterator i = phis.begin(); i != phis.end(); i++)
00287         i -> second -> set_g(new_bdry_assts[i -> first]);
00288       
00289       newv = at_all_points();
00290       change = norm(oldv-newv);
00291       
00292       //debug
00293       cout << "Change: " << change << endl;
00294     }while( change > this -> tolerance);
00295   }    

Here is the call graph for this function:

template<typename RBF>
double bvp::additive_schwarz_ddm< RBF >::avg_interp ( set< shared_ptr< const interpolator< RBF > > >  relevant_interpolators,
const point &  p 
) const [inline, private]

00237                                   {
00238       double result = 0;
00239       int n = 0;
00240       for(typename set<shared_ptr<const interpolator<RBF> > >::
00241             iterator i = relevant_interpolators.begin() ;
00242           i != relevant_interpolators.end(); i++){
00243         result += (*i) -> at(p);
00244         n++;
00245       }
00246       return result/n;
00247   }

Here is the call graph for this function:

template<typename RBF>
vector bvp::additive_schwarz_ddm< RBF >::at_all_points (  )  const [inline, private]

00299                                                        {
00300     set<point> art_bdry;
00301     for(set<shared_ptr<const domain> >::const_iterator i = 
00302           this -> domains.begin(); i != this -> domains.end(); i++)
00303       {
00304         shared_ptr<const overlapping_domain> j = 
00305           dynamic_pointer_cast<const overlapping_domain>(*i),
00306           zero; //The zero pointer.
00307 
00308         for(set<point>::iterator p = j -> get_boundary().begin();
00309             p != j -> get_boundary().end(); p++)
00310           {
00311             if(j -> which_domain(*p) != zero)
00312               art_bdry.insert(*p);
00313           }
00314       }
00315 
00316     set<point>::iterator I = art_bdry.begin();
00317     vector result(art_bdry.size() );
00318     for(size_t i = 1; i <= result.size(); i++){
00319       result(i) = at(*I);
00320       I++;
00321     }
00322     return result;
00323   }

Here is the call graph for this function:


Member Data Documentation

template<typename RBF>
map<shared_ptr<const overlapping_domain>, shared_ptr<interpolator<RBF> > > bvp::additive_schwarz_ddm< RBF >::phis [private]


The documentation for this class was generated from the following files:

Generated on Fri Jun 6 17:28:26 2008 by  doxygen 1.5.6