00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define DEBUG false
00022
00023
00024 #ifdef COMP_GNUOLD
00025 #include <iostream.h>
00026 #include <fstream.h>
00027 #include <time.h>
00028 #include <math.h>
00029 #else
00030 #include <iostream>
00031 #include <fstream>
00032 #include <ctime>
00033 #include <cmath>
00034 #endif
00035
00036
00037
00038 #include "../parser.h"
00039
00040
00041 #include "../paramete.h"
00042 #include "../abbrevi.h"
00043 #include "../math_lib/math_lib.h"
00044
00045
00046 #include "../basic/basic.h"
00047
00048
00049 #include "../domain/domain.h"
00050
00051
00052 #include "gpar.h"
00053 #include "parallel.h"
00054
00055 int MY_RANK;
00056
00057 Parallel_Info::~Parallel_Info() {
00058 for(int d=0;d<26;++d) {
00059 delete buffer_send[d];
00060 delete buffer_receive[d];
00061 }
00062 delete buffer_send_info;
00063 delete buffer_receive_info;
00064
00065
00066 int i_iter;
00067 Point_hashtable_proc* poi;
00068 for(i_iter=0;i_iter<hashtable_proc_leng;++i_iter) {
00069 poi=hashtable_proc_start[i_iter];
00070 delete poi;
00071 }
00072 delete hashtable_proc_start;
00073
00074 Point_hashtable_proc_corner* poic;
00075 for(i_iter=0;i_iter<hashtable_proc_corner_leng;++i_iter) {
00076 poic=hashtable_proc_corner_start[i_iter];
00077 delete poic;
00078 }
00079 delete hashtable_proc_corner_start;
00080 }
00081
00082 Parallel_Info::Parallel_Info(All_Domains* dom, MPI_Comm com) :
00083 domain(dom), comm(com) {
00084
00085
00086 for(int d=0;d<26;++d) {
00087 length_send[d] = 2;
00088 length_receive[d] = 2;
00089 buffer_send[d] = new double[2];
00090 buffer_receive[d] = new double[2];
00091 }
00092 length_send_info = 2;
00093 length_receive_info = 2;
00094 buffer_send_info = new int[2];
00095 buffer_receive_info = new int[2];
00096
00097
00098 MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
00099 MPI_Comm_size(MPI_COMM_WORLD, &p);
00100
00101
00102 Initialize_hash_proc(2*p);
00103 Initialize_hash_proc_corner(2*p);
00104
00105 MY_RANK=my_rank;
00106 }
00107
00108
00109
00110
00111 Parallel_Info::Parallel_Info(int n_max, All_Domains* dom,
00112 int pp, Grid_gen_parameters& gpara) :
00113 domain(dom) {
00114
00115
00116 refine_level = gpara.Give_r_parallel();
00117
00118
00119 double offset_square;
00120 double h_offset;
00121 offset_square = gpara.Give_offset_square();
00122 h_offset = offset_square * dom->GiveH() / Zweipotenz(n_max);
00123
00124
00125 A_bounding = dom->GiveA() + D3vector(-h_offset, -h_offset, -h_offset);
00126 H_bounding = dom->GiveH()+2.0*h_offset;
00127 H_bounding = gpara.Give_stretch_square() * H_bounding;
00128 max_level = n_max;
00129
00130
00131 if(gpara.Is_there_grid_point()) {
00132 make_grid_with_grid_point(gpara.Give_grid_point(),
00133 H_bounding / Zweipotenz(max_level));
00134 }
00135
00136
00137 for(int d=0;d<26;++d) {
00138 length_send[d] = 2;
00139 length_receive[d] = 2;
00140 buffer_send[d] = new double[2];
00141 buffer_receive[d] = new double[2];
00142 }
00143 length_send_info = 2;
00144 length_receive_info = 2;
00145 buffer_send_info = new int[2];
00146 buffer_receive_info = new int[2];
00147
00148
00149 my_rank=0;
00150 p = pp;
00151
00152
00153 Initialize_hash_proc(2*p);
00154 Initialize_hash_proc_corner(2*p);
00155
00156 MY_RANK=my_rank;
00157
00158
00159 Generate_processes();
00160 }
00161
00162 Parallel_Info::Parallel_Info(double h_finest_level, All_Domains* dom,
00163 int pp, Grid_gen_parameters& gpara) :
00164 domain(dom) {
00165 double h_offset, offset_square;
00166 int i;
00167
00168
00169 refine_level = gpara.Give_r_parallel();
00170
00171
00172 offset_square = gpara.Give_offset_square();
00173 h_offset = offset_square * h_finest_level;
00174
00175 A_bounding = dom->GiveA() + D3vector(-h_offset, -h_offset, -h_offset);
00176 H_bounding = dom->GiveH()+2.0*h_offset;
00177 H_bounding = gpara.Give_stretch_square() * H_bounding;
00178
00179
00180 if(h_finest_level > H_bounding / 4.0)
00181 cout << " Coose large meshsize h_finest_level!! " << endl;
00182
00183 if(gpara.Is_there_grid_point()) {
00184 make_grid_with_grid_point(gpara.Give_grid_point(),h_finest_level);
00185 }
00186
00187 for(i=2;(i<Max_number_levels) &&
00188 (H_bounding > ((double)(Zweipotenz(i)) * h_finest_level));i++) { };
00189
00190 max_level = i;
00191 H_bounding = Zweipotenz(max_level) * h_finest_level;
00192
00193
00194
00195
00196
00197 if(gpara.Is_there_grid_point()) {
00198 make_grid_with_grid_point(gpara.Give_grid_point(),
00199 H_bounding / Zweipotenz(max_level));
00200 }
00201
00202
00203 for(int d=0;d<26;++d) {
00204 length_send[d] = 2;
00205 length_receive[d] = 2;
00206 buffer_send[d] = new double[2];
00207 buffer_receive[d] = new double[2];
00208 }
00209 length_send_info = 2;
00210 length_receive_info = 2;
00211 buffer_send_info = new int[2];
00212 buffer_receive_info = new int[2];
00213
00214
00215 my_rank=0;
00216 p = pp;
00217
00218
00219 Initialize_hash_proc(2*p);
00220 Initialize_hash_proc_corner(2*p);
00221
00222 MY_RANK=my_rank;
00223
00224
00225 Generate_processes();
00226 }
00227
00228 void Parallel_Info::process_info() {
00229 cout << " Information about processes: " << endl;
00230 cout << " Number of processes: " << give_number_of_processes() << endl;
00231 cout << " Number of active processes: "
00232 << give_number_of_active_processes() << endl;
00233 #ifdef PERIODIC
00234 cout << " Periodic BC in z selected " << endl;
00235 #endif
00236 if(parallel_version == false) {
00237 cout << " This is the serial version! " << endl;
00238 }
00239 }
00240
00241 Index3D Parallel_Info::Give_level_index_of(int rang, int level) {
00242 if(level > n_parallel)
00243 level = n_parallel;
00244 iterate_hash_proc {
00245 if(point_proc->num_proc == rang)
00246 if(point_proc->Give_Index().Tiefe()==level)
00247 return point_proc->Give_Index();
00248 }
00249
00250
00251 return Index3D(3,3,3);
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 void Parallel_Info::Generate_processes() {
00268 Partitioning* pointer_parti;
00269 Partitioning* pointer_parti_old;
00270 rough_domain *pointer_rough_domain;
00271 int opt_I, opt_J, opt_K, n_nec, n_interior;
00272 int opt_I_old, opt_J_old, opt_K_old, n_nec_old, n_interior_old;
00273 int i;
00274
00275
00276
00277 for(p_level=0;Zweipotenz(p_level*3)<=p;++p_level) {};
00278 --p_level;
00279
00280
00281
00282
00283 pointer_parti = NULL;
00284 pointer_parti_old = NULL;
00285 for(n_nec=p-1;n_nec<p && p_level<max_level;++p_level) {
00286
00287 pointer_rough_domain = new rough_domain(p_level,refine_level,domain,
00288 A_bounding,H_bounding);
00289 n_interior_old = n_interior;
00290 n_interior = pointer_rough_domain->Give_n_interior();
00291
00292
00293
00294 n_nec_old = n_nec;
00295 opt_I_old = opt_I; opt_J_old = opt_J; opt_K_old = opt_K;
00296 if(pointer_parti_old!=NULL) delete(pointer_parti_old);
00297 pointer_parti_old = pointer_parti;
00298 pointer_parti = new Partitioning(p_level);
00299
00300 n_nec =
00301 pointer_rough_domain->Calc_optimal_partitioning(p,opt_I,opt_J,opt_K,
00302 pointer_parti);
00303
00304 delete(pointer_rough_domain);
00305
00306 if(DEBUG) {
00307 MPI_Barrier(MPI_COMM_WORLD);
00308 if(my_rank==0) {
00309
00310 cout << " Iteration: "
00311 << " p_level: " << p_level
00312 << " max_level: " << max_level
00313 << " n_nec: " << n_nec << endl;
00314 cout << " partitioning: " << endl;
00315 pointer_parti->Print();
00316
00317 }
00318 MPI_Barrier(MPI_COMM_WORLD);
00319 }
00320
00321 }
00322
00323 if(n_nec==p) {
00324 if(pointer_parti_old!=NULL) delete(pointer_parti_old);
00325 p_level=p_level-1;
00326 }
00327
00328 else {
00329 delete(pointer_parti);
00330 pointer_parti = pointer_parti_old;
00331 n_nec = n_nec_old;
00332 opt_I = opt_I_old; opt_J = opt_J_old; opt_K = opt_K_old;
00333 n_interior = n_interior_old;
00334 p_level=p_level-2;
00335 }
00336 if(MY_RANK==0) if(p_level>=max_level-2)
00337 cout << "\n Choose large value for n_level! \n" << endl;
00338
00339
00340 if(n_nec > p)
00341 cout << " Not implemented: Error in Parallel_Info::Generate_processes() "
00342 << endl;
00343
00344
00345 n_parallel=p_level+2;
00346
00347
00348
00349 if(domain->Is_periodic()) {
00350
00351 n_parallel=p_level+1;
00352
00353 }
00354 else {
00355 n_parallel=p_level+2;
00356
00357 max_level = max_level+1;
00358 A_bounding = A_bounding -
00359 H_bounding/(double)n_interior
00360 * D3vector((double)opt_I,(double)opt_J,(double)opt_K);
00361 H_bounding = H_bounding*2.0;
00362 }
00363
00364 if(MY_RANK==0) if(n_parallel>max_level-2)
00365 cout << "\n Error : Choose a finer grid or less processors! \n" << endl;
00366
00367 if(DEBUG) {
00368 cout << " opt_I " << opt_I << endl;
00369 cout << " opt_J " << opt_J << endl;
00370 cout << " opt_K " << opt_K << endl;
00371
00372 if(MY_RANK==0)
00373 cout << " take p_level: " << p_level
00374 << " max_level: " << max_level
00375 << " p_level: " << p_level
00376 << " n_parallel: " << n_parallel << endl;
00377 }
00378
00379 if(domain->Is_periodic()) {
00380
00381 Ixl = Index1D(0);
00382 Iyl = Index1D(0);
00383 Izl = Index1D(0);
00384
00385 Ixr = Index1D(1);
00386 Iyr = Index1D(1);
00387 Izr = Index1D(1);
00388 }
00389 else {
00390 Ixl = Index1D(0);
00391 Iyl = Index1D(0);
00392 Izl = Index1D(0);
00393
00394 for(i=0;i<opt_I;++i) Ixl = Ixl.next(Rd,p_level+refine_level+1);
00395 for(i=0;i<opt_J;++i) Iyl = Iyl.next(Rd,p_level+refine_level+1);
00396 for(i=0;i<opt_K;++i) Izl = Izl.next(Rd,p_level+refine_level+1);
00397
00398
00399 Ixr = Ixr.next(Rd,1);
00400 Iyr = Iyr.next(Rd,1);
00401 Izr = Izr.next(Rd,1);
00402 for(i=0;i<opt_I;++i) Ixr = Ixr.next(Rd,p_level+refine_level+1);
00403 for(i=0;i<opt_J;++i) Iyr = Iyr.next(Rd,p_level+refine_level+1);
00404 for(i=0;i<opt_K;++i) Izr = Izr.next(Rd,p_level+refine_level+1);
00405 }
00406
00407 pxl = Ixl.coordinate(); pyl = Iyl.coordinate(); pzl = Izl.coordinate();
00408 pxr = Ixr.coordinate(); pyr = Iyr.coordinate(); pzr = Izr.coordinate();
00409
00410
00411 Index3D ind(2,2,2);
00412
00413 if(n_parallel==1) {
00414 Add_proc_cell(ind);
00415 }
00416 else {
00417 Recursion_study_cells(ind, pointer_parti);
00418 }
00419
00420 if(DEBUG) {
00421 MPI_Barrier(MPI_COMM_WORLD);
00422 if(my_rank==0) {
00423 cout << " partitioning: " << endl;
00424 pointer_parti->Print();
00425 }
00426 MPI_Barrier(MPI_COMM_WORLD);
00427 }
00428
00429
00430 if(p < hashtable_proc_occ) {
00431 cout << " Number of processes is too small! "
00432 << p << ", active: "
00433 << hashtable_proc_occ << endl;
00434 return;
00435 }
00436
00437
00438 i=0;
00439 iterate_hash_proc {
00440 if(point_proc!=NULL) {
00441 point_proc->num_proc = i;
00442 if(i==my_rank) my_index = point_proc->Give_Index();
00443 ++i;
00444 }
00445 }
00446
00447
00448
00449 number_of_active_procs = hashtable_proc_occ;
00450
00451
00452 Calc_coarse_processors();
00453
00454
00455
00456 Set_rank_3D();
00457
00458
00459 if(I_am_active()) {
00460 for(i=0;i<6;++i) {
00461 coarse_faces[i] = my_index.surface((dir_3D)i);
00462 info_coarse_faces[i] = give_next_rank_destination((dir_3D)i,
00463 n_parallel-1) >= 0;
00464 }
00465 for(i=0;i<12;++i) {
00466 coarse_edges[i] = my_index.edge((Edges_cell)i);
00467 info_coarse_edges[i] = give_next_rank_destination((Edges_cell)i) >= 0;
00468 }
00469 for(i=0;i<8;++i) {
00470 coarse_corners[i] = my_index.neighbour((dir_sons)i);
00471 info_coarse_corners[i] = give_next_rank_destination((dir_sons)i) >= 0;
00472 info_coarse_corners[i] = true;
00473 }
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 if(DEBUG) {
00487 MPI_Barrier(MPI_COMM_WORLD);
00488 cout.precision(4);
00489 cout << " my_rank: " << my_rank
00490 << " my old bounding_box: "
00491 << " xl: " << pxl << " yl: " << pyl << " zl: " << pzl
00492 << " xr: " << pxr << " yr: " << pyr << " zr: " << pzr
00493 << endl;
00494 cout.precision(8);
00495 MPI_Barrier(MPI_COMM_WORLD);
00496 }
00497
00498
00499 delete(pointer_parti);
00500
00501
00502
00503
00504
00505
00506 if(DEBUG) {
00507
00508 MPI_Barrier(MPI_COMM_WORLD);
00509 if(my_rank==0) {
00510 cout << " procs von 0: " << endl;
00511 iterate_hash_proc {
00512 cout << " processor "
00513 << " x: " << point_proc->Give_Index().I_x().coordinate()
00514 << " y: " << point_proc->Give_Index().I_y().coordinate()
00515 << " z: " << point_proc->Give_Index().I_z().coordinate()
00516 << endl;
00517 }
00518 }
00519
00520 MPI_Barrier(MPI_COMM_WORLD);
00521 D3vector cooo;
00522 if(my_rank==0) {
00523 cout << " Physical Informations: " << endl;
00524 A_bounding.Print();
00525 cout << " \n "
00526 << H_bounding
00527 << endl;
00528
00529 cout << " procs von 0 physical: " << endl;
00530
00531 iterate_hash_proc {
00532 cooo = coord_in_domain(point_proc->Give_Index());
00533 cout << " processor "
00534 << " x: " << cooo.x
00535 << " y: " << cooo.y
00536 << " z: " << cooo.z
00537 << endl;
00538 }
00539 }
00540
00541 MPI_Barrier(MPI_COMM_WORLD);
00542 cout << " my_rank: " << my_rank
00543 << " x: " << my_index.I_x().coordinate()
00544 << " y: " << my_index.I_y().coordinate()
00545 << " z: " << my_index.I_z().coordinate()
00546 << " \n "
00547 << " x: " << my_index.I_x().get()
00548 << " y: " << my_index.I_y().get()
00549 << " z: " << my_index.I_z().get()
00550 << endl;
00551 MPI_Barrier(MPI_COMM_WORLD);
00552 }
00553
00554
00555
00556
00557 }
00558
00559
00560 void Parallel_Info::Generate_seriel_process() {
00561 int i;
00562
00563
00564 pxl = 0.0; pyl = 0.0; pzl = 0.0;
00565 pxr = 1.0; pyr = 1.0; pzr = 1.0;
00566
00567
00568 Index3D ind(2,2,2);
00569 my_index = ind;
00570
00571 my_rank=0;
00572 n_parallel = 0;
00573 my_coarsest_level = 0;
00574
00575
00576 for(i=0;i<6;++i) {
00577 coarse_faces[i] = my_index.surface((dir_3D)i);
00578 info_coarse_faces[i] = give_next_rank_destination((dir_3D)i,
00579 n_parallel-1) >= 0;
00580 }
00581 for(i=0;i<12;++i) {
00582 coarse_edges[i] = my_index.edge((Edges_cell)i);
00583 info_coarse_edges[i] = give_next_rank_destination((Edges_cell)i) >= 0;
00584 }
00585 for(i=0;i<8;++i) {
00586 coarse_corners[i] = my_index.neighbour((dir_sons)i);
00587 info_coarse_corners[i] = give_next_rank_destination((dir_sons)i) >= 0;
00588 info_coarse_corners[i] = true;
00589 }
00590 }
00591
00592 void Parallel_Info::make_grid_with_grid_point(D3vector gp, double fms) {
00593 double new_q;
00594 D3vector move_v;
00595 if(A_bounding.x >= gp.x ||
00596 A_bounding.y >= gp.y ||
00597 A_bounding.z >= gp.z ||
00598 A_bounding.x+H_bounding <= gp.x ||
00599 A_bounding.y+H_bounding <= gp.y ||
00600 A_bounding.z+H_bounding <= gp.z) {
00601 cout << " \n Error: Grid point is too far away from domain! \n" << endl;
00602 }
00603 else {
00604 for(new_q=gp.x;A_bounding.x<new_q;new_q=new_q-fms) {};
00605 move_v.x = A_bounding.x-new_q;
00606
00607 for(new_q=gp.y;A_bounding.y<new_q;new_q=new_q-fms) {};
00608 move_v.y = A_bounding.y-new_q;
00609
00610 for(new_q=gp.z;A_bounding.z<new_q;new_q=new_q-fms) {};
00611 move_v.z = A_bounding.z-new_q;
00612
00613 H_bounding = H_bounding + L_infty(move_v);
00614 A_bounding = A_bounding - move_v;
00615 }
00616 }
00617
00618 bool Parallel_Info::contained_in_old_bounding_box(Index3D I) const {
00619 if(I.I_x()==Ixl || I.I_x()==Ixr ||
00620 I.I_y()==Iyl || I.I_y()==Iyr ||
00621 I.I_z()==Izl || I.I_z()==Izr) return false;
00622 double s;
00623 s = I.I_x().coordinate();
00624 if(s<pxl || s>pxr) return false;
00625 s = I.I_y().coordinate();
00626 if(s<pyl || s>pyr) return false;
00627 s = I.I_z().coordinate();
00628 if(s<pzl || s>pzr) return false;
00629 return true;
00630 }
00631
00632
00633
00634 bool Parallel_Info::contained_in_boxes(Index3D I) const {
00635 int i;
00636
00637 #ifndef PERIODIC
00638 if(contained_in_old_bounding_box(I)) {
00639 #endif
00640
00641 if(my_index<=I) return true;
00642 for(i=0;i<6;++i) {
00643 if(coarse_faces[i]>>I) {
00644 if(info_coarse_faces[i]==false) return false;
00645 else if(coarse_faces[i]<=I) return true;
00646 }
00647 }
00648 for(i=0;i<12;++i) {
00649 if(coarse_edges[i]>>I) {
00650 if(info_coarse_edges[i]==false) return false;
00651 else if(coarse_edges[i]<=I) return true;
00652 }
00653 }
00654 for(i=0;i<8;++i) {
00655 if(coarse_corners[i]==I) {
00656 if(info_coarse_corners[i]==false) return false;
00657 }
00658 }
00659
00660
00661 return true;
00662 #ifndef PERIODIC
00663 }
00664 return false;
00665 #endif
00666 }
00667
00668
00669
00670 int Parallel_Info::give_next_rank_source(Edges_cell ed) {
00671 int t;
00672 Index3D next, sp;
00673
00674 ed = opposite3D(ed);
00675
00676 t = my_index.Tiefe();
00677 sp = my_index.next(ed,t);
00678
00679 #ifndef PERIODIC
00680 if(sp.I_x()==Index1D(0) || sp.I_y()==Index1D(0) || sp.I_z()==Index1D(0) ||
00681 sp.I_x()==Index1D(1) || sp.I_y()==Index1D(1) || sp.I_z()==Index1D(1))
00682 return -1;
00683 #endif
00684
00685 next = sp.next(ed,t);
00686
00687 iterate_hash_proc {
00688 if(point_proc!=NULL)
00689 if(point_proc->Give_Index() == next) {
00690 if(point_proc->num_proc == my_rank) return -1;
00691 return point_proc->num_proc;
00692 }
00693 }
00694 return -1;
00695 };
00696
00697 int Parallel_Info::give_next_rank_destination(Edges_cell ed) {
00698
00699 int t;
00700 Index3D next, sp;
00701
00702 t = my_index.Tiefe();
00703 sp = my_index.next(ed,t);
00704 #ifndef PERIODIC
00705 if(sp.I_x()==Index1D(0) || sp.I_y()==Index1D(0) || sp.I_z()==Index1D(0) ||
00706 sp.I_x()==Index1D(1) || sp.I_y()==Index1D(1) || sp.I_z()==Index1D(1))
00707 return -1;
00708 #endif
00709
00710 next = sp.next(ed,t);
00711
00712 iterate_hash_proc {
00713 if(point_proc!=NULL)
00714 if(point_proc->Give_Index() == next) {
00715 if(point_proc->num_proc == my_rank) return -1;
00716 return point_proc->num_proc;
00717 }
00718 }
00719 return -1;
00720 };
00721
00722
00723 int Parallel_Info::give_next_rank_destination(dir_sons d) {
00724
00725 int t;
00726 Index3D next, sp;
00727
00728 t = my_index.Tiefe();
00729 sp = my_index.next(d,t);
00730
00731 #ifndef PERIODIC
00732 if(sp.I_x()==Index1D(0) || sp.I_y()==Index1D(0) || sp.I_z()==Index1D(0) ||
00733 sp.I_x()==Index1D(1) || sp.I_y()==Index1D(1) || sp.I_z()==Index1D(1))
00734 return -1;
00735 #endif
00736
00737 next = sp.next(d,t);
00738
00739 iterate_hash_proc {
00740 if(point_proc!=NULL)
00741 if(point_proc->Give_Index() == next) {
00742 if(point_proc->num_proc == my_rank) return -1;
00743 return point_proc->num_proc;
00744 }
00745 }
00746 return -1;
00747 };
00748
00749 int Parallel_Info::give_next_rank_source(dir_sons d) {
00750
00751 int t;
00752 Index3D next, sp;
00753 dir_sons dd;
00754
00755 dd = d;
00756 d = opposite3D(dd);
00757
00758 t = my_index.Tiefe();
00759 sp = my_index.next(d,t);
00760
00761 #ifndef PERIODIC
00762 if(sp.I_x()==Index1D(0) || sp.I_y()==Index1D(0) || sp.I_z()==Index1D(0) ||
00763 sp.I_x()==Index1D(1) || sp.I_y()==Index1D(1) || sp.I_z()==Index1D(1))
00764 return -1;
00765 #endif
00766
00767 next = sp.next(d,t);
00768
00769 iterate_hash_proc {
00770 if(point_proc!=NULL)
00771 if(point_proc->Give_Index() == next) {
00772 if(point_proc->num_proc == my_rank) return -1;
00773 return point_proc->num_proc;
00774 }
00775 }
00776 return -1;
00777 };
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802 Index3D Parallel_Info::Give_next_on_level(int d,
00803 Index3D me) {
00804 int t;
00805 Index3D nextS;
00806
00807 t = me.Tiefe();
00808
00809 if(d<6) {
00810 nextS = me.next((dir_3D)d,t);
00811 nextS = nextS.next((dir_3D)d,t);
00812 }
00813 else if(d<18) {
00814 nextS = me.next((Edges_cell)(d-6),t);
00815 nextS = nextS.next((Edges_cell)(d-6),t);
00816 }
00817 else {
00818 nextS = me.next((dir_sons)(d-18),t);
00819 nextS = nextS.next((dir_sons)(d-18),t);
00820 }
00821 return nextS;
00822 }
00823
00824 void Parallel_Info::Calc_coarse_processors() {
00825 Index3D next, nnext;
00826 int i, l, rrr;
00827 bool found;
00828 Point_hashtable_proc* ppp;
00829
00830 dir_sons priority[8];
00831 priority[0] = ENTd;
00832 priority[1] = ENDd; priority[2] = ESTd; priority[3] = WNTd;
00833 priority[4] = ESDd; priority[5] = WNDd; priority[6] = WSTd;
00834 priority[7] = WSDd;
00835
00836 min_level = 1;
00837
00838
00839
00840 Index3D ind(2,2,2);
00841 Recursion_calc_coarse_processors(ind);
00842
00843
00844 iterate_hash_proc {
00845 ind = point_proc->Give_Index();
00846 l = ind.Tiefe();
00847 for(i=0;i<8;++i)
00848 Add_proc_corner(ind.neighbour((dir_sons)i),l-1);
00849 }
00850
00851 for(l=n_parallel;l>=min_level+1;--l) {
00852
00853 iterate_hash_proc {
00854 point_proc->used_on_coarser_grid=false;
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 iterate_hash_proc_corner {
00876 ind = point_proc_corner->ind;
00877
00878 if(ind.Tiefe()<l-1 &&
00879 point_proc_corner->maximal_level>=l-1) {
00880 found=false;
00881
00882 for(i=0;i<8 && found==false;++i) {
00883 next = ind.next(priority[i],l);
00884 if(Exists_proc(next)) {
00885 found = true;
00886
00887
00888 ppp = hashtable_proc_point(next);
00889 ppp->used_on_coarser_grid=true;
00890 rrr = ppp->num_proc;
00891
00892
00893 next = ind.next(ENTd,l-1);
00894 if(Exists_proc(next)==false) {
00895 Add_proc_cell(next);
00896 ppp = hashtable_proc_point(next);
00897 ppp->interior_processor = false;
00898 }
00899 else
00900 ppp = hashtable_proc_point(next);
00901 ppp->num_proc = rrr;
00902
00903
00904 point_proc_corner->num_proc = rrr;
00905 }
00906 }
00907 }
00908 }
00909
00910
00911 iterate_hash_proc_corner {
00912 ind = point_proc_corner->ind;
00913 if(ind.Tiefe()==l-1 &&
00914 point_proc_corner->maximal_level>=l-1) {
00915 found=false;
00916 for(i=0;i<8 && found==false;++i) {
00917 next = ind.next(priority[i],l);
00918 if(Exists_proc(next)) {
00919 found = true;
00920
00921
00922 ppp = hashtable_proc_point(next);
00923 rrr = ppp->num_proc;
00924
00925
00926 point_proc_corner->num_proc = rrr;
00927 }
00928 }
00929 if(developer_version) {
00930 if(found==false)
00931 cout << " error in Calc_coarse_processors(). 5. " << endl;
00932 }
00933 }
00934 }
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951 iterate_hash_proc {
00952 ind = point_proc->Give_Index();
00953 if(ind.Tiefe()==l-1) {
00954 if(point_proc->num_proc <0) {
00955
00956 found=false;
00957 for(i=0;i<8 && found==false;++i) {
00958 next = ind.son((dir_sons)i);
00959 if(Exists_proc(next)) {
00960 ppp = hashtable_proc_point(next);
00961 if(ppp->used_on_coarser_grid==false) {
00962
00963 found=true;
00964 point_proc->num_proc = ppp->num_proc;
00965 }
00966 }
00967 }
00968 if(found==false) {
00969 cout << " \n \n rise minimal level to: "
00970 << l-1 << endl;
00971 if(min_level<l-1)
00972 min_level = l-1;
00973 }
00974 }
00975 }
00976 }
00977 }
00978
00979
00980
00981
00982 if(I_am_active()) {
00983 int level;
00984 my_level_index = new Index3D[n_parallel];
00985 my_coarsest_level = n_parallel-1;
00986 for(level=n_parallel-1;level>min_level;level--) {
00987 my_level_index[level] = my_index.son(ENTd);
00988 iterate_hash_proc {
00989 if(point_proc!=NULL)
00990 if(point_proc->Give_Index().Tiefe() == level &&
00991 point_proc->num_proc==my_rank) {
00992 my_level_index[level] = point_proc->Give_Index();
00993 my_coarsest_level = level-1;
00994 }
00995 }
00996 }
00997 if(my_coarsest_level<1)
00998 my_coarsest_level=1;
00999 }
01000
01001
01002
01003 }
01004
01005
01006 void Parallel_Info::Recursion_calc_coarse_processors(Index3D I) {
01007 int level, i;
01008 bool no_sons;
01009
01010 level = I.Tiefe();
01011
01012 if(level<n_parallel-1) {
01013
01014 for(i=0;i<8;++i)
01015 Recursion_calc_coarse_processors(I.son((dir_sons)i));
01016 }
01017
01018 no_sons = true;
01019 for(i=0;i<8;++i)
01020 if(exists_process(I.son((dir_sons)i))) no_sons = false;
01021 if(no_sons == false) {
01022
01023 Add_proc_cell(I);
01024 }
01025 }
01026
01027 Index3D Parallel_Info::Give_my_level_index(int level) {
01028 if(level>=n_parallel) return my_index;
01029 return my_level_index[level];
01030 }
01031
01032 void Parallel_Info::Print_processors() {
01033 if(my_rank==0) {
01034 for(int l=n_parallel;l>=1;--l) {
01035 cout << " Processors on level: " << l << endl;
01036 iterate_hash_proc {
01037 if(point_proc->Give_Index().Tiefe() == l) {
01038 point_proc->Give_Index().coordinate().Print();
01039 cout << " rank: " << point_proc->num_proc << endl;
01040 }
01041 }
01042 }
01043 }
01044 }
01045
01046 void Parallel_Info::Set_rank_3D() {
01047 Index3D next, sp;
01048 bool stop;
01049 int d, num_pp;
01050 int lev;
01051
01052 if(I_am_active()) {
01053
01054
01055
01056
01057 for(d=0;d<6;++d) {
01058 stop=false;
01059 sp = my_index.next((dir_3D)d,my_index.Tiefe());
01060
01061 #ifndef PERIODIC
01062 if(sp.I_q(Main_direction((dir_3D)d))==OneDpart((dir_3D)d)) {
01063 next_rank_destination[d] = -1;
01064 next_rank_source[opposite3D((dir_3D)d)] = -1;
01065 stop = true;
01066 }
01067 #endif
01068 next = sp.next((dir_3D)d,my_index.Tiefe());
01069
01070 if(stop==false) {
01071 iterate_hash_proc {
01072 if(point_proc!=NULL)
01073 if(point_proc->Give_Index() == next) {
01074
01075 next_rank_destination[d] = point_proc->num_proc;
01076 next_rank_source[opposite3D((dir_3D)d)] = point_proc->num_proc;
01077 stop = true;
01078 }
01079 }
01080 }
01081 if(stop==false) {
01082
01083 next_rank_destination[d]=-1;
01084 next_rank_source[opposite3D((dir_3D)d)]=-1;
01085 }
01086 }
01087
01088
01089 for(d=0;d<6;++d) {
01090 next_rank_source_coarse[d] = new int[n_parallel-1];
01091 next_rank_destination_coarse[d] = new int[n_parallel-1];
01092 }
01093
01094
01095 for(d=0;d<6;++d) for(lev=0;lev<my_coarsest_level;++lev) {
01096 next_rank_source_coarse[d][lev] = -1;
01097 next_rank_destination_coarse[d][lev] = -1;
01098 }
01099
01100 for(d=0;d<6;++d) for(lev=my_coarsest_level;lev<n_parallel-1;++lev) {
01101 sp = my_level_index[lev+1].next((dir_3D)d,lev+1);
01102
01103 #ifndef PERIODIC
01104 if(sp.I_q(Main_direction((dir_3D)d))==OneDpart((dir_3D)d)) {
01105 next_rank_destination_coarse[d][lev] = -1;
01106 next_rank_source_coarse[opposite3D((dir_3D)d)][lev] = -1;
01107 }
01108 else
01109 #endif
01110 {
01111 next = sp.next((dir_3D)d,lev+1);
01112 num_pp = Give_proc_number(next);
01113 next_rank_destination_coarse[d][lev] = num_pp;
01114 next_rank_source_coarse[opposite3D((dir_3D)d)][lev] = num_pp;
01115 }
01116 }
01117
01118
01119
01120
01121
01122 for(d=0;d<12;++d) {
01123 next_rank_source_edges[d] =
01124 give_next_rank_source((Edges_cell)d);
01125 next_rank_destination_edges[d] =
01126 give_next_rank_destination((Edges_cell)d);
01127 }
01128
01129
01130 for(d=0;d<12;++d) {
01131 next_rank_source_coarse_edges[d] = new int[n_parallel-1];
01132 next_rank_destination_coarse_edges[d] = new int[n_parallel-1];
01133 }
01134
01135
01136 for(d=0;d<12;++d) for(lev=0;lev<my_coarsest_level;++lev) {
01137 next_rank_source_coarse_edges[d][lev] = -1;
01138 next_rank_destination_coarse_edges[d][lev] = -1;
01139 }
01140
01141 for(d=0;d<12;++d) for(lev=my_coarsest_level;lev<n_parallel-1;++lev) {
01142 sp = my_level_index[lev+1].next((Edges_cell)d,lev+1);
01143 next = sp.next((Edges_cell)d,lev+1);
01144
01145 num_pp = Give_proc_number(next);
01146 next_rank_destination_coarse_edges[d][lev] = num_pp;
01147 next_rank_source_coarse_edges[opposite3D((Edges_cell)d)][lev] = num_pp;
01148 }
01149
01150
01151
01152
01153
01154
01155 for(d=0;d<8;++d) {
01156 next_rank_source_corners[d] =
01157 give_next_rank_source((dir_sons)d);
01158 next_rank_destination_corners[d] =
01159 give_next_rank_destination((dir_sons)d);
01160 }
01161
01162
01163 for(d=0;d<8;++d) {
01164 next_rank_source_coarse_corners[d] = new int[n_parallel-1];
01165 next_rank_destination_coarse_corners[d] = new int[n_parallel-1];
01166 }
01167
01168
01169 for(d=0;d<8;++d) for(lev=0;lev<my_coarsest_level;++lev) {
01170 next_rank_source_coarse_corners[d][lev] = -1;
01171 next_rank_destination_coarse_corners[d][lev] = -1;
01172 }
01173
01174 for(d=0;d<8;++d) for(lev=my_coarsest_level;lev<n_parallel-1;++lev) {
01175 sp = my_level_index[lev+1].next((dir_sons)d,lev+1);
01176 next = sp.next((dir_sons)d,lev+1);
01177 num_pp = Give_proc_number(next);
01178 next_rank_destination_coarse_corners[d][lev]
01179 = num_pp;
01180 next_rank_source_coarse_corners[opposite3D((dir_sons)d)][lev]
01181 = num_pp;
01182 }
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217 }
01218 };
01219
01220 int* Parallel_Info::Give_buffer_send_info(int l) {
01221 if(length_send_info<l) {
01222 delete(buffer_send_info);
01223 buffer_send_info = new int[l];
01224 }
01225 return buffer_send_info;
01226 }
01227
01228 int* Parallel_Info::Give_buffer_receive_info(int l) {
01229 if(length_receive_info<l) {
01230 delete(buffer_receive_info);
01231 buffer_receive_info = new int[l];
01232 }
01233 return buffer_receive_info;
01234 }
01235
01236
01237 double* Parallel_Info::Give_buffer_send(int d, int l) {
01238 if(length_send[d]<l) {
01239 delete(buffer_send[d]);
01240 buffer_send[d] = new double[l];
01241 }
01242 return buffer_send[d];
01243 }
01244
01245 double* Parallel_Info::Give_buffer_receive(int d, int l) {
01246 if(length_receive[d]<l) {
01247 delete(buffer_receive[d]);
01248 buffer_receive[d] = new double[l];
01249 }
01250 return buffer_receive[d];
01251 }
01252
01253
01254
01255 void Parallel_Info::Recursion_study_cells(Index3D I, Partitioning* parti) {
01256 int i;
01257 Index3D I_neigh;
01258
01259 if(I.Tiefe() < n_parallel) {
01260 for(i=0;i<8;++i)
01261 Recursion_study_cells(I.son((dir_sons)i),parti);
01262 }
01263 else {
01264
01265 if(parti->Is_this_a_proc(I)) {
01266 Add_proc_cell(I);
01267 }
01268 }
01269 };
01270
01271 int Parallel_Info::Give_proc_number(Index3D I) {
01272 Point_hashtable_proc* ppp;
01273 ppp = hashtable_proc_point(I);
01274 if(ppp==NULL) return -1;
01275 return ppp->num_proc;
01276 }
01277
01278 bool Parallel_Info::Exists_proc(Index3D I) {
01279 Point_hashtable_proc* ppp;
01280 ppp = hashtable_proc_point(I);
01281 if(ppp==NULL) return false;
01282 return true;
01283 }
01284
01285 int Parallel_Info::Give_proc_corner_number(Index3D I) {
01286 Point_hashtable_proc_corner* ppp;
01287 ppp = hashtable_proc_corner_point(I);
01288 if(ppp==NULL) return -1;
01289 return ppp->num_proc;
01290 }
01291
01292 bool Parallel_Info::Exists_proc_corner(Index3D I) {
01293 Point_hashtable_proc_corner* ppp;
01294 ppp = hashtable_proc_corner_point(I);
01295 if(ppp==NULL) return false;
01296 return true;
01297 }
01298
01299 void Parallel_Info::Add_proc_cell(Index3D I) {
01300 static Point_hashtable_proc* point;
01301 point = hashtable_proc_start
01302 [hashtable_proc_function(I.ind_x.index,I.ind_y.index,I.ind_z.index,
01303 hashtable_proc_leng)];
01304 if(point==NULL) {
01305 hashtable_proc_occ++;
01306 point = new Point_hashtable_proc(I);
01307 hashtable_proc_start[hashtable_proc_function(I.ind_x.index,I.ind_y.index,
01308 I.ind_z.index,
01309 hashtable_proc_leng)] = point;
01310 }
01311 else {
01312 while(point->next!=NULL && point->ind!=I) point = point->next;
01313 if(point->ind!=I) {
01314 hashtable_proc_occ++;
01315 point->next = new Point_hashtable_proc(I);
01316 }
01317 }
01318 }
01319
01320 void Parallel_Info::Add_proc_corner(Index3D I, int l) {
01321 Point_hashtable_proc_corner* point;
01322 Point_hashtable_proc_corner* pp;
01323 point = hashtable_proc_corner_start
01324 [hashtable_proc_corner_function(I.ind_x.index,I.ind_y.index,I.ind_z.index,
01325 hashtable_proc_corner_leng)];
01326 if(point==NULL) {
01327 hashtable_proc_corner_occ++;
01328 point = new Point_hashtable_proc_corner(I);
01329 hashtable_proc_corner_start[hashtable_proc_corner_function(I.ind_x.index,
01330 I.ind_y.index,
01331 I.ind_z.index,
01332 hashtable_proc_corner_leng)] = point;
01333 pp = point;
01334 }
01335 else {
01336 while(point->next!=NULL && point->ind!=I) point = point->next;
01337 if(point->ind!=I) {
01338 hashtable_proc_corner_occ++;
01339 point->next = new Point_hashtable_proc_corner(I);
01340 pp = point->next;
01341 }
01342 else
01343 pp = point;
01344 }
01345 if(pp->maximal_level<l)
01346 pp->maximal_level=l;
01347 }
01348
01349
01350
01351 void Parallel_Info::Initialize_hash_proc(int lenght) {
01352 int i;
01353 hashtable_proc_leng = Find_next_prime(lenght);
01354 hashtable_proc_start = new Point_hashtable_proc*[hashtable_proc_leng];
01355 for(i=0;i<hashtable_proc_leng;++i)
01356 hashtable_proc_start[i] = NULL;
01357 hashtable_proc_occ=0;
01358 }
01359
01360 void Parallel_Info::Initialize_hash_proc_corner(int lenght) {
01361 int i;
01362 hashtable_proc_corner_leng = Find_next_prime(lenght);
01363 hashtable_proc_corner_start =
01364 new Point_hashtable_proc_corner*[hashtable_proc_corner_leng];
01365 for(i=0;i<hashtable_proc_corner_leng;++i)
01366 hashtable_proc_corner_start[i] = NULL;
01367 hashtable_proc_corner_occ=0;
01368 }
01369
01370
01371
01372
01373 inline void rough_domain::set(int i, int j, int k) {
01374 start[i+l*j+ll*k] = true;
01375 }
01376
01377 rough_domain::rough_domain(int P_level, int Refine_level, All_Domains* dom,
01378 D3vector A_bounding, double H_bounding) :
01379 p_level(P_level), refine_level(Refine_level) {
01380 int i,j,k;
01381 D3vector A;
01382 double h;
01383 bool nothing;
01384
01385
01386 is_periodic = dom->Is_periodic();
01387
01388
01389 n_interior = Zweipotenz(p_level+refine_level);
01390 n_side = Zweipotenz(refine_level);
01391 l = n_interior;
01392 ll = l*l;
01393
01394 start = new bool[l*l*l];
01395 for(i=0;i<l*l*l;++i) start[i]=false;
01396
01397
01398 A = A_bounding;
01399 h = H_bounding / (double)n_interior;
01400
01401 nothing=true;
01402 for(i=1;i<n_interior;++i)
01403 for(j=1;j<n_interior;++j)
01404 for(k=1;k<n_interior;++k) {
01405 if(dom->point_in_domain(D3vector(h*i,h*j,h*k)+A)) {
01406 nothing=false;
01407 set(i-1,j ,k); set(i,j ,k);
01408 set(i-1,j-1,k); set(i,j-1,k);
01409
01410 set(i-1,j ,k-1); set(i,j ,k-1);
01411 set(i-1,j-1,k-1); set(i,j-1,k-1);
01412 }
01413 }
01414
01415 if(nothing) {
01416 for(i=0;i<n_interior;++i)
01417 for(j=0;j<n_interior;++j)
01418 for(k=0;k<n_interior;++k)
01419 start[i+l*j+ll*k] =true;
01420 }
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436 };
01437
01438 rough_domain::~rough_domain() {
01439 delete(start);
01440 }
01441
01442 bool rough_domain::In_domain(int i, int j, int k) {
01443 if(developer_version) {
01444 if(i<1-n_side || j<1-n_side || k<1-n_side ||
01445 i>n_interior+n_side || j>n_interior+n_side || k>n_interior+n_side) {
01446 cout << " \n error in rough_domain::In_domain!!"
01447 << " i: " << i << " j: " << j << " k: " << k << endl;
01448 }
01449 }
01450 if(j<0 || i<0 || k<0 ||
01451 i>=n_interior || j>=n_interior || k>=n_interior) {
01452 return false;
01453 }
01454 return start[i+l*j+ll*k];
01455 };
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491 quality rough_domain::calc_quality(int I, int J, int K, int p) {
01492 int i,j,k,n_nec;
01493 int iS,jS,kS;
01494 int ii,jj,kk;
01495 int num_inter_sec, minimal_inter_sec, maximal_inter_sec;
01496 bool intersec;
01497
01498 minimal_inter_sec = (n_side+1)*(n_side+1)*(n_side+1);
01499 maximal_inter_sec = 0;
01500 n_nec=0;
01501 for(i=0;i<=n_interior/n_side;++i)
01502 for(j=0;j<=n_interior/n_side;++j)
01503 for(k=0;k<=n_interior/n_side;++k) {
01504 iS=-I+i*n_side;
01505 jS=-J+j*n_side;
01506 kS=-K+k*n_side;
01507
01508 num_inter_sec = 0;
01509 intersec = false;
01510 for(ii=0;ii<n_side;++ii)
01511 for(jj=0;jj<n_side;++jj)
01512 for(kk=0;kk<n_side;++kk) {
01513 if(In_domain(iS+ii,jS+jj,kS+kk)) {
01514 intersec=true;
01515
01516 ++num_inter_sec;
01517 }
01518 }
01519 if(intersec) {
01520 ++n_nec;
01521 if(num_inter_sec<minimal_inter_sec)
01522 minimal_inter_sec=num_inter_sec;
01523 if(num_inter_sec>maximal_inter_sec)
01524 maximal_inter_sec=num_inter_sec;
01525 }
01526 if(n_nec>p) return quality();
01527 }
01528
01529
01530
01531 return quality(n_nec,minimal_inter_sec,maximal_inter_sec);
01532
01533 };
01534
01535 void rough_domain::Set_partitioning(int I, int J, int K, Partitioning* parti) {
01536 int i,j,k;
01537 int iS,jS,kS;
01538 int ii,jj,kk;
01539 bool intersec;
01540
01541
01542
01543
01544
01545
01546 for(i=0;i<=n_interior/n_side;++i)
01547 for(j=0;j<=n_interior/n_side;++j)
01548 for(k=0;k<=n_interior/n_side;++k) {
01549 iS=-I+i*n_side;
01550 jS=-J+j*n_side;
01551 kS=-K+k*n_side;
01552
01553 intersec=false;
01554 for(ii=0;ii<n_side && intersec==false;++ii)
01555 for(jj=0;jj<n_side && intersec==false;++jj)
01556 for(kk=0;kk<n_side && intersec==false;++kk) {
01557 if(In_domain(iS+ii,jS+jj,kS+kk)) {
01558 intersec=true;
01559 }
01560 }
01561
01562 if(intersec==true) {
01563 parti->Put_proc(i,j,k);
01564 }
01565 }
01566 };
01567
01568
01569 int rough_domain::Calc_optimal_partitioning(int p,
01570 int& opt_I,int& opt_J,int& opt_K,
01571 Partitioning* parti) {
01572 int I,J,K;
01573
01574 quality q_new, q_opt;
01575
01576
01577 if(is_periodic) {
01578
01579 I = 0; J = 0; K = 0;
01580 opt_I=0; opt_J=0; opt_K=0;
01581
01582 q_new=calc_quality(opt_I,opt_J,opt_K,p);
01583 if(q_opt<q_new) {
01584 q_opt=q_new;
01585 opt_I=I; opt_J=J; opt_K=K;
01586 }
01587 }
01588 else {
01589 for(I=0;I<n_side;++I) for(J=0;J<n_side;++J) for(K=0;K<n_side;++K) {
01590 q_new=calc_quality(I,J,K,p);
01591 if(q_opt<q_new) {
01592 q_opt=q_new;
01593 opt_I=I; opt_J=J; opt_K=K;
01594 }
01595 }
01596 }
01597
01598 Set_partitioning(opt_I,opt_J,opt_K,parti);
01599 if(q_opt.positive_quality()) return q_opt.Give_p_nec();
01600 else return p+1;
01601 }
01602
01603
01604
01605
01606
01607 Partitioning::Partitioning(int level) {
01608 int i,j,k;
01609
01610 size = Zweipotenz(level+1);
01611
01612 start = new bool[size*size*size];
01613
01614
01615 for(i=0;i<size;++i)
01616 for(j=0;j<size;++j)
01617 for(k=0;k<size;++k) {
01618 start[i+size*j+size*size*k] = false;
01619 }
01620 };
01621
01622 Partitioning::~Partitioning() {
01623 delete(start);
01624 }
01625
01626 void Partitioning::Put_proc(int i, int j, int k) {
01627 if(developer_version) {
01628 if(i>=size || j>=size || k>=size) {
01629 cout << " Error in Partitioning::Put_proc at: "
01630 << i << ", " << j << ", " << k << ", " << size << endl;
01631 }
01632 }
01633 start[i+size*j+size*size*k]=true;
01634 }
01635
01636 bool Partitioning::Is_this_a_proc(Index3D Ind) {
01637 Index3D I;
01638 int t;
01639 t = Ind.Tiefe()-1;
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649 I = Ind.neighbour_non_periodic(WSDd);
01650 return
01651 start[I.I_x().cart_index(t)+
01652 size*I.I_y().cart_index(t)+
01653 size*size*I.I_z().cart_index(t)];
01654 }
01655
01656 void Partitioning::Print() {
01657 int i,j,k;
01658
01659 cout << " Partitioning: " << endl;
01660 for(i=0;i<size;++i) {
01661 cout << " \n new z-level: " << endl;
01662 for(j=0;j<size;++j) {
01663 cout << endl;
01664 for(k=0;k<size;++k) {
01665 cout << start[i+size*j+size*size*k] << ", ";
01666 }
01667 }
01668 }
01669 cout << endl;
01670 }