00001
00002
00003
00004
00005
00006 #ifndef AMROC_PROBLEM_H
00007 #define AMROC_PROBLEM_H
00008
00009 #include <cmath>
00010 #include "euler2.h"
00011 #include "ClpProblem.h"
00012 #undef NAUX
00013 #define NAUX 4
00014
00015 #define f_combl_read FORTRAN_NAME(cblread, CBLREAD)
00016
00017 extern "C" {
00018 void f_combl_read(INTEGER& NSph, DOUBLE xm[], DOUBLE rd[], INTEGER Np[]);
00019 }
00020
00021 #define OWN_FLAGGING
00022 #define OWN_GFMAMRSOLVER
00023 #include "ClpStdGFMProblem.h"
00024 #include "AMRGFMInterpolation.h"
00025
00026 class FlaggingSpecific :
00027 public AMRFlagging<VectorType,FixupType,FlagType,DIM> {
00028 typedef AMRFlagging<VectorType,FixupType,FlagType,DIM> base;
00029 public:
00030 FlaggingSpecific(base::solver_type& solver) : base(solver), _MaxLev(10000), _LastTime(10000.0) {
00031 base::AddCriterion(new ByValue<VectorType,FlagType,DIM>());
00032 base::AddCriterion(new ScaledGradient<VectorType,FlagType,DIM>());
00033 base::AddCriterion(new LimiterType<VectorType,FlagType,DIM>());
00034 base::AddCriterion(new AbsoluteError<VectorType,FixupType,FlagType,DIM>(solver));
00035 base::AddCriterion(new RelativeError<VectorType,FixupType,FlagType,DIM>(solver));
00036 #ifdef f_flgout
00037 base::AddCriterion(new F77ByValue<VectorType,FlagType,DIM>(f_flgout));
00038 base::AddCriterion(new F77ScaledGradient<VectorType,FlagType,DIM>(f_flgout));
00039 base::AddCriterion(new F77LimiterType<VectorType,FlagType,DIM>(f_flgout));
00040 base::AddCriterion(new F77AbsoluteError<VectorType,FixupType,FlagType,DIM>(solver,f_flgout));
00041 base::AddCriterion(new F77RelativeError<VectorType,FixupType,FlagType,DIM>(solver,f_flgout));
00042 #endif
00043 }
00044
00045 ~FlaggingSpecific() { DeleteAllCriterions(); }
00046
00047 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00048 base::register_at(Ctrl, prefix);
00049 RegisterAt(base::LocCtrl,"MaxLev",_MaxLev);
00050 RegisterAt(base::LocCtrl,"LastTime",_LastTime);
00051 }
00052 virtual void register_at(ControlDevice& Ctrl) { register_at(Ctrl, ""); }
00053
00054 virtual void SetFlags(const int Time, const int Level, double t, double dt) {
00055 if (t>_LastTime || Level<=_MaxLev)
00056 base::SetFlags(Time, Level, t,dt);
00057 else {
00058 forall (base::Flags(),Time,Level,c)
00059 base::Flags()(Time,Level,c) = GoodPoint;
00060 end_forall
00061 }
00062 }
00063
00064 protected:
00065 int _MaxLev;
00066 double _LastTime;
00067 };
00068
00069
00070 class SolverSpecific :
00071 public AMRGFMSolver<VectorType,FixupType,FlagType,DIM> {
00072 typedef VectorType::InternalDataType DataType;
00073 typedef AMRGFMSolver<VectorType,FixupType,FlagType,DIM> base;
00074 typedef AMRGFMInterpolation<VectorType,FixupType,FlagType,DIM> interpolation_type;
00075 typedef interpolation_type::point_type point_type;
00076 typedef F77GFMFileOutput<VectorType,FixupType,FlagType,DIM> output_type;
00077 public:
00078 SolverSpecific(IntegratorSpecific& integ,
00079 base::initial_condition_type& init,
00080 base::boundary_conditions_type& bc) : base(integ, init, bc), OutputDragEvery(1) {
00081 SetLevelTransfer(new F77LevelTransfer<VectorType,DIM>(f_prolong, f_restrict));
00082 #ifdef f_flgout
00083 SetFileOutput(new F77GFMFileOutput<VectorType,FixupType,FlagType,DIM>(*this,f_flgout));
00084 #else
00085 SetFileOutput(new GFMFileOutput<VectorType,FixupType,FlagType,DIM>(*this));
00086 #endif
00087 SetFixup(new FixupSpecific(integ));
00088 SetFlagging(new FlaggingSpecific(*this));
00089 AddGFM(new GhostFluidMethod<VectorType,DIM>(
00090 new F77GFMBoundary<VectorType,DIM>(f_ibndrfl,f_itrans),
00091 new F77GFMLevelSet<DataType,DIM>(f_lset)));
00092 _Interpolation = new interpolation_type(*this);
00093 }
00094
00095 ~SolverSpecific() {
00096 DeleteGFM(_GFM[0]);
00097 delete _Flagging;
00098 delete _Fixup;
00099 delete _Interpolation;
00100 }
00101
00102 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00103 base::register_at(Ctrl,prefix);
00104 RegisterAt(base::LocCtrl,"OutputDragEvery",OutputDragEvery);
00105 }
00106 virtual void register_at(ControlDevice& Ctrl) {
00107 base::register_at(Ctrl);
00108 }
00109
00110 virtual void SetupData() {
00111 base::SetupData();
00112 _Interpolation->SetupData(base::PGH(), base::NGhosts());
00113 }
00114
00115
00116
00117
00118 virtual double Tick(int VariableTimeStepping, const double dtv[],
00119 const double cflv[], int& Rejections) {
00120
00121 double cfl = base::Tick(VariableTimeStepping, dtv, cflv, Rejections);
00122
00123 int TimeZero = CurrentTime(base::GH(),0);
00124 TimeZero /= RefinedBy(base::GH(),MaxLevel(base::GH()));
00125 if (TimeZero % OutputDragEvery != 0) return cfl;
00126
00127 int me = MY_PROC;
00128 double pi = 4.0*std::atan(1.0);
00129
00130
00131 int NSph, Np[5];
00132 double xm[10], rd[5];
00133 point_type sum[5];
00134 f_combl_read(NSph,xm,rd,Np);
00135
00136
00137 for (register int l=0; l<=FineLevel(base::GH()); l++) {
00138 int Time = CurrentTime(base::GH(),l);
00139 int press_cnt = base::Dim()+4;
00140 ((output_type*) _FileOutput)->Transform(base::U(), base::Work(), Time, l,
00141 press_cnt, base::t[l]);
00142 }
00143
00144 for (int ns=0; ns<NSph; ns++) {
00145 int Npoints = 4*Np[ns];
00146 DataType* p = new DataType[Npoints];
00147 point_type* xc = new point_type[Npoints];
00148 point_type* normals = new point_type[Npoints];
00149 DataType* dist = (DataType*) 0;
00150 double dalpha = 0.5*pi/Np[ns];
00151
00152 register int n;
00153
00154
00155 for (n=0; n<Npoints; n++) {
00156 double alpha = dalpha*(n+0.5);
00157 xc[n](0) = xm[base::Dim()*ns ]+rd[ns]*std::cos(alpha);
00158 xc[n](1) = xm[base::Dim()*ns+1]+rd[ns]*std::sin(alpha);
00159 }
00160
00161
00162 _Interpolation->PointsValues(base::Work(),base::t[0],Npoints,xc,p);
00163 _Interpolation->ArrayCombine(VizServer,Npoints,p);
00164
00165
00166 _Interpolation->PointsGeom(base::GFM(0).Phi(),base::t[0],Npoints,xc,normals,dist);
00167 _Interpolation->ArrayCombine(VizServer,base::Dim()*Npoints,normals[0].data());
00168
00169
00170 if (me == VizServer) {
00171 sum[ns] = 0.0;
00172 double ds = 2.*pi*rd[ns]/Npoints;
00173 for (n=0; n<Npoints; n++)
00174 sum[ns] += p[n]*normals[n]*ds;
00175 }
00176
00177 delete [] p;
00178 delete [] xc;
00179 delete [] normals;
00180 }
00181
00182
00183 if (me == VizServer) {
00184 std::ofstream outfile;
00185 std::ostream* out;
00186 std::string fname = "drag.dat";
00187 outfile.open(fname.c_str(), std::ios::out | std::ios::app);
00188 out = new std::ostream(outfile.rdbuf());
00189 *out << base::t[0];
00190 for (int ns=0; ns<NSph; ns++)
00191 for (int d=0; d<base::Dim(); d++)
00192 *out << " " << sum[ns](d);
00193 *out << std::endl;
00194 outfile.close();
00195 delete out;
00196 }
00197
00198 return cfl;
00199 }
00200
00201 protected:
00202 int OutputDragEvery;
00203 interpolation_type* _Interpolation;