src/expde/grid/grid.cc

Go to the documentation of this file.
00001 //    expde: expression templates for partial differential equations.
00002 //    Copyright (C) 2001  Christoph Pflaum
00003 //    This program is free software; you can redistribute it and/or modify
00004 //    it under the terms of the GNU General Public License as published by
00005 //    the Free Software Foundation; either version 2 of the License, or
00006 //    (at your option) any later version.
00007 //
00008 //    This program is distributed in the hope that it will be useful,
00009 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //    GNU General Public License for more details.
00012 //
00013 //                 SEE  Notice1.doc made by 
00014 //                 LAWRENCE LIVERMORE NATIONAL LABORATORY
00015 //
00016 
00017 // ------------------------------------------------------------
00018 //
00019 // grid.cc
00020 //
00021 // ------------------------------------------------------------
00022 
00023 
00024 // Include level 0:
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 #ifdef USE_PBE
00038 #include "pbedefs.h"
00039 #endif
00040 
00041 // Include level 0:
00042 #include "../parser.h"   
00043 
00044 // Include level 1:
00045 #include "../paramete.h"
00046 #include "../abbrevi.h"
00047 #include "../math_lib/math_lib.h"
00048 
00049 // Include level 2:
00050 #include "../basic/basic.h"
00051 
00052 // Include level 3:
00053 #include "../domain/domain.h"
00054 #include "../domain/d_exam.h"
00055 
00056 // Include level 4:
00057 #include "../formulas/boundy.h"
00058 #include "../formulas/diffop.h"
00059 #include "../formulas/loc_sten.h"
00060 
00061 // Include level 5.0:
00062 #include "gpar.h"
00063 #include "parallel.h"
00064 #include "mgcoeff.h"
00065 #include "sto_man.h"
00066 #include "gridbase.h"
00067 #include "grid.h"
00068 #include "SSten.h"
00069 
00070 // Include level 5.1
00071 #include "../evpar/evpar.h"
00072 
00073 
00074 // calculation of computational time and MFlops
00075 void Grid::Add_operations(long_int ops, int level)  {
00076   operations=operations+ops*number_interior_points[level];
00077 }
00078 void Grid::Start_calc_time()  {
00079   calc_yn = 1;
00080   operations=0;
00081   t0_all=clock();
00082   t_sum_interior = 0;
00083   t_sum_nearbb = 0;
00084 }
00085 void Grid::Stop_calc_time()  {
00086   calc_yn = 0;
00087   t1_all=clock();
00088 }
00089 void Grid::Start_calc_time_interior()  {
00090   if(calc_yn)
00091     t0_interior=clock();
00092 }
00093 void Grid::Stop_calc_time_interior()  {
00094   if(calc_yn) {
00095     t1_interior=clock();
00096     t_sum_interior = t_sum_interior + (t1_interior - t0_interior);
00097   }
00098 }
00099 void Grid::Start_calc_time_nearbb()  {
00100   if(calc_yn) {
00101     t0_nearbb=clock();
00102   }
00103 }
00104 void Grid::Stop_calc_time_nearbb()  {
00105   if(calc_yn) {
00106     t1_nearbb=clock();
00107     t_sum_nearbb = t_sum_nearbb + (t1_nearbb - t0_nearbb);
00108   }
00109 }
00110 void Grid::Report_calc_time( const char * what )  {
00111   /*
00112   double t_all = ((double)t1_all-t0_all)/CLOCKS_PER_SEC;
00113   double t_interior = ((double)t_sum_interior)/CLOCKS_PER_SEC;
00114   double t_nearbb = ((double)t_sum_nearbb)/CLOCKS_PER_SEC;
00115   calc_yn = 0;
00116 
00117   printf("\n Report for %s : ",what);
00118   printf("\n Time interior: %g seconds", t_interior);
00119   printf("\n Time near the boundary: %g seconds", t_nearbb);
00120   printf("\n Time all: %g seconds", t_all);
00121   printf("\n Number of operations at interior points: %f " , operations);
00122   printf("\n Interior effiency: %g Mflops\n", operations/t_interior/1000000 );
00123   */
00124 }
00125           
00126 
00127 // parallel constructors                                           
00128 Grid::Grid(int n_max, All_Domains* dom, 
00129            Grid_gen_parameters& gpara, MPI_Comm comm) : 
00130   Grid_base(n_max, dom, gpara, comm) {
00131   non_bock_sending = true;
00132   Construct_storage();
00133 }
00134 Grid::Grid(int n_max, All_Domains* dom, MPI_Comm comm) : 
00135   Grid_base(n_max, dom, comm) {
00136   non_bock_sending = true;
00137   Construct_storage();
00138 }
00139 Grid::Grid(double h_finest_level, All_Domains* dom, 
00140            Grid_gen_parameters& gpara, MPI_Comm comm) : 
00141   Grid_base(h_finest_level, dom, gpara, comm) {
00142   non_bock_sending = true;
00143   Construct_storage();
00144 }
00145 Grid::Grid(double h_finest_level, All_Domains* dom, MPI_Comm comm) : 
00146   Grid_base(h_finest_level, dom, comm) {
00147   non_bock_sending = true;
00148   Construct_storage();
00149 }
00150 
00151 
00152 // seriell constructors                                           
00153 Grid::Grid(int n_max, All_Domains* dom, 
00154            Grid_gen_parameters& gpara) : 
00155   Grid_base(n_max, dom, gpara, 0) {
00156   if(parallel_version)
00157     cout << " Do not use Grid::Grid(int n_max, All_Domains* dom, Grid_gen_parameters& gpara);  in parallel version!! " << endl;
00158   Construct_storage();
00159 }
00160 Grid::Grid(double h_finest_level, All_Domains* dom, 
00161            Grid_gen_parameters& gpara) : 
00162   Grid_base(h_finest_level, dom, gpara, 0) {
00163   if(parallel_version)
00164     cout << " Do not use Grid::Grid(int n_max, All_Domains* dom, Grid_gen_parameters& gpara);  in parallel version!! " << endl;
00165   Construct_storage();
00166 }
00167 
00168 Grid::Grid(int n_max, All_Domains* dom) : 
00169   Grid_base(n_max, dom, 0) {
00170   if(parallel_version)
00171     cout << " Do not use Grid::Grid(int n_max, All_Domains* dom);  in parallel version!! " << endl;
00172   Construct_storage();
00173 }
00174 
00175 Grid::Grid(double h_finest_level, All_Domains* dom) : 
00176   Grid_base(h_finest_level, dom, 0) {
00177   if(parallel_version)
00178     cout << " Do not use Grid::Grid(int n_max, All_Domains* dom);  in parallel version!! " << endl;
00179   Construct_storage();
00180 }
00181 
00182 void Grid::Do_non_bock_sending(bool yn) {
00183   non_bock_sending = yn;
00184 }
00185 
00186 void Grid::Construct_storage() {
00187   int i;
00188   nearb_ablage = new Nearb_Ablage;
00189   vector_ablage = new double[27];
00190   label_on_cell = new bool[28];
00191   eight_bools   = new bool[8];
00192 
00193   stencils_fine = new double*[8];
00194   for(i=0;i<8;++i)
00195     stencils_fine[i] = new double[64];
00196   weight_27 = new double[27];
00197   restriction_stencil = new Restriction_stencil_container;
00198 
00199   coarse_grid_functions = new int[216];
00200   for(i=0;i<8;++i)
00201     Set_coarse_function(&(coarse_grid_functions[i*27]),(dir_sons)i);
00202 }
00203 
00204 void Grid::Print_maximal_interior_angles() {
00205   double* h;
00206   int num;
00207   double max_edge_ang;
00208   double max_face_ang;
00209   double ang;
00210 
00211   if(!Is_storage_initialized()) Initialize();
00212 
00213   max_edge_ang = max_face_ang = 0.0;
00214   h = new double[30];
00215 
00216   Tetraeder_storage* tet;
00217   iterate_hash2 {
00218     for(num=0;num<bocell->Give_number_points();++num) {
00219       if(bocell->edge_point(num)==edge_poi_typ) {
00220         h[num] = Give_h(bocell->Give_Index().neighbour(bocell->corner(num)),
00221                         bocell->edge_dir(num));
00222       }
00223     }
00224     
00225     for(tet=bocell->Give_tets();tet!=NULL;tet=tet->Next()) {
00226       ang = calc_maximal_face_angle(bocell->coord(tet->N0(),h),
00227                                     bocell->coord(tet->N1(),h),
00228                                     bocell->coord(tet->N2(),h),
00229                                     bocell->coord(tet->N3(),h));
00230       if(ang>max_face_ang) max_face_ang = ang;
00231       if(Print_wrong_Tet) { // only for finding a bug
00232         if(ang > 155) {
00233           bocell->Print();
00234           cout << "Ecken des Tet: "
00235                << tet->N0() << ", "
00236                << tet->N1() << ", "
00237                << tet->N2() << ", "
00238                << tet->N3() << endl;
00239           cout << "Koordinaten des Tet: \n";
00240           bocell->coord(tet->N0(),h).Print(); cout << endl;
00241           bocell->coord(tet->N1(),h).Print(); cout << endl;
00242           bocell->coord(tet->N2(),h).Print(); cout << endl;
00243           bocell->coord(tet->N3(),h).Print(); cout << endl;
00244         }
00245       }
00246       ang = calc_maximal_edge_angle(bocell->coord(tet->N0(),h),
00247                                     bocell->coord(tet->N1(),h),
00248                                     bocell->coord(tet->N2(),h),
00249                                     bocell->coord(tet->N3(),h));
00250       if(Print_wrong_Tet) { // only for finding a bug
00251         if(ang > 136) {
00252           bocell->Print();
00253           cout << "Ecken des Tet: "
00254                << tet->N0() << ", "
00255                << tet->N1() << ", "
00256                << tet->N2() << ", "
00257                << tet->N3() << endl;
00258           cout << "Koordinaten des Tet: \n";
00259           bocell->coord(tet->N0(),h).Print(); cout << endl;
00260           bocell->coord(tet->N1(),h).Print(); cout << endl;
00261           bocell->coord(tet->N2(),h).Print(); cout << endl;
00262           bocell->coord(tet->N3(),h).Print(); cout << endl;
00263         }
00264       }
00265       if(ang>max_edge_ang) max_edge_ang = ang;
00266     }
00267   }
00268   
00269   if(max_edge_ang > 136 || max_face_ang > 155) {
00270     cout << "\n Error: Too large interior angle!" <<
00271       " Tell Christoph Pflaum this error! ";
00272   }
00273   
00274   cout << "\n Maximal interior face angle: " << max_face_ang;
00275   cout << "\n Maximal interior edge angle: " << max_edge_ang << endl;
00276   delete h;
00277 }
00278 
00279 double Grid::Total_number_interior_points(int lev) {
00280   double sum, total_sum;
00281   sum = (double)number_interior_points[lev];
00282   
00283   if(parallel_version)
00284     MPI_Allreduce(&sum,&total_sum,1,MPI_DOUBLE,MPI_SUM,comm);
00285   else total_sum = sum;
00286   return total_sum;
00287 };
00288 
00289 double Grid::Total_number_exteri_points(int lev) {
00290  double sum, total_sum;
00291   sum = (double)number_exteri_points[lev];
00292   
00293   if(parallel_version)
00294     MPI_Allreduce(&sum,&total_sum,1,MPI_DOUBLE,MPI_SUM,comm);
00295   else total_sum = sum;
00296   return total_sum;
00297 };
00298 
00299 double Grid::Total_number_nearb_points(int lev) {
00300  double sum, total_sum;
00301   sum = (double)number_nearb_points[lev];
00302   
00303   if(parallel_version)
00304     MPI_Allreduce(&sum,&total_sum,1,MPI_DOUBLE,MPI_SUM,comm);
00305   else total_sum = sum;
00306   return total_sum;
00307 };
00308 
00309 double Grid::Total_number_bo2p_points(int lev) {
00310  double sum, total_sum;
00311   sum = (double)number_bo2p_points[lev];
00312   
00313   if(parallel_version)
00314     MPI_Allreduce(&sum,&total_sum,1,MPI_DOUBLE,MPI_SUM,comm);
00315   else total_sum = sum;
00316   return total_sum;
00317 };
00318 
00319 double Grid::Total_number_cellpoi_points(int lev) {
00320  double sum, total_sum;
00321   sum = (double)number_cellpoi_points[lev];
00322   
00323   if(parallel_version)
00324     MPI_Allreduce(&sum,&total_sum,1,MPI_DOUBLE,MPI_SUM,comm);
00325   else total_sum = sum;
00326   return total_sum;
00327 };
00328 
00329 void Grid::Print_poi_Info(int lev) {
00330   double sumr, sumin;
00331   sumr = 0;
00332   sumin = 0;
00333   cout << "\n on level: " << lev << ": " << endl;
00334   cout << "------------------------------------ \n";
00335   // Summe Innen
00336   sumin = sumin + (double)Total_number_interior_points(lev);
00337   cout << "number of interior points: " 
00338        << Total_number_interior_points(lev) << endl;
00339   // Summe Randnah
00340   sumr = sumr + number_nearb_points[lev];
00341   cout << "number of points near the boundary: " 
00342        << (double)number_nearb_points[lev] << endl;
00343   // Summe Randpunkte
00344   sumr = sumr + number_bo2p_points[lev];
00345   cout << "number of boundary points: " 
00346        << (double)number_bo2p_points[lev] << endl;
00347   // Summe Randzellen
00348   sumr = sumr + (double)number_cellpoi_points[lev];
00349   cout << "number of points in boundary cells: ";
00350   cout << (double)number_cellpoi_points[lev] << endl;
00351   cout << " \n ratio of points interior / near boundary: " 
00352        << (double)sumin / (double)sumr << endl;
00353   cout << "  sum of all points: " << sumin + sumr << endl;
00354 }
00355 
00356 void Grid::Print_poi_Sum_Info() {
00357   int i;
00358   double sumi;
00359   double sumr, sumin;
00360   cout << "\n sum over all levels: " << endl;
00361   cout << "-------------------------- \n";
00362   // Summe Innen
00363   sumi=0;
00364   for(i=0;i<Max_number_levels;++i) {
00365     sumi = Total_number_interior_points(i) + sumi;
00366   }
00367   cout << "number of interior points: " << sumi << endl;
00368   sumin = sumi;
00369   // Summe Randnah
00370   sumi=0;
00371   for(i=0;i<Max_number_levels;++i) {
00372     sumi = (double)number_nearb_points[i] + sumi;
00373   }
00374   cout << "number of points near the boundary: " << sumi << endl;
00375   sumr = sumi;
00376   // Summe Innen
00377   sumi=0;
00378   for(i=0;i<Max_number_levels;++i) {
00379     sumi = (double)number_bo2p_points[i] + sumi;
00380   }
00381   cout << "number of boundary points: " <<  sumi << endl;
00382   sumr = sumr + sumi;
00383   // Summe Innen
00384   sumi=0;
00385   for(i=0;i<Max_number_levels;++i) {
00386     sumi = (double)number_cellpoi_points[i] + sumi;
00387   }
00388   cout << "number of points in boundary cells: " <<  sumi << endl;
00389   sumr = sumr + sumi;
00390   cout << " \n ratio of points interior / near boundary: "
00391        << (double)sumin / (double)sumr << endl;
00392   cout << "  sum of all points: " << sumin + sumr << endl;
00393 }
00394 
00395 
00396 void Grid::Print_poi_Info_all(int lev) {
00397   int i;
00398   double sp;
00399 
00400   if(my_rank==0) {
00401     cout << "\n information until level: " << endl;
00402     cout << "------------------------------------ \n";
00403   }
00404   if(lev>=0 && lev<Max_number_levels) {
00405     // Innen
00406     for(i=1;i<=lev;++i) {
00407       sp = Total_number_interior_points(i);
00408       if(my_rank==0) {
00409         cout << "number of interior points on level " << i << " is: ";
00410         cout << sp << endl;
00411       }
00412     }
00413     // Randnah
00414     for(i=1;i<=lev;++i) {
00415       sp = Total_number_nearb_points(i);
00416       if(my_rank==0) {
00417         cout << "number of points near the boundary on level " << i << " is: ";
00418         cout << sp << endl;
00419       }
00420     }
00421     // Randpunkte
00422     for(i=1;i<=lev;++i) {
00423       sp = Total_number_bo2p_points(i);
00424       if(my_rank==0) {
00425         cout << "number of boundary points on level " << i << " is: ";
00426         cout << sp << endl;
00427       }
00428     }
00429     // Zellpunkte  
00430     for(i=1;i<=lev;++i) {
00431       sp = Total_number_cellpoi_points(i);
00432       if(my_rank==0) {
00433         cout << "number of points in boundary cells on level " << i << " is: ";
00434         cout << sp << endl;
00435       }
00436     }
00437     // Exterior mg points 
00438     for(i=1;i<=lev;++i) {
00439       sp = Total_number_exteri_points(i);
00440       if(my_rank==0) {
00441         cout << "number of exterior points for mg on level " << i << " is: ";
00442         cout << sp << endl;
00443       }
00444     }
00445   }
00446 }
00447 
00448 void Grid::Print_poi_Info() {
00449   double sumin, sumr, sp;
00450 
00451   if(my_rank==0) cout << "\n information about finest level: " << endl;
00452   if(my_rank==0) cout << "------------------------------------ \n";
00453   // Innen
00454   if(my_rank==0) cout << "number of interior points is:       ";
00455   sp = Total_number_interior_points(max_level);
00456   if(my_rank==0) cout << sp << endl;
00457   sumin = sp;
00458   // Randnah
00459   if(my_rank==0) cout << "number of points near the boundary: ";
00460   sp = Total_number_nearb_points(max_level);
00461   if(my_rank==0) cout << sp << endl;
00462   sumr = sp;
00463   // Randpunkte
00464   if(my_rank==0) cout << "number of boundary points:          ";
00465   sp = Total_number_bo2p_points(max_level);
00466   if(my_rank==0) cout << sp << endl;
00467   sumr += sp;
00468   // Zellpunkte  
00469   if(my_rank==0) cout << "number of points in boundary cells: ";
00470   sp = Total_number_cellpoi_points(max_level);
00471   if(my_rank==0) cout << sp << endl;
00472   sumr += sp;
00473   // Sum:
00474   if(my_rank==0) cout << "sum of all points:                  " 
00475                       << sumin + sumr << endl;
00476   if(my_rank==0) cout << "ratio of points interior / near boundary: "
00477                       << (double)sumin / (double)sumr << endl;
00478 
00479 }
00480 
00481 void Grid::Refine(Index3D ind)  {
00482   Add_point(ind);
00483   
00484   cout << " \n Please do not use Grid::Refine! " << endl;
00485 
00486   // 4.Schritt: 
00487   Fullfill_B1B2();
00488 }
00489 
00490 
00491 void Grid::Initialize() {
00492   Pointtype typ_point;
00493   int i, j;
00494   Index3D I, Inext;
00495   int lev;
00496 
00497   if(Is_storage_initialized() == false) {
00498     if(I_am_active()) {
00499       nearb_ablage->Initialize_leer(Give_max_num_var());
00500       
00501       Initialize_variable();
00502     }
00503     // Teil IV: Berechnung Listen
00504     //-----------------------------
00505     if(print_status_of_grid_generator) if(my_rank==0) {
00506       cout << " IV. calculate lists; " << endl;
00507     } 
00508 #ifdef USE_PBE
00509     pbe_start(23,"IV_calc_lists");
00510 #endif
00511     
00512     // IV.1.Schritt: Initialisierung der Startpunkte
00513     start_P_interior = new P_interior**[anzahl_colors];
00514     for(j=0;j<anzahl_colors;++j) {
00515       start_P_interior[j] = new P_interior*[Max_number_levels];
00516       for(i=0;i < Max_number_levels;++i) start_P_interior[j][i]=NULL;
00517     }
00518     start_P_nearb = new P_nearb**[anzahl_colors];
00519     for(j=0;j<anzahl_colors;++j) {
00520       start_P_nearb[j] = new P_nearb*[Max_number_levels];
00521       for(i=0;i < Max_number_levels;++i) start_P_nearb[j][i]=NULL;
00522     }
00523     start_P_exteri = new P_nearb**[anzahl_colors];
00524     for(j=0;j<anzahl_colors;++j) {
00525       start_P_exteri[j] = new P_nearb*[Max_number_levels];
00526       for(i=0;i < Max_number_levels;++i) start_P_exteri[j][i]=NULL;
00527     }
00528     start_P_Bo2p = new P_Bo2p**[anzahl_colors];
00529     for(j=0;j<anzahl_colors;++j) {
00530       start_P_Bo2p[j] = new P_Bo2p*[Max_number_levels];
00531       for(i=0;i < Max_number_levels;++i) start_P_Bo2p[j][i]=NULL;
00532     }
00533     start_P_cellpoi = new P_cellpoi**[1];
00534     for(j=0;j<1;++j) {
00535       start_P_cellpoi[j] = new P_cellpoi*[Max_number_levels];
00536       for(i=0;i < Max_number_levels;++i) start_P_cellpoi[j][i]=NULL;
00537     }
00538 
00539     // for cell variables
00540     start_P_interior_cell = new P_interior_cell*[Max_number_levels];
00541     for(i=0;i < Max_number_levels;++i) start_P_interior_cell[i]=NULL;
00542 
00543     start_P_boundary_tet = new P_boundary_tet*[Max_number_levels];
00544     for(i=0;i < Max_number_levels;++i) start_P_boundary_tet[i]=NULL;
00545 
00546     // ^^^^^^^^ parallel ^^^^^^^^
00547     start_P_parallel = new P_parallel*[Max_number_levels];
00548     for(i=0;i < Max_number_levels;++i) start_P_parallel[i]=NULL;
00549     
00550     for(i=0;i < Max_number_levels;++i) number_interior_points[i] = 0;
00551     for(i=0;i < Max_number_levels;++i) number_nearb_points[i] = 0;
00552     for(i=0;i < Max_number_levels;++i) number_exteri_points[i] = 0;
00553     for(i=0;i < Max_number_levels;++i) number_cellpoi_points[i] = 0;
00554     for(i=0;i < Max_number_levels;++i) number_bo2p_points[i] = 0;
00555 
00556     for(i=0;i < Max_number_levels;++i) number_interior_cell_points[i] = 0;
00557     for(i=0;i < Max_number_levels;++i) number_boundary_cell_tet[i] = 0;
00558     // ^^^^^^^^ parallel ^^^^^^^^
00559     for(i=0;i < Max_number_levels;++i) number_parallel_points[i] = 0;
00560 
00561 #ifdef USE_PBE
00562   pbe_stop(23);
00563 #endif
00564     
00565     // IV.2.Schritt: innere Punkte und Randnahe Punkte 
00566     // und Datenspeicher bereitstellen, hashtable 4 !!
00567     // fuer hashtable 4:
00568     if(print_status_of_grid_generator) if(my_rank==0) {
00569       cout << "   IV. 2. interior points and points near boundary; " << endl;
00570     } 
00571 #ifdef USE_PBE
00572     pbe_start(24,"IV-2._interior_and_near_boundary_points");
00573 #endif
00574 
00575     Initialize_hash4(Factor_hashtable4_lenght*hashtable1_occ+7);
00576 
00577     // Beachte: wenn ein Prozessor fuer einen Punkt verantwortlich ist
00578     // (responsible)), dann ist er dies auch auf allen groeberen
00579     // Prozessoren, auf Grund der Konstruktion der groben Zuteilung
00580     // der Prozessoren
00581 
00582     if(I_am_active()) {    
00583       iterate_hash1 {
00584         typ_point = point1->typ;
00585 
00586         // cout << " point: " << typ_point << endl;
00587 
00588         if(typ_point==hierarchical || typ_point==ausnahme)
00589           Add_list_interior(point1->ind);
00590         if(typ_point==nearb)
00591           Add_list_nearb(point1->ind);
00592         // ^^^^^^^^ parallel ^^^^^^^^
00593         if(typ_point==parallel_p)
00594           Add_list_parallel(point1->ind);
00595         // ^^^^^^^^ exterior ^^^^^^^^
00596         if(typ_point==multigrid) {
00597             Add_list_exteri(point1->ind);
00598         }
00599       }
00600       // IV.3.1.Schritt: Randpunkte 2.Art; 
00601       //                nur Punkte des eigenen Prozesses
00602       iterate_hash3 {
00603         if(I_am_responsible_for(bo2point->Give_boindex())) { // ^^ parallel ^^
00604           Add_list_bo2p(bo2point);
00605         }
00606       }
00607       // IV.3.2.Schritt: Punkte der Randzellfreiheitsgrade;
00608       //                nur Punkte des eigenen Prozesses
00609       iterate_hash2 {
00610         if(I_am_responsible_for(bocell->Give_Index())) { // ^^ parallel ^^
00611           //  if(true) {
00612           if(bocell->Exists_bocellpoint()) {
00613             Add_list_cellpoi(bocell);
00614           }
00615         }
00616       }
00617       // IV.4.Schritt: Punkte der Zellen-Variablen und Initialisierung
00618       if(Give_max_num_fine_all_cells()>0) {
00619         iterate_hash0 {
00620           if(point0->Give_Index().Cell_index())
00621             // if(I_am_responsible_for(point0->Give_Index())) {
00622             if(point0->typ==int_cell || point0->typ==bo_cell) {
00623               Add_list_interior_cell(point0);
00624             }
00625         }
00626         // -> boundary tets: see Grid_base::Calc_boundary_2points
00627         start_P_boundary_tet[Max_level()]       = auxiliary_P;
00628         ++number_boundary_cell_tet[Max_level()] = auxiliary_number;
00629         /*
00630         Tetraeder_storage* tet;
00631         iterate_hash2 {
00632           for(tet=bocell->Give_tets();tet!=NULL;tet=tet->Next()) {
00633             Add_list_boundary_tet(bocell,tet);
00634           }
00635         }
00636         */
00637       }
00638 #ifdef USE_PBE
00639   pbe_stop(24);
00640 #endif
00641       // IV.5.Schritt: Zeiger auf double auf Randzellen uebertragen
00642       if(print_status_of_grid_generator) if(my_rank==0) {
00643         cout << "   IV. 5. pointer in boundary cells; " << endl;
00644       } 
00645 #ifdef USE_PBE
00646     pbe_start(25,"IV-5_pointer_in_boundary_cells");
00647 #endif
00648 
00649       Set_pointer_on_bocell();
00650       
00651       // IV.6.Schritt: Preparation for Prolongation
00652       if(print_status_of_grid_generator) if(my_rank==0) {
00653         cout << "   IV. 6. restriction weights; " << endl;
00654       } 
00655     }   
00656 #ifdef USE_PBE
00657   pbe_stop(25);
00658 #endif
00659     // IV.7.Schritt: Caculate coarsest level
00660     if(print_status_of_grid_generator) if(my_rank==0) {
00661       cout << "   IV. 7. coarsest level; " << endl;
00662     }
00663 
00664 #ifdef USE_PBE
00665     pbe_start(26,"IV-7_coarsest_level");
00666 #endif
00667     int min_level_local;
00668     min_level_local = my_coarsest_level;
00669 
00670     if(I_am_active()) {
00671       for(i=my_coarsest_level;i<max_level;++i) {
00672         if(number_nearb_points[i]+
00673            number_interior_points[i]+
00674            number_exteri_points[i] == 0)
00675           min_level_local = i+1;
00676       }
00677     }
00678     else {
00679       min_level_local=max_level;
00680     }
00681     MPI_Allreduce(&min_level_local,&min_level,1,MPI_INT,MPI_MIN,comm);
00682     
00683 
00684     /*
00685     if(min_level < n_parallel) {
00686       if(my_rank==0) cout << " min_level wir auf n_parallel gesetzt! \n " 
00687                           << " von: " << min_level 
00688                           << " auf: " << n_parallel
00689                           << endl;
00690       min_level = n_parallel;
00691     }
00692     */
00693 #ifdef USE_PBE
00694   pbe_stop(26);
00695 #endif
00696 
00697     if(I_am_active()) {   
00698       
00699       // IV.8.Schritt: Initialize lists
00700       if(print_status_of_grid_generator) if(my_rank==0) {
00701         cout << "   IV. 8. initialize lists; " << endl;
00702       } 
00703 #ifdef USE_PBE
00704     pbe_start(27,"IV-8_init_lists");
00705 #endif
00706       int color;
00707       if(initialize_interior) {
00708         P_interior* iter_i;
00709         //      for(lev=Max_level()-1;lev <= Max_level();++lev)
00710         for(lev=0;lev <= Max_level();++lev)
00711           for(color=0;color < anzahl_colors;++color)
00712             for(iter_i=Start_P_interior(lev,color);
00713                 iter_i!=NULL;iter_i=iter_i->Next()) {
00714               iter_i->initialize(this,lev);
00715             }
00716       }
00717     
00718       if(initialize_nearb) {
00719         P_nearb* iter_nb;
00720         // for(lev=Max_level();lev <= Max_level();++lev)
00721         for(lev=0;lev <= Max_level();++lev)
00722           for(color=0;color < anzahl_colors;++color)
00723             for(iter_nb=Start_P_nearb(lev,color);
00724                 iter_nb!=NULL;iter_nb=iter_nb->Next()) {
00725               iter_nb->initialize(this,lev);
00726           }
00727 
00728         // for(lev=Max_level();lev <= Max_level();++lev)
00729         for(lev=0;lev <= Max_level();++lev)
00730           for(color=0;color < anzahl_colors;++color)
00731             for(iter_nb=Start_P_exteri(lev,color);
00732                 iter_nb!=NULL;iter_nb=iter_nb->Next()) {
00733               iter_nb->initialize(this,lev);
00734           }
00735       }
00736       if(initialize_cellpoi) {
00737         P_cellpoi* iter_cf;
00738         for(lev=0;lev <= Max_level();++lev)
00739             for(iter_cf=Start_P_cellpoi(lev);
00740                 iter_cf!=NULL;iter_cf=iter_cf->Next()) {
00741               iter_cf->initialize(this,lev);
00742             }
00743       }
00744       if(initialize_bo) {
00745         P_Bo2p* iter_bo;
00746         for(lev=0;lev <= Max_level();++lev)
00747           for(color=0;color < anzahl_colors;++color)
00748             for(iter_bo=Start_P_Bo2p(lev,color);
00749                 iter_bo!=NULL;iter_bo=iter_bo->Next()) {
00750               iter_bo->initialize(this,lev);
00751             }
00752       }
00753       if(initialize_pa) {
00754         P_parallel* iter_pa;
00755         for(lev=Max_level();lev <= Max_level();++lev)
00756           //    for(lev=0;lev <= Max_level();++lev)
00757           for(iter_pa=Start_P_parallel(lev);
00758               iter_pa!=NULL;iter_pa=iter_pa->Next()) {
00759             iter_pa->initialize(this,lev);
00760           }
00761       }
00762 #ifdef USE_PBE
00763   pbe_stop(27);
00764 #endif
00765       // IV.9.Schritt: Initialize MG - storage
00766       if(print_status_of_grid_generator) if(my_rank==0) {
00767         cout << "   IV. 9. calc mg; " << endl;
00768       } 
00769 #ifdef USE_PBE
00770     pbe_start(28,"IV-9_calc_mg");
00771 #endif
00772       if(mg_coefficients) Calc_MG_Coefficients();
00773       
00774 #ifdef USE_PBE
00775   pbe_stop(28);
00776 #endif
00777       // V.Schritt: prepare evaluation  ^^^^^^^^ parallel ^^^^^^^^
00778       // if(my_rank==0) cout << " No Prepare_communication(); " << endl;
00779       if(print_status_of_grid_generator) if(my_rank==0) {
00780         cout << "   V.1 prepare evaluation; " << endl;
00781       } 
00782 #ifdef USE_PBE
00783     pbe_start(29,"V1_prep_eval.");
00784 #endif
00785       eval_par_object =
00786         new Evaluation_Parallelization_object(this,Give_max_num_var());
00787       // -> parallel
00788 #ifdef USE_PBE
00789   pbe_stop(29);
00790 #endif
00791       if(parallel_version) {
00792         if(print_status_of_grid_generator) if(my_rank==0) {
00793           cout << "   V.2 prepare parallel; " << endl;
00794           cout << "   a) ; " << endl;
00795         }
00796 
00797 #ifdef USE_PBE
00798     pbe_start(30,"V2-1");
00799 #endif
00800 
00801         Prepare_communication();
00802         if(print_status_of_grid_generator) if(my_rank==0) {
00803           cout << "   b) ; " << endl;
00804         }
00805 #ifdef USE_PBE
00806         pbe_stop(30);
00807 #endif
00808 
00809 #ifdef USE_PBE
00810     pbe_start(31,"V2-2");
00811 #endif
00812 
00813         Prepare_communication_boundary_stencils();
00814         if(print_status_of_grid_generator) if(my_rank==0) {
00815           cout << "   c) ; " << endl;
00816         }
00817 #ifdef USE_PBE
00818         pbe_stop(31);
00819 #endif
00820 
00821 #ifdef USE_PBE
00822     pbe_start(32,"V2-3");
00823 #endif
00824 
00825         Prepare_communication_interior_stencils();
00826         if(print_status_of_grid_generator) if(my_rank==0) {
00827           cout << "   end prepare ; " << endl;
00828         }
00829 #ifdef USE_PBE
00830         pbe_stop(32);
00831 #endif
00832       }
00833     }
00834   }
00835   
00836   // VI.  Schritt: store finest meshsize
00837   finest_meshsize = finest_mesh_size();
00838 
00839   // VII. Schritt:
00840   // cal min_interior_level
00841   for(i=max_level;i >= min_level;--i) {
00842     if(Total_number_interior_points(i) +
00843        Total_number_nearb_points(i)  > 1) {
00844       min_interior_level = i;
00845     }
00846   }
00847 
00848   Storge_initialization_done();
00849 }
00850 
00851 // IV.5.Schritt: 
00852 void Grid::Set_pointer_on_bocell() {
00853   int num_points, num;
00854   Index3D I;
00855   iterate_hash2 {
00856     num_points = bocell->Give_number_points();
00857     I = bocell->ind;
00858     for(num=0;num<num_points;++num) {
00859       if(bocell->edge_point(num)==edge_poi_typ) {
00860         bocell->Set_variable_pointer(num,
00861                     Give_variable(I.neighbour(bocell->corner(num)),
00862                                   bocell->edge_dir(num)));
00863       }
00864       if(bocell->edge_point(num)==corner_poi_typ) {
00865         bocell->Set_variable_pointer(num,
00866                     Give_variable_slow(I.neighbour(bocell->corner(num)),
00867                                        I.Tiefe()-1));
00868       }
00869     }
00870     if(bocell->Exists_bocellpoint()) {
00871       bocell->Set_variable_pointer(num_points,bocell->var);
00872     }
00873   }
00874 }
00875 
00876 
00877 void Grid::Test_init() {
00878   if(Is_storage_initialized() == false) Initialize();
00879 }
00880 
00881 
00882 
00883 // IV.2.Schritt:
00884 void Grid::Add_list_interior(Index3D I) {
00885   static Index3D Inext;
00886   static bool weiter;
00887   static int t, i;
00888 
00889   t = I.Tiefe();
00890   if(t<my_coarsest_level)
00891     t = my_coarsest_level;
00892 
00893   for(;t<=Max_level();++t) {
00894     weiter = true;     // Suppose: no neighbour boundary cell
00895 
00896     for(i=0;i<8 && weiter;++i) {
00897       Inext = I.next((dir_sons)i,t+1);
00898       if(Give_cell_typ(Inext)==bo_cell ||
00899          Give_cell_typ(Inext)==fine_bo_cell) weiter=false;
00900     }
00901     if(weiter == true) {
00902       Add_list_interior(I,t);    // interior point with respect to this level
00903     }
00904     else {
00905       Add_list_nearb(I,t);       // nearb point with respect to this level
00906     }
00907   }
00908 }
00909 
00910 
00911 void Grid::Add_list_interior(Index3D I, int level) {  
00912   dir_sons color;
00913   //cout << " \n interior " ; I.coordinate().Print(); cout << endl;
00914 
00915   if(developer_version)
00916     if(level >= Max_number_levels) {
00917       cout << " \n level zu gross bei Add_list_interior " << endl;
00918     }
00919 
00920   color = I.color(level);
00921   color = reordering_formula(color);
00922 
00923   start_P_interior[color][level] = 
00924     new P_interior(I,start_P_interior[color][level]);
00925   ++number_interior_points[level];
00926 
00927   Add_double(I,level,Give_max_num_var());
00928 }
00929 
00930 
00931 void Grid::Add_list_nearb(Index3D I) {
00932   static Index3D Inext;
00933   static int t;
00934 
00935   t = I.Tiefe();
00936   if(t<my_coarsest_level)
00937     t = my_coarsest_level;
00938   
00939   for(;t<=Max_level();++t) {
00940     //    if(I_am_responsible_for(I,t))
00941     Add_list_nearb(I,t);        // nearb point with respect to this level
00942   }
00943 }
00944 
00945 
00946 void Grid::Add_list_nearb(Index3D I, int level) {
00947   dir_sons color;
00948   color = I.color(level);
00949   color = reordering_formula(color);
00950 
00951   start_P_nearb[color][level] = new P_nearb(I,start_P_nearb[color][level]);
00952   ++number_nearb_points[level];
00953 
00954   Add_double(I,level,Give_max_num_var());
00955 }
00956 
00957 void Grid::Add_list_exteri(Index3D I) {
00958   Index3D Inext;
00959   int t, t_max;
00960 
00961   t = I.Tiefe();
00962   if(t<my_coarsest_level)
00963     t = my_coarsest_level;
00964 
00965   t_max = Give_finest_level(I);
00966 
00967   //  for(;t<Max_level();++t) {
00968   for(;t<=t_max;++t) {
00969     Add_list_exteri(I,t);        // exteri point with respect to this level
00970   }
00971 }
00972 
00973 
00974 void Grid::Add_list_exteri(Index3D I, int level) {
00975   dir_sons color;
00976   color = I.color(level);
00977   color = reordering_formula(color);
00978 
00979   start_P_exteri[color][level] = new P_nearb(I,start_P_exteri[color][level]);
00980   ++number_exteri_points[level];
00981 
00982   Add_double(I,level,Give_max_num_var());
00983 }
00984 
00985 
00986 void Grid::Add_list_bo2p(Bo2Point* bopoint) {
00987   dir_sons color;
00988   /* old ordering
00989   color = bopoint->ind.color(bopoint->level);
00990   color = reordering_formula(color);
00991   */
00992   color = reordering_boundary_formula(bopoint->ind,
00993                                       bopoint->direction,
00994                                       my_index);
00995 
00996   start_P_Bo2p[color][bopoint->level] = 
00997     new P_Bo2p(bopoint->ind,bopoint->direction,
00998                start_P_Bo2p[color][bopoint->level]);
00999   ++number_bo2p_points[bopoint->level];
01000 }
01001 
01002 
01003 
01004 
01005 
01006 void Grid::Add_list_cellpoi(BoCell* bocellf) {
01007   int lev;
01008   lev = bocell->ind.Tiefe() - 1;
01009   start_P_cellpoi[0][lev] = 
01010     new P_cellpoi(bocell->ind,start_P_cellpoi[0][lev]);
01011   ++number_cellpoi_points[lev];
01012 }
01013 
01014 void Grid::Add_list_interior_cell(Point_hashtable0* cellp) {
01015   int lev;
01016   lev = cellp->ind.Tiefe() - 1;
01017 
01018   start_P_interior_cell[lev] = 
01019     new P_interior_cell(cellp->ind,start_P_interior_cell[lev],
01020                         cellp->Give_var());
01021   ++number_interior_cell_points[lev];
01022 }
01023 
01024 /*
01025 void Grid::Add_list_boundary_tet(BoCell* cellp, Tetraeder_storage* tet) {
01026   int lev;
01027   lev = cellp->ind.Tiefe() - 1;
01028 
01029   start_P_boundary_tet[lev] = 
01030     new P_boundary_tet(cellp->ind,start_P_boundary_tet[lev],
01031                         tet->Give_variable());
01032   ++number_boundary_cell_tet[lev];
01033 }
01034 */
01035 
01036 int Grid::Min_interior_level() {
01037   // return max_level-1;
01038 
01039   return min_interior_level;
01040   
01041   // return max_level;
01042   // return max_level-1;
01043   
01044   //  return min_level;
01045 };  
01046 
01047 double Grid::Give_number_interior_grid_points(int lev) {
01048   if(developer_version) {
01049      if(lev<0 || lev >max_level)
01050        cout << "error in Grid::Give_number_interior_gid_points!! " << endl;
01051   }
01052   return Total_number_interior_points(lev) +
01053     Total_number_nearb_points(lev);
01054 };  
01055 
01056 
01057 void Grid::Set_type_of_update(int number_variable, int level, 
01058                               type_of_update type) const {
01059   eval_par_object->Set_type_of_update(number_variable,level,type); 
01060 }
01061 
01063 // delete storage
01064 
01065 void Grid::Delete_storage() {
01066   // a) hashtables
01067   Remove_all_hashtables();
01068 
01069   // b) delete things which were constructed in  Grid::Construct_storage()
01070   delete nearb_ablage;
01071   delete vector_ablage;
01072   delete label_on_cell;
01073   delete eight_bools;
01074   
01075   for(int i=0;i<8;++i)
01076     delete stencils_fine[i];
01077   delete stencils_fine;
01078 
01079   delete weight_27 ;
01080   delete restriction_stencil;
01081   delete coarse_grid_functions;
01082 
01083   // c) lists
01084   int color, lev;
01085   P_interior *iter_i, *iter_i_old;
01086   for(lev=0;lev <= Max_level();++lev)
01087     for(color=0;color < anzahl_colors;++color)
01088       for(iter_i=Start_P_interior(lev,color);
01089           iter_i!=NULL;) {
01090         iter_i_old = iter_i;
01091         iter_i=iter_i->Next();
01092         delete iter_i_old;
01093       }
01094 
01095   P_nearb *iter_nb, *iter_nb_old;
01096   for(lev=0;lev <= Max_level();++lev)
01097     for(color=0;color < anzahl_colors;++color)
01098       for(iter_nb=Start_P_nearb(lev,color);
01099           iter_nb!=NULL;) {
01100         iter_nb_old = iter_nb;
01101         iter_nb=iter_nb->Next();
01102         delete iter_nb_old;
01103       }
01104 
01105   P_cellpoi *iter_cf, *iter_cf_old;
01106   for(lev=0;lev <= Max_level();++lev)
01107     for(iter_cf=Start_P_cellpoi(lev);
01108         iter_cf!=NULL;) {
01109       iter_cf_old = iter_cf;
01110       iter_cf=iter_cf->Next();
01111         delete iter_cf_old;
01112     }
01113 
01114   P_Bo2p *iter_bo, *iter_bo_old;
01115   for(lev=0;lev <= Max_level();++lev)
01116     for(color=0;color < anzahl_colors;++color)
01117       for(iter_bo=Start_P_Bo2p(lev,color);
01118           iter_bo!=NULL;iter_bo=iter_bo->Next()) {
01119         iter_bo_old = iter_bo;
01120         iter_bo=iter_bo->Next();
01121         delete iter_bo_old;
01122       }
01123 
01124   P_parallel *iter_pa, *iter_pa_old;
01125   for(lev=Max_level();lev <= Max_level();++lev)
01126     for(iter_pa=Start_P_parallel(lev);
01127         iter_pa!=NULL;iter_pa=iter_pa->Next()) {
01128       iter_pa_old = iter_pa;
01129       iter_pa=iter_pa->Next();
01130       delete iter_pa_old;
01131     }
01132 
01133   // for cell variables
01134   int i;
01135   
01136   for(i=0;i < Max_number_levels;++i) delete start_P_interior_cell[i];
01137   for(i=0;i < Max_number_levels;++i) delete start_P_boundary_tet[i];
01138   delete start_P_interior_cell;
01139   delete start_P_boundary_tet;
01140 
01141   for(i=0;i<anzahl_colors;++i)
01142       delete start_P_interior[i];
01143   delete start_P_interior;
01144 
01145   for(i=0;i<anzahl_colors;++i)
01146       delete start_P_nearb[i];
01147   delete start_P_nearb;
01148 
01149   for(i=0;i<1;++i) 
01150       delete start_P_cellpoi[i];
01151   delete start_P_cellpoi;
01152 
01153  for(i=0;i<anzahl_colors;++i) 
01154       delete start_P_Bo2p[i];
01155   delete start_P_Bo2p;
01156 
01157   delete start_P_parallel;
01158 
01159   for(lev=0;lev <= Max_level();++lev)
01160     for(color=0;color < anzahl_colors;++color)
01161       for(iter_nb=Start_P_exteri(lev,color);
01162           iter_nb!=NULL;) {
01163         iter_nb_old = iter_nb;
01164         iter_nb=iter_nb->Next();
01165         delete iter_nb_old;
01166       }
01167   for(i=0;i<anzahl_colors;++i)
01168       delete start_P_exteri[i];
01169   delete start_P_exteri;
01170 }

Generated on Mon Jan 16 13:23:40 2006 for IPPL by  doxygen 1.4.6