vtf-logo

clawpack/applications/euler_chem/2d/ConvWedge/src/Problem.h

00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2003-2007 California Institute of Technology
00004 // David Hill, Ralf Deiterding
00005 
00006 #ifndef AMROC_PROBLEM_H
00007 #define AMROC_PROBLEM_H
00008 
00009 #include "eulerrhok2.h"
00010 
00011 #define NEQUATIONS  7
00012 #define NEQUSED     7
00013 #define NFIXUP      6
00014 #define NAUX        1
00015 
00016 #include "ClpProblem.h"
00017 
00018 #define f_track FORTRAN_NAME(track, TRACK)
00019 
00020 
00021 extern "C" {
00022   void f_track(const INTEGER &, const DOUBLE *, const DOUBLE *, DOUBLE *, INTEGER&,
00023                const DOUBLE&, const DOUBLE&, const DOUBLE&,
00024                 DOUBLE&, DOUBLE&, DOUBLE&, DOUBLE&, DOUBLE&, DOUBLE&); 
00025 }
00026 
00027 #define f_getangles FORTRAN_NAME(getangles, GETANGLES)
00028 
00029 extern "C" {
00030   void f_getangles(DOUBLE&, DOUBLE&, DOUBLE&); 
00031 }
00032 
00033 #define OWN_FLAGGING
00034 #define OWN_GFMAMRSOLVER
00035 #include "ClpStdGFMProblem.h"
00036 #include "AMRGFMInterpolation.h"
00037 #include "F77Interfaces/F77UpdateLevelTransfer.h"
00038 #include "SpecialOutput/AMRGridAccumulation.h"
00039 
00040 
00041 class FlaggingSpecific : 
00042   public AMRFlagging<VectorType,FixupType,FlagType,DIM> {
00043   typedef AMRFlagging<VectorType,FixupType,FlagType,DIM> base;
00044 public:
00045   FlaggingSpecific(solver_type& solver) : base(solver) {
00046       base::AddCriterion(new ScaledGradient<VectorType,FlagType,DIM>());
00047       base::AddCriterion(new LimiterType<VectorType,FlagType,DIM>());
00048       base::AddCriterion(new AbsoluteError<VectorType,FixupType,FlagType,DIM>(solver));
00049       base::AddCriterion(new RelativeError<VectorType,FixupType,FlagType,DIM>(solver));
00050       base::AddCriterion(new F77ScaledGradient<VectorType,FlagType,DIM>(f_flg));
00051       base::AddCriterion(new F77LimiterType<VectorType,FlagType,DIM>(f_flg));
00052       base::AddCriterion(new F77AbsoluteError<VectorType,FixupType,FlagType,DIM>(solver,f_flg));
00053       base::AddCriterion(new F77RelativeError<VectorType,FixupType,FlagType,DIM>(solver,f_flg));
00054     }
00055   ~FlaggingSpecific() { DeleteAllCriterions(); }
00056 };
00057 
00058 class SolverSpecific : 
00059   public AMRGFMSolver<VectorType,FixupType,FlagType,DIM> {
00060   typedef VectorType::InternalDataType DataType;
00061   typedef AMRGFMSolver<VectorType,FixupType,FlagType,DIM> base;
00062   typedef AMRGFMInterpolation<VectorType,FixupType,FlagType,DIM> interpolation_type;
00063   typedef interpolation_type::point_type point_type;
00064   typedef F77GFMFileOutput<VectorType,FixupType,FlagType,DIM> output_type;
00065 public:
00066   SolverSpecific(IntegratorSpecific& integ, 
00067                  base::initial_condition_type& init,
00068                  base::boundary_conditions_type& bc) : base(integ, init, bc) {
00069     SetLevelTransfer(new F77UpdateLevelTransfer<VectorType,DIM>(f_prolong, f_restrict, f_tupdate));
00070     SetFileOutput(new F77GFMFileOutput<VectorType,FixupType,FlagType,DIM>(*this,f_out)); 
00071     SetFixup(new FixupSpecific(integ));
00072     SetFlagging(new FlaggingSpecific(*this)); 
00073     AddGFM(new GhostFluidMethod<VectorType,DIM>(
00074               new F77GFMBoundary<VectorType,DIM>(f_ibndrfl,f_itrans),
00075               new F77GFMLevelSet<DataType,DIM>(f_lset)));
00076     _Interpolation = new interpolation_type(*this);
00077   }  
00078  
00079   ~SolverSpecific() {
00080     DeleteGFM(_GFM[0]);
00081     delete _LevelTransfer;
00082     delete _Flagging;
00083     delete _Fixup;
00084     delete _FileOutput;
00085     delete _Interpolation;
00086   }
00087 
00088   virtual void SetupData() {
00089     base::SetupData();
00090     _Interpolation->SetupData(base::PGH(), base::NGhosts());
00091   }
00092 
00093   //  use the Tick function to take pressure readings at
00094   //  locations that corespond to the transducers in the experiment
00095   virtual double Tick(int VariableTimeStepping, const double dtv[], const double cflv[],
00096                       int& Rejections) {
00097 
00098     double cfl = base::Tick(VariableTimeStepping, dtv, cflv, Rejections);
00099 
00100     int me = MY_PROC;
00101     
00102     double pi = 4.0*std::atan(1.0);
00103     // the wegde angles in radians
00104     // upper plate
00105     double alpha1; // = 13.9576*pi/180.;
00106     // lower plate
00107     double alpha2; // = 9.45*pi/180.;
00108     double radi; // hinge radius in meters = .25*0.254
00109     double ra; // hinge radius in inches
00110     // use fortran function that sees the cuser.i
00111     // to pull out the wedge angles and hinge radius
00112     f_getangles(alpha1,alpha2,radi);
00113     // convert to inches
00114     ra = radi/0.0254;
00115     // save trig results
00116     double c1 = std::cos(alpha1);
00117     double s1 = std::sin(alpha1);
00118     double c2 = std::cos(alpha2);
00119     double s2 = std::sin(alpha2);
00120     // get the finest grid spacing
00121     int finelevel = FineLevel(base::GH());
00122     double dx = DeltaX(base::GH(),0,finelevel);
00123     double dy = DeltaX(base::GH(),1,finelevel);
00124     double dl;
00125     dl = std::sqrt(dx*dx+dy*dy);
00126 
00127     // seven transducers bottom plate
00128     // and seven on top on wedge plate
00129     int Npoints = 14;
00130     // an array for the interpolated pressure
00131     DataType* p = new DataType[Npoints];
00132     // an array for the radial distance to transducers
00133     DataType* r = new DataType[Npoints];
00134     // an array for the locations of the transducers
00135     point_type* xc = new point_type[Npoints];
00136     
00137     // radial transducer locations in inches
00138     // measures from hinge outward.  for distance to
00139     // apex add 1/4 inch.
00140     //
00141 
00142 //  old distances - wedge was altered
00143 //     // load the bottom plate locations first
00144 //     r[0] = 9.5;      r[1] = 7.0;   r[2] = 4.25;
00145 //     r[3] = 2.75;     r[4] = 1.5;   r[5] = 0.6;
00146 //     r[6] = 0.25;
00147 //     //load the top plate locations from tip to apex
00148 //     r[7] = 10.72;    r[8] = 6.0;   r[9] = 3.5;
00149 //     r[10] = 2.0;     r[11] = 0.75; r[12] = 0.4 ;
00150  
00151 // new distances
00152     // load the bottom plate locations first
00153     r[0] = 9.3;      r[1] = 7.0;   r[2] = 4.25;
00154     r[3] = 2.75;     r[4] = 1.5;   r[5] = 0.6;
00155     r[6] = 0.25;
00156     //load the top plate locations from tip to apex
00157     r[7] = 9.3; 
00158     r[8] = 8.0;    r[9] = 6.0;   r[10] = 3.5;
00159     r[11] = 2.0;     r[12] = 0.75; r[13] = 0.5 ;
00160 
00161     // create the x/y locations of the transducers 
00162     // relative to apexin meters. 
00163     // offset locations by 'dl' into fluid so we don't 
00164     // use ghost values when interpolating for the pressure
00165     //
00166     //bottom plate
00167     register int n ;
00168     for(n=0; n<=6; n++) {
00169       xc[n](0) =  -dl*s2-0.0254*c2*(r[n]+ra);
00170       xc[n](1) = dl*c2-0.0254*s2*(r[n]+ra);
00171     }
00172     //top plate
00173      for(n=7; n<=13; n++) {
00174       xc[n](0) =   -dl*s1 -0.0254*c1*(r[n]+ra);
00175       xc[n](1) = -dl*c1+0.0254*s1*(r[n]+ra);
00176     }
00177 
00178     
00179     // get the pressure from the conserved vector of state
00180     for (register int l=0; l<=FineLevel(base::GH()); l++) {
00181       int Time = CurrentTime(base::GH(),l);
00182       int press_cnt = base::Dim()+4;
00183       ((output_type*) _FileOutput)->Transform(base::U(), base::Work(), Time, l, 
00184                                               press_cnt, base::t[l]);
00185     }
00186     // interpolate the pressure values
00187     _Interpolation->PointsValues(base::Work(),base::t[0],Npoints,xc,p);
00188     _Interpolation->ArrayCombine(VizServer,Npoints,p);
00189     
00190     // output the pressures to one file (transducer)
00191     if (me == VizServer) {
00192       std::ofstream outfile;
00193       std::ostream* out;
00194       std::string fname = "transducer.dat";
00195       outfile.open(fname.c_str(), std::ios::out | std::ios::app);
00196       out = new std::ostream(outfile.rdbuf());
00197       // output the time,location,pressure
00198       *out << base::t[0];
00199       for( n=0; n<Npoints; n++) {
00200         *out << " " <<p[n];
00201       }
00202       *out << std::endl;
00203       outfile.close();
00204       delete out;      
00205     }
00206     
00207     delete [] p;
00208     delete [] r; 
00209     delete [] xc;
00210  
00211     // now do the shock speed along the centerline.
00212     
00213 
00214     // the probe diameter is .0016meters
00215     double y0rdi = 0.0016;
00216     
00217     double pmax = 0.0;
00218     // double rpmaxloc = -1.0;
00219     double shk_pos = -0.12;
00220     double reflection_time = 0.0010;
00221     double aMa,aMb,aMc,aMd,aMe,aMm;
00222     double fmin = 20000, fmax = 200000.;
00223     double dfmin = 0.1;
00224 
00225     // get the number of points to be used
00226     Npoints = base::shape[0]*RefinedBy(base::GH(),finelevel);
00227     
00228     // set up the new arrays
00229     DataType* pc = new DataType[Npoints];
00230     DataType* rc = new DataType[Npoints];
00231     DataType* xrc = new DataType[Npoints];
00232     point_type* xcc = new point_type[Npoints];
00233   
00234     for (n=0; n<Npoints; n++) {
00235       rc[n] =  base::geom[0]+Npoints*dx -(n+0.5)*dx;
00236       //r[n] = lngth/Npoints*n;
00237       if((rc[n])>radi) {
00238         xcc[n](0) = radi-dl/2.;
00239       } else {
00240         xcc[n](0) = rc[n];
00241       }
00242       xcc[n](1) = y0rdi;
00243     }
00244     
00245         // get the pressure from the conserved vector of state
00246     for (register int l=0; l<=FineLevel(base::GH()); l++) {
00247       int Time = CurrentTime(base::GH(),l);
00248       int press_cnt = base::Dim()+4;
00249       ((output_type*) _FileOutput)->Transform(base::U(), base::Work(), Time, l, 
00250                                                 press_cnt, base::t[l]);
00251     }
00252 
00253     // interpolate the pressure values
00254     _Interpolation->PointsValues(base::Work(),base::t[0],Npoints,xcc,pc);
00255     _Interpolation->ArrayCombine(VizServer,Npoints,pc);
00256     
00257     if (me == VizServer) {
00258       int nc;
00259       for (n=0; n<Npoints; n++) 
00260         if (pc[n]>pmax) {
00261           pmax = pc[n];
00262           // rpmaxloc = x0rdi-r[n];
00263           // rpmaxloc = xcc[n](0);
00264         }
00265       if (base::t[0]<reflection_time) {
00266         dfmin = 0.0000000001;
00267         f_track(Npoints,pc,rc,xrc,nc,fmin,fmax,dfmin,aMa,aMb,aMc,aMd,aMe,aMm);
00268         // 0 is the point with the largest x-coordinate (see indexing above)
00269         // shk_pos = x0rdi-xr[0];
00270         shk_pos = xrc[0];
00271       }
00272       else {
00273         dfmin = 0.1;
00274         f_track(Npoints,pc,rc,xrc,nc,fmin,fmax,dfmin,aMa,aMb,aMc,aMd,aMe,aMm);
00275         // nc-1 is the point with the smallest x-coordinate (see indexing above)
00276         //shk_pos = x0rdi-xr[nc-1];
00277         shk_pos = xrc[nc-1];
00278       }
00279     }
00280   
00281       
00282     delete [] pc;
00283     delete [] rc;
00284     delete [] xrc;      
00285     delete [] xcc;
00286     
00287     
00288     // done extracting the shock locations along the ray
00289     // now output the locations to the file shk.dat
00290 
00291     if (me == VizServer) {
00292       std::ofstream outfile;
00293       std::ostream* out;
00294       std::string fname = "shk.dat";
00295       outfile.open(fname.c_str(), std::ios::out | std::ios::app);
00296       out = new std::ostream(outfile.rdbuf());
00297       // output the time and the max pressure
00298       *out << base::t[0] << " " << shk_pos << " " << pmax;
00299       // also output the shock location
00300       *out << " " << aMa << " " << aMb << " " << aMc;
00301       *out << " " << aMd << " " << aMe << " " << aMm;
00302       *out << std::endl;
00303       outfile.close();
00304       delete out;      
00305     }
00306 
00307 
00308 
00309     return cfl ;
00310          
00311   }
00312 protected:
00313   interpolation_type* _Interpolation;