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
00013 #define f_combl_read FORTRAN_NAME(cblread, CBLREAD)
00014 #define f_combl_write FORTRAN_NAME(cblwrite, CBLWRITE)
00015 #define f_ipvel FORTRAN_NAME(ipvel, IPVEL)
00016
00017 extern "C" {
00018 void f_combl_read(INTEGER& NSph, DOUBLE xm[], DOUBLE vm[], DOUBLE cm[], DOUBLE rd[], INTEGER Np[]);
00019 void f_combl_write(INTEGER& NSph, DOUBLE xm[], DOUBLE vm[], DOUBLE cm[], DOUBLE rd[], INTEGER Np[]);
00020 void f_ipvel();
00021 }
00022
00023 #define OWN_GFMAMRSOLVER
00024 #include "ClpStdGFMProblem.h"
00025 #include "AMRGFMInterpolation.h"
00026
00027 class SolverSpecific :
00028 public AMRGFMSolver<VectorType,FixupType,FlagType,DIM> {
00029 typedef VectorType::InternalDataType DataType;
00030 typedef AMRGFMSolver<VectorType,FixupType,FlagType,DIM> base;
00031 typedef AMRGFMInterpolation<VectorType,FixupType,FlagType,DIM> interpolation_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,f_ipvel),
00048 new F77GFMLevelSet<DataType,DIM>(f_lset)));
00049 _Interpolation = new interpolation_type(*this);
00050 }
00051
00052 ~SolverSpecific() {
00053 DeleteGFM(_GFM[0]);
00054 delete _Flagging;
00055 delete _Fixup;
00056 delete _Interpolation;
00057 }
00058
00059 virtual void SetupData() {
00060 base::SetupData();
00061 _Interpolation->SetupData(base::PGH(), base::NGhosts());
00062 }
00063
00064
00065
00066
00067 virtual double Tick(int VariableTimeStepping, const double dtv[],
00068 const double cflv[], int& Rejections) {
00069
00070 int me = MY_PROC;
00071
00072 point_type force_old[5];
00073 double t_old = base::t[0];
00074 CalculateForce(force_old);
00075
00076 double cfl = base::Tick(VariableTimeStepping, dtv, cflv, Rejections);
00077
00078 point_type a, force_new[5];
00079 double dt = base::t[0]-t_old;
00080 CalculateForce(force_new);
00081
00082 int NSph, Np[5];
00083 double xm[10], vm[10], cm[5], rd[5];
00084 f_combl_read(NSph,xm,vm,cm,rd,Np);
00085
00086 for (int ns=0; ns<NSph; ns++) {
00087 a = 0.5/cm[ns]*(force_old[ns]+force_new[ns]);
00088 vm[base::Dim()*ns ] += a(0)*dt;
00089 vm[base::Dim()*ns+1] += a(1)*dt;
00090 xm[base::Dim()*ns ] += vm[base::Dim()*ns ]*dt;
00091 xm[base::Dim()*ns+1] += vm[base::Dim()*ns+1]*dt;
00092 }
00093
00094 f_combl_write(NSph,xm,vm,cm,rd,Np);
00095
00096
00097 if (me == VizServer) {
00098 std::ofstream outfile;
00099 std::ostream* out;
00100 std::string fname = "drag.dat";
00101 outfile.open(fname.c_str(), std::ios::out | std::ios::app);
00102 out = new std::ostream(outfile.rdbuf());
00103 *out << base::t[0];
00104 for (int ns=0; ns<NSph; ns++) {
00105 int d;
00106 for (d=0; d<base::Dim(); d++)
00107 *out << " " << force_new[ns](d);
00108 for (d=0; d<base::Dim(); d++)
00109 *out << " " << xm[base::Dim()*ns+d];
00110 for (d=0; d<base::Dim(); d++)
00111 *out << " " << vm[base::Dim()*ns+d];
00112 }
00113 *out << std::endl;
00114 outfile.close();
00115 delete out;
00116 }
00117
00118 return cfl;
00119 }
00120
00121
00122 void CalculateForce(point_type* sum) {
00123 int me = MY_PROC;
00124
00125 double pi = 4.0*std::atan(1.0);
00126
00127
00128 int NSph, Np[5];
00129 double xm[10], vm[10], cm[5], rd[5];
00130 f_combl_read(NSph,xm,vm,cm,rd,Np);
00131
00132
00133 for (register int l=0; l<=FineLevel(base::GH()); l++) {
00134 int Time = CurrentTime(base::GH(),l);
00135 int press_cnt = base::Dim()+4;
00136 ((output_type*) _FileOutput)->Transform(base::U(), base::Work(), Time, l,
00137 press_cnt, base::t[l]);
00138 }
00139
00140 for (int ns=0; ns<NSph; ns++) {
00141 int Npoints = 4*Np[ns];
00142 DataType* p = new DataType[Npoints];
00143 point_type* xc = new point_type[Npoints];
00144 point_type* normals = new point_type[Npoints];
00145 DataType* dist = (DataType*) 0;
00146 double dalpha = 0.5*pi/Np[ns];
00147
00148 register int n;
00149
00150
00151 for (n=0; n<Npoints; n++) {
00152 double alpha = dalpha*(n+0.5);
00153 xc[n](0) = xm[base::Dim()*ns ]+rd[ns]*std::cos(alpha);
00154 xc[n](1) = xm[base::Dim()*ns+1]+rd[ns]*std::sin(alpha);
00155 }
00156
00157
00158 _Interpolation->PointsValues(base::Work(),base::t[0],Npoints,xc,p);
00159 _Interpolation->ArrayCombine(VizServer,Npoints,p);
00160
00161
00162 _Interpolation->PointsGeom(base::GFM(0).Phi(),base::t[0],Npoints,xc,normals,dist);
00163 _Interpolation->ArrayCombine(VizServer,base::Dim()*Npoints,normals[0].data());
00164
00165
00166 if (me == VizServer) {
00167 int Nerr = 0;
00168 for (n=0; n<Npoints; n++)
00169 if (p[n]<=-1.e37) Nerr++;
00170 Npoints -= Nerr;
00171 sum[ns] = 0.0;
00172 double ds = 2.*pi*rd[ns]/Npoints;
00173 for (n=0; n<Npoints; n++)
00174 if (p[n]>-1.e37)
00175 sum[ns] += p[n]*normals[n]*ds;
00176 }
00177
00178 delete [] p;
00179 delete [] xc;
00180 delete [] normals;
00181 }
00182
00183 #ifdef DAGH_NO_MPI
00184 #else
00185 if (comm_service::dce() && comm_service::proc_num() > 1) {
00186 int num = comm_service::proc_num();
00187 MPI_Status status;
00188 int R;
00189 int size = sizeof(DataType)*5;
00190 int tag = 10001;
00191 if (me == VizServer)
00192 for (int proc=0; proc<num; proc++) {
00193 if (proc==VizServer) continue;
00194 R = MPI_Send((void *)sum, size, MPI_BYTE, proc, tag, comm_service::comm());
00195 if ( MPI_SUCCESS != R )
00196 comm_service::error_die( "SumCombine", "MPI_Send", R );
00197 }
00198 else {
00199 R = MPI_Recv((void *)sum, size, MPI_BYTE, VizServer, tag, comm_service::comm(), &status);
00200 if ( MPI_SUCCESS != R )
00201 comm_service::error_die( "ArrayCombine", "MPI_Recv", R );
00202 }
00203 }
00204 #endif
00205 }
00206
00207 protected:
00208 interpolation_type* _Interpolation;