vtf-logo

clawpack/applications/euler/2d/Conical_Shocktube/src/Problem.h

00001 // -*- C++ -*-
00002 
00003 #ifndef AMROC_PROBLEM_H
00004 #define AMROC_PROBLEM_H
00005 
00006 #include "euler2.h"
00007 
00008 #undef  NAUX
00009 #define NAUX       1
00010 
00011 #include "ClpProblem.h"
00012 
00013 #define f_track FORTRAN_NAME(track, TRACK)
00014 
00015 extern "C" {
00016   void f_track(const INTEGER &, const DOUBLE *, const DOUBLE *, DOUBLE *, INTEGER&,
00017                const DOUBLE&, const DOUBLE&, const DOUBLE&,
00018                DOUBLE&, DOUBLE&, DOUBLE&, DOUBLE&, DOUBLE&, DOUBLE&); 
00019 }
00020 
00021 #define OWN_GFMAMRSOLVER
00022 #include "ClpStdGFMProblem.h"
00023 #include "AMRGFMInterpolation.h"
00024 #include "SpecialOutput/AMRGridAccumulation.h"
00025 
00026 class SolverSpecific : 
00027   public AMRGFMSolver<VectorType,FixupType,FlagType,DIM> {
00028   typedef VectorType::InternalDataType DataType;
00029   typedef AMRGFMSolver<VectorType,FixupType,FlagType,DIM> base;
00030   typedef AMRGFMInterpolation<VectorType,FixupType,FlagType,DIM> interpolation_type;
00031   typedef AMRGridAccumulation<DataType,DIM> accumulation_type;
00032   typedef interpolation_type::point_type point_type;
00033   typedef F77GFMFileOutput<VectorType,FixupType,FlagType,DIM> output_type;
00034 public:
00035   SolverSpecific(IntegratorSpecific& integ, 
00036                  base::initial_condition_type& init,
00037                  base::boundary_conditions_type& bc) : base(integ, init, bc) {
00038     SetLevelTransfer(new F77LevelTransfer<VectorType,DIM>(f_prolong, f_restrict));
00039 #ifdef f_flgout
00040     SetFileOutput(new F77GFMFileOutput<VectorType,FixupType,FlagType,DIM>(*this,f_flgout)); 
00041 #else   
00042     SetFileOutput(new GFMFileOutput<VectorType,FixupType,FlagType,DIM>(*this)); 
00043 #endif
00044     SetFixup(new FixupSpecific(integ));
00045     SetFlagging(new FlaggingSpecific(*this)); 
00046     AddGFM(new GhostFluidMethod<VectorType,DIM>(
00047               new F77GFMBoundary<VectorType,DIM>(f_ibndrfl,f_itrans),
00048               new F77GFMLevelSet<DataType,DIM>(f_lset)));
00049     _Interpolation = new interpolation_type(*this);
00050     _Accumulation = new accumulation_type();
00051     MaxType = 1;
00052   }  
00053  
00054   ~SolverSpecific() {
00055     DeleteGFM(_GFM[0]);
00056     delete _Flagging;
00057     delete _Fixup;
00058     delete _Interpolation;
00059     delete _Accumulation;
00060   }
00061 
00062   virtual void register_at(ControlDevice& Ctrl) { base::register_at(Ctrl); }
00063   virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00064     base::register_at(Ctrl, prefix);
00065     RegisterAt(base::LocCtrl,"MaxType",MaxType);
00066     _Accumulation->register_at(base::LocCtrl, prefix);
00067   }
00068 
00069   virtual void SetupData() {
00070     base::SetupData();
00071     _Interpolation->SetupData(base::PGH(), base::NGhosts());
00072     _Accumulation->SetupData(base::PGH(), base::NGhosts());
00073   }
00074 
00075   virtual void Initialize_(const double& dt_start) {
00076     base::Initialize_(dt_start);
00077     _Accumulation->Initialize();
00078   }
00079 
00080   virtual void Output() {
00081     int Time = CurrentTime(base::GH(),0);
00082     if (Time == base::LastOutputTime()) return;
00083     _Accumulation->GridCombine(VizServer);
00084     int me = MY_PROC; 
00085     if (me == VizServer) {
00086       int Level = _Accumulation->AccLevel();
00087       base::FileOutput_().WriteOut(_Accumulation->AccGrid(),_Accumulation->AccName(),
00088                                    Time,Level,base::t[0]);
00089     }
00090     base::Output();
00091   }
00092 
00093   virtual void Checkpointing_(const char* CheckpointFile) {
00094     base::Checkpointing_(CheckpointFile);
00095     _Accumulation->Checkpointing();
00096   }
00097 
00098   virtual bool Restart_(const char* CheckpointFile) {
00099     bool ret = base::Restart_(CheckpointFile);
00100     if (ret) _Accumulation->Restart();
00101     return ret;
00102   }
00103 
00104   virtual void AdvanceLevel(const int Level, int RegridEvery, bool RegridDone, 
00105                             bool ShadowAllowed, bool DoFixup,
00106                             bool RecomposeBaseLev, bool RecomposeHighLev) {
00107 
00108     base::AdvanceLevel(Level,RegridEvery,RegridDone,ShadowAllowed,
00109                        DoFixup,RecomposeBaseLev,RecomposeHighLev);
00110 
00111     int Time = CurrentTime(base::GH(),Level);
00112     if (MaxType) {
00113       AdaptiveBoundaryUpdate(base::U(),Time,Level);
00114       Sync(base::U(),Time,Level);
00115       ExternalBoundaryUpdate(base::U(),Time,Level);
00116       
00117       int irho = 1;
00118       int iu   = NEQUSED-DIM-2;
00119       int iv   = NEQUSED-DIM-1;
00120       int TStep = TimeStep(base::U(),Level);
00121       ((output_type*) base::_FileOutput)->Transform(base::U(), base::Work(), Time+TStep, 
00122                                                     Level, irho, base::t[Level]);
00123       forall (base::U(),Time,Level,c)
00124         Coords ss(base::U()(Time,Level,c).bbox().stepsize());
00125         BBox bbi(base::U().interiorbbox(Time,Level,c));
00126         BeginFastIndex2(U, base::U()(Time,Level,c).bbox(), 
00127                         base::U()(Time,Level,c).data(), VectorType);
00128         BeginFastIndex2(Work, Work()(Time,Level,c).bbox(), 
00129                         Work()(Time,Level,c).data(), DataType);
00130         BeginFastIndex2(WorkN, Work()(Time+TStep,Level,c).bbox(), 
00131                         Work()(Time+TStep,Level,c).data(), DataType);
00132         DataType uy, vx;
00133         DCoords dx = base::GH().worldStep(ss);
00134         for_2 (i, j, bbi, ss)
00135           vx = (FastIndex2(U,i+ss(0),j)(iv)/FastIndex2(WorkN,i+ss(0),j)-
00136                 FastIndex2(U,i-ss(0),j)(iv)/FastIndex2(WorkN,i-ss(0),j))/(2.0*dx(0));
00137           uy = (FastIndex2(U,i,j+ss(1))(iu)/FastIndex2(WorkN,i,j+ss(1))-
00138                 FastIndex2(U,i,j-ss(1))(iu)/FastIndex2(WorkN,i,j-ss(1)))/(2.0*dx(1));
00139           FastIndex2(Work,i,j) = std::fabs(vx-uy);
00140         end_for
00141         EndFastIndex2(U);      
00142         EndFastIndex2(Work);      
00143         EndFastIndex2(WorkN);      
00144       end_forall
00145     }
00146     else {
00147       int ipress = base::Dim()+4;      
00148       ((output_type*) base::_FileOutput)->Transform(base::U(), base::Work(), Time, Level, 
00149                                                     ipress, base::t[Level]);
00150     }
00151   
00152     _Accumulation->Accumulate(base::Work(), Time,  Level, base::t[Level]);
00153   }
00154 
00155   virtual double Tick(int VariableTimeStepping, const double dtv[], const double cflv[],
00156                       int& Rejections) {
00157 
00158     double cfl = base::Tick(VariableTimeStepping, dtv, cflv, Rejections);
00159 
00160     int me = MY_PROC;
00161     // int Npoints=2000;
00162     int Npoints; 
00163     int finelevel = FineLevel(base::GH());
00164     Npoints = base::shape[0]*RefinedBy(base::GH(),finelevel);
00165     double dx = DeltaX(base::GH(),0,finelevel);
00166     //double dy = DeltaX(base::GH(),1,finelevel);
00167 
00168     double pmax = 0.0;
00169     // double rpmaxloc = -1.0;
00170     double shk_pos = -0.12;
00171     double aMa,aMb,aMc,aMd,aMe,aMm;
00172     double fmin = 150.00, fmax = 20000.;
00173     double dfmin = 0.1;
00174     double x0rdi = 0.424779, y0rdi;
00175     // the probe diameter is .0016meters
00176     y0rdi = 0.0016;
00177     // y0rdi = .5*dy;
00178     double reflection_time = 0.00021;
00179     // double lngth = 0.424779+0.12;
00180     // Npoints = int(lngth/dx);
00181  
00182     DataType* p = new DataType[Npoints];
00183     DataType* r = new DataType[Npoints];
00184     DataType* xr = new DataType[Npoints];
00185     point_type* xc = new point_type[Npoints];
00186     register int n;
00187 
00188     for (n=0; n<Npoints; n++) {
00189       r[n] =  base::geom[0]+Npoints*dx -(n+0.5)*dx;
00190       //r[n] = lngth/Npoints*n;
00191       if((r[n])>x0rdi) {
00192         xc[n](0) = x0rdi;
00193       } else {
00194         xc[n](0) = r[n];
00195       }
00196       xc[n](1) = y0rdi;
00197     }
00198 
00199     // get the pressure from the conserved vector of state
00200     for (register int l=0; l<=FineLevel(base::GH()); l++) {
00201       int Time = CurrentTime(base::GH(),l);
00202       int press_cnt = base::Dim()+4;
00203       ((output_type*) _FileOutput)->Transform(base::U(), base::Work(), Time, l, 
00204                                                 press_cnt, base::t[l]);
00205     }
00206     // interpolate the pressure values
00207     _Interpolation->PointsValues(base::Work(),base::t[0],Npoints,xc,p);
00208     _Interpolation->ArrayCombine(VizServer,Npoints,p);
00209     
00210     if (me == VizServer) {
00211       int nc;
00212       for (n=0; n<Npoints; n++) 
00213         if (p[n]>pmax) {
00214           pmax = p[n];
00215           // rpmaxloc = x0rdi-r[n];
00216           // rpmaxloc = xc[n](0);
00217         }
00218       if (base::t[0]<reflection_time) {
00219         dfmin = 0.0000000001;
00220         f_track(Npoints,p,r,xr,nc,fmin,fmax,dfmin,aMa,aMb,aMc,aMd,aMe,aMm);
00221         // 0 is the point with the largest x-coordinate (see indexing above)
00222         // shk_pos = x0rdi-xr[0];
00223         shk_pos = xr[0];
00224       }
00225       else {
00226         dfmin = 0.1;
00227         f_track(Npoints,p,r,xr,nc,fmin,fmax,dfmin,aMa,aMb,aMc,aMd,aMe,aMm);
00228         // nc-1 is the point with the smallest x-coordinate (see indexing above)
00229         //shk_pos = x0rdi-xr[nc-1];
00230         shk_pos = xr[nc-1];
00231       }
00232     }
00233       
00234     delete [] p;
00235     delete [] r;
00236     delete [] xr;       
00237     delete [] xc;
00238   
00239     
00240     // done extracting the shock locations along the ray
00241     // now output the locations to the file shk.dat
00242 
00243     if (me == VizServer) {
00244       std::ofstream outfile;
00245       std::ostream* out;
00246       std::string fname = "shk.dat";
00247       outfile.open(fname.c_str(), std::ios::out | std::ios::app);
00248       out = new std::ostream(outfile.rdbuf());
00249       // output the time and the max pressure
00250       *out << base::t[0] << " " << shk_pos << " " << pmax;
00251       // also output the shock location
00252       *out << " " << aMa << " " << aMb << " " << aMc;
00253       *out << " " << aMd << " " << aMe << " " << aMm;
00254       *out << std::endl;
00255       outfile.close();
00256       delete out;      
00257     }
00258     return cfl;
00259   } 
00260 
00261 protected:
00262   int MaxType;
00263   interpolation_type* _Interpolation; 
00264   accumulation_type* _Accumulation;