src/expde/grid/pridxpa.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 
00077 
00079 // 2. finest level
00081 
00082 
00083 
00084 
00085 
00086 void Grid_base::Print_Variable_OpenDx_parallel(ofstream *Datei, 
00087                                                int number_var) {
00088   int number_cells, number, ebene;
00089   int number_points;
00090   int n_proc,i;
00091 
00092   int *number_cells_process;
00093   int *number_points_process;
00094   int total_number_cells;
00095   int total_number_points;
00096 
00097   MPI_Status status;
00098 
00099   D3vector loc;
00100   int num, start_num, start_poi;
00101 
00102   int max_number_cells;
00103   int max_number_points;
00104 
00105   int*    buffer_send_int;
00106   double* buffer_send_double;
00107 
00108   int*    buffer_rec_int;
00109   double* buffer_rec_double;
00110 
00111   Index3D ind;
00112   int number_of_vars;   // wird in der Kopfzeile eingesetzt
00113 
00114   number_of_vars=1;
00115 
00116   MPI_Barrier(comm);
00117 
00118   if(Is_storage_initialized()==false) { 
00119     cout << " \n Fehler in Print_Variable_OpenDx! Initialisierung fehlt! "
00120          << endl;
00121     return;
00122   }
00123   if(Give_max_num_var() <= number_var) {
00124     cout << " \n Fehler in Print_Variable_OPENDX! number_var zu gross! " 
00125          << endl;
00126   }
00127   else { 
00128     // Teil 0: Write information
00129     *Datei << "# File created by ExPDE " << endl;
00130     *Datei << "# dx file format for OpenDx " << endl;
00131     *Datei << "# scalar value " << endl;
00132 
00133     
00134     // Teil 1: Anzahl der Zellen zaehlen
00135     // Teil 1.1: Innerer Zellen
00136     ind = my_index;
00137     number_cells = Recursion_Count_Cells(ind);
00138     // Teil 1.2: Randzellen
00139     iterate_hash2 {
00140       if(bocell->Give_Index()<<my_index) 
00141         number_cells = opendx_bo_cell(bocell,Datei,false,number_cells);
00142     }
00143     // Teil 1.3: Anzahl der Punkte
00144     // a) innen und randnah
00145     number_points=0;
00146     iterate_hash1 {
00147 
00148       /*
00149 if(point1->ind == Index3D(9,9,2)) {
00150   cout << " Hi: sort: " 
00151        << " \n  my rank: " << my_rank 
00152        << " \n  typ: " << point1->typ
00153        << " \n  responsible? " << (point1->Give_Index()<<my_index)
00154        << endl;
00155   point1->ind.Print();
00156   cout << endl;
00157   my_index.Print();
00158   cout << endl;
00159 }
00160       */
00161 
00162 
00163       if((point1->typ >= interior || point1->typ==parallel_p) && 
00164          point1->Give_Index()<<my_index && 
00165          point1->finest_level == max_level) { 
00166         point1->nummer = number_points; 
00167         number_points++; 
00168       }
00169       else point1->nummer = -1;
00170     }
00171     // b) Randpunkte
00172     iterate_hash3 {
00173       bo2point->Set_number_avs(number_points);
00174       ++number_points;
00175     }
00176     // c) Randzellfreiheitsgrad
00177     iterate_hash2 {
00178       if(bocell->Give_Index()<<my_index) {
00179         if(bocell->Exists_bocellpoint()) {
00180           bocell->Set_number_avs(number_points);
00181           number_points++;
00182         }
00183       }
00184     }
00185 
00186     // Teil 1.5: gather data 
00187     n_proc = give_number_of_processes();  
00188     number_cells_process = new int[n_proc];  
00189     number_points_process = new int[n_proc];  
00190     MPI_Gather(&number_points,1,MPI_INT,number_points_process,1,MPI_INT,  
00191                0,comm);  
00192     MPI_Gather(&number_cells,1,MPI_INT,number_cells_process,1,MPI_INT,  
00193                0,comm);  
00194     total_number_points =0;  
00195     total_number_cells =0;  
00196     max_number_points =0;  
00197     max_number_cells =0;  
00198     for(i=0;i<n_proc;++i) {  
00199       total_number_points = total_number_points + number_points_process[i];  
00200       total_number_cells  = total_number_cells  + number_cells_process[i];  
00201     }  
00202     for(i=0;i<n_proc;++i) {  
00203       if(number_points_process[i] > max_number_points)  
00204         max_number_points = number_points_process[i];  
00205       if(number_cells_process[i] > max_number_cells)  
00206         max_number_cells = number_cells_process[i];  
00207     }  
00208     // Teil 1.7: make buffer
00209     if(my_rank==0) {  
00210       buffer_rec_int    = new int[max_number_cells  * 4];  
00211       buffer_rec_double = new double[max_number_points * 3];  
00212     }  
00213     buffer_send_int    = new int[number_cells  * 4];  
00214     buffer_send_double = new double[number_points * 3];  
00215 
00216     // Teil 1.8: make buffer 
00217     if(my_rank==0) {  
00218       *Datei << "object 1 class array type float rank 1 shape 3 items "
00219              << total_number_points << " data follows" << endl;
00220     }
00221 
00222 
00223     // Teil 2: Koordinaten der Punkte eingeben 
00224     // a) set values in buffer 
00225     if(I_am_active()) {  
00226       // i) alle inneren Punkte  
00227       iterate_hash1 {  
00228         if(point1->nummer != -1) { 
00229           loc = transform_coord(point1->ind.coordinate());  
00230           buffer_send_double[point1->nummer*3]   = loc.x;  
00231           buffer_send_double[point1->nummer*3+1] = loc.y;  
00232           buffer_send_double[point1->nummer*3+2] = loc.z;  
00233         }  
00234       }  
00235       // ii) alle Randpunkte 
00236       iterate_hash3 {  
00237         loc = bo2point->transform_coord(Give_A(),H_mesh());  
00238         buffer_send_double[bo2point->nummer*3]   = loc.x;  
00239         buffer_send_double[bo2point->nummer*3+1] = loc.y;  
00240         buffer_send_double[bo2point->nummer*3+2] = loc.z;  
00241       }  
00242       // iii) alle Randzellfreiheitsgrad  
00243       iterate_hash2 {  
00244         if(bocell->Give_Index()<<my_index) {  
00245           if(bocell->Exists_bocellpoint()) {  
00246             loc =  transform_coord(bocell->ind.coordinate()) +   
00247               bocell->Local_coord_bocellpoint();  
00248             buffer_send_double[bocell->Number_avs()*3]   = loc.x;  
00249             buffer_send_double[bocell->Number_avs()*3+1] = loc.y;  
00250             buffer_send_double[bocell->Number_avs()*3+2] = loc.z;  
00251           }  
00252         }  
00253       }  
00254     }  
00255     // b) send 
00256     if(my_rank!=0) {  
00257       MPI_Send(buffer_send_double,number_points * 3,  
00258                MPI_DOUBLE,0,50,comm);  
00259     }  
00260     else {  
00261       start_num=0;  
00262       for(i=0;i<n_proc;++i) {  
00263         // c) receive  
00264         if(i!=0) {  
00265           MPI_Recv(buffer_rec_double,number_points_process[i] * 3,  
00266                    MPI_DOUBLE,i,50,comm,&status);  
00267         }  
00268         else {  
00269           for(num=0;num<number_points_process[i];++num) {  
00270             buffer_rec_double[num*3]   = buffer_send_double[num*3];  
00271             buffer_rec_double[num*3+1] = buffer_send_double[num*3+1];  
00272             buffer_rec_double[num*3+2] = buffer_send_double[num*3+2];  
00273           }  
00274         }  
00275         // d) print in file  
00276         for(num=0;num<number_points_process[i];++num) {  
00277           loc.x =  buffer_rec_double[num*3];  
00278           loc.y =  buffer_rec_double[num*3+1];  
00279           loc.z =  buffer_rec_double[num*3+2];  
00280           *Datei << " " << loc.x    
00281                  << " " << loc.y    
00282                  << " " << loc.z  
00283                  << "\n";  
00284         }  
00285         start_num = start_num + number_points_process[i];  
00286       }  
00287     }  
00288 
00289 
00290     // Teil 3: Zellen ausgeben 
00291     // Teil 3.0: Header file for tetrahedra:
00292     if(my_rank==0) {  
00293       *Datei << "object 2 class array type int rank 1 shape 4 items "
00294              << total_number_cells << " data follows" << endl;
00295     }
00296 
00297     // a) set values in buffer 
00298     if(I_am_active()) { 
00299       // Teil 3.1: Innere Zellen ausgeben 
00300       ind = my_index;  
00301       number=Recursion_Cells_AVS_parallel(ind,0,buffer_send_int);  
00302       // Teil 3.2: Randzellen 
00303       iterate_hash2 {  
00304         if(bocell->Give_Index()<<my_index) {
00305           number = avs_bo_cell_parallel(bocell,number,buffer_send_int);  
00306         }
00307       }
00308     }
00309     // b) send 
00310     if(my_rank!=0) {   
00311       MPI_Send(buffer_send_int,number_cells * 4,  
00312                MPI_INT,0,51,comm);  
00313     }  
00314     else {  
00315       start_num=0;  
00316       start_poi=0;  
00317       for(i=0;i<n_proc;++i) {  
00318         // c) receive   
00319         if(i!=0) {  
00320           MPI_Recv(buffer_rec_int,number_cells_process[i] * 4,  
00321                    MPI_INT,i,51,comm,&status);  
00322         }  
00323         else {  
00324           for(num=0;num<number_cells_process[i];++num) {  
00325             buffer_rec_int[num*4]   = buffer_send_int[num*4];   
00326             buffer_rec_int[num*4+1] = buffer_send_int[num*4+1];   
00327             buffer_rec_int[num*4+2] = buffer_send_int[num*4+2];   
00328             buffer_rec_int[num*4+3] = buffer_send_int[num*4+3];   
00329           }  
00330         }  
00331         // d) print in file  
00332         if(i<n_proc) {  
00333           for(num=0;num<number_cells_process[i];++num) {  
00334             *Datei << start_poi + buffer_rec_int[num*4]   
00335                    << " " << start_poi + buffer_rec_int[num*4+1]   
00336                    << " " << start_poi + buffer_rec_int[num*4+2]   
00337                    << " " << start_poi + buffer_rec_int[num*4+3]   
00338                    << "\n";  
00339           }  
00340         }  
00341         start_num = start_num + number_cells_process[i];  
00342         start_poi = start_poi + number_points_process[i];  
00343       }  
00344     }  
00345     if(my_rank==0) {
00346       *Datei << "attribute " << '"' << "element type" 
00347              << '"' << " string " << '"' << "tetrahedra" << '"' << "" << endl;
00348       *Datei << "attribute " << '"' << "ref" << '"' 
00349              << " string " << '"' << "positions" << '"' << "" << endl;
00350       
00351       // Teil 4: Header file for one variable:
00352       *Datei << "object 3 class array type float rank 0 items "
00353              << total_number_points << " data follows" << endl;
00354     }
00355 
00356     if(I_am_active()) {
00357     // Teil 2: Werte der Punkte ausgeben
00358     // a) set values in buffer
00359     // i) alle inneren Punkte
00360     iterate_hash1 {
00361       if(point1->nummer != -1) {
00362         ebene = Give_finest_level(point1->ind);
00363         buffer_send_double[point1->nummer] = 
00364           Give_variable(point1->ind,ebene)[number_var];
00365 
00366 
00367         /*      
00368 if(Give_variable(point1->ind,ebene)[number_var] < 0.5) {
00369   if(point1->ind == Index3D(2,4,2)) {
00370     cout << " Hi: dx: " 
00371          <<  Give_variable(point1->ind,ebene)[number_var] 
00372          << " my rank: " << my_rank 
00373          << endl;
00374     point1->ind.Print();
00375     cout << endl;
00376 
00377     buffer_send_double[point1->nummer] = 666;
00378   }
00379 }
00380         */
00381         
00382 
00383 
00384 
00385       }
00386     }
00387     // ii) alle Randpunkte
00388     iterate_hash3 {
00389       buffer_send_double[bo2point->nummer] = 
00390         Give_variable(bo2point->ind,bo2point->direction)[number_var];
00391     }
00392     // iii alle Randzellfreiheitsgrad
00393     iterate_hash2 {
00394       if(bocell->Give_Index()<<my_index) {
00395         if(bocell->Exists_bocellpoint()) {
00396           buffer_send_double[bocell->Number_avs()] =
00397             bocell->Give_var()[number_var];
00398         }
00399       }
00400     }
00401     }
00402 
00403     // b) send
00404     if(my_rank!=0) {
00405       MPI_Send(buffer_send_double,number_points,
00406                MPI_DOUBLE,0,52,comm);
00407     }
00408     else {
00409       start_num=0;
00410       for(i=0;i<n_proc;++i) {
00411         // c) receive
00412         if(i!=0) {
00413           MPI_Recv(buffer_rec_double,number_points_process[i],
00414                    MPI_DOUBLE,i,52,comm,&status);       
00415         }
00416         else {
00417           for(num=0;num<number_points_process[i];++num) {
00418             buffer_rec_double[num] = buffer_send_double[num];
00419           }
00420         }
00421         // d) print in file
00422         if(i<n_proc) {
00423           for(num=0;num<number_points_process[i];++num) {
00424             *Datei << " " << buffer_rec_double[num]
00425                    << "\n";
00426           }
00427         }
00428         start_num = start_num + number_points_process[i];
00429       }
00430     }
00431 
00432 
00433     // Teil 7: end remarks
00434     if(my_rank==0) {
00435       *Datei << "object " << '"' 
00436              << "irregular positions irregular connections"
00437              << '"' << " class field" << 
00438         endl;
00439       *Datei << "component " << '"' << "positions" << '"' << " value 1" << endl;
00440       *Datei << "component " 
00441              << '"' << "connections" << '"' << " value 2" << endl;
00442       *Datei << "component " << '"' << "data" << '"' << " value 3" << endl;
00443       *Datei << "end" << endl; 
00444     }      
00445 
00446     // Teil 8:
00447     if(I_am_active()) {
00448        delete(number_cells_process);
00449        delete(number_points_process);
00450     }
00451     delete(buffer_send_int);
00452     delete(buffer_send_double);
00453     if(my_rank==0) {
00454       delete(buffer_rec_int);
00455       delete(buffer_rec_double);
00456     }
00457 
00458     
00459   }
00460 
00461 
00462 
00463   MPI_Barrier(comm);
00464 }
00465 
00466 

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