7#include "curvedPoissonIntegrator.h"
8#include "../math_lib.h"
22 D3vector limit1,limit2;
29 SGPoint(D3vector levels_,D3vector locs_,\
30 D3vector &limit1, D3vector &limit2):levels(levels_),locs(locs_){
31 this->limit1 = limit1;
32 this->limit2 = limit2;
37 supp_sizes[i] = limit2[i]-limit1[i];
39 coords[i] = limit1[i];
41 else if(locs[i] == 2){
42 coords[i] = limit2[i];
46 supp_sizes[i] = (limit2[i]-limit1[i])/pow(2,levels[i]-1);
47 coords[i] = limit1[i]+locs[i]*supp_sizes[i]*0.5;
53 SGPoint& operator=(SGPoint& point){
54 this->coords = point.coords;
55 this->levels = point.levels;
56 this->locs = point.locs;
57 this->supp_sizes = point.supp_sizes;
63 std::cout<<coords[0]<<
" "<<coords[1]<<
" "<<coords[2]<<std::endl;
66 double volume(
int dim);
84 void reset(D3vector levels_,D3vector locs_,D3vector &limit1, D3vector &limit2);
90 std::queue<SGPoint> refine_queue;
91 std::vector<SGPoint> refined_set;
99 SGIntegrator(
double tol_,
int dim_):tol(tol_),dim(dim_){
104 void setTol(
double &tol_){
109 bool isBoundaryPoint(SGPoint &p);
112 void refine(SGPoint &p);
114 void decideMinMax(D3vector &min, D3vector &max, D3vector &levels);
127 double smolyakIntegrate(
IntegratorPoissonCurved& ipc, Curvedfunc funcToIntegrate, D3vector &limit1, D3vector &limit2,
int max_level);
131inline bool operator==(SGPoint point1, SGPoint point2){
132 return(point1.getCoords() == point2.getCoords() &&\
133 point1.getLevels() == point2.getLevels() &&\
134 point1.getLocs() == point2.getLocs());
147void SGPoint::reset(D3vector levels_,D3vector locs_,D3vector &limit1, D3vector &limit2){
148 this->levels = levels_;
151 this->limit1 = limit1;
152 this->limit2 = limit2;
155 for(
int i=0;i<3;i++){
157 supp_sizes[i] = limit2[i]-limit1[i];
159 coords[i] = limit1[i];
161 else if(locs[i] == 2){
162 coords[i] = limit2[i];
166 supp_sizes[i] = (limit2[i]-limit1[i])/pow(2,levels[i]-1);
167 coords[i] = limit1[i]+locs[i]*supp_sizes[i]*0.5;
173double SGPoint::volume(
int dim){
176 for(
int i=0;i<dim;i++){
177 vol *= 0.5*supp_sizes[i];
182bool SGIntegrator::isBoundaryPoint(SGPoint &p){
184 D3vector levels = p.getLevels();
185 for(
int i=0;i<this->dim;i++){
186 test = test || (levels[i] == 0);
191void SGIntegrator::refine(SGPoint& current){
192 D3vector levels = current.getLevels();
193 D3vector locs = current.getLocs();
195 D3vector levels_temp = levels,locs_temp = locs;
198 for(
int i=0;i<this->dim;i++){
203 current.reset(levels_temp,locs_temp,limit1,limit2);
204 refine_queue.push(current);
207 levels_temp[i] = levels[i];
208 locs_temp[i] = locs[i];
216 locs_temp[i] = 2*locs_temp[i]+1;
217 current.reset(levels_temp,locs_temp,limit1,limit2);
218 refine_queue.push(current);
222 current.reset(levels_temp,locs_temp,limit1,limit2);
223 refine_queue.push(current);
226 levels_temp[i] = levels[i];
227 locs_temp[i] = locs[i];
236 D3vector h = p.getSizes();
237 D3vector coords = p.getCoords();
238 D3vector levels = p.getLevels();
241 double surplus = (ipc.*func)(coords);
244 for(
int i=0;i<this->dim;i++){
246 coords[i] += 0.5*h[i];
247 surplus -= 0.5*(ipc.*func)(coords);
250 surplus -= 0.5*(ipc.*func)(coords);
252 coords = p.getCoords();
257 int num_planes = ((this->dim)*(this->dim-1))/2;
258 for(
int i=0;i<num_planes;i++){
260 i2 = (i+1)%(this->dim);
262 if(levels[i1] != 0 && levels[i2] != 0){
263 coords[i1] += 0.5*h[i1];
264 coords[i2] += 0.5*h[i2];
265 surplus += 0.25*(ipc.*func)(coords);
268 surplus += 0.25*(ipc.*func)(coords);
271 surplus += 0.25*(ipc.*func)(coords);
274 surplus += 0.25*(ipc.*func)(coords);
277 coords = p.getCoords();
282 if(this->dim == 3 && levels[0] != 0 && levels[1] != 0 && levels[2] != 0){
283 for(
int i=0;i<2;i++){
284 for(
int j=0;j<2;j++){
285 for(
int k=0;k<2;k++){
286 coords = p.getCoords();
287 coords[0] += 0.5*corn(i)*h[0];
288 coords[1] += 0.5*corn(j)*h[1];
289 coords[2] += 0.5*corn(k)*h[2];
291 surplus -= 0.125*(ipc.*func)(coords);
305void SGIntegrator::decideMinMax(D3vector &min, D3vector &max, D3vector &levels){
306 for(
int i=0;i<3;i++){
317 max[i] = pow(2,levels[i])-1;
324double SGIntegrator::subspaceIntegral(
IntegratorPoissonCurved& ipc, Curvedfunc funcToIntegrate,
int level_x,
int level_y,\
327 D3vector levels(level_x,level_y,level_z);
328 D3vector locs,boundary_coords;
330 double subspace_integral = 0.0;
333 decideMinMax(min,max,levels);
335 for(
int i = min[0]; i <= max[0] ;i += 2){
336 for(
int j = min[1]; j <= max[1];j += 2){
337 for(
int k = min[2]; k <= max[2];k += 2){
338 locs[0] = i; locs[1] = j; locs[2] = k;
340 grid_point.reset(levels,locs,limit1,limit2);
342 subspace_integral += findHierarchicalSurplus(ipc,grid_point,funcToIntegrate)*grid_point.volume(this->dim);
346 return subspace_integral;
349double SGIntegrator::smolyakIntegrate(
IntegratorPoissonCurved& ipc, Curvedfunc funcToIntegrate, D3vector &limit1, D3vector &limit2,
int max_level){
350 double integral = 0.0;
353 this->limit1 = limit1;
354 this->limit2 = limit2;
357 bool dim_2 = (this->dim >= 2);
358 bool dim_3 = (this->dim >= 3);
360 for(
int i=0;i<=max_level;i++){
362 max_y = max_level-i+this->dim-1;
365 for(
int j=0;j<=max_y;j++){
367 max_z = max_level-i-j+this->dim-1;
370 for(
int k=0;k<=max_z;k++){
372 integral += subspaceIntegral(ipc,funcToIntegrate,i,j,k);
379double SGIntegrator::integrate(
IntegratorPoissonCurved& ipc, Curvedfunc funcToIntegrate,D3vector &limit1, D3vector &limit2){
380 double integral = 0.0;
381 double loc_integral = 1.0;
382 double surplus = 0.0;
385 this->limit1 = limit1;
386 this->limit2 = limit2;
389 D3vector levels_0(0.0,0.0,0.0);
393 bool dim_2 = (this->dim >= 2);
394 bool dim_3 = (this->dim >= 3);
397 for(
int i = 0;i <= 2;i += 2){
400 for(
int j = 0;j <= max_y;j += 2){
403 for(
int k = 0;k <= max_z; k += 2){
404 locs[0] = i; locs[1] = j; locs[2] = k;
405 current.reset(levels_0,locs,limit1,limit2);
406 refine_queue.push(current);
412 while(!refine_queue.empty()){
413 current = refine_queue.front();
416 if(std::find(refined_set.begin(),refined_set.end(),current) == refined_set.end()){
419 surplus = findHierarchicalSurplus(ipc,current,funcToIntegrate);
421 loc_integral = surplus;
422 loc_integral = surplus*current.volume(this->dim);
423 integral += loc_integral;
427 refined_set.push_back(current);
430 if(fabs(surplus) >= this->tol || current.getLevels() == levels_0){
Definition curvedPoissonIntegrator.h:19