src/expde/grid/printpa.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 // print_pa.cc
00020 //
00021 // ------------------------------------------------------------
00022 
00023 
00024 
00025 // Include level 0:
00026 #ifdef COMP_GNUOLD
00027  #include <iostream.h>
00028  #include <fstream.h>
00029  #include <time.h>
00030  #include <math.h>
00031  #define Problemzeile  Datei->setf(ios::scientific,ios::floatfield);       
00032 #else
00033  #include <iostream>
00034  #include <fstream>
00035  #include <ctime>
00036  #include <cmath>
00037  #define Problemzeile  Datei->setf(std::ios::scientific,std::ios::floatfield);
00038 #endif 
00039   
00040 // Include level 0:
00041 #include "../parser.h"
00042 
00043 // Include level 1:
00044 #include "../paramete.h"
00045 #include "../abbrevi.h"
00046 #include "../math_lib/math_lib.h"
00047  
00048 // Include level 2:
00049 #include "../basic/basic.h"
00050 
00051 // Include level 3:
00052 #include "../domain/domain.h"
00053 
00054 // Include level 4:
00055 #include "../formulas/boundy.h"
00056 #include "../formulas/loc_sten.h"
00057 
00058 // Include level 5:
00059 #include "gpar.h"
00060 #include "parallel.h"
00061 #include "mgcoeff.h"
00062 #include "sto_man.h"
00063 #include "gridbase.h"
00064 #include "grid.h"
00065 
00066 
00068 // 1. coarese level
00069 // 2. finest  level
00070 // 3. region  level
00071 // 4. surface level
00072 // 5. cells
00074 
00075 
00076 
00078 // 1. coarese level
00080 
00081 
00082 void Grid_base::Print_Variable_AVS_parallel(ofstream *Datei, int number_var,
00083                                             int level) {
00084   int number_cells;
00085   int number_points;
00086   int n_proc,i;
00087 
00088   int *number_cells_process;
00089   int *number_points_process;
00090   int total_number_cells;
00091   int total_number_points;
00092 
00093   MPI_Status status;
00094 
00095   D3vector loc;
00096   int num, start_num, start_poi;
00097 
00098   int max_number_cells;
00099   int max_number_points;
00100 
00101   int*    buffer_send_int;
00102   double* buffer_send_double;
00103 
00104   int*    buffer_rec_int;
00105   double* buffer_rec_double;
00106 
00107   Index3D ind, I;
00108 
00109   if(Is_storage_initialized()==false) { 
00110     cout << " \n Fehler in Print_Variable_AVS! Initialisierung fehlt! "
00111          << endl;
00112     return;
00113   }
00114   if(Give_max_num_var() <= number_var) {
00115     cout << " \n Fehler in Print_Variable_AVS! number_var zu gross! " << endl;
00116   }
00117   else {
00118     // Teil 0: Write information
00119     if(my_rank==0) {
00120       *Datei << "# File created by ExPDE " << endl;
00121       *Datei << "# UCD file format for AVS parallel " << endl;
00122       *Datei << "# scalar value " << endl;
00123     }
00124 
00125     /* Teil 1: Anzahl der Zellen zaehlen */
00126     number_cells = 0;
00127     if(I_am_active()) {
00128       /* Teil 1.1: Innerer Zellen */
00129       iterate_hash0 {
00130         I = point0->Give_Index();
00131         if(I<<my_index && I.Cell_index() 
00132            && (Celltype)point0->typ == int_cell && I.Tiefe() == level+1) {
00133           number_cells = number_cells + 6;
00134         }
00135       }
00136     }
00137     /* Teil 1.3: Anzahl der Punkte */
00138     number_points=0;
00139     if(I_am_active()) {
00140       /* a) innen und randnah */
00141       iterate_hash1 {
00142         I = point1->Give_Index();
00143         if(point1->typ != exterior 
00144            && I.Tiefe()            <= level // for excluding too fine points
00145            && point1->finest_level >= level // for excluding too coarse
00146            && I<<my_index) {                // for responsibility
00147           point1->nummer = number_points;
00148           number_points++;
00149         }
00150         else point1->nummer = -1;
00151       }
00152     }
00153     /* Teil 1.5: gather data */  
00154     n_proc = give_number_of_processes(); 
00155     number_cells_process = new int[n_proc]; 
00156     number_points_process = new int[n_proc]; 
00157     MPI_Gather(&number_points,1,MPI_INT,number_points_process,1,MPI_INT, 
00158                0,comm); 
00159     MPI_Gather(&number_cells,1,MPI_INT,number_cells_process,1,MPI_INT, 
00160                0,comm); 
00161     total_number_points =0; 
00162     total_number_cells =0; 
00163     max_number_points =0; 
00164     max_number_cells =0; 
00165     for(i=0;i<n_proc;++i) { 
00166       total_number_points = total_number_points + number_points_process[i]; 
00167       total_number_cells  = total_number_cells  + number_cells_process[i]; 
00168     } 
00169     for(i=0;i<n_proc;++i) { 
00170       if(number_points_process[i] > max_number_points) 
00171         max_number_points = number_points_process[i]; 
00172       if(number_cells_process[i] > max_number_cells) 
00173         max_number_cells = number_cells_process[i]; 
00174     } 
00175     /* Teil 1.7: make buffer */
00176     if(my_rank==0) { 
00177       buffer_rec_int    = new int[max_number_cells  * 4]; 
00178       buffer_rec_double = new double[max_number_points * 3]; 
00179     } 
00180     buffer_send_int    = new int[number_cells  * 4]; 
00181     buffer_send_double = new double[number_points * 3]; 
00182     /* Teil 1.6: Kopfzeile schreiben */  
00183     if(my_rank==0) { 
00184       *Datei << total_number_points << " " 
00185              << total_number_cells << " 1 0 0" << endl; 
00186     } 
00187     /* Teil 2: Koordinaten der Punkte eingeben */ 
00188     /* a) set values in buffer */ 
00189     if(I_am_active()) { 
00190       /* i) alle inneren Punkte */
00191       iterate_hash1 { 
00192         if(point1->nummer != -1) { 
00193           loc = transform_coord(point1->ind.coordinate()); 
00194           buffer_send_double[point1->nummer*3]   = loc.x; 
00195           buffer_send_double[point1->nummer*3+1] = loc.y; 
00196           buffer_send_double[point1->nummer*3+2] = loc.z; 
00197         } 
00198       } 
00199     }
00200     /* b) send */
00201     if(my_rank!=0) { 
00202       MPI_Send(buffer_send_double,number_points * 3, 
00203                MPI_DOUBLE,0,50,comm); 
00204     } 
00205     else { 
00206       start_num=0; 
00207       for(i=0;i<n_proc;++i) { 
00208         /* c) receive */
00209         if(i!=0) { 
00210           MPI_Recv(buffer_rec_double,number_points_process[i] * 3, 
00211                    MPI_DOUBLE,i,50,comm,&status); 
00212         } 
00213         else { 
00214           for(num=0;num<number_points_process[i];++num) { 
00215             buffer_rec_double[num*3]   = buffer_send_double[num*3]; 
00216             buffer_rec_double[num*3+1] = buffer_send_double[num*3+1]; 
00217             buffer_rec_double[num*3+2] = buffer_send_double[num*3+2]; 
00218           } 
00219         } 
00220         /* d) print in file */ 
00221         for(num=0;num<number_points_process[i];++num) { 
00222           loc.x =  buffer_rec_double[num*3]; 
00223           loc.y =  buffer_rec_double[num*3+1]; 
00224           loc.z =  buffer_rec_double[num*3+2];
00225           
00226           *Datei << start_num+num 
00227                  << " " << fixed << loc.x   
00228                  << " " << fixed << loc.y   
00229                  << " " << fixed << loc.z 
00230                  << "\n"; 
00231         } 
00232         start_num = start_num + number_points_process[i]; 
00233       } 
00234     } 
00235     /* Teil 3: Zellen ausgeben */    
00236     /* a) set values in buffer */    
00237     if(I_am_active()) {
00238       number_cells = 0;
00239       /* Teil 1.1: Innerer Zellen */
00240       iterate_hash0 {
00241         I = point0->Give_Index();
00242         if(I<<my_index && I.Cell_index() 
00243            && (Celltype)point0->typ == int_cell && I.Tiefe() == level+1) {
00244           number_cells = Write_Cells_AVS_parallel(I,
00245                                                   number_cells,
00246                                                   buffer_send_int);
00247         }
00248       }
00249     }
00250     /* b) send */  
00251     if(my_rank!=0) {  
00252       MPI_Send(buffer_send_int,number_cells * 4, 
00253                MPI_INT,0,51,comm); 
00254     } 
00255     else { 
00256       start_num=0; 
00257       start_poi=0; 
00258       for(i=0;i<n_proc;++i) { 
00259         /* c) receive */ 
00260         if(i!=0) { 
00261           MPI_Recv(buffer_rec_int,number_cells_process[i] * 4, 
00262                    MPI_INT,i,51,comm,&status); 
00263         } 
00264         else { 
00265           for(num=0;num<number_cells_process[i];++num) { 
00266             buffer_rec_int[num*4]   = buffer_send_int[num*4];  
00267             buffer_rec_int[num*4+1] = buffer_send_int[num*4+1];  
00268             buffer_rec_int[num*4+2] = buffer_send_int[num*4+2];  
00269             buffer_rec_int[num*4+3] = buffer_send_int[num*4+3];  
00270           } 
00271         } 
00272        /* d) print in file */   
00273         if(i<n_proc) { 
00274           for(num=0;num<number_cells_process[i];++num) { 
00275             *Datei << start_num+num+1 << " 1 tet " 
00276                    << " " << start_poi + buffer_rec_int[num*4]  
00277                    << " " << start_poi + buffer_rec_int[num*4+1]  
00278                    << " " << start_poi + buffer_rec_int[num*4+2]  
00279                    << " " << start_poi + buffer_rec_int[num*4+3]  
00280                    << "\n"; 
00281           } 
00282         } 
00283         start_num = start_num + number_cells_process[i]; 
00284         start_poi = start_poi + number_points_process[i]; 
00285       } 
00286     } 
00287     if(my_rank==0) { 
00288       /* Teil 4: */
00289       *Datei << "1 1" << "\n";
00290 
00291 
00292       /*
00293       // Teil 5:
00294       *Datei << "processes " << "\n";
00295 
00296       // Teil 6: Print number of processor
00297       start_num=0;
00298       for(i=0;i<n_proc;++i) {
00299         for(num=0;num<number_points_process[i];++num) {
00300           *Datei << start_num+num << "   " << i  << "\n";
00301         }
00302         start_num = start_num + number_points_process[i];
00303       }
00304       *Datei << endl;
00305       */
00306 
00307      // Teil 5:
00308       *Datei << "variable, unit " << "\n";
00309     }
00310 
00311     if(I_am_active()) {
00312       // Teil 2: Koordinaten der Punkte eingeben
00313       // a) set values in buffer
00314       // i) alle inneren Punkte
00315       iterate_hash1 {
00316         if(point1->nummer != -1) {
00317           buffer_send_double[point1->nummer] = 
00318             Give_variable(point1->ind,level)[number_var];
00319         }
00320       }
00321     }
00322 
00323     // b) send
00324     if(my_rank!=0) {
00325       MPI_Send(buffer_send_double,number_points,
00326                MPI_DOUBLE,0,52,comm);
00327     }
00328     else {
00329       start_num=0;
00330       for(i=0;i<n_proc;++i) {
00331         // c) receive
00332         if(i!=0) {
00333           MPI_Recv(buffer_rec_double,number_points_process[i],
00334                    MPI_DOUBLE,i,52,comm,&status);       
00335         }
00336         else {
00337           for(num=0;num<number_points_process[i];++num) {
00338             buffer_rec_double[num] = buffer_send_double[num];
00339           }
00340         }
00341         // d) print in file
00342         if(i<n_proc) {
00343           for(num=0;num<number_points_process[i];++num) {
00344             *Datei << start_num+num
00345                    << " " << buffer_rec_double[num]
00346                    << "\n";
00347           }
00348         }
00349         start_num = start_num + number_points_process[i];
00350       }
00351     }
00352 
00353     // Teil 7:
00354     if(I_am_active()) {
00355       delete(number_cells_process);
00356       delete(number_points_process);
00357     }
00358     delete(buffer_send_int);
00359     delete(buffer_send_double);
00360     if(my_rank==0) {
00361       delete(buffer_rec_int);
00362       delete(buffer_rec_double);
00363     }
00364   }
00365   MPI_Barrier(comm);
00366 }
00367 
00368 
00370 // 2. finest level
00372 
00373 #define Macro_PRINT_Einsetzen  \
00374     /* Teil 1: Anzahl der Zellen zaehlen */ \
00375     number_cells = 0; \
00376     if(I_am_active()) { \
00377     /* Teil 1.1: Innerer Zellen */ \
00378     ind = my_index; \
00379     number_cells = Recursion_Count_Cells(ind); \
00380     /* Teil 1.2: Randzellen */  \
00381     iterate_hash2 { \
00382         if(bocell->Give_Index()<<my_index) \
00383           number_cells = avs_bo_cell(bocell,Datei,false,number_cells); \
00384       } \
00385     } \
00386     /* Teil 1.3: Anzahl der Punkte */ \
00387     number_points=0; \
00388     if(I_am_active()) { \
00389       /* a) innen und randnah */ \
00390       iterate_hash1 { \
00391         if((point1->typ >= interior || point1->typ==parallel_p) && \
00392            point1->Give_Index()<<my_index && \
00393            point1->finest_level == max_level) { \
00394           point1->nummer = number_points; \
00395           number_points++; \
00396         } \
00397         else point1->nummer = -1; \
00398       } \
00399     /* b) Randpunkte */  \
00400       iterate_hash3 {  \
00401         bo2point->Set_number_avs(number_points);  \
00402         ++number_points;  \
00403       }  \
00404     /* c) Randzellfreiheitsgrad */  \
00405       iterate_hash2 {  \
00406         if(bocell->Give_Index()<<my_index) {  \
00407           if(bocell->Exists_bocellpoint()) {  \
00408             bocell->Set_number_avs(number_points);  \
00409             number_points++;  \
00410           } \
00411         } \
00412       } \
00413     } \
00414     /* Teil 1.5: gather data */   \
00415     n_proc = give_number_of_processes();  \
00416     number_cells_process = new int[n_proc];  \
00417     number_points_process = new int[n_proc];  \
00418     MPI_Gather(&number_points,1,MPI_INT,number_points_process,1,MPI_INT,  \
00419                0,comm);  \
00420     MPI_Gather(&number_cells,1,MPI_INT,number_cells_process,1,MPI_INT,  \
00421                0,comm);  \
00422     total_number_points =0;  \
00423     total_number_cells =0;  \
00424     max_number_points =0;  \
00425     max_number_cells =0;  \
00426     for(i=0;i<n_proc;++i) {  \
00427       total_number_points = total_number_points + number_points_process[i];  \
00428       total_number_cells  = total_number_cells  + number_cells_process[i];  \
00429     }  \
00430     for(i=0;i<n_proc;++i) {  \
00431       if(number_points_process[i] > max_number_points)  \
00432         max_number_points = number_points_process[i];  \
00433       if(number_cells_process[i] > max_number_cells)  \
00434         max_number_cells = number_cells_process[i];  \
00435     }  \
00436     /* Teil 1.7: make buffer */ \
00437     if(my_rank==0) {  \
00438       buffer_rec_int    = new int[max_number_cells  * 4];  \
00439       buffer_rec_double = new double[max_number_points * 3];  \
00440     }  \
00441     buffer_send_int    = new int[number_cells  * 4];  \
00442     buffer_send_double = new double[number_points * 3];  \
00443     /* Teil 1.6: Kopfzeile schreiben */   \
00444     if(my_rank==0) {  \
00445       *Datei << total_number_points << " "  \
00446              << total_number_cells << " " \
00447              << number_of_vars << " 0 0" << endl;  \
00448     }  \
00449     /* Teil 2: Koordinaten der Punkte eingeben */  \
00450     /* a) set values in buffer */  \
00451     if(I_am_active()) {  \
00452       /* i) alle inneren Punkte */ \
00453       iterate_hash1 {  \
00454         if(point1->nummer != -1) {  \
00455           loc = transform_coord(point1->ind.coordinate());  \
00456           buffer_send_double[point1->nummer*3]   = loc.x;  \
00457           buffer_send_double[point1->nummer*3+1] = loc.y;  \
00458           buffer_send_double[point1->nummer*3+2] = loc.z;  \
00459         }  \
00460       }  \
00461     /* ii) alle Randpunkte */   \
00462       iterate_hash3 {  \
00463         loc = bo2point->transform_coord(Give_A(),H_mesh());  \
00464         buffer_send_double[bo2point->nummer*3]   = loc.x;  \
00465         buffer_send_double[bo2point->nummer*3+1] = loc.y;  \
00466         buffer_send_double[bo2point->nummer*3+2] = loc.z;  \
00467       }  \
00468     /* iii) alle Randzellfreiheitsgrad */   \
00469       iterate_hash2 {  \
00470         if(bocell->Give_Index()<<my_index) {  \
00471           if(bocell->Exists_bocellpoint()) {  \
00472             loc =  transform_coord(bocell->ind.coordinate()) +   \
00473               bocell->Local_coord_bocellpoint();  \
00474             buffer_send_double[bocell->Number_avs()*3]   = loc.x;  \
00475             buffer_send_double[bocell->Number_avs()*3+1] = loc.y;  \
00476             buffer_send_double[bocell->Number_avs()*3+2] = loc.z;  \
00477           }  \
00478         }  \
00479       }  \
00480     }  \
00481     /* b) send */ \
00482     if(my_rank!=0) {  \
00483       MPI_Send(buffer_send_double,number_points * 3,  \
00484                MPI_DOUBLE,0,50,comm);  \
00485     }  \
00486     else {  \
00487       start_num=0;  \
00488       for(i=0;i<n_proc;++i) {  \
00489         /* c) receive */ \
00490         if(i!=0) {  \
00491           MPI_Recv(buffer_rec_double,number_points_process[i] * 3,  \
00492                    MPI_DOUBLE,i,50,comm,&status);  \
00493         }  \
00494         else {  \
00495           for(num=0;num<number_points_process[i];++num) {  \
00496             buffer_rec_double[num*3]   = buffer_send_double[num*3];  \
00497             buffer_rec_double[num*3+1] = buffer_send_double[num*3+1];  \
00498             buffer_rec_double[num*3+2] = buffer_send_double[num*3+2];  \
00499           }  \
00500         }  \
00501         /* d) print in file */  \
00502         for(num=0;num<number_points_process[i];++num) {  \
00503           loc.x =  buffer_rec_double[num*3];  \
00504           loc.y =  buffer_rec_double[num*3+1];  \
00505           loc.z =  buffer_rec_double[num*3+2];  \
00506           *Datei << start_num+num  \
00507                  << " " << fixed << loc.x    \
00508                  << " " << fixed << loc.y    \
00509                  << " " << fixed << loc.z  \
00510                  << "\n";  \
00511         }  \
00512         start_num = start_num + number_points_process[i];  \
00513       }  \
00514     }  \
00515     /* Teil 3: Zellen ausgeben */     \
00516     /* a) set values in buffer */     \
00517     if(I_am_active()) { \
00518       /* Teil 3.1: Innere Zellen ausgeben */ \
00519       ind = my_index;  \
00520       number=Recursion_Cells_AVS_parallel(ind,0,buffer_send_int);  \
00521       /* Teil 3.2: Randzellen */   \
00522       iterate_hash2 {  \
00523         if(bocell->Give_Index()<<my_index)  \
00524           number = avs_bo_cell_parallel(bocell,number,buffer_send_int);  \
00525       }  \
00526     }  \
00527     /* b) send */   \
00528     if(my_rank!=0) {   \
00529       MPI_Send(buffer_send_int,number_cells * 4,  \
00530                MPI_INT,0,51,comm);  \
00531     }  \
00532     else {  \
00533       start_num=0;  \
00534       start_poi=0;  \
00535       for(i=0;i<n_proc;++i) {  \
00536         /* c) receive */  \
00537         if(i!=0) {  \
00538           MPI_Recv(buffer_rec_int,number_cells_process[i] * 4,  \
00539                    MPI_INT,i,51,comm,&status);  \
00540         }  \
00541         else {  \
00542           for(num=0;num<number_cells_process[i];++num) {  \
00543             buffer_rec_int[num*4]   = buffer_send_int[num*4];   \
00544             buffer_rec_int[num*4+1] = buffer_send_int[num*4+1];   \
00545             buffer_rec_int[num*4+2] = buffer_send_int[num*4+2];   \
00546             buffer_rec_int[num*4+3] = buffer_send_int[num*4+3];   \
00547           }  \
00548         }  \
00549        /* d) print in file */    \
00550         if(i<n_proc) {  \
00551           for(num=0;num<number_cells_process[i];++num) {  \
00552             *Datei << start_num+num+1 << " 1 tet "  \
00553                    << " " << start_poi + buffer_rec_int[num*4]   \
00554                    << " " << start_poi + buffer_rec_int[num*4+1]   \
00555                    << " " << start_poi + buffer_rec_int[num*4+2]   \
00556                    << " " << start_poi + buffer_rec_int[num*4+3]   \
00557                    << "\n";  \
00558           }  \
00559         }  \
00560         start_num = start_num + number_cells_process[i];  \
00561         start_poi = start_poi + number_points_process[i];  \
00562       }  \
00563     }  \
00564     if(my_rank==0) {
00565 
00566 
00567 
00568 
00569 
00570 // Ausgabe der Tetraeder
00571 int Grid_base::avs_bo_cell_parallel(BoCell* bo, int number, int* buffer) {
00572   Tetraeder_storage* tets;
00573   int num;
00574   Index3D I;
00575   Cell_type_points typ;
00576   
00577   I = bo->Give_Index();
00578 
00579 #ifdef PERIODIC
00580   if(I.neighbour_non_periodic(WSDd).Is_non_periodic()) {
00581     return number;
00582   }
00583 #endif
00584 
00585   for(tets = bo->Give_tets();tets!=NULL;tets = tets->Next()) {
00586     // Punkt 0:
00587     num = tets->N0();
00588     typ = bo->edge_point(num);
00589     if(typ==edge_poi_typ) {
00590       buffer[number*4  ] =Give_Nummer(I.neighbour(bo->corner(num)),
00591                                       bo->edge_dir(num));
00592     }
00593     if(typ==corner_poi_typ) {
00594       buffer[number*4  ] =Give_Nummer(I.neighbour(bo->corner(num)));    
00595     }
00596     if(typ==cell_poi_typ) {
00597       buffer[number*4  ] =Give_Nummer_cellpoi(I);       
00598     }
00599     // Punkt 1:
00600     num = tets->N1();
00601     typ = bo->edge_point(num);
00602     if(typ==edge_poi_typ) {
00603       buffer[number*4+1] =Give_Nummer(I.neighbour(bo->corner(num)),
00604                             bo->edge_dir(num));
00605     }
00606     if(typ==corner_poi_typ) {
00607       buffer[number*4+1] =Give_Nummer(I.neighbour(bo->corner(num)));    
00608     }
00609     if(typ==cell_poi_typ) {
00610       buffer[number*4+1] =Give_Nummer_cellpoi(I);       
00611     }
00612     // Punkt 2:
00613     num = tets->N2();
00614     typ = bo->edge_point(num);
00615     if(typ==edge_poi_typ) {
00616       buffer[number*4+2] =Give_Nummer(I.neighbour(bo->corner(num)),
00617                             bo->edge_dir(num));
00618     }
00619     if(typ==corner_poi_typ) {
00620       buffer[number*4+2] =Give_Nummer(I.neighbour(bo->corner(num)));
00621     }
00622     if(typ==cell_poi_typ) {
00623       buffer[number*4+2] =Give_Nummer_cellpoi(I);       
00624     }
00625     // Punkt 3:
00626     num = tets->N3();
00627     typ = bo->edge_point(num);
00628     if(typ==edge_poi_typ) {
00629       buffer[number*4+3] =Give_Nummer(I.neighbour(bo->corner(num)),
00630                             bo->edge_dir(num));
00631     }
00632     if(typ==corner_poi_typ) {
00633       buffer[number*4+3] =Give_Nummer(I.neighbour(bo->corner(num)));
00634     }
00635     if(typ==cell_poi_typ) {
00636       buffer[number*4+3] =Give_Nummer_cellpoi(I);       
00637     }
00638 
00639     ++number; 
00640   }
00641   return number;
00642 }
00643 
00644 
00645 
00646 int Grid_base::Recursion_Cells_AVS_parallel(Index3D I,
00647                                             int nummer,int* buffer) {
00648   int i;
00649   Index3D Ison;
00650   for(i=0;i<8;++i) {
00651     if(Exists_Point(I.son((dir_sons)i)))
00652       nummer = Recursion_Cells_AVS_parallel(I.son((dir_sons)i),nummer,buffer);
00653     else {
00654       Ison = I.son((dir_sons)i);
00655 #ifdef PERIODIC
00656       if(Ison.neighbour_non_periodic(WSDd).Is_non_periodic()
00657          && Give_cell_typ(Ison) == int_cell) {
00658 #else
00659       if(Give_cell_typ(Ison) == int_cell) {
00660 #endif
00661         Ison = I.son((dir_sons)i);
00662 
00663         // 0. Tet: WND, WNT, WST, EST 
00664         buffer[nummer*4]   = Give_Nummer(Ison.neighbour(WNTd));
00665         buffer[nummer*4+1] = Give_Nummer(Ison.neighbour(WNDd));
00666         buffer[nummer*4+2] = Give_Nummer(Ison.neighbour(WSTd));
00667         buffer[nummer*4+3] = Give_Nummer(Ison.neighbour(ESTd));
00668         nummer++;
00669 
00670         // 1. Tet: EST, WND, WST, ESD  
00671         buffer[nummer*4  ] = Give_Nummer(Ison.neighbour(ESTd));
00672         buffer[nummer*4+1] = Give_Nummer(Ison.neighbour(WNDd));
00673         buffer[nummer*4+2] = Give_Nummer(Ison.neighbour(WSTd));
00674         buffer[nummer*4+3] = Give_Nummer(Ison.neighbour(ESDd));
00675         nummer++;
00676 
00677         // 2. Tet: WND, WSD, WST, ESD        
00678         buffer[nummer*4  ] = Give_Nummer(Ison.neighbour(WNDd));
00679         buffer[nummer*4+1] = Give_Nummer(Ison.neighbour(WSDd));
00680         buffer[nummer*4+2] = Give_Nummer(Ison.neighbour(WSTd));
00681         buffer[nummer*4+3] = Give_Nummer(Ison.neighbour(ESDd));
00682         nummer++;
00683 
00684         // 3. Tet: EST, WND, ESD, END
00685         buffer[nummer*4  ] = Give_Nummer(Ison.neighbour(ESTd));
00686         buffer[nummer*4+1] = Give_Nummer(Ison.neighbour(WNDd));
00687         buffer[nummer*4+2] = Give_Nummer(Ison.neighbour(ESDd));
00688         buffer[nummer*4+3] = Give_Nummer(Ison.neighbour(ENDd));
00689         nummer++;
00690 
00691         // 4. Tet: ENT, WNT, EST, END
00692         buffer[nummer*4  ] = Give_Nummer(Ison.neighbour(ENTd));
00693         buffer[nummer*4+1] = Give_Nummer(Ison.neighbour(WNTd));
00694         buffer[nummer*4+2] = Give_Nummer(Ison.neighbour(ESTd));
00695         buffer[nummer*4+3] = Give_Nummer(Ison.neighbour(ENDd));
00696         nummer++;
00697         
00698         // 5. Tet: WNT, WND, EST, END
00699         buffer[nummer*4  ] = Give_Nummer(Ison.neighbour(WNTd));
00700         buffer[nummer*4+1] = Give_Nummer(Ison.neighbour(WNDd));
00701         buffer[nummer*4+2] = Give_Nummer(Ison.neighbour(ESTd));
00702         buffer[nummer*4+3] = Give_Nummer(Ison.neighbour(ENDd));
00703         nummer++;
00704       }
00705     }
00706   }
00707   return nummer;
00708 }
00709 
00710 
00711 int Grid_base::Write_Cells_AVS_parallel(Index3D I,
00712                                         int nummer,int* buffer) {
00713   // 0. Tet: WND, WNT, WST, EST 
00714   buffer[nummer*4]   = Give_Nummer(I.neighbour(WNTd));
00715   buffer[nummer*4+1] = Give_Nummer(I.neighbour(WNDd));
00716   buffer[nummer*4+2] = Give_Nummer(I.neighbour(WSTd));
00717   buffer[nummer*4+3] = Give_Nummer(I.neighbour(ESTd));
00718   nummer++;
00719   
00720   // 1. Tet: EST, WND, WST, ESD  
00721   buffer[nummer*4  ] = Give_Nummer(I.neighbour(ESTd));
00722   buffer[nummer*4+1] = Give_Nummer(I.neighbour(WNDd));
00723   buffer[nummer*4+2] = Give_Nummer(I.neighbour(WSTd));
00724   buffer[nummer*4+3] = Give_Nummer(I.neighbour(ESDd));
00725   nummer++;
00726   
00727   // 2. Tet: WND, WSD, WST, ESD        
00728   buffer[nummer*4  ] = Give_Nummer(I.neighbour(WNDd));
00729   buffer[nummer*4+1] = Give_Nummer(I.neighbour(WSDd));
00730   buffer[nummer*4+2] = Give_Nummer(I.neighbour(WSTd));
00731   buffer[nummer*4+3] = Give_Nummer(I.neighbour(ESDd));
00732   nummer++;
00733   
00734   // 3. Tet: EST, WND, ESD, END
00735   buffer[nummer*4  ] = Give_Nummer(I.neighbour(ESTd));
00736   buffer[nummer*4+1] = Give_Nummer(I.neighbour(WNDd));
00737   buffer[nummer*4+2] = Give_Nummer(I.neighbour(ESDd));
00738   buffer[nummer*4+3] = Give_Nummer(I.neighbour(ENDd));
00739   nummer++;
00740   
00741   // 4. Tet: ENT, WNT, EST, END
00742   buffer[nummer*4  ] = Give_Nummer(I.neighbour(ENTd));
00743   buffer[nummer*4+1] = Give_Nummer(I.neighbour(WNTd));
00744   buffer[nummer*4+2] = Give_Nummer(I.neighbour(ESTd));
00745   buffer[nummer*4+3] = Give_Nummer(I.neighbour(ENDd));
00746   nummer++;
00747   
00748   // 5. Tet: WNT, WND, EST, END
00749   buffer[nummer*4  ] = Give_Nummer(I.neighbour(WNTd));
00750   buffer[nummer*4+1] = Give_Nummer(I.neighbour(WNDd));
00751   buffer[nummer*4+2] = Give_Nummer(I.neighbour(ESTd));
00752   buffer[nummer*4+3] = Give_Nummer(I.neighbour(ENDd));
00753   nummer++;
00754 
00755   return nummer;
00756 }
00757  
00758 
00759 
00760 
00761 
00762 
00763 void Grid_base::Print_Variable_AVS_parallel(ofstream *Datei, int number_var) {
00764   int number_cells, number, ebene;
00765   int number_points;
00766   int n_proc,i;
00767 
00768   int *number_cells_process;
00769   int *number_points_process;
00770   int total_number_cells;
00771   int total_number_points;
00772 
00773   MPI_Status status;
00774 
00775   D3vector loc;
00776   int num, start_num, start_poi;
00777 
00778   int max_number_cells;
00779   int max_number_points;
00780 
00781   int*    buffer_send_int;
00782   double* buffer_send_double;
00783 
00784   int*    buffer_rec_int;
00785   double* buffer_rec_double;
00786 
00787   Index3D ind;
00788   int number_of_vars;   // wird in der Kopfzeile eingesetzt
00789 
00790   number_of_vars=1;
00791 
00792   MPI_Barrier(comm);
00793 
00794   if(Is_storage_initialized()==false) { 
00795     cout << " \n Fehler in Print_Variable_AVS! Initialisierung fehlt! "
00796          << endl;
00797     return;
00798   }
00799   if(Give_max_num_var() <= number_var) {
00800     cout << " \n Fehler in Print_Variable_AVS! number_var zu gross! " << endl;
00801   }
00802   else {
00803     // Teil 0: Write information
00804     if(my_rank==0) {
00805       *Datei << "# File created by ExPDE " << endl;
00806       *Datei << "# UCD file format for AVS parallel " << endl;
00807       *Datei << "# scalar value " << endl;
00808     }
00809   MPI_Barrier(comm);
00810     Macro_PRINT_Einsetzen 
00811 
00812       /* Teil 4: */
00813       *Datei << "1 1" << "\n";
00814       // Teil 5:
00815       *Datei << "variable, unit " << "\n";
00816     }
00817 
00818     if(I_am_active()) {
00819     // Teil 2: Werte der Punkte ausgeben
00820     // a) set values in buffer
00821     // i) alle inneren Punkte
00822     iterate_hash1 {
00823       if(point1->nummer != -1) {
00824         ebene = Give_finest_level(point1->ind);
00825         buffer_send_double[point1->nummer] = 
00826           Give_variable(point1->ind,ebene)[number_var];
00827       }
00828     }
00829     // ii) alle Randpunkte
00830     iterate_hash3 {
00831       buffer_send_double[bo2point->nummer] = 
00832         Give_variable(bo2point->ind,bo2point->direction)[number_var];
00833     }
00834     // iii alle Randzellfreiheitsgrad
00835     iterate_hash2 {
00836       if(bocell->Give_Index()<<my_index) {
00837         if(bocell->Exists_bocellpoint()) {
00838           buffer_send_double[bocell->Number_avs()] =
00839             bocell->Give_var()[number_var];
00840         }
00841       }
00842     }
00843     }
00844 
00845     // b) send
00846     if(my_rank!=0) {
00847       MPI_Send(buffer_send_double,number_points,
00848                MPI_DOUBLE,0,52,comm);
00849     }
00850     else {
00851       start_num=0;
00852       for(i=0;i<n_proc;++i) {
00853         // c) receive
00854         if(i!=0) {
00855           MPI_Recv(buffer_rec_double,number_points_process[i],
00856                    MPI_DOUBLE,i,52,comm,&status);       
00857         }
00858         else {
00859           for(num=0;num<number_points_process[i];++num) {
00860             buffer_rec_double[num] = buffer_send_double[num];
00861           }
00862         }
00863         // d) print in file
00864         if(i<n_proc) {
00865           for(num=0;num<number_points_process[i];++num) {
00866             *Datei << start_num+num
00867                    << " " << buffer_rec_double[num]
00868                    << "\n";
00869           }
00870         }
00871         start_num = start_num + number_points_process[i];
00872       }
00873     }
00874 
00875     // Teil 7:
00876     if(I_am_active()) {
00877        delete(number_cells_process);
00878        delete(number_points_process);
00879     }
00880     delete(buffer_send_int);
00881     delete(buffer_send_double);
00882     if(my_rank==0) {
00883       delete(buffer_rec_int);
00884       delete(buffer_rec_double);
00885     }
00886   }
00887 
00888   MPI_Barrier(comm);
00889 }
00890 
00891 
00892 void Grid_base::Print_Variable_AVS_moved_parallel(ofstream *Datei, 
00893                                                   int number_var,
00894                                                   int number_var_a, 
00895                                                   int number_var_b, 
00896                                                   int number_var_c) {
00897   int number_cells, number, ebene;
00898   int number_points;
00899   int n_proc,i;
00900 
00901   int *number_cells_process;
00902   int *number_points_process;
00903   int total_number_cells;
00904   int total_number_points;
00905   double *zeiger;
00906 
00907   MPI_Status status;
00908 
00909   D3vector loc;
00910   int num, start_num, start_poi;
00911 
00912   int max_number_cells;
00913   int max_number_points;
00914 
00915   int*    buffer_send_int;
00916   double* buffer_send_double;
00917 
00918   int*    buffer_rec_int;
00919   double* buffer_rec_double;
00920 
00921   Index3D ind;
00922   int number_of_vars;   // wird in der Kopfzeile eingesetzt
00923 
00924   number_of_vars=1;
00925 
00926   MPI_Barrier(comm);
00927 
00928   if(Is_storage_initialized()==false) { 
00929     cout << " \n Fehler in Print_Variable_AVS! Initialisierung fehlt! "
00930          << endl;
00931     return;
00932   }
00933   if(Give_max_num_var() <= number_var) {
00934     cout << " \n Fehler in Print_Variable_AVS! number_var zu gross! " << endl;
00935   }
00936   else {
00937     // Teil 0: Write information
00938     if(my_rank==0) {
00939       *Datei << "# File created by ExPDE " << endl;
00940       *Datei << "# UCD file format for AVS parallel " << endl;
00941       *Datei << "# scalar value moved by a vector" << endl;
00942     }
00943   MPI_Barrier(comm);
00944 
00945     /* Teil 1: Anzahl der Zellen zaehlen */ 
00946     number_cells = 0; 
00947     if(I_am_active()) { 
00948     /* Teil 1.1: Innerer Zellen */ 
00949     ind = my_index; 
00950     number_cells = Recursion_Count_Cells(ind); 
00951     /* Teil 1.2: Randzellen */  
00952     iterate_hash2 { 
00953         if(bocell->Give_Index()<<my_index) 
00954           number_cells = avs_bo_cell(bocell,Datei,false,number_cells); 
00955       } 
00956     } 
00957     /* Teil 1.3: Anzahl der Punkte */ 
00958     number_points=0; 
00959     if(I_am_active()) { 
00960       /* a) innen und randnah */ 
00961       iterate_hash1 { 
00962         if((point1->typ >= interior || point1->typ==parallel_p) && 
00963            point1->Give_Index()<<my_index &&
00964            point1->finest_level == max_level) { 
00965           point1->nummer = number_points; 
00966           number_points++; 
00967         } 
00968         else point1->nummer = -1; 
00969       } 
00970     /* b) Randpunkte */  
00971       iterate_hash3 {  
00972         bo2point->Set_number_avs(number_points);  
00973         ++number_points;  
00974       }  
00975     /* c) Randzellfreiheitsgrad */  
00976       iterate_hash2 {  
00977         if(bocell->Give_Index()<<my_index) {  
00978           if(bocell->Exists_bocellpoint()) {  
00979             bocell->Set_number_avs(number_points);  
00980             number_points++;  
00981           } 
00982         } 
00983       } 
00984     } 
00985     /* Teil 1.5: gather data */   
00986     n_proc = give_number_of_processes();  
00987     number_cells_process = new int[n_proc];  
00988     number_points_process = new int[n_proc];  
00989     MPI_Gather(&number_points,1,MPI_INT,number_points_process,1,MPI_INT,  
00990                0,comm);  
00991     MPI_Gather(&number_cells,1,MPI_INT,number_cells_process,1,MPI_INT,  
00992                0,comm);  
00993     total_number_points =0;  
00994     total_number_cells =0;  
00995     max_number_points =0;  
00996     max_number_cells =0;  
00997     for(i=0;i<n_proc;++i) {  
00998       total_number_points = total_number_points + number_points_process[i];  
00999       total_number_cells  = total_number_cells  + number_cells_process[i];  
01000     }  
01001     for(i=0;i<n_proc;++i) {  
01002       if(number_points_process[i] > max_number_points)  
01003         max_number_points = number_points_process[i];  
01004       if(number_cells_process[i] > max_number_cells)  
01005         max_number_cells = number_cells_process[i];  
01006     }  
01007     /* Teil 1.7: make buffer */ 
01008     if(my_rank==0) {  
01009       buffer_rec_int    = new int[max_number_cells  * 4];  
01010       buffer_rec_double = new double[max_number_points * 3];  
01011     }  
01012     buffer_send_int    = new int[number_cells  * 4];  
01013     buffer_send_double = new double[number_points * 3];  
01014     /* Teil 1.6: Kopfzeile schreiben */   
01015     if(my_rank==0) {  
01016       *Datei << total_number_points << " "  
01017              << total_number_cells << " " 
01018              << number_of_vars << " 0 0" << endl;  
01019     }  
01020     /* Teil 2: Koordinaten der Punkte eingeben */  
01021     /* a) set values in buffer */  
01022     if(I_am_active()) {  
01023       /* i) alle inneren Punkte */ 
01024       iterate_hash1 {  
01025         if(point1->nummer != -1) {  
01026           zeiger = Give_variable(point1->ind,Max_level());
01027           loc = transform_coord(point1->ind.coordinate()) +
01028             D3vector(zeiger[number_var_a],
01029                      zeiger[number_var_b],
01030                      zeiger[number_var_c]);
01031  
01032           buffer_send_double[point1->nummer*3]   = loc.x;  
01033           buffer_send_double[point1->nummer*3+1] = loc.y;  
01034           buffer_send_double[point1->nummer*3+2] = loc.z;  
01035         }  
01036       }  
01037     /* ii) alle Randpunkte */   
01038       iterate_hash3 {
01039         zeiger = Give_variable(bo2point->ind,bo2point->direction);
01040         loc = bo2point->transform_coord(Give_A(),H_mesh()) +
01041           D3vector(zeiger[number_var_a],
01042                    zeiger[number_var_b],
01043                    zeiger[number_var_c]);
01044  
01045         buffer_send_double[bo2point->nummer*3]   = loc.x;  
01046         buffer_send_double[bo2point->nummer*3+1] = loc.y;  
01047         buffer_send_double[bo2point->nummer*3+2] = loc.z;  
01048       }  
01049     /* iii) alle Randzellfreiheitsgrad */   
01050       iterate_hash2 {  
01051         if(bocell->Give_Index()<<my_index) {  
01052           if(bocell->Exists_bocellpoint()) {
01053             zeiger = bocell->Give_var();
01054             loc =  transform_coord(bocell->ind.coordinate()) +   
01055               bocell->Local_coord_bocellpoint() +
01056               D3vector(zeiger[number_var_a],
01057                        zeiger[number_var_b],
01058                        zeiger[number_var_c]);
01059             buffer_send_double[bocell->Number_avs()*3]   = loc.x;  
01060             buffer_send_double[bocell->Number_avs()*3+1] = loc.y;  
01061             buffer_send_double[bocell->Number_avs()*3+2] = loc.z;  
01062           }  
01063         }  
01064       }  
01065     }  
01066     /* b) send */ 
01067     if(my_rank!=0) {  
01068       MPI_Send(buffer_send_double,number_points * 3,  
01069                MPI_DOUBLE,0,50,comm);  
01070     }  
01071     else {  
01072       start_num=0;  
01073       for(i=0;i<n_proc;++i) {  
01074         /* c) receive */ 
01075         if(i!=0) {  
01076           MPI_Recv(buffer_rec_double,number_points_process[i] * 3,  
01077                    MPI_DOUBLE,i,50,comm,&status);  
01078         }  
01079         else {  
01080           for(num=0;num<number_points_process[i];++num) {  
01081             buffer_rec_double[num*3]   = buffer_send_double[num*3];  
01082             buffer_rec_double[num*3+1] = buffer_send_double[num*3+1];  
01083             buffer_rec_double[num*3+2] = buffer_send_double[num*3+2];  
01084           }  
01085         }  
01086         /* d) print in file */  
01087         for(num=0;num<number_points_process[i];++num) {  
01088           loc.x =  buffer_rec_double[num*3];  
01089           loc.y =  buffer_rec_double[num*3+1];  
01090           loc.z =  buffer_rec_double[num*3+2];  
01091           *Datei << start_num+num  
01092                  << " " << fixed << loc.x    
01093                  << " " << fixed << loc.y    
01094                  << " " << fixed << loc.z  
01095                  << "\n";  
01096         }  
01097         start_num = start_num + number_points_process[i];  
01098       }  
01099     }  
01100     /* Teil 3: Zellen ausgeben */     
01101     /* a) set values in buffer */     
01102     if(I_am_active()) { 
01103       /* Teil 3.1: Innere Zellen ausgeben */ 
01104       ind = my_index;  
01105       number=Recursion_Cells_AVS_parallel(ind,0,buffer_send_int);  
01106       /* Teil 3.2: Randzellen */   
01107       iterate_hash2 {  
01108         if(bocell->Give_Index()<<my_index)  
01109           number = avs_bo_cell_parallel(bocell,number,buffer_send_int);  
01110       }  
01111     }  
01112     /* b) send */   
01113     if(my_rank!=0) {   
01114       MPI_Send(buffer_send_int,number_cells * 4,  
01115                MPI_INT,0,51,comm);  
01116     }  
01117     else {  
01118       start_num=0;  
01119       start_poi=0;  
01120       for(i=0;i<n_proc;++i) {  
01121         /* c) receive */  
01122         if(i!=0) {  
01123           MPI_Recv(buffer_rec_int,number_cells_process[i] * 4,  
01124                    MPI_INT,i,51,comm,&status);  
01125         }  
01126         else {  
01127           for(num=0;num<number_cells_process[i];++num) {  
01128             buffer_rec_int[num*4]   = buffer_send_int[num*4];   
01129             buffer_rec_int[num*4+1] = buffer_send_int[num*4+1];   
01130             buffer_rec_int[num*4+2] = buffer_send_int[num*4+2];   
01131             buffer_rec_int[num*4+3] = buffer_send_int[num*4+3];   
01132           }  
01133         }  
01134        /* d) print in file */    
01135         if(i<n_proc) {  
01136           for(num=0;num<number_cells_process[i];++num) {  
01137             *Datei << start_num+num+1 << " 1 tet "  
01138                    << " " << start_poi + buffer_rec_int[num*4]   
01139                    << " " << start_poi + buffer_rec_int[num*4+1]   
01140                    << " " << start_poi + buffer_rec_int[num*4+2]   
01141                    << " " << start_poi + buffer_rec_int[num*4+3]   
01142                    << "\n";  
01143           }  
01144         }  
01145         start_num = start_num + number_cells_process[i];  
01146         start_poi = start_poi + number_points_process[i];  
01147       }  
01148     }  
01149     if(my_rank==0) {
01150       /* Teil 4: */
01151       *Datei << "1 1" << "\n";
01152       // Teil 5:
01153       *Datei << "variable, unit " << "\n";
01154     }
01155 
01156     if(I_am_active()) {
01157     // Teil 2: Werte der Punkte ausgeben
01158     // a) set values in buffer
01159     // i) alle inneren Punkte
01160     iterate_hash1 {
01161       if(point1->nummer != -1) {
01162         ebene = Give_finest_level(point1->ind);
01163         buffer_send_double[point1->nummer] = 
01164           Give_variable(point1->ind,ebene)[number_var];
01165       }
01166     }
01167     // ii) alle Randpunkte
01168     iterate_hash3 {
01169       buffer_send_double[bo2point->nummer] = 
01170         Give_variable(bo2point->ind,bo2point->direction)[number_var];
01171     }
01172     // iii alle Randzellfreiheitsgrad
01173     iterate_hash2 {
01174       if(bocell->Give_Index()<<my_index) {
01175         if(bocell->Exists_bocellpoint()) {
01176           buffer_send_double[bocell->Number_avs()] =
01177             bocell->Give_var()[number_var];
01178         }
01179       }
01180     }
01181     }
01182 
01183     // b) send
01184     if(my_rank!=0) {
01185       MPI_Send(buffer_send_double,number_points,
01186                MPI_DOUBLE,0,52,comm);
01187     }
01188     else {
01189       start_num=0;
01190       for(i=0;i<n_proc;++i) {
01191         // c) receive
01192         if(i!=0) {
01193           MPI_Recv(buffer_rec_double,number_points_process[i],
01194                    MPI_DOUBLE,i,52,comm,&status);       
01195         }
01196         else {
01197           for(num=0;num<number_points_process[i];++num) {
01198             buffer_rec_double[num] = buffer_send_double[num];
01199           }
01200         }
01201         // d) print in file
01202         if(i<n_proc) {
01203           for(num=0;num<number_points_process[i];++num) {
01204             *Datei << start_num+num
01205                    << " " << buffer_rec_double[num]
01206                    << "\n";
01207           }
01208         }
01209         start_num = start_num + number_points_process[i];
01210       }
01211     }
01212 
01213     // Teil 7:
01214     if(I_am_active()) {
01215        delete(number_cells_process);
01216        delete(number_points_process);
01217     }
01218     delete(buffer_send_int);
01219     delete(buffer_send_double);
01220     if(my_rank==0) {
01221       delete(buffer_rec_int);
01222       delete(buffer_rec_double);
01223     }
01224   }
01225 
01226   MPI_Barrier(comm);
01227 }
01228 
01229 
01230 
01231 void Grid_base::Print_Variable_AVS_parallel(ofstream *Datei, int number_var,
01232                                             int number_varb, int number_varc) {
01233   int number_cells, number, ebene;
01234   int number_points;
01235   int n_proc,i;
01236 
01237   int *number_cells_process;
01238   int *number_points_process;
01239   int total_number_cells;
01240   int total_number_points;
01241 
01242   MPI_Status status;
01243 
01244   D3vector loc;
01245   int num, start_num, start_poi;
01246 
01247   int max_number_cells;
01248   int max_number_points;
01249 
01250   int*    buffer_send_int;
01251   double* buffer_send_double;
01252 
01253   int*    buffer_rec_int;
01254   double* buffer_rec_double;
01255 
01256   Index3D ind;
01257   int number_of_vars;   // wird in der Kopfzeile eingesetzt
01258 
01259   number_of_vars=3;
01260 
01261   Datei->precision(3);
01262 
01263   Problemzeile
01264 
01265   if(Is_storage_initialized()==false) { 
01266     cout << " \n Fehler in Print_Variable_AVS! Initialisierung fehlt! "
01267          << endl;
01268     return;
01269   }
01270   if(Give_max_num_var() <= number_var) {
01271     cout << " \n Fehler in Print_Variable_AVS! number_var zu gross! " << endl;
01272   }
01273   else {
01274     // Teil 0: Write information
01275     if(my_rank==0) {
01276       *Datei << "# File created by ExPDE " << endl;
01277       *Datei << "# UCD file format for AVS parallel " << endl;
01278       *Datei << "# vector field " << endl;
01279     }
01280     Macro_PRINT_Einsetzen 
01281       /* Teil 4: */ 
01282       *Datei << "3 1 1 1" << "\n";
01283       // Teil 5:
01284       *Datei << "x-coord " << "\n";
01285       *Datei << "y-coord " << "\n";
01286       *Datei << "z-coord " << "\n";
01287     }
01288 
01289     if(I_am_active()) {
01290     // Teil 2: Werte der Punkte ausgeben
01291     // a) set values in buffer
01292     // i) alle inneren Punkte
01293     iterate_hash1 {
01294       if(point1->nummer != -1) {
01295         ebene = Give_finest_level(point1->ind);
01296         buffer_send_double[3*point1->nummer] = 
01297           Give_variable(point1->ind,ebene)[number_var];
01298         buffer_send_double[3*point1->nummer+1] = 
01299           Give_variable(point1->ind,ebene)[number_varb];
01300         buffer_send_double[3*point1->nummer+2] = 
01301           Give_variable(point1->ind,ebene)[number_varc];
01302       }
01303     }
01304     // ii) alle Randpunkte
01305     iterate_hash3 {
01306       buffer_send_double[3*bo2point->nummer] = 
01307         Give_variable(bo2point->ind,bo2point->direction)[number_var];
01308       buffer_send_double[3*bo2point->nummer+1] = 
01309         Give_variable(bo2point->ind,bo2point->direction)[number_varb];
01310       buffer_send_double[3*bo2point->nummer+2] = 
01311         Give_variable(bo2point->ind,bo2point->direction)[number_varc];
01312     }
01313     // iii alle Randzellfreiheitsgrad
01314     iterate_hash2 {
01315       if(bocell->Give_Index()<<my_index) {
01316         if(bocell->Exists_bocellpoint()) {
01317           buffer_send_double[3*bocell->Number_avs()] =
01318             bocell->Give_var()[number_var];
01319           buffer_send_double[3*bocell->Number_avs()+1] =
01320             bocell->Give_var()[number_varb];
01321           buffer_send_double[3*bocell->Number_avs()+2] =
01322             bocell->Give_var()[number_varc];
01323         }
01324       }
01325     }
01326     }
01327 
01328     // b) send
01329     if(my_rank!=0) {
01330       MPI_Send(buffer_send_double,3*number_points,
01331                MPI_DOUBLE,0,52,comm);
01332     }
01333     else {
01334       start_num=0;
01335       for(i=0;i<n_proc;++i) {
01336         // c) receive
01337         if(i!=0) {
01338           MPI_Recv(buffer_rec_double,3*number_points_process[i],
01339                    MPI_DOUBLE,i,52,comm,&status);       
01340         }
01341         else {
01342           for(num=0;num<3*number_points_process[i];++num) {
01343             buffer_rec_double[num] = buffer_send_double[num];
01344           }
01345         }
01346         // d) print in file
01347         if(i<n_proc) {
01348           for(num=0;num<number_points_process[i];++num) {
01349             *Datei << start_num+num
01350                    << " " << buffer_rec_double[3*num]
01351                    << " " << buffer_rec_double[3*num+1]
01352                    << " " << buffer_rec_double[3*num+2]
01353                    << "\n";
01354           }
01355         }
01356         start_num = start_num + number_points_process[i];
01357       }
01358     }
01359 
01360     // Teil 7:
01361     if(I_am_active()) {
01362        delete(number_cells_process);
01363        delete(number_points_process);
01364     }
01365     delete(buffer_send_int);
01366     delete(buffer_send_double);
01367     if(my_rank==0) {
01368       delete(buffer_rec_int);
01369       delete(buffer_rec_double);
01370     }
01371   }
01372 
01373   MPI_Barrier(comm);
01374 }
01375 
01376 
01377 void Grid_base::Print_processes_UCD(ofstream *Datei) {
01378   int number_cells, number;
01379   int number_points;
01380   int n_proc,i;
01381 
01382   int *number_cells_process;
01383   int *number_points_process;
01384   int total_number_cells;
01385   int total_number_points;
01386 
01387   MPI_Status status;
01388 
01389   D3vector loc;
01390   int num, start_num, start_poi;
01391 
01392   int max_number_cells;
01393   int max_number_points;
01394 
01395   int*    buffer_send_int;
01396   double* buffer_send_double;
01397 
01398   int*    buffer_rec_int;
01399   double* buffer_rec_double;
01400 
01401   Index3D ind;
01402   int number_of_vars;   // wird in der Kopfzeile eingesetzt
01403 
01404   number_of_vars=1;
01405 
01406 
01407   if(Is_storage_initialized()==false) { 
01408     cout << " \n Fehler in Print...! Initialisierung fehlt! "
01409          << endl;
01410     return;
01411   }
01412   else {
01413     if(my_rank==0) {
01414       // Teil 0: Write information
01415       *Datei << "# File created by ExPDE PARALLEL" << endl;
01416       *Datei << "# UCD file format for AVS " << endl;
01417       *Datei << "# processes colored " << endl;
01418     }
01419     Macro_PRINT_Einsetzen 
01420       /* Teil 4: */
01421       *Datei << "1 1" << "\n";
01422       // Teil 5:
01423       *Datei << "processes " << "\n";
01424 
01425       // Teil 6: Print number of processor
01426       start_num=0;
01427       for(i=0;i<n_proc;++i) {
01428         for(num=0;num<number_points_process[i];++num) {
01429           *Datei << start_num+num << "   " << i  << "\n";
01430         }
01431         start_num = start_num + number_points_process[i];
01432       }
01433       *Datei << endl;
01434     }
01435 
01436     // Teil 7:
01437     if(I_am_active()) {
01438       delete(number_cells_process);
01439       delete(number_points_process);
01440     }
01441     delete(buffer_send_int);
01442     delete(buffer_send_double);
01443     if(my_rank==0) {
01444       delete(buffer_rec_int);
01445       delete(buffer_rec_double);
01446     }
01447   }
01448   MPI_Barrier(comm);
01449 }
01450 
01451 
01453 // 3. region
01455 
01456 void Grid_base::Print_region_processes_UCD(ofstream *Datei) {
01457   int i;
01458   D3vector v;
01459 
01460   if(my_rank==0) {
01461     // Teil 0: Write information
01462     *Datei << "# File created by ExPDE PARALLEL" << endl;
01463     *Datei << "# UCD file format for AVS " << endl;
01464     *Datei << "# scalar value " << endl;
01465     
01466     // Teil 1: Kopfzeile schreiben
01467     *Datei << 8*give_number_of_active_processes() << " "
01468            <<   give_number_of_active_processes() << " 1 0 0" << endl;
01469 
01470     // Teil 2: Koordinaten der Punkte ausgeben
01471     iterate_hash_proc {
01472       if(point_proc!=NULL)
01473         if(point_proc->Give_Index().Tiefe()==n_parallel) {
01474           for(i=0;i<8;++i) {
01475             v = transform_coord(
01476                   point_proc->Give_Index().neighbour_non_periodic(
01477                   (dir_sons)i).coordinate());
01478                  *Datei << point_proc->Give_num_proc()*8+i
01479                  << " " << fixed << v.x  
01480                  << " " << fixed << v.y  
01481                  << " " << fixed << v.z
01482                  << "\n";
01483         }
01484       }
01485     }
01486     
01487     // Teil 3: Zellen ausgeben
01488     iterate_hash_proc {
01489      if(point_proc!=NULL)
01490        if(point_proc->Give_Index().Tiefe()==n_parallel) {
01491         *Datei << point_proc->Give_num_proc() << "  1  hex  "
01492                << point_proc->Give_num_proc()*8+WNTd << " "
01493                << point_proc->Give_num_proc()*8+WSTd << " "
01494                << point_proc->Give_num_proc()*8+ESTd << " "
01495                << point_proc->Give_num_proc()*8+ENTd << " "
01496                << point_proc->Give_num_proc()*8+WNDd << " "
01497                << point_proc->Give_num_proc()*8+WSDd << " "
01498                << point_proc->Give_num_proc()*8+ESDd << " "
01499                << point_proc->Give_num_proc()*8+ENDd << " "
01500                << "\n";
01501       }
01502     }
01503 
01504     // Teil 4:
01505     *Datei << "1 1" << "\n";
01506     *Datei << "processes " << "\n";
01507     
01508     // Teil 5:  Nummer der Prozesses an Punkten ausgeben
01509     iterate_hash_proc {
01510       if(point_proc!=NULL)
01511        if(point_proc->Give_Index().Tiefe()==n_parallel) {
01512         for(i=0;i<8;++i) {
01513           *Datei << point_proc->Give_num_proc()*8+i << " " 
01514                  << point_proc->Give_num_proc()
01515                  << "\n";
01516         }
01517       }
01518     }
01519     *Datei << endl;
01520   }
01521 }
01522 
01523 void Parallel_Info::Print_region_processes_UCD_normalized(ofstream *Datei) {
01524   int i;
01525   D3vector v;
01526 
01527   if(my_rank==0) {
01528     // Teil 0: Write information
01529     *Datei << "# File created by ExPDE PARALLEL" << endl;
01530     *Datei << "# UCD file format for AVS " << endl;
01531     *Datei << "# scalar value " << endl;
01532     
01533     // Teil 1: Kopfzeile schreiben
01534     *Datei << 8*give_number_of_active_processes() << " "
01535            <<   give_number_of_active_processes() << " 1 0 0" << endl;
01536 
01537     // Teil 2: Koordinaten der Punkte ausgeben
01538     iterate_hash_proc {
01539       if(point_proc!=NULL)
01540         if(point_proc->Give_Index().Tiefe()==n_parallel) {
01541           for(i=0;i<8;++i) {
01542             v = point_proc->Give_Index().neighbour(
01543                   (dir_sons)i).coordinate();
01544                  *Datei << point_proc->Give_num_proc()*8+i
01545                  << " " << fixed << v.x  
01546                  << " " << fixed << v.y  
01547                  << " " << fixed << v.z
01548                  << "\n";
01549         }
01550       }
01551     }
01552     
01553     // Teil 3: Zellen ausgeben
01554     iterate_hash_proc {
01555      if(point_proc!=NULL)
01556        if(point_proc->Give_Index().Tiefe()==n_parallel) {
01557         *Datei << point_proc->Give_num_proc() << "  1  hex  "
01558                << point_proc->Give_num_proc()*8+WNTd << " "
01559                << point_proc->Give_num_proc()*8+WSTd << " "
01560                << point_proc->Give_num_proc()*8+ESTd << " "
01561                << point_proc->Give_num_proc()*8+ENTd << " "
01562                << point_proc->Give_num_proc()*8+WNDd << " "
01563                << point_proc->Give_num_proc()*8+WSDd << " "
01564                << point_proc->Give_num_proc()*8+ESDd << " "
01565                << point_proc->Give_num_proc()*8+ENDd << " "
01566                << "\n";
01567       }
01568     }
01569 
01570     // Teil 4:
01571     *Datei << "1 1" << "\n";
01572     *Datei << "processes " << "\n";
01573     
01574     // Teil 5:  Nummer der Prozesses an Punkten ausgeben
01575     iterate_hash_proc {
01576       if(point_proc!=NULL)
01577        if(point_proc->Give_Index().Tiefe()==n_parallel) {
01578         for(i=0;i<8;++i) {
01579           *Datei << point_proc->Give_num_proc()*8+i << " " 
01580                  << point_proc->Give_num_proc()
01581                  << "\n";
01582         }
01583       }
01584     }
01585     *Datei << endl;
01586   }
01587 }
01588 
01589 
01591 // 4. only surface
01593 
01594 
01595 // Ausgabe der Tetraeder
01596 int Grid_base::avs_bo_cell_parallel_surface(BoCell* bo, int number, 
01597       int* buffer, bool print_or_calc) {
01598   Tetraeder_storage* tets;
01599   int num, numad;
01600   Index3D I;
01601   Cell_type_points typ0, typ1, typ2, typ3;
01602 
01603   if(print_or_calc==false) {
01604     for(tets = bo->Give_tets();tets!=NULL;tets = tets->Next()) {
01605     // Punkt 0:
01606     num = tets->N0();
01607     typ0 = bo->edge_point(num);
01608     num = tets->N1();
01609     typ1 = bo->edge_point(num);
01610     num = tets->N2();
01611     typ2 = bo->edge_point(num);
01612     num = tets->N3();
01613     typ3 = bo->edge_point(num);
01614     if(((int)(typ0==edge_poi_typ) + (int)(typ1==edge_poi_typ) + 
01615         (int)(typ2==edge_poi_typ) + (int)(typ3==edge_poi_typ))==3) {
01616        number++;
01617     }
01618    }
01619   }
01620   else {
01621     I = bo->Give_Index();
01622     for(tets = bo->Give_tets();tets!=NULL;tets = tets->Next()) {
01623       num = tets->N0();
01624       typ0 = bo->edge_point(num);
01625       num = tets->N1();
01626       typ1 = bo->edge_point(num);
01627       num = tets->N2();
01628       typ2 = bo->edge_point(num);
01629       num = tets->N3();
01630       typ3 = bo->edge_point(num);
01631       if(((int)(typ0==edge_poi_typ) + (int)(typ1==edge_poi_typ) + 
01632           (int)(typ2==edge_poi_typ) + (int)(typ3==edge_poi_typ))==3) {
01633           numad=0;
01634           // Punkt 0:
01635           num = tets->N0();
01636           if(typ0==edge_poi_typ) {
01637           buffer[number*3+numad] = Give_Nummer(I.neighbour(bo->corner(num)),
01638                                    bo->edge_dir(num));
01639             ++numad;
01640           }
01641           // Punkt 1:
01642           num = tets->N1();
01643           if(typ1==edge_poi_typ) {
01644             buffer[number*3+numad] = Give_Nummer(I.neighbour(bo->corner(num)),
01645                                      bo->edge_dir(num));
01646             ++numad;
01647            }
01648           // Punkt 2:
01649           num = tets->N2();
01650           if(typ2==edge_poi_typ) {
01651             buffer[number*3+numad] = Give_Nummer(I.neighbour(bo->corner(num)),
01652                                      bo->edge_dir(num));
01653             ++numad;
01654            }
01655            // Punkt 3:
01656            num = tets->N3();
01657            if(typ3==edge_poi_typ) {
01658              buffer[number*3+numad] = Give_Nummer(I.neighbour(bo->corner(num)),
01659                                       bo->edge_dir(num));
01660              ++numad;
01661             }
01662             ++number;
01663          }
01664       }
01665   }
01666   return number;
01667 }
01668 
01669 
01670 
01671 
01672 
01673 #define Macro_PRINT_sur_Einsetzen  \
01674   /* Teil 1: Anzahl der Zellen zaehlen */ \
01675     number_cells = 0; \
01676     if(I_am_active()) { \
01677     /* Teil 1.1: Randzellen */  \
01678     iterate_hash2 { \
01679         if(bocell->Give_Index()<<my_index) \
01680           number_cells = avs_bo_cell_parallel_surface(bocell,number_cells, \
01681                                                       NULL,false); \
01682       } \
01683     } \
01684     /* Teil 1.2: Anzahl der Punkte */ \
01685     number_points=0; \
01686     if(I_am_active()) { \
01687     /* a) Randpunkte */  \
01688       iterate_hash3 {  \
01689         bo2point->Set_number_avs(number_points);  \
01690         ++number_points;  \
01691       } \
01692     }  \
01693     /* Teil 1.5: gather data */   \
01694     n_proc = give_number_of_processes();  \
01695     number_cells_process = new int[n_proc];  \
01696     number_points_process = new int[n_proc];  \
01697     MPI_Gather(&number_points,1,MPI_INT,number_points_process,1,MPI_INT,  \
01698                0,comm);  \
01699     MPI_Gather(&number_cells,1,MPI_INT,number_cells_process,1,MPI_INT,  \
01700                0,comm);  \
01701     total_number_points =0;  \
01702     total_number_cells =0;  \
01703     max_number_points =0;  \
01704     max_number_cells =0;  \
01705     for(i=0;i<n_proc;++i) {  \
01706       total_number_points = total_number_points + number_points_process[i];  \
01707       total_number_cells  = total_number_cells  + number_cells_process[i];  \
01708     }  \
01709     for(i=0;i<n_proc;++i) {  \
01710       if(number_points_process[i] > max_number_points)  \
01711         max_number_points = number_points_process[i]; \
01712       if(number_cells_process[i] > max_number_cells)  \
01713         max_number_cells = number_cells_process[i];  \
01714     }  \
01715     /* Teil 1.7: make buffer */ \
01716     if(my_rank==0) {  \
01717       buffer_rec_int    = new int[max_number_cells  * 3];  \
01718       buffer_rec_double = new double[max_number_points * 3];  \
01719     }  \
01720     buffer_send_int    = new int[number_cells  * 3];  \
01721     buffer_send_double = new double[number_points * 3];  \
01722     /* Teil 1.6: Kopfzeile schreiben */   \
01723     if(my_rank==0) {  \
01724       *Datei << total_number_points << " "  \
01725              << total_number_cells << " 1 0 0" << endl;  \
01726     }  \
01727     /* Teil 2: Koordinaten der Punkte eingeben */  \
01728     /* a) set values in buffer */  \
01729     if(I_am_active()) {  \
01730     /* i) alle Randpunkte */   \
01731       iterate_hash3 {  \
01732         loc = bo2point->transform_coord(Give_A(),H_mesh());  \
01733         buffer_send_double[bo2point->nummer*3]   = loc.x;  \
01734         buffer_send_double[bo2point->nummer*3+1] = loc.y;  \
01735         buffer_send_double[bo2point->nummer*3+2] = loc.z;  \
01736       }  \
01737     }  \
01738     /* b) send */ \
01739     if(my_rank!=0) {  \
01740       MPI_Send(buffer_send_double,number_points * 3,  \
01741                MPI_DOUBLE,0,50,comm);  \
01742     }  \
01743     else {  \
01744       start_num=0;  \
01745       for(i=0;i<n_proc;++i) {  \
01746         /* c) receive */ \
01747         if(i!=0) {  \
01748           MPI_Recv(buffer_rec_double,number_points_process[i] * 3,  \
01749                    MPI_DOUBLE,i,50,comm,&status);  \
01750         }  \
01751         else {  \
01752           for(num=0;num<number_points_process[i];++num) {  \
01753             buffer_rec_double[num*3]   = buffer_send_double[num*3];  \
01754             buffer_rec_double[num*3+1] = buffer_send_double[num*3+1]; \
01755             buffer_rec_double[num*3+2] = buffer_send_double[num*3+2];  \
01756           }  \
01757         }  \
01758         /* d) print in file */  \
01759         for(num=0;num<number_points_process[i];++num) {  \
01760           loc.x =  buffer_rec_double[num*3];  \
01761           loc.y =  buffer_rec_double[num*3+1];  \
01762           loc.z =  buffer_rec_double[num*3+2];  \
01763           *Datei << start_num+num  \
01764                  << " " << fixed << loc.x    \
01765                  << " " << fixed << loc.y    \
01766                  << " " << fixed << loc.z  \
01767                  << "\n";  \
01768         }  \
01769         start_num = start_num + number_points_process[i];  \
01770       }  \
01771     }  \
01772     /* Teil 3: Zellen ausgeben */     \
01773     /* a) set values in buffer */ \
01774     if(I_am_active()) { \
01775       number=0; \
01776       /* Teil 3.1: Randzellen */  \
01777       iterate_hash2 {  \
01778         if(bocell->Give_Index()<<my_index)  \
01779           number = avs_bo_cell_parallel_surface(bocell,number,     \
01780                                                 buffer_send_int,true);  \
01781       }  \
01782     }  \
01783     /* b) send */   \
01784     if(my_rank!=0) {   \
01785       MPI_Send(buffer_send_int,number_cells * 3,  \
01786                MPI_INT,0,51,comm);  \
01787     }  \
01788     else {  \
01789       start_num=0;  \
01790       start_poi=0;  \
01791       for(i=0;i<n_proc;++i) {  \
01792         /* c) receive */  \
01793         if(i!=0) {  \
01794           MPI_Recv(buffer_rec_int,number_cells_process[i] * 3,  \
01795                    MPI_INT,i,51,comm,&status);  \
01796         }  \
01797         else {  \
01798           for(num=0;num<number_cells_process[i];++num) {  \
01799             buffer_rec_int[num*3]   = buffer_send_int[num*3];   \
01800             buffer_rec_int[num*3+1] = buffer_send_int[num*3+1];   \
01801             buffer_rec_int[num*3+2] = buffer_send_int[num*3+2];   \
01802           }  \
01803         }  \
01804        /* d) print in file */    \
01805         if(i<n_proc) {  \
01806           for(num=0;num<number_cells_process[i];++num) {  \
01807             *Datei << start_num+num+1 << "  1  tri  "  \
01808                    << " " << start_poi + buffer_rec_int[num*3]   \
01809                    << " " << start_poi + buffer_rec_int[num*3+1]   \
01810                    << " " << start_poi + buffer_rec_int[num*3+2]   \
01811                    << "\n";  \
01812           }  \
01813         }  \
01814         start_num = start_num + number_cells_process[i];  \
01815         start_poi = start_poi + number_points_process[i];  \
01816       }  \
01817     }  \
01818     if(my_rank==0) {  \
01819       /* Teil 4: */ \
01820       *Datei << "1 1" << "\n";
01821 
01822 
01823 
01824 
01825 
01826 
01827 
01828 
01829 
01830 
01831 void Grid_base::Print_surface_processes_UCD(ofstream *Datei) {
01832   int number_cells, number;
01833   int number_points;
01834   int n_proc,i;
01835 
01836   int *number_cells_process;
01837   int *number_points_process;
01838   int total_number_cells;
01839   int total_number_points;
01840 
01841   MPI_Status status;
01842 
01843   D3vector loc;
01844   int num, start_num, start_poi;
01845 
01846   int max_number_cells;
01847   int max_number_points;
01848 
01849   int*    buffer_send_int;
01850   double* buffer_send_double;
01851 
01852   int*    buffer_rec_int;
01853   double* buffer_rec_double;
01854 
01855   Index3D ind;
01856 
01857 
01858   if(Is_storage_initialized()==false) { 
01859     cout << " \n Fehler in Print...! Initialisierung fehlt! "
01860          << endl;
01861     return;
01862   }
01863   else {
01864     if(my_rank==0) {
01865       // Teil 0: Write information
01866       *Datei << "# File created by ExPDE PARALLEL" << endl;
01867       *Datei << "# UCD file format for AVS " << endl;
01868       *Datei << "# processes colored " << endl;
01869     }
01870    Macro_PRINT_sur_Einsetzen 
01871   
01872 
01873    
01874       // Teil 5:
01875       *Datei << "processes " << "\n";
01876 
01877       // Teil 6: Print number of processor
01878       start_num=0;
01879       for(i=0;i<n_proc;++i) {
01880         for(num=0;num<number_points_process[i];++num) {
01881           *Datei << start_num+num << "   " << i  << "\n";
01882         }
01883         start_num = start_num + number_points_process[i];
01884       }
01885       *Datei << endl;
01886     }
01887 
01888     // Teil 7:
01889     if(I_am_active()) {
01890       delete(number_cells_process);
01891       delete(number_points_process);
01892     }
01893     delete(buffer_send_int);
01894     delete(buffer_send_double);
01895     if(my_rank==0) {
01896       delete(buffer_rec_int);
01897       delete(buffer_rec_double);
01898     }
01899   }
01900   MPI_Barrier(comm);
01901 }
01902 
01903 
01904 
01905 void Grid_base::Print_surface_Variable_AVS_parallel(ofstream *Datei,
01906         int number_var) {
01907 int number_cells, number;
01908 int number_points;
01909 int n_proc,i;
01910 
01911   int *number_cells_process;
01912   int *number_points_process;
01913   int total_number_cells;
01914   int total_number_points;
01915 
01916   MPI_Status status;
01917 
01918   D3vector loc;
01919   int num, start_num, start_poi;
01920 
01921   int max_number_cells;
01922   int max_number_points;
01923 
01924   int*    buffer_send_int;
01925   double* buffer_send_double;
01926 
01927   int*    buffer_rec_int;
01928   double* buffer_rec_double;
01929 
01930   Index3D ind;
01931 
01932   if(Is_storage_initialized()==false) { 
01933     cout << " \n Fehler in Print_Variable_AVS! Initialisierung fehlt! "
01934          << endl;
01935     return;
01936   }
01937 if(Give_max_num_var() <= number_var) {
01938 cout << " \n Fehler in Print_Variable_AVS! number_var zu gross! " << endl;
01939   }
01940   else {
01941     // Teil 0: Write information
01942     if(my_rank==0) {
01943       *Datei << "# File created by ExPDE " << endl;
01944       *Datei << "# UCD file format for AVS parallel " << endl;
01945       *Datei << "# scalar value " << endl;
01946     }
01947     Macro_PRINT_sur_Einsetzen 
01948       
01949       // Teil 5:
01950       *Datei << "variable, unit " << "\n";
01951     }
01952 
01953     if(I_am_active()) {
01954     // Teil 2: Koordinaten der Punkte eingeben
01955     // a) set values in buffer
01956     // ii) alle Randpunkte
01957     iterate_hash3 {
01958       buffer_send_double[bo2point->nummer] = 
01959         Give_variable(bo2point->ind,bo2point->direction)[number_var];
01960     }
01961     }
01962     // b) send
01963     if(my_rank!=0) {
01964       MPI_Send(buffer_send_double,number_points,
01965                MPI_DOUBLE,0,52,comm);
01966     }
01967     else {
01968       start_num=0;
01969       for(i=0;i<n_proc;++i) {
01970         // c) receive
01971         if(i!=0) {
01972           MPI_Recv(buffer_rec_double,number_points_process[i],
01973                    MPI_DOUBLE,i,52,comm,&status);       
01974         }
01975         else {
01976           for(num=0;num<number_points_process[i];++num) {
01977             buffer_rec_double[num] = buffer_send_double[num];
01978           }
01979         }
01980         // d) print in file
01981         if(i<n_proc) {
01982           for(num=0;num<number_points_process[i];++num) {
01983             *Datei << start_num+num
01984                    << " " << buffer_rec_double[num]
01985                    << "\n";
01986           }
01987         }
01988         start_num = start_num + number_points_process[i];
01989       }
01990     }
01991 
01992     // Teil 7:
01993     if(I_am_active()) {
01994       delete(number_cells_process);
01995       delete(number_points_process);
01996     }
01997     delete(buffer_send_int);
01998     delete(buffer_send_double);
01999     if(my_rank==0) {
02000       delete(buffer_rec_int);
02001       delete(buffer_rec_double);
02002     }
02003   }
02004 
02005   MPI_Barrier(comm);
02006 }
02007 
02008 
02010 // 5. cell
02013 // for cell variable
02015 
02016 void Grid_base::Print_Cell_Variable_AVS_parallel(ofstream *Datei, 
02017               int number_cell_var) {
02018   int number_cells, number;
02019   int number_points;
02020   int n_proc,i;
02021 
02022   int *number_cells_process;
02023   int *number_points_process;
02024   int total_number_cells;
02025   int total_number_points;
02026 
02027   MPI_Status status;
02028 
02029   D3vector loc;
02030   int num, start_num, start_poi;
02031 
02032   int max_number_cells;
02033   int max_number_points;
02034 
02035   int*    buffer_send_int;
02036   double* buffer_send_double;
02037 
02038   int*    buffer_rec_int;
02039   double* buffer_rec_double;
02040 
02041   Index3D ind, I;
02042 
02043   if(Is_storage_initialized()==false) { 
02044     cout << " \n Fehler 1 in Print_Cell_Variable_AVS_parallel! Initialisierung fehlt! "
02045          << endl;
02046     return;
02047   }
02048   if(Give_max_num_cell_var() <= number_cell_var) {
02049     cout << " \n Fehler 2 in Print_Cell_Variable_AVS_parallel!  " << endl;
02050   }
02051   else {
02052     // Teil 0: Write information
02053     *Datei << "# File created by ExPDE " << endl;
02054     *Datei << "# UCD file format for AVS " << endl;
02055     *Datei << "# scalar value on cells" << endl;
02056 
02057     /* Teil 1: Anzahl der Zellen zaehlen */ 
02058     number_cells = 0; 
02059     if(I_am_active()) { 
02060     /* Teil 1.1: Innerer Zellen */ 
02061     ind = my_index; 
02062     number_cells = Recursion_Count_Cells(ind); 
02063     /* Teil 1.2: Randzellen */  
02064     iterate_hash2 { 
02065         if(bocell->Give_Index()<<my_index) 
02066           number_cells = avs_bo_cell(bocell,Datei,false,number_cells); 
02067       } 
02068     } 
02069     /* Teil 1.3: Anzahl der Punkte */ 
02070     number_points=0; 
02071     if(I_am_active()) { 
02072       /* a) innen und randnah */ 
02073       iterate_hash1 { 
02074         if((point1->typ >= interior || point1->typ==parallel_p) && 
02075            point1->Give_Index()<<my_index) { 
02076           point1->nummer = number_points; 
02077           number_points++; 
02078         } 
02079         else point1->nummer = -1; 
02080       } 
02081     /* b) Randpunkte */  
02082       iterate_hash3 {  
02083         bo2point->Set_number_avs(number_points);  
02084         ++number_points;  
02085       }  
02086     /* c) Randzellfreiheitsgrad */  
02087       iterate_hash2 {  
02088         if(bocell->Give_Index()<<my_index) {  
02089           if(bocell->Exists_bocellpoint()) {  
02090             bocell->Set_number_avs(number_points);  
02091             number_points++;  
02092           } 
02093         } 
02094       } 
02095     } 
02096     /* Teil 1.5: gather data */   
02097     n_proc = give_number_of_processes();  
02098     number_cells_process = new int[n_proc];  
02099     number_points_process = new int[n_proc];  
02100     MPI_Gather(&number_points,1,MPI_INT,number_points_process,1,MPI_INT,  
02101                0,comm);  
02102     MPI_Gather(&number_cells,1,MPI_INT,number_cells_process,1,MPI_INT,  
02103                0,comm);  
02104     total_number_points =0;  
02105     total_number_cells =0;  
02106     max_number_points =0;  
02107     max_number_cells =0;  
02108     for(i=0;i<n_proc;++i) {  
02109       total_number_points = total_number_points + number_points_process[i];  
02110       total_number_cells  = total_number_cells  + number_cells_process[i];
02111     }  
02112     for(i=0;i<n_proc;++i) {  
02113       if(number_points_process[i] > max_number_points)  
02114         max_number_points = number_points_process[i];  
02115       if(number_cells_process[i] > max_number_cells)  
02116         max_number_cells = number_cells_process[i];  
02117     }  
02118     /* Teil 1.7: make buffer */ 
02119     if(my_rank==0) {  
02120       buffer_rec_int    = new int[max_number_cells  * 4];  
02121       buffer_rec_double = new double[max_number_points * 3];  
02122     }  
02123     buffer_send_int    = new int[number_cells  * 4];  
02124     buffer_send_double = new double[number_cells * 3];  
02125     /* Teil 1.6: Kopfzeile schreiben */   
02126     if(my_rank==0) {
02127        *Datei << total_number_points << " "  
02128              << total_number_cells << " 0 1 0" << endl; 
02129     }  
02130     /* Teil 2: Koordinaten der Punkte eingeben */  
02131     /* a) set values in buffer */  
02132     if(I_am_active()) {  
02133       /* i) alle inneren Punkte */ 
02134       iterate_hash1 {  
02135         if(point1->nummer != -1) {  
02136           loc = transform_coord(point1->ind.coordinate());  
02137           buffer_send_double[point1->nummer*3]   = loc.x;  
02138           buffer_send_double[point1->nummer*3+1] = loc.y;  
02139           buffer_send_double[point1->nummer*3+2] = loc.z;  
02140         }  
02141       }  
02142     /* ii) alle Randpunkte */   
02143       iterate_hash3 {  
02144         loc = bo2point->transform_coord(Give_A(),H_mesh());  
02145         buffer_send_double[bo2point->nummer*3]   = loc.x;  
02146         buffer_send_double[bo2point->nummer*3+1] = loc.y;  
02147         buffer_send_double[bo2point->nummer*3+2] = loc.z;  
02148       }  
02149     /* iii) alle Randzellfreiheitsgrad */   
02150       iterate_hash2 {  
02151         if(bocell->Give_Index()<<my_index) {  
02152           if(bocell->Exists_bocellpoint()) {  
02153             loc =  transform_coord(bocell->ind.coordinate()) +   
02154               bocell->Local_coord_bocellpoint();  
02155             buffer_send_double[bocell->Number_avs()*3]   = loc.x;  
02156             buffer_send_double[bocell->Number_avs()*3+1] = loc.y;  
02157             buffer_send_double[bocell->Number_avs()*3+2] = loc.z;  
02158           }  
02159         }  
02160       }  
02161     }  
02162     /* b) send */ 
02163     if(my_rank!=0) {  
02164       MPI_Send(buffer_send_double,number_points * 3,  
02165                MPI_DOUBLE,0,50,comm);  
02166     }  
02167     else {  
02168       start_num=0;  
02169       for(i=0;i<n_proc;++i) {  
02170         /* c) receive */ 
02171         if(i!=0) {  
02172           MPI_Recv(buffer_rec_double,number_points_process[i] * 3,  
02173                    MPI_DOUBLE,i,50,comm,&status);  
02174         }  
02175         else {  
02176           for(num=0;num<number_points_process[i];++num) {  
02177             buffer_rec_double[num*3]   = buffer_send_double[num*3];  
02178             buffer_rec_double[num*3+1] = buffer_send_double[num*3+1];  
02179             buffer_rec_double[num*3+2] = buffer_send_double[num*3+2];  
02180           }  
02181         }  
02182         /* d) print in file */  
02183         for(num=0;num<number_points_process[i];++num) {  
02184           loc.x =  buffer_rec_double[num*3];  
02185           loc.y =  buffer_rec_double[num*3+1];  
02186           loc.z =  buffer_rec_double[num*3+2];  
02187           *Datei << start_num+num  
02188           << " " << fixed << loc.x    
02189           << " " << fixed << loc.y    
02190           << " " << fixed << loc.z  
02191                  << "\n";  
02192         }  
02193         start_num = start_num + number_points_process[i];  
02194       }  
02195     }  
02196     /* Teil 3: Zellen ausgeben */     
02197     /* a) set values in buffer */     
02198     if(I_am_active()) { 
02199       /* Teil 3.1: Innere Zellen ausgeben */ 
02200       ind = my_index;  
02201       number=Recursion_Cells_AVS_parallel(ind,0,buffer_send_int);  
02202       /* Teil 3.2: Randzellen */   
02203       iterate_hash2 {  
02204         if(bocell->Give_Index()<<my_index)  
02205           number = avs_bo_cell_parallel(bocell,number,buffer_send_int);  
02206       }  
02207     }  
02208     /* b) send */   
02209     if(my_rank!=0) {   
02210       MPI_Send(buffer_send_int,number_cells * 4,  
02211                MPI_INT,0,51,comm);  
02212     }  
02213     else {  
02214       start_num=0;  
02215       start_poi=0;  
02216       for(i=0;i<n_proc;++i) {  
02217         /* c) receive */  
02218         if(i!=0) {  
02219           MPI_Recv(buffer_rec_int,number_cells_process[i] * 4,  
02220                    MPI_INT,i,51,comm,&status);  
02221         }  
02222         else {  
02223           for(num=0;num<number_cells_process[i];++num) {  
02224             buffer_rec_int[num*4]   = buffer_send_int[num*4];   
02225             buffer_rec_int[num*4+1] = buffer_send_int[num*4+1];   
02226             buffer_rec_int[num*4+2] = buffer_send_int[num*4+2];   
02227             buffer_rec_int[num*4+3] = buffer_send_int[num*4+3];   
02228           }  
02229         }  
02230        /* d) print in file */    
02231         if(i<n_proc) {  
02232           for(num=0;num<number_cells_process[i];++num) {  
02233             *Datei << start_num+num+1 << " 1 tet "  
02234                    << " " << start_poi + buffer_rec_int[num*4]   
02235                    << " " << start_poi + buffer_rec_int[num*4+1]   
02236                    << " " << start_poi + buffer_rec_int[num*4+2]   
02237                    << " " << start_poi + buffer_rec_int[num*4+3]   
02238                    << "\n";  
02239           }  
02240         }  
02241         start_num = start_num + number_cells_process[i];  
02242         start_poi = start_poi + number_points_process[i];  
02243       }  
02244     }  
02245     if(my_rank==0) {  
02246       /* Teil 4: */ 
02247       *Datei << "1 1" << "\n";
02248     }
02249     
02250     // Teil 5:
02251     *Datei << "variable, unit " << "\n";
02252 
02253     if(I_am_active()) {
02254     // Teil 6: Ausgabe der Werte der Zell-Variablen
02255     // a) set values in buffer
02256     /* i)  Innere Zellen */ 
02257     ind = my_index; 
02258     number = Recursion_Cells_parallel(ind,0,number_cell_var,
02259                                       buffer_send_double); 
02260     /* ii) Randzellen */  
02261     iterate_hash2 { 
02262         if(bocell->Give_Index()<<my_index) 
02263           number = avs_bo_cell_parallel(bocell,number,number_cell_var,
02264                                         buffer_send_double); 
02265     }
02266     }
02267     // b) send
02268     if(my_rank!=0) {
02269       MPI_Send(buffer_send_double,number_cells,
02270                MPI_DOUBLE,0,52,comm);
02271     }
02272     else {
02273       start_num=0;
02274       for(i=0;i<n_proc;++i) {
02275         // c) receive
02276         if(i!=0) {
02277           MPI_Recv(buffer_rec_double,number_cells_process[i],
02278                    MPI_DOUBLE,i,52,comm,&status);       
02279         }
02280         else {
02281           for(num=0;num<number_cells_process[i];++num) {
02282             buffer_rec_double[num] = buffer_send_double[num];
02283           }
02284         }
02285         // d) print in file
02286         if(i<n_proc) {
02287           for(num=0;num<number_cells_process[i];++num) {
02288             *Datei << start_num+num
02289                    << " " << buffer_rec_double[num]
02290                    << "\n";
02291           }
02292         }
02293         start_num = start_num + number_cells_process[i];
02294       }
02295     }
02296 
02297     // Teil 7:
02298     if(I_am_active()) {
02299       delete(number_cells_process);
02300       delete(number_points_process);
02301     }
02302     delete(buffer_send_int);
02303     delete(buffer_send_double);
02304     if(my_rank==0) {
02305       delete(buffer_rec_int);
02306       delete(buffer_rec_double);
02307     }
02308   }
02309   MPI_Barrier(comm);
02310 }
02311 
02312 
02313 int Grid_base::avs_bo_cell_parallel(BoCell* bo,
02314                            int number, int number_cell_var,
02315                            double* buffer_send_double) {
02316   Tetraeder_storage* tets;
02317 
02318   for(tets = bo->Give_tets();tets!=NULL;tets = tets->Next()) {
02319     buffer_send_double[number] = tets->Give_variable()[number_cell_var];
02320     ++number; 
02321   }
02322   return number;
02323 }
02324 
02325 int Grid_base::Recursion_Cells_parallel(Index3D I, int number, 
02326                                         int number_cell_var,
02327                                         double* buffer_send_double) {
02328   int i;
02329   Index3D Ison;
02330   double value;
02331 
02332   for(i=0;i<8;++i) {
02333     if(Exists_Point(I.son((dir_sons)i)))
02334       number = Recursion_Cells_parallel(I.son((dir_sons)i),number,
02335                                    number_cell_var,buffer_send_double);
02336     else {
02337       if(Give_cell_typ(I.son((dir_sons)i)) == int_cell) {
02338         Ison = I.son((dir_sons)i);
02339         value = Give_cell_variable(Ison)[number_cell_var];
02340 
02341         buffer_send_double[number] = value;
02342         // 0. Tet: WND, WNT, WST, EST 
02343         number++;
02344         buffer_send_double[number] = value;
02345         // 1. Tet: EST, WND, WST, ESD  
02346         number++;
02347         buffer_send_double[number] = value;
02348         // 2. Tet: WND, WSD, WST, ESD        
02349         number++;
02350         buffer_send_double[number] = value;
02351         // 3. Tet: EST, WND, ESD, END
02352         number++;
02353         buffer_send_double[number] = value;
02354         // 4. Tet: ENT, WNT, EST, END
02355         number++;
02356         buffer_send_double[number] = value;
02357         // 5. Tet: WNT, WND, EST, END
02358         number++;
02359       }
02360     }
02361   }
02362   return number;
02363 }

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