#include <ddm.hpp>
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 |
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 }
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 }
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 }
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 }
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 }
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 }
map<shared_ptr<const overlapping_domain>, shared_ptr<interpolator<RBF> > > bvp::additive_schwarz_ddm< RBF >::phis [private] |