vtf-logo

clawpack/applications/euler/3d/MovingSpheres/src/Problem.h

00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2003-2007 California Institute of Technology
00004 // Ralf Deiterding, ralf@amroc.net
00005 
00006 #ifndef AMROC_PROBLEM_H
00007 #define AMROC_PROBLEM_H
00008 
00009 #include <cmath>
00010 #include "euler3.h"
00011 #include "ClpProblem.h"
00012 
00013 #define f_combl_write FORTRAN_NAME(cblwrite, CBLWRITE)
00014 #define f_ipvel FORTRAN_NAME(ipvel, IPVEL)
00015 
00016 extern "C" {
00017   void f_combl_write(INTEGER& NSph, DOUBLE* xm, DOUBLE* vm, DOUBLE rd[]); 
00018   void f_ipvel(); 
00019 }
00020 
00021 #define OWN_GFMAMRSOLVER
00022 #include "ClpStdGFMProblem.h"
00023 #include "AMRGFMInterpolation.h"
00024 
00025 class SolverSpecific : 
00026   public AMRGFMSolver<VectorType,FixupType,FlagType,DIM> {
00027   typedef VectorType::InternalDataType DataType;
00028   typedef AMRGFMSolver<VectorType,FixupType,FlagType,DIM> base;
00029   typedef AMRGFMInterpolation<VectorType,FixupType,FlagType,DIM> interpolation_type;
00030   typedef interpolation_type::point_type point_type;
00031   typedef F77GFMFileOutput<VectorType,FixupType,FlagType,DIM> output_type;
00032 public:
00033   SolverSpecific(IntegratorSpecific& integ, 
00034                  base::initial_condition_type& init,
00035                  base::boundary_conditions_type& bc) : base(integ, init, bc), 
00036     CouplingLevel(0), NSph(0), Np(0), xm(0), vm(0), fm(0), cm(0), rd(0), tm(0) {
00037     SetLevelTransfer(new F77LevelTransfer<VectorType,DIM>(f_prolong, f_restrict));
00038 #ifdef f_flgout
00039     SetFileOutput(new F77GFMFileOutput<VectorType,FixupType,FlagType,DIM>(*this,f_flgout)); 
00040 #else   
00041     SetFileOutput(new GFMFileOutput<VectorType,FixupType,FlagType,DIM>(*this)); 
00042 #endif
00043     SetFixup(new FixupSpecific(integ));
00044     SetFlagging(new FlaggingSpecific(*this)); 
00045     AddGFM(new GhostFluidMethod<VectorType,DIM>(
00046               new F77GFMBoundary<VectorType,DIM>(f_ibndrfl,f_itrans,f_ipvel),
00047               new F77GFMLevelSet<DataType,DIM>(f_lset)));
00048     _Interpolation = new interpolation_type(*this);
00049     pi = 4.0*std::atan(1.0);
00050   }  
00051  
00052   ~SolverSpecific() {
00053     DeleteGFM(_GFM[0]);
00054     delete _Flagging;
00055     delete _Fixup;
00056     delete _Interpolation;
00057     if (Np) delete [] Np;
00058     if (xm) delete [] xm;
00059     if (vm) delete [] vm;
00060     if (fm) delete [] fm;
00061     if (cm) delete [] cm;
00062     if (rd) delete [] rd;
00063     if (tm) delete [] tm;
00064   }
00065 
00066   virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00067     base::register_at(Ctrl,prefix);
00068     RegisterAt(base::LocCtrl,"CouplingLevel",CouplingLevel);
00069   } 
00070   virtual void register_at(ControlDevice& Ctrl) {
00071     base::register_at(Ctrl);
00072   }
00073 
00074   virtual void SetupData() {
00075     base::SetupData();
00076     _Interpolation->SetupData(base::PGH(), base::NGhosts());
00077     if (CouplingLevel>base::MaxLev-1) 
00078       CouplingLevel=base::MaxLev-1;    
00079   }
00080 
00081   virtual void Initialize(double& t, double &dt) {
00082     std::ifstream ifs("spheres.dat", std::ios::in);
00083     ifs >> NSph;
00084     Np = new int[NSph];
00085     xm = new point_type[NSph];
00086     vm = new point_type[NSph];
00087     fm = new point_type[NSph];
00088     cm = new DataType[NSph];
00089     rd = new DataType[NSph];
00090     tm = new DataType[NSph];
00091     for (int n=0; n<NSph; n++) {
00092       ifs >> xm[n](0) >> xm[n](1) >> xm[n](2) >> rd[n] 
00093           >> vm[n](0) >> vm[n](1) >> vm[n](2) >> cm[n]
00094           >> tm[n] >> Np[n];
00095       cm[n] = cm[n]*pi*4./3.*rd[n]*rd[n]*rd[n];
00096     }
00097     f_combl_write(NSph,&xm[0](0),&vm[0](0),rd);
00098     ifs.close();
00099     base::Initialize(t,dt);
00100     OutputFiles(t);
00101   }
00102 
00103   virtual void Restart(double& t, double& dt) {
00104     std::ifstream ifs("spheres.cp", std::ios::in);
00105     ifs.read((char*)&NSph,sizeof(int));
00106     Np = new int[NSph];
00107     xm = new point_type[NSph];
00108     vm = new point_type[NSph];
00109     fm = new point_type[NSph];
00110     cm = new DataType[NSph];
00111     rd = new DataType[NSph];
00112     tm = new DataType[NSph];
00113     ifs.read((char*)Np,NSph*sizeof(int));    
00114     ifs.read((char*)xm,NSph*sizeof(point_type));
00115     ifs.read((char*)vm,NSph*sizeof(point_type));
00116     ifs.read((char*)fm,NSph*sizeof(point_type));
00117     ifs.read((char*)cm,NSph*sizeof(DataType));
00118     ifs.read((char*)rd,NSph*sizeof(DataType));
00119     ifs.read((char*)tm,NSph*sizeof(DataType));
00120     ifs.close();
00121     f_combl_write(NSph,&xm[0](0),&vm[0](0),rd);
00122     base::Restart(t,dt);
00123   }
00124   virtual void Checkpointing() {
00125     int me = MY_PROC; 
00126     if (me == VizServer) {
00127       std::ofstream ofs("spheres.cp", std::ios::out);
00128       ofs.write((char*)&NSph,sizeof(int));
00129       ofs.write((char*)Np,NSph*sizeof(int));    
00130       ofs.write((char*)xm,NSph*sizeof(point_type));
00131       ofs.write((char*)vm,NSph*sizeof(point_type));
00132       ofs.write((char*)fm,NSph*sizeof(point_type));
00133       ofs.write((char*)cm,NSph*sizeof(DataType));
00134       ofs.write((char*)rd,NSph*sizeof(DataType));
00135       ofs.write((char*)tm,NSph*sizeof(DataType));
00136       ofs.close();
00137     }
00138     base::Checkpointing();
00139   }
00140 
00141   virtual double IntegrateLevel(vec_grid_fct_type& u, const int Time, const int Level, 
00142                                 double t, double dt, bool DoFixup, double tc, 
00143                                 const int which) {
00144 
00145     double cfl = base::IntegrateLevel(u,Time,Level,t,dt,DoFixup,tc,which);
00146 #ifdef DEBUG_PRINT
00147     ( comm_service::log() << "*** base::IntegrateLevel() " << Level << " finished.\n" ).flush();
00148 #endif
00149 
00150     if (which==0 && Level==CouplingLevel) {
00151       point_type* fm_old = new point_type[NSph];
00152       for (int ns=0; ns<NSph; ns++) 
00153         fm_old[ns] = fm[ns];
00154       point_type a;
00155       CalculateForce();   
00156       for (int ns=0; ns<NSph; ns++) {
00157         if (t+dt<=tm[ns]) continue;
00158         a = 0.5/cm[ns]*(fm[ns]+fm_old[ns]);
00159         vm[ns] += a*dt;
00160         xm[ns] += vm[ns]*dt;
00161       }
00162       delete [] fm_old;
00163       f_combl_write(NSph,&xm[0](0),&vm[0](0),rd);
00164       OutputFiles(t+dt);
00165     }
00166 
00167     return cfl;
00168   }  
00169 
00170   void CalculateForce() {
00171     // Calculate pressure
00172     for (register int l=0; l<=FineLevel(base::GH()); l++) {
00173       int Time = CurrentTime(base::GH(),l);
00174       int press_cnt = base::Dim()+4;      
00175       ((output_type*) _FileOutput)->Transform(base::U(), base::Work(), Time, l, 
00176                                               press_cnt, base::t[l]);
00177     }
00178 
00179     double *force = new double[3*NSph];
00180     for (int ns=0; ns<NSph; ns++) {
00181       int Npoints = 8*Np[ns]*Np[ns];
00182       DataType* p = new DataType[Npoints];
00183       point_type* xc = new point_type[Npoints];
00184       point_type* normals = new point_type[Npoints];
00185       DataType* ds = new DataType[Npoints];
00186       DataType* dist = (DataType*) 0;    
00187       double dalpha = 0.5*pi/Np[ns];
00188       double dbeta = 0.5*pi/Np[ns];
00189       register int n = 0;
00190 
00191       // Calculate points on shere's surfaces
00192       for (register int l=0; l<4*Np[ns]; l++) {
00193         double alpha = dalpha*(l+0.5);
00194         for (register int m=0; m<2*Np[ns]; m++) {
00195           double beta = dalpha*(m+0.5);
00196           xc[n](0) = xm[ns](0)+rd[ns]*std::cos(alpha)*std::sin(beta); 
00197           xc[n](1) = xm[ns](1)+rd[ns]*std::sin(alpha)*std::sin(beta);
00198           xc[n](2) = xm[ns](2)+rd[ns]*std::cos(beta);
00199           ds[n] = pi*rd[ns]*rd[ns]*dbeta*std::sin(beta)/(2.*Np[ns]);
00200           n++;
00201         }
00202       }
00203     
00204       // Interpolate/extrapolate pressure values and normals
00205       _Interpolation->PointsValues(base::Work(),base::t[0],Npoints,xc,p);
00206       _Interpolation->PointsGeom(base::GFM(0).Phi(),base::t[0],Npoints,xc,normals,dist);
00207 
00208       force[3*ns  ] = 0.0; 
00209       force[3*ns+1] = 0.0; 
00210       force[3*ns+2] = 0.0; 
00211       for (n=0; n<Npoints; n++)
00212         if (p[n]>-1.e37) {
00213           force[3*ns  ] += p[n]*normals[n](0)*ds[n]; 
00214           force[3*ns+1] += p[n]*normals[n](1)*ds[n]; 
00215           force[3*ns+2] += p[n]*normals[n](2)*ds[n]; 
00216         }
00217 
00218       delete [] p;
00219       delete [] xc;
00220       delete [] normals;
00221       delete [] ds;
00222     }
00223 
00224 #ifdef DAGH_NO_MPI
00225     for (int ns=0; ns<NSph; ns++) {
00226       fm[ns](0) = force[3*ns  ];
00227       fm[ns](1) = force[3*ns+1];
00228       fm[ns](2) = force[3*ns+2];
00229     }
00230 #else
00231     int Nval = 3*NSph;
00232     double *global_force = new double[3*NSph];
00233     MPI_Allreduce(force, global_force, Nval, MPI_DOUBLE, MPI_SUM, base::Comm());
00234     for (int ns=0; ns<NSph; ns++) {
00235       fm[ns](0) = global_force[3*ns  ];
00236       fm[ns](1) = global_force[3*ns+1];
00237       fm[ns](2) = global_force[3*ns+2];
00238     }
00239 #endif
00240 
00241     delete [] force;
00242   }    
00243 
00244   void OutputFiles(double t) {
00245     int me = MY_PROC; 
00246     if (me == VizServer) {
00247       std::ofstream ofs1("positions.txt", std::ios::out | std::ios::app );
00248       ofs1 << t;
00249       for (int ns=0; ns<NSph; ns++)
00250         ofs1 << " " << xm[ns](0) << " " << xm[ns](1) << " " << xm[ns](2);  
00251       ofs1 << std::endl;
00252         ofs1.close();
00253 
00254       std::ofstream ofs2("forces.txt", std::ios::out | std::ios::app );
00255       ofs2 << t;
00256       for (int ns=0; ns<NSph; ns++)
00257         ofs2 << " " << fm[ns](0) << " " << fm[ns](1) << " " << fm[ns](2);  
00258       ofs2 << std::endl;
00259         ofs2.close();
00260 
00261       std::ofstream ofs3("velocities.txt", std::ios::out | std::ios::app );
00262       ofs3 << t;
00263       for (int ns=0; ns<NSph; ns++)
00264         ofs3 << " " << vm[ns](0) << " " << vm[ns](1) << " " << vm[ns](2);  
00265       ofs3 << std::endl;
00266         ofs3.close();
00267     }
00268   }    
00269 
00270 protected:
00271   interpolation_type* _Interpolation;
00272   int CouplingLevel, NSph, *Np;
00273   point_type *xm, *vm, *fm;
00274   DataType *cm, *rd, *tm, pi;