00001
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 base::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