vtf-logo

AMRGridAccumulation.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 #ifndef AMROC_AMR_GRIDACCUMULATION_H
00004 #define AMROC_AMR_GRIDACCUMULATION_H
00005 
00013 #include <string>
00014 #include <ios>
00015 #include <fstream>
00016 #include <cstdio>
00017 #include <cmath>
00018 #include <unistd.h>
00019 #include <sys/stat.h>
00020 #include "SpecialOutput/AMRAccumulation.h"
00021 
00028 template <class DataType, int dim>
00029 class AMRGridAccumulation : public AMRAccumulation<DataType,dim> {
00030   typedef AMRAccumulation<DataType,dim> base;
00031 public:
00032   typedef typename base::grid_fct_type grid_fct_type;
00033   typedef typename base::grid_data_type grid_data_type;
00034 
00035   typedef void (*veloc_func_type) ( const DOUBLE v[] );
00036 
00037   AMRGridAccumulation() : base(), f_veloc(0) { InitVar();}  
00038   AMRGridAccumulation(veloc_func_type veloc) : base(), f_veloc(veloc) { InitVar();}  
00039 
00040   void InitVar() {  
00041     _AccGrid = (grid_data_type *) 0;
00042     for (int d=0; d<dim; d++) {
00043       accoffset[d] = 0.0;
00044       accvelocity[d] = 0.0;
00045       accminshape[d] = 0;
00046       accmaxshape[d] = 0;
00047     }
00048     CheckpointSave = 1;
00049     char Name[16];
00050     std::sprintf(Name,"acc");
00051     _CheckpointName = Name;
00052   }
00053 
00054   virtual ~AMRGridAccumulation() {
00055     if (_AccGrid) delete _AccGrid;
00056   }
00057 
00058   virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00059     base::register_at(Ctrl, prefix);
00060     char VariableName[32];
00061     for (int d=0; d<dim; d++) {
00062       std::sprintf(VariableName,"CellMin(%d)",d+1);
00063       RegisterAt(base::LocCtrl,VariableName,accminshape[d]);
00064       std::sprintf(VariableName,"CellMax(%d)",d+1);
00065       RegisterAt(base::LocCtrl,VariableName,accmaxshape[d]);
00066       std::sprintf(VariableName,"Offset(%d)",d+1);
00067       RegisterAt(base::LocCtrl,VariableName,accoffset[d]);
00068       std::sprintf(VariableName,"Velocity(%d)",d+1);
00069       RegisterAt(base::LocCtrl,VariableName,accvelocity[d]);
00070     }
00071     RegisterAt(base::LocCtrl,"CheckpointSave",CheckpointSave);
00072     RegisterAt(base::LocCtrl,"CheckpointName",_CheckpointName);
00073   }
00074   virtual void register_at(ControlDevice& Ctrl) { register_at(Ctrl, ""); }
00075 
00076   virtual void finish() { 
00077     if (_AccGrid) delete _AccGrid;
00078     _AccGrid = (grid_data_type *) 0;    
00079   }
00080 
00081   virtual void SetupData(GridHierarchy* gh, const int& ghosts) {
00082     base::_Hierarchy = gh;
00083     base::_Ghosts = ghosts;
00084 
00085     if (base::_AccLevel > TotalLevels(base::GH())-1) base::_AccLevel = TotalLevels(base::GH())-1;
00086     Coords accl = Coords(dim,accminshape)*base::GH().wholebbox().stepsize();
00087     Coords accu = Coords(dim,accmaxshape)*base::GH().wholebbox().stepsize();
00088     _AccBBox = BBox(accl,accu,base::GH().wholebbox().stepsize());
00089     if (base::_AccLevel<0) _AccBBox.setempty();
00090     if (_AccBBox.empty()) return;
00091     _AccBBox.refine(base::GH().refinedby(base::_AccLevel));
00092     _AccGrid = new grid_data_type(_AccBBox);
00093     if (f_veloc) {
00094       DataType veloc[dim]; 
00095       f_veloc(veloc);
00096       for (int d=0; d<dim; d++) 
00097         accvelocity[d] = veloc[d];
00098     }
00099   }
00100 
00101   virtual void Initialize() {
00102     GridInitializationOp(AccGrid());    
00103   }
00104 
00105   virtual void Restart() {
00106     int me = MY_PROC; 
00107     char fname[32];
00108     std::sprintf(fname,"%s.%d.cp",CheckpointName(),me);
00109     std::ifstream infile;
00110     infile.open(fname, std::ios::in);
00111     infile >> *_AccGrid;   
00112     infile.close();
00113   }
00114 
00115   virtual void Checkpointing() {
00116     int me = MY_PROC; 
00117     char fname[256];
00118     std::sprintf(fname,"%s.%d.cp",CheckpointName(),me);
00119     int len = std::strlen(fname);
00120     for (int i=0; i<len; i++) 
00121       if (fname[i]=='/') {
00122         fname[i]='\0';
00123         mkdir(fname, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
00124         fname[i]='/';
00125       }
00126     if (CheckpointSave) {
00127       char ofname[256];
00128       int last = -1;
00129       for (int i=0; i<len-1; i++) 
00130         if (fname[i]=='/') 
00131           last = i;
00132       if (last>=0) std::strncpy(ofname,fname,last+1);
00133       ofname[++last] = '.';
00134       std::strncpy(ofname+last+1,fname+last,len-last);
00135       ofname[len+1] = '\0';
00136       rename(fname,ofname);
00137     }
00138     std::ofstream outfile;
00139     outfile.open(fname, std::ios::out);
00140     outfile << *_AccGrid;   
00141     outfile.close();
00142   }
00143 
00144   virtual void Accumulate(grid_fct_type& u, const int& Time, 
00145                           const int& Level, const double& t) {
00146     if (AccBBox().empty()) return;
00147     Coords offset(dim,0);
00148     for (int d=0; d<dim; d++) 
00149       offset(d) = int((accoffset[d]+accvelocity[d]*t/DeltaX(base::GH(),d,base::AccLevel())))*
00150         AccBBox().stepsize(d);
00151 
00152     forall (u,Time,Level,c)
00153       base::AccumulateGrid(u(Time,Level,c),u.interiorbbox(Time,Level,c),
00154                            AccGrid(),AccBBox(),offset);
00155     end_forall
00156   }    
00157 
00158   void GridCombine(const int TargetNode) {
00159     if (AccBBox().empty()) return;
00160 #ifdef DAGH_NO_MPI
00161 #else
00162     if (comm_service::dce() && comm_service::proc_num() > 1) {  
00163       int num = comm_service::proc_num();
00164       MPI_Status status;
00165       int R;
00166       int size = sizeof(DataType)*AccBBox().size();
00167       int tag = 10001;
00168       if (MY_PROC!=TargetNode) {
00169         R = MPI_Send((void *)AccGrid().data(), size, MPI_BYTE, TargetNode, tag, comm_service::comm());
00170         if ( MPI_SUCCESS != R ) 
00171           comm_service::error_die( "GridCombine", "MPI_Send", R );
00172       }
00173       else {
00174         grid_data_type hGrid(AccBBox());
00175         for (int proc=0; proc<num; proc++) {
00176           if (proc==TargetNode) continue;
00177           R = MPI_Recv((void *)hGrid.data(), size, MPI_BYTE, proc, tag, comm_service::comm(), &status);
00178           if ( MPI_SUCCESS != R ) 
00179             comm_service::error_die( "GridCombine", "MPI_Recv", R );
00180           base::GridAccumulationOp(AccGrid(),hGrid);
00181         }
00182       }
00183     }
00184 #endif
00185   }
00186 
00187   inline grid_data_type& AccGrid() { return *_AccGrid;}
00188   inline const BBox& AccBBox() const { return _AccBBox;}
00189   inline BBox AccBBox() { return _AccBBox;}
00190   inline const char* CheckpointName() { return _CheckpointName.c_str(); }
00191 
00192   inline void SetFunc(veloc_func_type veloc) { f_veloc = veloc; }
00193   veloc_func_type GetFunc() const { return f_veloc; }
00194 
00195 
00196 protected:
00197   veloc_func_type f_veloc;
00198   grid_data_type *_AccGrid;
00199   BBox _AccBBox;
00200   std::string _CheckpointName;
00201   DataType accoffset[dim];
00202   DataType accvelocity[dim];
00203   int accminshape[dim];  
00204   int accmaxshape[dim];  
00205   int CheckpointSave;  
00206 }; 
00207  
00208 
00209 #endif

Generated on Fri Aug 24 13:00:46 2007 for AMROC Fluid-solver Framework - by  doxygen 1.4.7