src/expde/grid/ggen.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 // ggen.cc
00020 //
00021 // ------------------------------------------------------------
00022 
00023 
00025 //  Grid_base::Grid_base
00027 
00028 // Include level 0:
00029 #ifdef COMP_GNUOLD
00030  #include <iostream.h>
00031  #include <fstream.h>
00032  #include <time.h>
00033  #include <math.h>
00034 #else
00035  #include <iostream>
00036  #include <fstream>
00037  #include <ctime>
00038  #include <cmath>
00039 #endif
00040  
00041 #ifdef USE_PBE
00042 #include "pbedefs.h"
00043 #endif
00044 
00045 // Include level 0:
00046 #include "../parser.h"
00047 
00048 // Include level 1:
00049 #include "../paramete.h"
00050 #include "../abbrevi.h"
00051 #include "../math_lib/math_lib.h"
00052 
00053 // Include level 2:
00054 #include "../basic/basic.h"
00055 
00056 // Include level 3:
00057 #include "../domain/domain.h"
00058 
00059 // Include level 4:
00060 #include "../formulas/boundy.h"
00061 #include "../formulas/loc_sten.h"
00062 
00063 // Include level 5
00064 #include "gpar.h"
00065 #include "parallel.h"
00066 #include "mgcoeff.h"
00067 #include "sto_man.h"
00068 #include "gridbase.h"
00069 #include "grid.h"
00070 
00071 
00072 // for not active processes
00073 void Grid_base::Dummy_grid_generation() {
00074  Initialize_hash0(hashtable0_lenght);
00075  Initialize_hash1(1);
00076  Initialize_hash2(1);
00077  Initialize_hash3(1);
00078 
00079   // I.2. Schritt: Vermeidung von typ d) Flaechen auf feinsten Zellen
00080   bool go_on;
00081   Start_for_face_correction_parallel();
00082   for(go_on=must_edges_be_send();go_on;go_on=must_edges_be_send()) {
00083   }
00084   End_for_face_correction_parallel();
00085 }
00086 
00087 
00088 void Grid_base::Grid_generation(int n_max) {
00089   int number_for_hashs;
00090   int l;
00091 
00092   // Teil O: Preparations
00093   // ---------------------
00094 
00095 //  MPI_Barrier(comm);
00096 // cout << "C: " << endl;
00097 
00098   // 0.1.Schritt: Maximal level
00099   if(n_max<=1)
00100     cout << " please choose maximal level at least 2 in constructor of Grid! "
00101          << endl;
00102   if(n_max<domain->Give_n_uniform())
00103     cout << " level is too small for the discretization of this domain! "
00104          << endl;
00105   
00106   // 0.2.Schritt: Construction of hash table 0:  
00107   Initialize_hash0(hashtable0_lenght);
00108 
00109   if(print_status_of_grid_generator) if(my_rank==0) {
00110     cout << "  I Basic grid generation by edges; " << endl;
00111   } 
00112 
00113 #ifdef USE_PBE
00114   pbe_start(2,"I-Calc_type_of_edges_uniform");
00115 #endif
00116 
00117   // Teil I: Basic grid generation by edges 
00118   //----------------------------------------
00119   // I.1. Schritt: Berechne Typ der Kanten
00120   // verbessern ( nur einmal ueber Kanten gehen!)
00121   Calc_type_of_edges_uniform();  // studies all edges of cells in finest level
00122 
00123 #ifdef USE_PBE
00124   pbe_stop(2);
00125 #endif
00126 
00127   // I.2. Schritt: Vermeidung von typ d) Flaechen auf feinsten Zellen
00128   if(print_status_of_grid_generator) if(my_rank==0) {
00129     cout << "   I.2 edge correction; " << endl;
00130   } 
00131 
00132 #ifdef USE_PBE
00133   pbe_start(3,"I.2-edges_correction");
00134 #endif
00135 
00136   bool go_on, send_yn;
00137   Start_for_face_correction_parallel();
00138   while(Correct_faces_uniform()) {};
00139   // -> parallel
00140   if(parallel_version) {
00141     for(go_on=must_edges_be_send();go_on;go_on=must_edges_be_send()) {
00142       send_yn = send_edges();
00143       if(send_yn) {
00144         while(Correct_faces_uniform()) {};
00145       }
00146     }
00147   }
00148   End_for_face_correction_parallel();
00149 
00150   // I.3. Schritt: Resize hashtable0
00151   Resize_hash0(Factor_hashtable0_lenght*hashtable0_occ+7);       
00152 
00153 #ifdef USE_PBE
00154   pbe_stop(3);
00155 #endif
00156 
00157 
00158   if(print_status_of_grid_generator) if(my_rank==0) {
00159     cout << "  II Calculation of points and cells; " << endl;
00160   } 
00161   // Teil II: Calculation of interior points, cell points and 
00162   //          points near the boundary
00163   //----------------------------------------
00164 #ifdef USE_PBE
00165   pbe_start(4,"II-1_Construction_of_hash_table");
00166 #endif
00167 
00168   // II.1.Schritt: Construction of hash table 1:  
00169   Initialize_hash1(Factor_hashtable1_lenght*hashtable0_occ+7);       
00170 
00171 #ifdef USE_PBE
00172   pbe_stop(4);
00173 #endif
00174 
00175 
00176   // II.2.Schritt: Uebertragung der Eckpunkte der Kanten Hash0 in Hash1
00177   //               typ: nearb
00178   if(print_status_of_grid_generator) if(my_rank==0) {
00179     cout << "   II.2 construct basic points; " << endl;
00180   } 
00181 
00182 #ifdef USE_PBE
00183   pbe_start(5,"II-2_basic_points");
00184 #endif
00185 
00186   Construct_points_hash1();
00187 
00188   if(print_status_of_grid_generator) if(my_rank==0) {
00189     cout << "        send them; " << endl;
00190   } 
00191 #ifdef USE_PBE
00192   pbe_stop(5);
00193 #endif
00194 
00195 
00196 #ifdef USE_PBE
00197   pbe_start(6,"II-2_send_basic_points");
00198 #endif
00199 
00200   Send_grid_points_direct_parallel(nearb);
00201 
00202 #ifdef USE_PBE
00203   pbe_stop(6);
00204 #endif
00205 
00206 
00207   // II.3.Schritt: add some exterior
00208   if(print_status_of_grid_generator) if(my_rank==0) {
00209     cout << "   II.3 fullfill B1B2; " << endl;
00210   } 
00211 
00212 #ifdef USE_PBE
00213   pbe_start(7,"II-3_fullfull_B1B2");
00214 #endif
00215 
00216   Fullfill_B1B2();                
00217 
00218 #ifdef USE_PBE
00219   pbe_stop(7);
00220 #endif
00221 
00222 
00223   // II.4.Schritt: construct cell points of Hash0; look at interior>= points
00224   if(print_status_of_grid_generator) if(my_rank==0) {
00225     cout << "   II-4_construct_cell_points; " << endl;
00226   } 
00227 
00228 #ifdef USE_PBE
00229   pbe_start(8,"II-4_cosntr_cell_points");
00230 #endif
00231 
00232   Construct_cell_points_hash0();
00233 
00234 #ifdef USE_PBE
00235   pbe_stop(8);
00236 #endif
00237 
00238 
00239   // II.61.Schritt: Typ der Zellen berechnen auf feinsten Gitter (Part1) 
00240   //               int_cell, ex_cell, fine_bo_cell
00241   //               cell type depends on the type of corners
00242   if(print_status_of_grid_generator) if(my_rank==0) {
00243     cout << "   II.61 interior cell part 1; " << endl;
00244   }
00245 
00246 #ifdef USE_PBE
00247   pbe_start(9,"II-61_interior_cell_part_1");
00248 #endif
00249 
00250   Calc_interior_cells_Part1();
00251 
00252 #ifdef USE_PBE
00253   pbe_stop(9);
00254 #endif
00255 
00256 
00257   // II.62.Schritt: 
00258   // ^^^^^^^^ Parallel ^^^^^^^^
00259   // Send info about neighbour boundary cells and edges of them
00260   // -> parallel
00261 
00262   if(parallel_version) {
00263     if(print_status_of_grid_generator) if(my_rank==0) {
00264       cout << "   II.62 sends of boundary cells; " << endl;
00265     }
00266 
00267 #ifdef USE_PBE
00268     pbe_start(10,"II-62_(P)_sends_of_boundary_cells");
00269 #endif
00270 
00271 
00272 #ifdef USE_PBE
00273     pbe_start(33,"II-62_(P)Send_boundary_cells_parallel");
00274 #endif
00275     Send_boundary_cells_parallel();
00276 #ifdef USE_PBE
00277   pbe_stop(33);
00278 #endif
00279 
00280 #ifdef USE_PBE
00281     pbe_start(34,"II-62_(P)Send_grid_points_direct_parallel(MG)");
00282 #endif
00283     Send_grid_points_direct_parallel(multigrid);
00284 #ifdef USE_PBE
00285   pbe_stop(34);
00286 #endif
00287 
00288 #ifdef USE_PBE
00289   pbe_stop(10);
00290 #endif
00291 
00292   }
00293 
00294   // Test_just_this();
00295 
00296   // II.63.Schritt: Typ der Zellen berechnen bei restlichen Zellen (Part2) 
00297   //                int_cell, ex_cell, bo_cell fine_bo_cell
00298   //                vergroebert bis auf ganzes Gebiet bis n_parallel
00299   //                nicht eigene groebere Zellen werden exterior
00300   if(print_status_of_grid_generator) if(my_rank==0) {
00301     cout << "   II.63 interior cell part 2; " << endl;
00302   }
00303 
00304 #ifdef USE_PBE
00305     pbe_start(11,"II-63_(P)_interior_cells_part_2");
00306 #endif
00307   Calc_interior_cells_Part2();
00308 #ifdef USE_PBE
00309   pbe_stop(11);
00310 #endif
00311 
00312   // -> parallel
00313   if(parallel_version) {
00314     if(print_status_of_grid_generator) if(my_rank==0) {
00315       cout << "        send them; " << endl;
00316     }
00317 #ifdef USE_PBE
00318     pbe_start(12,"II-62_(P)_send_them");
00319 #endif
00320     // a) for finer cells
00321     // here l is the level of the cell point -1
00322     for(l=Max_level();l>=n_parallel-1;--l) 
00323       Send_cells_parallel(l);
00324 
00325 
00326     // b) for coarser cells
00327     // maximal coarsest level:
00328     //    cout << " my my_coarsest_level: " << my_coarsest_level 
00329     //   << " my rank: : "  << my_rank << endl;
00330     for(l=n_parallel-2;l>=my_coarsest_level;--l) {
00331     //    for(l=n_parallel-2;l>=1;--l) {
00332       Calc_interior_cells_Part3(l); 
00333       Send_cells_parallel(l);
00334     }
00335 #ifdef USE_PBE
00336   pbe_stop(12);
00337 #endif
00338   }
00339 
00340   // II.7.Schritt:
00341   // Einschub: beseitige Punkte die unnoetig sind
00342   // ---------
00343   if(print_status_of_grid_generator) if(my_rank==0) {
00344     cout << "   II.7 calc multigrid points; " << endl;
00345   }
00346   // Teil A. - Berechne Multigrid-Punkte
00347   //           Dies sind hoechstens alte exterior Punkte, 
00348   //           die Ecken einer nicht exterior Zelle sind
00349   //         - restlichen exterior Punkte werden in B. beseitigt
00350   //         - genauere Feststellung der Multigrid-Punkte
00351   //           erfolgt in mgcoeff.cc aus Interpolationsoperatoreigenschaft 
00352 #ifdef USE_PBE
00353     pbe_start(13,"II-7_calc_mg_points");
00354 #endif
00355 
00356   Calc_multigrid_points_part1();
00357 
00358 #ifdef USE_PBE
00359   pbe_stop(13);
00360 #endif
00361 
00362   if(print_status_of_grid_generator) if(my_rank==0) {
00363     cout << "   II.7 remove exterior points; " << endl;
00364   }
00365 #ifdef USE_PBE
00366     pbe_start(14,"II-7_(P)_remove_exterior_points");
00367 #endif
00368 
00369   // Teil B. Beseitige exterior Punkte
00370   Remove_exterior_points();
00371 
00372 #ifdef USE_PBE
00373   pbe_stop(14);
00374 #endif
00375   // II.8.Schritt: Berechnung der Ecken 2.Teil:
00376   //            von randnah auf randnah oder ausnahme oder hierarchical
00377   //            oder p_parallel ^^^^^^^^ Parallel ^^^^^^^^
00378   if(print_status_of_grid_generator) if(my_rank==0) {
00379     cout << "   II.8 calc interior points; " << endl;
00380   }
00381 #ifdef USE_PBE
00382     pbe_start(15,"II-8_calc_interior_points");
00383 #endif
00384   Calc_interior_points();
00385 #ifdef USE_PBE
00386   pbe_stop(15);
00387 #endif
00388 
00389   // II.9.Schritt: Send coarse grid points
00390   // -> parallel
00391   if(parallel_version) {
00392     if(print_status_of_grid_generator) if(my_rank==0) {
00393       cout << "   II.9 send coarse grid points; " << endl;
00394     }
00395 #ifdef USE_PBE
00396     pbe_start(16,"II-9_(P)_sends_coarse_grid_points");
00397 #endif
00398 
00399     Send_coarse_grid_points_parallel();
00400 #ifdef USE_PBE
00401   pbe_stop(16);
00402 #endif
00403   }
00404   
00405   
00406   if(print_status_of_grid_generator) if(my_rank==0) {
00407     cout << "  III Calculation of boundary; " << endl;
00408   } 
00409   // Teil III: Berechnung der Randzellen und Randpunkte
00410   //----------------------------------------------------
00411 #ifdef USE_PBE
00412     pbe_start(17,"III-1_Calc_of_boundary_(hash_init)");
00413 #endif
00414 
00415   // 1.Schritt: Schritt Hash2, Hash3
00416   number_for_hashs = Calc_number_boundary_cells_for_hash2() + 7;
00417   Initialize_hash2(Factor_hashtable2_lenght * number_for_hashs + 7);
00418   Initialize_hash3(Factor_hashtable3_lenght * number_for_hashs + 7);
00419 
00420 #ifdef USE_PBE
00421   pbe_stop(17);
00422 #endif
00423   // 2.Schritt: Randzellen berechnen
00424   if(print_status_of_grid_generator) if(my_rank==0) {
00425     cout << "   III.2 boundary cells; " << endl;
00426   }
00427 
00428 #ifdef USE_PBE
00429     pbe_start(18,"III-2_boundary_cells");
00430 #endif
00431 
00432   Calc_boundary_cells();
00433 
00434 #ifdef USE_PBE
00435   pbe_stop(18);
00436 #endif
00437   // other Schritt's of Teil III: are contained in:
00438   //               Grid_base::Initialize_variable();
00439   // see also:     Grid::Initialize();
00440 
00441 //Information();
00442 //Info_hashtable0();
00443 //Info_hashtable1();
00444 
00445 }
00446 
00447 
00448 // II.3.Schritt:
00449 //--------------
00450 void Grid_base::Fullfill_B1B2() {
00451   static int occ_old;
00452   // Schneller machen !!
00453   occ_old = 0;
00454   while(occ_old != hashtable1_occ) {
00455     occ_old = hashtable1_occ;
00456     iterate_hash1 {
00457       Add_B1B2(point1->ind);
00458     }
00459   }
00460 }
00461 void Grid_base::Add_B1B2(Index3D I) {
00462   static int t, i, j, k;
00463   static Index3D In;
00464 
00465   t = I.Tiefe();
00466   if(I.ind_x.Tiefe() > 0 && I.ind_z.Tiefe() > 0 && I.ind_y.Tiefe() > 0) {
00467     // B1 Bedingung: 
00468     if(I.ind_x.Tiefe() == t && I.ind_y.Tiefe() == t && I.ind_z.Tiefe() == t) {
00469       for(i=0;i<3;++i) for(j=0;j<3;++j) for(k=0;k<3;++k) {
00470         In = I.next((Ort1D)i,(Ort1D)j,(Ort1D)k,t);
00471         if(!Exists_Point(In)) Add_point(In);
00472       }
00473     }
00474     else {
00475       // B2 Bedingung: 
00476       if(I.ind_x.Tiefe() == t) {
00477         if(I.ind_y.Tiefe() == t) {
00478           // zwei Zellen in z_Richtung 
00479           for(i=0;i<2;++i) Add_points_of_cell(I.next_TD((dir1D)i,t));
00480         }
00481         else {
00482           if(I.ind_z.Tiefe() == t) {
00483             // zwei Zellen in y_Richtung 
00484             for(i=0;i<2;++i) Add_points_of_cell(I.next_NS((dir1D)i,t));
00485           }
00486           else {
00487             // vier Zellen in yz_Richtung 
00488             for(i=0;i<2;++i) for(j=0;j<2;++j) 
00489               Add_points_of_cell(I.next_NS((dir1D)i,t).next_TD((dir1D)j,t));
00490           }
00491         }
00492       }
00493       else {
00494         if(I.ind_y.Tiefe() == t) {
00495           if(I.ind_z.Tiefe() == t) {
00496             // zwei Zellen in x_Richtung 
00497             for(i=0;i<2;++i) Add_points_of_cell(I.next_EW((dir1D)i,t));
00498           }
00499           else {
00500             // vier Zellen in xz_Richtung 
00501             for(i=0;i<2;++i) for(j=0;j<2;++j) 
00502               Add_points_of_cell(I.next_EW((dir1D)i,t).next_TD((dir1D)j,t));
00503           }
00504         }
00505         else {
00506           // vier Zellen in xy_Richtung 
00507           for(i=0;i<2;++i) for(j=0;j<2;++j) 
00508             Add_points_of_cell(I.next_EW((dir1D)i,t).next_NS((dir1D)j,t));
00509         }
00510       }
00511     }
00512   }
00513 }
00514 
00515 
00516 // II.4.Schritt: construct cell points of Hash0
00517 //----------------------------------------------
00518 void Grid_base::Construct_cell_points_hash0() {
00519   int i;
00520   Index3D I, I_next;
00521   // part 1: add cells near interior points
00522   iterate_hash1 {
00523     I = point1->Give_Index();
00524     if(point1->typ>=interior && I<<my_index)
00525       // if(point1->typ>=interior)
00526       for(i=0;i<8;++i) {
00527         I_next = I.next((dir_sons)i,max_level+1);
00528         if(my_index<=I_next) {  // diese Bedingung war auch mal auskommentiert
00529           Add_cell(I_next);
00530           Add_points_of_cell(I_next);
00531           // part 2: add recursive coarse cells
00532           Recursion_Construct_cell_points_hash0(I_next);
00533         }
00534       }
00535   }
00536   // part 3: add basic cell
00537   Add_cell(my_index);
00538   Recursion_Construct_cell_points_hash0(my_index);
00539 }
00540 
00541 void Grid_base::Recursion_Construct_cell_points_hash0(Index3D I) {
00542   Index3D ind(2,2,2);
00543 
00544   if(I == Index3D(0,0,0)) {
00545 
00546     cout << "Hallo" ;
00547 
00548   }
00549 
00550   // Rekursiv weiter
00551   if(I!=ind) Recursion_Construct_cell_points_hash0(I.father());
00552   Add_cell(I);
00553   Add_points_of_cell(I);
00554 }
00555 
00556 
00557 // II.2.Schritt: Uebertragung der Eckpunkte der Kanten Hash0 in Hash1
00558 //--------------
00559 void Grid_base::Construct_points_hash1() {
00560   Index3D ind;
00561   int i;
00562   iterate_hash0 {
00563     ind=point0->Give_Index();
00564     if(developer_version) {
00565       if(point0->typ!=edge_interior ||
00566          !ind.Edge_index())
00567         cout << " Error in Grid_base::Construct_points_hash1() " << endl;
00568     }
00569     for(i=0;i<2;++i) {
00570       Add_point(ind.corner_of_edge_index((dir1D)i),nearb);
00571     }
00572   }
00573 }
00574 
00575 
00576 // I.1. Schritt: Berechne Typ der Kanten
00577 //--------------
00578 void Grid_base::Calc_type_of_edges_uniform() {
00579   Index3D ind;
00580   /* for seriel:
00581   ind = ind.son(ENTd);
00582   ind = ind.son(WSDd);
00583   */
00584 
00585   ind = my_index;
00586 
00587   // for pre_check_box_grid_generation
00588   A_domain_sp = domain->GiveA();
00589   B_domain_sp = A_domain_sp + domain->GiveVecH();
00590   Recursion_Calc_type_of_edges_uniform(ind);
00591 }
00592 
00593 void Grid_base::Recursion_Calc_type_of_edges_uniform(Index3D I) {
00594   int i, j;
00595   Index3D I_son;
00596   IndexEdge Iedge;
00597   Index3D indL, indR;
00598   D3vector VL, VR;
00599   Edgetype edge_now;
00600 
00601   if(I.Tiefe()<max_level+1) {
00602     // I ist nicht Index einer feinsten Zelle    
00603     for(i=0;i<8;++i) {
00604       I_son = I.son((dir_sons)i);
00605       // Rekursiv weiter
00606       if(pre_check_box_grid_generation) {
00607         VL = transform_coord(I_son.neighbour_non_periodic(WSDd));
00608         VR = transform_coord(I_son.neighbour_non_periodic(ENTd));
00609 
00610         if(B_domain_sp.x > VL.x && A_domain_sp.x < VR.x &&
00611            B_domain_sp.y > VL.y && A_domain_sp.y < VR.y &&
00612            B_domain_sp.z > VL.z && A_domain_sp.z < VR.z) {
00613 
00614           Recursion_Calc_type_of_edges_uniform(I_son);
00615         }
00616       }
00617       else
00618         Recursion_Calc_type_of_edges_uniform(I_son);
00619     }
00620   }
00621   else {
00622     // Untersuche Kanten
00623     for(j=0;j<12;++j) {
00624       Iedge = I.edge((Edges_cell)j);
00625       if(Give_edge_typ(Iedge.I())!=edge_interior) {
00626         indL = Iedge.corner(Ld);
00627         indR = Iedge.corner(Rd);
00628         // Keine Ecke der Kante ist am Rand von [0,1]^3 bzw. my_cell
00629         if(contained_in_boxes(indL) &&
00630            contained_in_boxes(indR)) {
00631           // Kante ist im Inneren von [0,1]^3
00632           VL = transform_coord(indL);
00633           VR = transform_coord(indR);
00634           if(domain->calc_edge(VL,VR)) {
00635             edge_now = (Edgetype)domain->edge(VL,VR);
00636             if(edge_now==edge_interior) {
00637               Add_edge(Iedge.I());
00638             }
00639           }
00640           else {
00641             cout <<
00642               "\n Dies ist in Recursion_Calc_type_of_edges noch nicht fertig!" 
00643                  << endl;
00644           }
00645         }
00646       }
00647     }
00648   }
00649 }
00650 
00651 // I.2. Schritt: Vermeidung von typ d) Flaechen auf feinsten Zellen
00652 //--------------
00653 
00654 // new version
00655 bool Grid_base::Correct_faces_uniform() {
00656   bool back;
00657 
00658   back = false;
00659 
00660   Index3D I;
00661   iterate_hash0 {
00662     I = point0->Give_Index();
00663     Correct_edge(I);
00664   }
00665   return back;
00666 }
00667 
00668 bool Grid_base::Correct_edge(Index3D I) {
00669   bool back;
00670 
00671   back = false;
00672   if(I << my_index) {
00673     if(I.I_x().Tiefe() == max_level+1) {
00674       back = back || Correct_face(IndexSurface(I.next_S(max_level+1),Ddir)); 
00675       back = back || Correct_face(IndexSurface(I.next_N(max_level+1),Ddir)); 
00676       back = back || Correct_face(IndexSurface(I.next_T(max_level+1),Sdir)); 
00677       back = back || Correct_face(IndexSurface(I.next_D(max_level+1),Sdir)); 
00678     }
00679     if(I.I_y().Tiefe() == max_level+1) {
00680       back = back || Correct_face(IndexSurface(I.next_E(max_level+1),Ddir)); 
00681       back = back || Correct_face(IndexSurface(I.next_W(max_level+1),Ddir)); 
00682       back = back || Correct_face(IndexSurface(I.next_T(max_level+1),Wdir)); 
00683       back = back || Correct_face(IndexSurface(I.next_D(max_level+1),Wdir)); 
00684     }
00685     if(I.I_z().Tiefe() == max_level+1) {
00686       back = back || Correct_face(IndexSurface(I.next_S(max_level+1),Wdir)); 
00687       back = back || Correct_face(IndexSurface(I.next_N(max_level+1),Wdir)); 
00688       back = back || Correct_face(IndexSurface(I.next_E(max_level+1),Sdir)); 
00689       back = back || Correct_face(IndexSurface(I.next_W(max_level+1),Sdir)); 
00690     }
00691   }
00692   return back;
00693 }
00694 
00695 bool Grid_base::Correct_face(IndexSurface Isur) {
00696   int i;
00697   int anz;
00698   // Anzahl der inneren Kanten zaehlen:
00699   anz=0;
00700   for(i=0;i<4;++i) {
00701     if(Give_edge_typ(Isur.edge((dir_2D)i))==edge_interior) ++anz;
00702   }
00703   if(anz==3) {
00704     // Typ d) Flache: also umformen zu Flaeche mit 4 inneren Kanten:
00705     for(i=0;i<4;++i) {
00706       if(Give_edge_typ(Isur.edge((dir_2D)i))!=edge_interior) {
00707         Add_edge_parallel(Isur.edge((dir_2D)i));
00708         Correct_edge(Isur.edge((dir_2D)i));
00709       }
00710     }
00711     return true;
00712   }
00713   else return false;
00714 }
00715 
00716 /* old version
00717 bool Grid_base::Correct_faces_uniform() {
00718   bool back;
00719   back = false;
00720 
00721   Index3D I;
00722   iterate_hash0 {
00723     I = point0->Give_Index();
00724     if(I.I_x().Tiefe() == max_level+1) {
00725       back = back || Correct_face(IndexSurface(I.next_S(max_level+1),Ddir)); 
00726       back = back || Correct_face(IndexSurface(I.next_N(max_level+1),Ddir)); 
00727       back = back || Correct_face(IndexSurface(I.next_T(max_level+1),Sdir)); 
00728       back = back || Correct_face(IndexSurface(I.next_D(max_level+1),Sdir)); 
00729     }
00730     if(I.I_y().Tiefe() == max_level+1) {
00731       back = back || Correct_face(IndexSurface(I.next_E(max_level+1),Ddir)); 
00732       back = back || Correct_face(IndexSurface(I.next_W(max_level+1),Ddir)); 
00733       back = back || Correct_face(IndexSurface(I.next_T(max_level+1),Wdir)); 
00734       back = back || Correct_face(IndexSurface(I.next_D(max_level+1),Wdir)); 
00735     }
00736     if(I.I_z().Tiefe() == max_level+1) {
00737       back = back || Correct_face(IndexSurface(I.next_S(max_level+1),Wdir)); 
00738       back = back || Correct_face(IndexSurface(I.next_N(max_level+1),Wdir)); 
00739       back = back || Correct_face(IndexSurface(I.next_E(max_level+1),Sdir)); 
00740       back = back || Correct_face(IndexSurface(I.next_W(max_level+1),Sdir)); 
00741     }
00742   }
00743   return back;
00744 }
00745 
00746 bool Grid_base::Correct_face(IndexSurface Isur) {
00747   int i;
00748   int anz;
00749   // Anzahl der inneren Kanten zaehlen:
00750   anz=0;
00751   for(i=0;i<4;++i) {
00752     if(Give_edge_typ(Isur.edge((dir_2D)i))==edge_interior) ++anz;
00753   }
00754   if(anz==3) {
00755     // Typ d) Flache: also umformen zu Flaeche mit 4 inneren Kanten:
00756     for(i=0;i<4;++i) {
00757       if(Give_edge_typ(Isur.edge((dir_2D)i))!=edge_interior)
00758         Add_edge_parallel(Isur.edge((dir_2D)i));
00759     }
00760     return true;
00761   }
00762   else return false;
00763 }
00764 */
00765 
00766 
00767 // Schritt II.61 nd 62
00768 //---------------------
00769 
00770 
00771 void Grid_base::Calc_interior_cells_Part1() {
00772   Index3D ind;
00773   Celltype ce_type;
00774   
00775   ind = my_index;
00776 
00777   ce_type = Recursion_calc_interior_cells_Part1(ind);
00778   Set_cell_typ(ind,ce_type);
00779 }
00780 
00781 void Grid_base::Calc_interior_cells_Part2() {
00782   Index3D ind(2,2,2);
00783   Celltype ce_type;
00784 
00785   // calc my cells
00786   ce_type = Recursion_calc_interior_cells_Part2(ind);
00787 
00788   Set_cell_typ(ind,ce_type);
00789 
00790   // Set not my cells exterior
00791   Index3D I;
00792   iterate_hash0 {
00793     I = point0->Give_Index();
00794     if(((I < my_index) == false) && (I.Tiefe()<= Max_level()))
00795       point0->typ=ex_cell;
00796   }
00797 }
00798 
00799 // I ist Index einer Zelle, die nicht im Gebiet ist
00800 // Es wird der Zelltyp mit Mittelpunktindex I berechnet
00801 Celltype Grid_base::Calc_cell_type(Index3D I) {
00802   static bool labelex;
00803   static bool labelin;
00804   static Pointtype poitype;
00805   static int k;
00806 
00807   //  1. Teil untersuche Ecken:
00808   labelin=false; //Annahme: Es gibt keine innere Ecke
00809   labelex=false; //Annahme: Es gibt keine aussere Ecke
00810   for(k=0;k<8;k++) {
00811     poitype = Give_type(I.neighbour((dir_sons)k));
00812     if(poitype!=exterior  && 
00813        poitype!=multigrid &&
00814        poitype!=boundary) labelin=true;
00815    if(poitype==exterior || poitype==multigrid) labelex=true;
00816   }
00817   if(labelin==false) return ex_cell;
00818   if(labelex==true)  return bo_cell;
00819 
00820   //  2. Teil Es ist notwendig zusaetzlich die Kanten zu untersuchen
00821   //          Zelle ist entweder innere Zelle oder Randzelle
00822   /*
00823   for(k=0;k<12;k++) {
00824     if(Give_edge_typ(I.I_edge((Edges_cell)k))==edge_not_interior)
00825       return bo_cell;
00826   }
00827   */
00828   return int_cell;
00829 }
00830 
00831 
00832 
00833 
00834 Celltype Grid_base::Recursion_calc_interior_cells_Part1(Index3D I) {
00835   Index3D I_son;
00836   Celltype ce_type;
00837   bool not_ex;
00838   bool not_in;
00839   int i;
00840   not_ex=false;                 //Annahme: Es gibt keinen Son nicht ex_cell
00841   not_in=false;                 //Annahme: Es gibt keinen Son nicht in_cell
00842   if(I.Tiefe()<max_level+1) {
00843     // I ist nicht Index einer feinsten Zelle    
00844     for(i=0;i<8;++i) {
00845       I_son = I.son((dir_sons)i);
00846       if(Exists_Cell(I_son)) { // Rekursion
00847         ce_type = Recursion_calc_interior_cells_Part1(I_son);
00848         // Setze Zelltyp
00849         Set_cell_typ(I_son,ce_type);      
00850         if(ce_type != int_cell) not_in=true;
00851         if(ce_type != ex_cell)  not_ex=true;
00852       }
00853       else not_in=true;
00854     }
00855     ce_type = bo_cell;
00856     if(not_in==false) ce_type = int_cell;
00857     if(not_ex==false) ce_type = ex_cell;
00858   }
00859   else {   // Berechne Typ der Zelle entsprechend der Ecken der Zelle
00860     ce_type = Calc_cell_type(I);
00861     if(ce_type==bo_cell) ce_type=fine_bo_cell;
00862     
00863     // Setze Zelltyp
00864     if(ce_type != ex_cell) {
00865       Set_cell_typ(I,ce_type);
00866     }
00867   }
00868   return ce_type;
00869 }
00870 
00871 Celltype Grid_base::Recursion_calc_interior_cells_Part2(Index3D I) {
00872   Index3D I_son;
00873   Celltype ce_type;
00874   bool not_ex;
00875   bool not_in;
00876   int i;
00877   not_ex=false;                 //Annahme: Es gibt keinen Son nicht ex_cell
00878                                 // d.h. Annahme: alle Son ex_cell
00879   not_in=false;                 //Annahme: Es gibt keinen Son nicht in_cell
00880                                 // d.h. Annahme: alle Son in_cell
00881   if(I.Tiefe()<max_level+1) {
00882     // I ist nicht Index einer feinsten Zelle    
00883     for(i=0;i<8;++i) {
00884       I_son = I.son((dir_sons)i);
00885       if(Exists_Cell(I_son)) { // Rekursion
00886         ce_type = Recursion_calc_interior_cells_Part2(I_son);
00887         // Setze Zelltyp
00888         Set_cell_typ(I_son,ce_type);      
00889         if(ce_type != int_cell) not_in=true;
00890         if(ce_type != ex_cell)  not_ex=true;
00891       }
00892       else not_in=true;
00893     }
00894     ce_type = bo_cell;
00895     if(not_in==false) ce_type = int_cell;
00896     if(not_ex==false) ce_type = ex_cell;
00897   }
00898   else { 
00899     ce_type = Give_cell_typ(I);
00900     if(I<my_index == false && ce_type!=fine_bo_cell) { 
00901       // Berechne Typ der Zelle entsprechend der Ecken der Zelle
00902       ce_type = Calc_cell_type(I);
00903     }
00904   }
00905   // Setze Zelltyp
00906   if(ce_type != ex_cell) {
00907     Set_cell_typ(I,ce_type);
00908   }
00909   return ce_type;
00910 }
00911 
00912 void Grid_base::Calc_interior_cells_Part3(int level) {
00913   Index3D ind(2,2,2);
00914   Recursion_calc_interior_cells_Part3(ind,level);
00915 }
00916 
00917 
00918 
00919 void Grid_base::Recursion_calc_interior_cells_Part3(Index3D I, int level) {
00920   int i;
00921   Index3D I_son;
00922   Celltype ce_type;
00923   bool not_ex;
00924   bool not_in;
00925 
00926   if(I.Tiefe()<level+1) {
00927     // I not fine enough   
00928     for(i=0;i<8;++i) {
00929       I_son = I.son((dir_sons)i);
00930         Recursion_calc_interior_cells_Part3(I_son,level);
00931     }
00932   }
00933   else {
00934     // I is on the right level
00935     not_ex=false;                 //Annahme: Es gibt keinen Son nicht ex_cell
00936                                   // d.h. Annahme: alle Son ex_cell
00937     not_in=false;                 //Annahme: Es gibt keinen Son nicht in_cell
00938                                   // d.h. Annahme: alle Son in_cell
00939     
00940     for(i=0;i<8;++i) {
00941       I_son = I.son((dir_sons)i);
00942       if(Exists_Cell(I_son)) {
00943         ce_type = Give_cell_typ(I_son);
00944         if(ce_type != int_cell) not_in=true;
00945         if(ce_type != ex_cell)  not_ex=true;
00946       }
00947       else not_in=true;
00948     }
00949     ce_type = bo_cell;
00950     if(not_in==false) ce_type = int_cell;
00951     if(not_ex==false) ce_type = ex_cell;
00952     // Setze Zelltyp
00953     if(ce_type != ex_cell) {
00954       Add_cell(I);
00955       /*
00956       cout << " my rank: " << my_rank
00957            << " level: " << I.Tiefe() << endl;
00958       */
00959       Set_cell_typ(I,ce_type);
00960     }
00961   }
00962 }
00963 
00964 
00965 // Schritt II.8
00966 //--------------
00967 void Grid_base::Calc_interior_points() {
00968   Pointtype point_typ;
00969   Index3D I, Inext;
00970   int i;
00971   bool weiter;
00972 
00973   iterate_hash1 {
00974     point_typ = point1->typ;
00975     if(point_typ != exterior && point_typ != multigrid) {
00976       I = point1->ind;
00977       if(I<my_index) {//  ^^^^^^^^ parallel ^^^^^^^^^^^^^
00978         weiter = true;     // Suppose: no neighbour boundary cell
00979         for(i=0;i<8 && weiter;++i) {
00980           Inext = I.next((dir_sons)i,Max_level()+1);
00981           if(my_index<=Inext) { //  ^^^^^^^^ parallel ^^^^^^^^^^^^^
00982             if(Give_cell_typ(Inext)!=int_cell) weiter=false;
00983           }
00984         }
00985         if(weiter == true)
00986           point1->typ = hierarchical;
00987       }
00988       else 
00989         point1->typ = parallel_p;
00990     }
00991     /* adaptive version, later!!
00992     point_typ = point1->typ;
00993     if(point_typ != exterior && point_typ != multigrid) {
00994       // gut??
00995       //      point1->typ = nearb;
00996       I = point1->ind;
00997       weiter = true;  // Annahme: es gibt einen Punkt in der Naehe
00998       for(t=I.Tiefe();weiter;++t) {
00999         no_27_S   = false;   // Annahme: es gibt 27-Stern
01000         weiter    = false;   // Annahme: nicht feinere Sterne untersuchen
01001         for(i=0;i<3;++i)     // fehlt: besser machen mit stop
01002           for(j=0;j<3;++j)
01003             for(k=0;k<3;++k) if(!((i==1) && (j==1) && (k==1)))  {
01004               Inext = I.next((Ort1D)i,(Ort1D)j,(Ort1D)k,t);
01005               if(Exists_Point(Inext)) {
01006                 weiter    = true;          // Untersuche feinere Sterne
01007                 point_typ = Give_type(Inext);
01008                 // hier fehlt Test der Zellen!!!!!
01009                 if(point_typ == exterior || point_typ == multigrid)
01010                   no_27_S=true;               // kein 27-Stern vorhanden
01011               }
01012               else {
01013                 no_27_S   = true;             // stop kein 27-Stern vorhanden
01014               }
01015             }
01016         if(no_27_S==false) {
01017           weiter = false;                  // 27-Stern gefunden
01018 
01019           point1->level = t;
01020           if(t==I.Tiefe()) {
01021             point1->typ = hierarchical;
01022           }
01023           else {
01024             point1->typ = ausnahme;
01025           }
01026           //      point1->typ = interior;
01027         }
01028       }
01029       if(no_27_S==true) {          // kein 27-Stern vorhanden
01030         point1->level = t-2;
01031         //  cout << "\n no: " << t; I.coordinate().Print();
01032       }
01033     }
01034     */
01035   }
01036 }
01037 
01038 
01039 // Schritt III.2
01040 //---------------
01041 void Grid_base::Calc_boundary_cells() {
01042   iterate_hash0 {
01043     if(point0->isCell()) {
01044       if(point0->typ==fine_bo_cell)
01045         Add_bocell(point0->ind);
01046     }
01047   }
01048 }
01049 
01050 
01051 // Teil II.1: 
01052 //----------
01053 int Grid_base::Calc_number_boundary_cells_for_hash2() {
01054   int number;
01055   number=0;
01056   iterate_hash0 {
01057     if(point0->isCell())
01058       if(point0->typ==fine_bo_cell) ++number;
01059   }
01060   return number;
01061 }
01062 
01063 
01064 
01065 // Schritt II.7.B
01066 //---------------
01067 void Grid_base::Calc_multigrid_points_part1() {
01068   int i;
01069   Index3D I, Icell;
01070   Pointtype typI;
01071 
01072   iterate_hash0 {
01073     Icell = point0->Give_Index();
01074     if(point0->isCell()) {
01075       if((point0->typ > ex_cell) && ((Icell.Tiefe()-1) >= my_coarsest_level)) {
01076         for(i=0;i<8;++i) {
01077           // study corners of cell
01078           I = Icell.neighbour((dir_sons)i);
01079           Add_point(I);
01080           typI = Give_type(I);
01081           if(typI==exterior) {
01082             Set_point_typ(I,multigrid);
01083             /*
01084             t = point0->ind.Tiefe()-1; 
01085             if(t<max_level) // not points on finest level
01086               Put_finest_level_minimal(I,t);
01087             */
01088           }
01089           else if(typI==multigrid) {
01090             /*
01091             t = point0->ind.Tiefe()-1;
01092             if(t<max_level) // not points on finest level
01093               Put_finest_level_minimal(I,t);
01094             */
01095           }
01096         }
01097       }
01098     }
01099   }
01100 }
01101 
01102 
01103 
01104 //-----------------------------------------------------
01105 // some old member functions
01106 
01107 void Grid_base::Add_Uniform_Grid(int Max_tiefe) {
01108   Index3D ind(2,2,2);
01109 
01110   if(Max_tiefe < 1) Max_tiefe = 1;
01111   Recursion_add_Uniform_Grid(ind,Max_tiefe);
01112 }
01113 
01114 void Grid_base::Recursion_add_Uniform_Grid(Index3D I,int Max_tiefe) {
01115   int i;
01116 
01117   // lassen wir zur Zeit weg:
01118   //  V = transform_coord(I);
01119   //  if(domain->point_in_domain(V)) {
01120   Add_point(I);
01121   //  }
01122 
01123   if(I.Tiefe() <  Max_tiefe) 
01124     for(i=0;i<8;++i)
01125       Recursion_add_Uniform_Grid(I.son((dir_sons)i),Max_tiefe);
01126 }

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