00001
00002
00003
00004
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
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
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
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;