00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef COMP_GNUOLD
00026 #include <iostream.h>
00027 #include <fstream.h>
00028 #include <time.h>
00029 #include <math.h>
00030 #else
00031 #include <iostream>
00032 #include <fstream>
00033 #include <ctime>
00034 #include <cmath>
00035 #endif
00036
00037
00038
00039
00040 #include "../parser.h"
00041
00042
00043 #include "../paramete.h"
00044 #include "../abbrevi.h"
00045 #include "../math_lib/math_lib.h"
00046
00047
00048 #include "../basic/basic.h"
00049
00050
00051 #include "../domain/domain.h"
00052
00053
00054 #include "../formulas/boundy.h"
00055 #include "../formulas/loc_sten.h"
00056
00057
00058 #include "../grid/gpar.h"
00059 #include "../grid/parallel.h"
00060 #include "../grid/mgcoeff.h"
00061 #include "../grid/sto_man.h"
00062 #include "../grid/gridbase.h"
00063 #include "../grid/grid.h"
00064
00066
00067
00069
00070
00071
00072
00074
00076
00077
00078 bool Grid_base::Send_boundary_stencils_in_direction(Point_hashtable0* poi,
00079 int level,
00080 Index3D my_lev_index,
00081 Index3D next_index) {
00082
00083 Index3D I;
00084 int co;
00085
00086
00087
00088
00089
00090
00091
00092
00093 I = poi->ind;
00094
00095 for(co=0;co<8;++co) {
00096
00097 if(I.neighbour((dir_sons)co) << next_index)
00098 return true;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108 return false;
00109 }
00110
00111
00112
00113 void Grid_base::Prepare_communication_boundary_stencils() {
00114 int l,i;
00115
00116
00117 for(i=0;i<26;++i)
00118 for(l=0;l<Max_number_levels;++l) {
00119 number_send_bo_stencil[l][i] = 0;
00120 number_receive_bo_stencil[l][i] = 0;
00121 }
00122
00123
00124 for(l=min_level+1;l<=max_level;++l)
00125
00126 Prepare_communication_boundary_stencils(l);
00127 }
00128
00129 void Grid_base::Prepare_communication_boundary_stencils(int level) {
00130
00131 int d;
00132 Index3D I;
00133
00134 int number_bo_send, number_bo_rec, num_message, num;
00135 Index3D my_lev_index;
00136 Index3D next_index;
00137
00138 int* send_info;
00139 int* receive_info;
00140
00141 int counter_bo_stencil;
00142 double* sp;
00143 Point_hashtable0* poi0;
00144
00145 MPI_Request req[2];
00146 MPI_Status status[2];
00147
00148 int rank_source, rank_destination;
00149
00150
00151
00152 my_lev_index = Give_my_level_index(level);
00153
00154
00155
00156 int lenght_invar_array = 0;
00157 iterate_hash0 {
00158 if(point0->isCell()) {
00159 if(point0->Give_Tiefe() == level) {
00160 if(point0->ind < my_lev_index) {
00161 if(point0->typ==bo_cell) {
00162 lenght_invar_array++;
00163 }
00164 }
00165 }
00166 }
00167 }
00168 Point_hashtable0** invariant_array = new Point_hashtable0*[lenght_invar_array];
00169 int array_i = 0;
00170 iterate_hash0 {
00171 if(point0->isCell()) {
00172 if(point0->Give_Tiefe() == level) {
00173 if(point0->ind < my_lev_index) {
00174 if(point0->typ==bo_cell) {
00175 invariant_array[array_i] = point0;
00176 array_i++;
00177 }
00178 }
00179 }
00180 }
00181 }
00182
00183 for(d=0;d<26;++d) {
00184
00185 next_index = Give_next_on_level(d,my_lev_index);
00186
00187
00188 if(d<6) {
00189 rank_source = give_next_rank_source((dir_3D)d,level-1);
00190 rank_destination = give_next_rank_destination((dir_3D)d,level-1);
00191 }
00192 else if(d<18) {
00193 rank_source = give_next_rank_source((Edges_cell)(d-6),level-1);
00194 rank_destination = give_next_rank_destination((Edges_cell)(d-6),level-1);
00195 }
00196 else {
00197 rank_source = give_next_rank_source((dir_sons)(d-18),level-1);
00198 rank_destination = give_next_rank_destination((dir_sons)(d-18),level-1);
00199 }
00200
00201
00202
00203
00204 number_bo_send = 0;
00205
00206 for(int i = 0;i < lenght_invar_array;i++) {
00207 if(Send_boundary_stencils_in_direction(invariant_array[i],level,
00208 my_lev_index,next_index)) {
00209
00210 number_send_bo_stencil[level][d]++;
00211 ++number_bo_send;
00212 }
00213 }
00214
00215
00216 if(number_send_bo_stencil[level][d]!=0)
00217 bo_stencil_send[level][d] = new double*[number_send_bo_stencil[level][d]];
00218 else bo_stencil_send[level][d] = NULL;
00219
00220
00221 number_bo_rec = 0;
00222 num_message = 0;
00223 if(rank_source != -1) {
00224 MPI_Irecv(&number_bo_rec,1,MPI_INT,rank_source,1,comm,
00225 &req[num_message]);
00226 ++num_message;
00227 }
00228 if(rank_destination != -1) {
00229 MPI_Isend(&number_bo_send,1,MPI_INT,rank_destination,1,comm,
00230 &req[num_message]);
00231 ++num_message;
00232 }
00233 MPI_Waitall(num_message,req,status);
00234
00235
00236 number_receive_bo_stencil[level][d] = number_bo_rec;
00237 if(number_receive_bo_stencil[level][d]!=0)
00238 bo_stencil_receive[level][d] =
00239 new double*[number_receive_bo_stencil[level][d]];
00240 else bo_stencil_receive[level][d] = NULL;
00241
00242
00243
00244
00245
00246
00247 counter_bo_stencil = 0;
00248
00249
00250 send_info = Give_buffer_send_info(3*number_bo_send);
00251 receive_info = Give_buffer_receive_info(3*number_bo_rec);
00252
00253 num = 0;
00254 for(int i = 0;i < lenght_invar_array;i++) {
00255 point0 = invariant_array[i];
00256 if(Send_boundary_stencils_in_direction(point0,level,
00257 my_lev_index,next_index)) {
00258
00259
00260 I = point0->ind;
00261
00262 send_info[num*3] = I.I_x().get();
00263 send_info[num*3+1] = I.I_y().get();
00264 send_info[num*3+2] = I.I_z().get();
00265 num++;
00266
00267 bo_stencil_send[level][d][counter_bo_stencil] =
00268 Give_pointer_stencil(I);
00269 counter_bo_stencil++;
00270 }
00271 }
00272
00273
00274 num_message = 0;
00275 if(rank_source != -1 && number_bo_rec>0) {
00276 MPI_Irecv(receive_info,3*number_bo_rec,MPI_INT,rank_source,2,comm,
00277 &req[num_message]);
00278 ++num_message;
00279 }
00280 if(rank_destination != -1 && number_bo_send>0) {
00281 MPI_Isend(send_info,3*number_bo_send,MPI_INT,rank_destination,2,comm,
00282 &req[num_message]);
00283 ++num_message;
00284 }
00285
00286 MPI_Waitall(num_message,req,status);
00287
00288
00289
00290 counter_bo_stencil = 0;
00291
00292
00293 for(num=0;num<number_bo_rec;++num) {
00294 I = Index3D(receive_info[num*3],
00295 receive_info[num*3+1],
00296 receive_info[num*3+2]);
00297
00298 if(developer_version) {
00299 if(I.Cell_index()==false)
00300 cout << "\n Mistake I in Prepare_communication_boundary_stencils() "
00301 << endl;
00302 if(Exists_Cell(I)==false) {
00303 cout << "\n Mistake II in Prepare_communication_boundary_stencils() "
00304 << endl;
00305 }
00306 if(I.Tiefe()!=level) {
00307 cout << "\n Mistake III in Prepare_communication_boundary_stencils() "
00308 << endl;
00309 }
00310 }
00311
00312 bo_stencil_receive[level][d][counter_bo_stencil] =
00313 Give_pointer_stencil(I);
00314 if(developer_version) {
00315 if(bo_stencil_receive[level][d][counter_bo_stencil]==NULL
00316 && Give_max_num_bo_cells()>0) {
00317
00318 cout << "\n Mistake IIV in Prepare_communication_boundary_stencils() "
00319 << Give_cell_typ(I)
00320 << " level: " << I.Tiefe()
00321 << " x: " << I.I_x().get()
00322 << " y: " << I.I_y().get()
00323 << " z: " << I.I_z().get()
00324 << " my_rank: " << my_rank << endl;
00325 I.coordinate().Print();
00326 cout << endl;
00327 }
00328 }
00329
00330 if(bo_stencil_receive[level][d][counter_bo_stencil]==NULL
00331
00332 && ((I < my_index)==false)) {
00333 sp = newdouble(Give_max_num_bo_cells());
00334 poi0 = hashtable0_point(I);
00335 poi0->var = sp;
00336 poi0->typ = bo_cell;
00337 bo_stencil_receive[level][d][counter_bo_stencil] = sp;
00338 }
00339
00340 counter_bo_stencil++;
00341 }
00342 }
00343 delete invariant_array;
00344 }
00345
00346 void Grid::Update_boundary_stencil(int num_stencil, int level) {
00347 int num, iv;
00348 int d;
00349 MPI_Request req[12];
00350 MPI_Status status[12];
00351 int num_message;
00352 double* send_info;
00353 double* receive_info;
00354 int number_send;
00355 int number_receive;
00356 int number_start;
00357
00358
00359
00360 double** bo_stencil_sendd;
00361 double** bo_stencil_received;
00362
00363 int rank_source, rank_destination;
00364
00365
00366 if(I_am_active()) {
00367
00368 number_start = cell_number_of_bo_stencil(num_stencil);
00369
00370 for(d=0;d<26;++d) {
00371
00372 if(d<6) {
00373 rank_source = give_next_rank_source((dir_3D)d,level-1);
00374 rank_destination = give_next_rank_destination((dir_3D)d,level-1);
00375 }
00376 else if(d<18) {
00377 rank_source = give_next_rank_source((Edges_cell)(d-6),level-1);
00378 rank_destination = give_next_rank_destination((Edges_cell)(d-6),level-1);
00379 }
00380 else {
00381 rank_source = give_next_rank_source((dir_sons)(d-18),level-1);
00382 rank_destination = give_next_rank_destination((dir_sons)(d-18),level-1);
00383 }
00384
00385
00386 number_send =
00387 number_send_bo_stencil[level][d] * 64;
00388 number_receive =
00389 number_receive_bo_stencil[level][d] * 64;
00390
00391
00392 send_info = Give_buffer_send(d,number_send);
00393 receive_info = Give_buffer_receive(d,number_receive);
00394
00395 bo_stencil_sendd=bo_stencil_send[level][d];
00396 for(num=0;num<number_send_bo_stencil[level][d];++num) {
00397 for(iv=0;iv<64;++iv) {
00398 send_info[num*64+iv] =
00399 bo_stencil_sendd[num][number_start+iv];
00400 }
00401 }
00402
00403
00404 num_message = 0;
00405 if(rank_source != -1 && number_receive>0) {
00406 MPI_Irecv(receive_info ,number_receive,
00407 MPI_DOUBLE,rank_source,10,comm,
00408 &req[num_message]);
00409 ++num_message;
00410 }
00411 if(rank_destination != -1 && number_send>0) {
00412 MPI_Isend(send_info,number_send,
00413 MPI_DOUBLE,rank_destination,10,comm,
00414 &req[num_message]);
00415 ++num_message;
00416 }
00417 MPI_Waitall(num_message,req,status);
00418
00419
00420 bo_stencil_received=bo_stencil_receive[level][d];
00421 for(num=0;num<number_receive_bo_stencil[level][d];++num) {
00422
00423
00424
00425 for(iv=0;iv<64;++iv) {
00426 bo_stencil_received[num][number_start+iv] =
00427 receive_info[num*64+iv];
00428 }
00429 }
00430 }
00431 }
00432 }
00433
00434
00436
00438
00439 bool Grid_base::Send_interior_stencils_in_direction(Point_hashtable0* poi,
00440 int level,
00441 Index3D my_lev_index,
00442 Index3D next_index) {
00443
00444 Index3D I;
00445 int co;
00446
00447 I = poi->ind;
00448 if(poi->isCell()) {
00449 if(poi->Give_Tiefe() == level) {
00450 if(I < my_lev_index) {
00451 if(poi->typ==int_cell) {
00452
00453 for(co=0;co<8;++co) {
00454
00455 if(I.neighbour((dir_sons)co) << next_index)
00456 return true;
00457 }
00458 }
00459 }
00460 }
00461 }
00462 return false;
00463 }
00464
00465
00466
00467 void Grid_base::Prepare_communication_interior_stencils() {
00468 int l,i;
00469
00470
00471 for(i=0;i<26;++i)
00472 for(l=0;l<Max_number_levels;++l) {
00473 number_send_stencil[l][i] = 0;
00474 number_receive_stencil[l][i] = 0;
00475 }
00476
00477
00478 if(Give_max_num_coarse_int_cells()>0)
00479 for(l=min_level+1;l<=max_level;++l)
00480
00481 Prepare_communication_interior_stencils(l);
00482 }
00483
00484 void Grid_base::Prepare_communication_interior_stencils(int level) {
00485
00486 int d;
00487 Index3D I;
00488
00489 int number_send, number_rec, num_message, num;
00490 Index3D my_lev_index;
00491 Index3D next_index;
00492
00493 int* send_info;
00494 int* receive_info;
00495
00496 int counter_stencil;
00497 double* sp;
00498 Point_hashtable0* poi0;
00499
00500 MPI_Request req[2];
00501 MPI_Status status[2];
00502
00503 int rank_source, rank_destination;
00504
00505
00506
00507 my_lev_index = Give_my_level_index(level);
00508
00509 for(d=0;d<26;++d) {
00510
00511 next_index = Give_next_on_level(d,my_lev_index);
00512
00513
00514 if(d<6) {
00515 rank_source = give_next_rank_source((dir_3D)d,level-1);
00516 rank_destination = give_next_rank_destination((dir_3D)d,level-1);
00517 }
00518 else if(d<18) {
00519 rank_source = give_next_rank_source((Edges_cell)(d-6),level-1);
00520 rank_destination = give_next_rank_destination((Edges_cell)(d-6),level-1);
00521 }
00522 else {
00523 rank_source = give_next_rank_source((dir_sons)(d-18),level-1);
00524 rank_destination = give_next_rank_destination((dir_sons)(d-18),level-1);
00525 }
00526
00527
00528
00529
00530 number_send = 0;
00531 iterate_hash0 {
00532 if(Send_interior_stencils_in_direction(point0,level,
00533 my_lev_index,next_index)) {
00534
00535 number_send_stencil[level][d]++;
00536 ++number_send;
00537 }
00538 }
00539
00540
00541 if(number_send_stencil[level][d]!=0)
00542 stencil_send[level][d] = new double*[number_send_stencil[level][d]];
00543 else stencil_send[level][d] = NULL;
00544
00545
00546 number_rec = 0;
00547 num_message = 0;
00548 if(rank_source != -1) {
00549 MPI_Irecv(&number_rec,1,MPI_INT,rank_source,1,comm,
00550 &req[num_message]);
00551 ++num_message;
00552 }
00553 if(rank_destination != -1) {
00554 MPI_Isend(&number_send,1,MPI_INT,rank_destination,1,comm,
00555 &req[num_message]);
00556 ++num_message;
00557 }
00558 MPI_Waitall(num_message,req,status);
00559
00560
00561 number_receive_stencil[level][d] = number_rec;
00562 if(number_receive_stencil[level][d]!=0)
00563 stencil_receive[level][d] =
00564 new double*[number_receive_stencil[level][d]];
00565 else stencil_receive[level][d] = NULL;
00566
00567
00568
00569
00570
00571
00572 counter_stencil = 0;
00573
00574
00575 send_info = Give_buffer_send_info(3*number_send);
00576 receive_info = Give_buffer_receive_info(3*number_rec);
00577
00578 num = 0;
00579 iterate_hash0 {
00580 if(Send_interior_stencils_in_direction(point0,level,
00581 my_lev_index,next_index)) {
00582
00583
00584 I = point0->ind;
00585
00586 send_info[num*3] = I.I_x().get();
00587 send_info[num*3+1] = I.I_y().get();
00588 send_info[num*3+2] = I.I_z().get();
00589 num++;
00590
00591 stencil_send[level][d][counter_stencil] =
00592 Give_pointer_stencil(I);
00593 counter_stencil++;
00594 }
00595 }
00596
00597
00598 num_message = 0;
00599 if(rank_source != -1 && number_rec>0) {
00600 MPI_Irecv(receive_info,3*number_rec,MPI_INT,rank_source,2,comm,
00601 &req[num_message]);
00602 ++num_message;
00603 }
00604 if(rank_destination != -1 && number_send>0) {
00605 MPI_Isend(send_info,3*number_send,MPI_INT,rank_destination,2,comm,
00606 &req[num_message]);
00607 ++num_message;
00608 }
00609
00610 MPI_Waitall(num_message,req,status);
00611
00612
00613
00614 counter_stencil = 0;
00615
00616
00617 for(num=0;num<number_rec;++num) {
00618 I = Index3D(receive_info[num*3],
00619 receive_info[num*3+1],
00620 receive_info[num*3+2]);
00621
00622 if(developer_version) {
00623 if(I.Cell_index()==false)
00624 cout << "\n Mistake I in Prepare_communication_interior_stencils() "
00625 << endl;
00626 if(Exists_Cell(I)==false) {
00627 cout << "\n Mistake II in Prepare_communication_interior_stencils() "
00628 << endl;
00629 }
00630 if(I.Tiefe()!=level) {
00631 cout << "\n Mistake III in Prepare_communication_interior_stencils() "
00632 << endl;
00633 }
00634 }
00635
00636 stencil_receive[level][d][counter_stencil] =
00637 Give_pointer_stencil(I);
00638 if(developer_version) {
00639 if(stencil_receive[level][d][counter_stencil]==NULL
00640 && Give_max_num_coarse_int_cells()>0) {
00641
00642 cout << "\n Mistake IIV in Prepare_communication_interior_stencils() "
00643 << Give_cell_typ(I)
00644 << " level: " << I.Tiefe()
00645 << " x: " << I.I_x().get()
00646 << " y: " << I.I_y().get()
00647 << " z: " << I.I_z().get()
00648 << " my_rank: " << my_rank << endl;
00649 I.coordinate().Print();
00650 cout << endl;
00651 }
00652 }
00653
00654 if(stencil_receive[level][d][counter_stencil]==NULL
00655
00656 && ((I < my_index)==false)) {
00657 sp = newdouble(Give_max_num_coarse_int_cells());
00658 poi0 = hashtable0_point(I);
00659 poi0->var = sp;
00660 poi0->typ = bo_cell;
00661 stencil_receive[level][d][counter_stencil] = sp;
00662 }
00663
00664 counter_stencil++;
00665 }
00666 }
00667 }
00668
00669 void Grid::Update_global_stencil(int num_stencil, int level) {
00670 int num, iv;
00671 int d;
00672 MPI_Request req[12];
00673 MPI_Status status[12];
00674 int num_message;
00675 double* send_info;
00676 double* receive_info;
00677 int number_send;
00678 int number_receive;
00679 int number_start;
00680
00681
00682
00683 double** stencil_sendd;
00684 double** stencil_received;
00685
00686 int rank_source, rank_destination;
00687
00688
00689 number_start = cell_number_of_stencil(num_stencil);
00690
00691 if(I_am_active()) {
00692
00693 for(d=0;d<26;++d) {
00694
00695 if(d<6) {
00696 rank_source = give_next_rank_source((dir_3D)d,level-1);
00697 rank_destination = give_next_rank_destination((dir_3D)d,level-1);
00698 }
00699 else if(d<18) {
00700 rank_source = give_next_rank_source((Edges_cell)(d-6),level-1);
00701 rank_destination = give_next_rank_destination((Edges_cell)(d-6),level-1);
00702 }
00703 else {
00704 rank_source = give_next_rank_source((dir_sons)(d-18),level-1);
00705 rank_destination = give_next_rank_destination((dir_sons)(d-18),level-1);
00706 }
00707
00708
00709 number_send =
00710 number_send_stencil[level][d] * 64;
00711 number_receive =
00712 number_receive_stencil[level][d] * 64;
00713
00714
00715 send_info = Give_buffer_send(d,number_send);
00716 receive_info = Give_buffer_receive(d,number_receive);
00717
00718 stencil_sendd=stencil_send[level][d];
00719 for(num=0;num<number_send_stencil[level][d];++num) {
00720 for(iv=0;iv<64;++iv) {
00721 send_info[num*64+iv] =
00722 stencil_sendd[num][number_start+iv];
00723 }
00724 }
00725
00726
00727 num_message = 0;
00728 if(rank_source != -1 && number_receive>0) {
00729 MPI_Irecv(receive_info ,number_receive,
00730 MPI_DOUBLE,rank_source,10,comm,
00731 &req[num_message]);
00732 ++num_message;
00733 }
00734 if(rank_destination != -1 && number_send>0) {
00735 MPI_Isend(send_info,number_send,
00736 MPI_DOUBLE,rank_destination,10,comm,
00737 &req[num_message]);
00738 ++num_message;
00739 }
00740 MPI_Waitall(num_message,req,status);
00741
00742
00743 stencil_received=stencil_receive[level][d];
00744 for(num=0;num<number_receive_stencil[level][d];++num) {
00745
00746
00747
00748 for(iv=0;iv<64;++iv) {
00749 stencil_received[num][number_start+iv] =
00750 receive_info[num*64+iv];
00751 }
00752 }
00753 }
00754
00755
00756 for(d=0;d<26;++d) {
00757
00758 if(d<6) {
00759 rank_source = give_next_rank_source((dir_3D)d,level-1);
00760 rank_destination = give_next_rank_destination((dir_3D)d,level-1);
00761 }
00762 else if(d<18) {
00763 rank_source = give_next_rank_source((Edges_cell)(d-6),level-1);
00764 rank_destination = give_next_rank_destination((Edges_cell)(d-6),level-1);
00765 }
00766 else {
00767 rank_source = give_next_rank_source((dir_sons)(d-18),level-1);
00768 rank_destination = give_next_rank_destination((dir_sons)(d-18),level-1);
00769 }
00770
00771
00772 number_send =
00773 number_send_bo_stencil[level][d] * 64;
00774 number_receive =
00775 number_receive_bo_stencil[level][d] * 64;
00776
00777
00778 send_info = Give_buffer_send(d,number_send);
00779 receive_info = Give_buffer_receive(d,number_receive);
00780
00781 stencil_sendd=bo_stencil_send[level][d];
00782 for(num=0;num<number_send_bo_stencil[level][d];++num) {
00783 for(iv=0;iv<64;++iv) {
00784 send_info[num*64+iv] =
00785 stencil_sendd[num][number_start+iv];
00786 }
00787 }
00788
00789
00790 num_message = 0;
00791 if(rank_source != -1 && number_receive>0) {
00792 MPI_Irecv(receive_info ,number_receive,
00793 MPI_DOUBLE,rank_source,10,comm,
00794 &req[num_message]);
00795 ++num_message;
00796 }
00797 if(rank_destination != -1 && number_send>0) {
00798 MPI_Isend(send_info,number_send,
00799 MPI_DOUBLE,rank_destination,10,comm,
00800 &req[num_message]);
00801 ++num_message;
00802 }
00803 MPI_Waitall(num_message,req,status);
00804
00805
00806 stencil_received=bo_stencil_receive[level][d];
00807 for(num=0;num<number_receive_bo_stencil[level][d];++num) {
00808
00809
00810
00811 for(iv=0;iv<64;++iv) {
00812 stencil_received[num][number_start+iv] =
00813 receive_info[num*64+iv];
00814 }
00815 }
00816 }
00817 }
00818 }
00819
00820
00821
00822