00001
00002
00003
00004
00005
00006 #ifndef AMROC_PROBLEM_H
00007 #define AMROC_PROBLEM_H
00008
00009 #include "eulerm2.h"
00010
00011 #undef NAUX
00012 #define NAUX 1
00013
00014 #include "ClpProblem.h"
00015
00016 #define f_combl_read FORTRAN_NAME(cblread, CBLREAD)
00017 #define f_combl_write FORTRAN_NAME(cblwrite, CBLWRITE)
00018 #define f_ipvel FORTRAN_NAME(ipvel, IPVEL)
00019
00020 extern "C" {
00021 void f_combl_read(DOUBLE xm[], DOUBLE vm[], DOUBLE& cm, DOUBLE& rd, INTEGER& Np);
00022 void f_combl_write(DOUBLE xm[], DOUBLE vm[], DOUBLE& cm, DOUBLE& rd, INTEGER& Np);
00023 void f_ipvel();
00024 }
00025
00026 #define OUTPUTPOINTSMAX 20
00027 #define OWN_GFMAMRSOLVER
00028 #include "ClpStdGFMProblem.h"
00029 #include "AMRGFMInterpolation.h"
00030
00031 class SolverSpecific :
00032 public AMRGFMSolver<VectorType,FixupType,FlagType,DIM> {
00033 typedef VectorType::InternalDataType DataType;
00034 typedef AMRGFMSolver<VectorType,FixupType,FlagType,DIM> base;
00035 typedef AMRGFMInterpolation<VectorType,FixupType,FlagType,DIM> interpolation_type;
00036 typedef interpolation_type::point_type point_type;
00037 typedef F77GFMFileOutput<VectorType,FixupType,FlagType,DIM> output_type;
00038 typedef GhostFluidMethod<VectorType,DIM>::boundary_conditions_type gfm_bc_type;
00039 public:
00040 typedef base::vec_grid_data_type vec_grid_data_type;
00041
00042 SolverSpecific(IntegratorSpecific& integ,
00043 base::initial_condition_type& init,
00044 base::boundary_conditions_type& bc) : base(integ, init, bc), OutputEvery(0), Nxc(0) {
00045 SetLevelTransfer(new F77LevelTransfer<VectorType,DIM>(f_prolong, f_restrict));
00046 #ifdef f_flgout
00047 SetFileOutput(new F77GFMFileOutput<VectorType,FixupType,FlagType,DIM>(*this,f_flgout));
00048 #else
00049 SetFileOutput(new GFMFileOutput<VectorType,FixupType,FlagType,DIM>(*this));
00050 #endif
00051 SetFixup(new FixupSpecific(integ));
00052 SetFlagging(new FlaggingSpecific(*this));
00053 AddGFM(new GhostFluidMethod<VectorType,DIM>(
00054 new F77GFMBoundary<VectorType,DIM>(f_ibndrfl,f_itrans,f_ipvel),
00055 new F77GFMLevelSet<DataType,DIM>(f_lset),
00056 (gfm_bc_type*)(new F77BoundaryConditions<Vector<DataType,1>,DIM>(f_boundary))));
00057 _Interpolation = new interpolation_type(*this);
00058 }
00059
00060 ~SolverSpecific() {
00061 delete _GFM[0]->GetBoundaryConditionsP();
00062 DeleteGFM(_GFM[0]);
00063 delete _Flagging;
00064 delete _Fixup;
00065 delete _Interpolation;
00066 }
00067
00068 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00069 base::register_at(Ctrl,prefix);
00070 SensorsCtrl = base::LocCtrl.getSubDevice("SensorsOutput");
00071 RegisterAt(SensorsCtrl,"OutputEvery",OutputEvery);
00072 RegisterAt(SensorsCtrl,"NSensors",Nxc);
00073 char VariableName[32];
00074 for (register int i=0; i<OUTPUTPOINTSMAX; i++)
00075 for (register int d=0; d<base::Dim(); d++) {
00076 std::sprintf(VariableName,"xc(%d,%d)",i+1,d+1);
00077 RegisterAt(SensorsCtrl,VariableName,xc[i](d));
00078 }
00079 }
00080 virtual void register_at(ControlDevice& Ctrl) {
00081 base::register_at(Ctrl);
00082 }
00083
00084 virtual void SetupData() {
00085 base::SetupData();
00086 _GFM[0]->BoundaryConditions_().SetupData(base::PGH(), base::NGhosts());
00087 _Interpolation->SetupData(base::PGH(), base::NGhosts());
00088 if (OutputEvery<0) OutputEvery=0;
00089 if (Nxc<0) Nxc=0;
00090 if (Nxc>OUTPUTPOINTSMAX) Nxc=OUTPUTPOINTSMAX;
00091 }
00092
00093
00094 virtual void Advance(double& t, double& dt) {
00095
00096 int me = MY_PROC;
00097 point_type force_old;
00098 double t_old = t;
00099 CalculateForce(force_old);
00100
00101 base::Advance(t,dt);
00102
00103 point_type a, force_new;
00104 CalculateForce(force_new);
00105
00106 int Np;
00107 double xm[2], vm[2], cm, rd;
00108 f_combl_read(xm,vm,cm,rd,Np);
00109
00110 a = 0.5/cm*(force_old+force_new);
00111 vm[0] += a(0)*dt;
00112 vm[1] += a(1)*dt;
00113 xm[0] += vm[0]*dt;
00114 xm[1] += vm[1]*dt;
00115
00116 f_combl_write(xm,vm,cm,rd,Np);
00117
00118
00119 if (me == VizServer) {
00120 std::ofstream outfile;
00121 std::ostream* out;
00122 std::string fname = "boundary.txt";
00123 outfile.open(fname.c_str(), std::ios::out | std::ios::app);
00124 out = new std::ostream(outfile.rdbuf());
00125 *out << t;
00126 int d;
00127 for (d=0; d<base::Dim(); d++)
00128 *out << " " << force_new(d);
00129 for (d=0; d<base::Dim(); d++)
00130 *out << " " << xm[d];
00131 for (d=0; d<base::Dim(); d++)
00132 *out << " " << vm[d];
00133 *out << std::endl;
00134 outfile.close();
00135 delete out;
00136 }
00137
00138 if (!OutputEvery) return;
00139
00140 int TimeZero = CurrentTime(base::GH(),0);
00141 TimeZero /= RefinedBy(base::GH(),MaxLevel(base::GH()));
00142 if (TimeZero % OutputEvery != 0) return;
00143
00144 VectorType* dat = new VectorType[Nxc];
00145
00146
00147 _Interpolation->PointsValues(base::U(),t,Nxc,xc,dat);
00148 int NValues = Nxc*base::NEquations();
00149 _Interpolation->ArrayCombine(VizServer,NValues,&(dat[0](0)));
00150
00151
00152 if (MY_PROC == VizServer) {
00153 DataType* output_data = new DataType[_FileOutput->Ncnt()*Nxc];
00154 BBox bb(2,0,0,Nxc-1,0,1,1);
00155 vec_grid_data_type val(bb,dat);
00156 for (int cnt=1;cnt<=_FileOutput->Ncnt(); cnt++) {
00157 if (_FileOutput->OutputName(cnt-1).c_str()[0] == '-') continue;
00158 grid_data_type output(bb,output_data+(cnt-1)*Nxc);
00159 ((output_type::out_2_func_type) (((output_type*) base::_FileOutput)->GetOutFunc()))
00160 (FA(2,val),FA(2,output),BOUNDING_BOX(bb),base::NEquations(),cnt,t);
00161 DataType* dummy;
00162 output.deallocate(dummy);
00163 }
00164 VectorType* dummy;
00165 val.deallocate(dummy);
00166 std::ofstream outfile;
00167 std::ostream* out;
00168 std::string fname = "sensors.txt";
00169 outfile.open(fname.c_str(), std::ios::out | std::ios::app);
00170 out = new std::ostream(outfile.rdbuf());
00171 *out << t << " ";
00172 for (register int j=0;j<Nxc; j++)
00173 for (int cnt=0;cnt<_FileOutput->Ncnt(); cnt++)
00174 if (_FileOutput->OutputName(cnt).c_str()[0] != '-')
00175 *out << " " << output_data[cnt*Nxc+j];
00176 *out << std::endl;
00177 delete [] output_data;
00178 outfile.close();
00179 delete out;
00180 }
00181 delete [] dat;
00182 }
00183
00184 void CalculateForce(point_type& sum) {
00185 int me = MY_PROC;
00186
00187 double pi = 4.0*std::atan(1.0);
00188
00189
00190 int Np;
00191 double xm[2], vm[2], cm, rd;
00192 f_combl_read(xm,vm,cm,rd,Np);
00193
00194
00195 for (register int l=0; l<=FineLevel(base::GH()); l++) {
00196 int Time = CurrentTime(base::GH(),l);
00197 int press_cnt = base::Dim()+4;
00198 ((output_type*) _FileOutput)->Transform(base::U(), base::Work(), Time, l,
00199 press_cnt, base::t[l]);
00200 }
00201
00202 DataType* p = new DataType[Np];
00203 point_type* xc = new point_type[Np];
00204
00205 register int n;
00206
00207 for (n=0; n<Np; n++) {
00208 xc[n](0) = xm[0];
00209 xc[n](1) = xm[1]+(2.*n/Np-1.)*rd;
00210 }
00211
00212
00213 _Interpolation->PointsValues(base::Work(),base::t[0],Np,xc,p);
00214 _Interpolation->ArrayCombine(VizServer,Np,p);
00215
00216
00217 if (me == VizServer) {
00218 sum = 0.;
00219 int c=0;
00220 for (n=0; n<Np; n++)
00221 if (p[n]>-1.e37) {
00222 sum(0) += p[n]; c++;
00223 }
00224 sum(0) /= c;
00225 sum(0) -= 101325.;
00226 sum(0) *= pi*rd*rd;
00227
00228 delete [] p;
00229 delete [] xc;
00230 }
00231
00232 #ifdef DAGH_NO_MPI
00233 #else
00234 if (comm_service::dce() && comm_service::proc_num() > 1) {
00235 int num = comm_service::proc_num();
00236 MPI_Status status;
00237 int R;
00238 int size = sizeof(DataType);
00239 int tag = 10001;
00240 if (me == VizServer)
00241 for (int proc=0; proc<num; proc++) {
00242 if (proc==VizServer) continue;
00243 R = MPI_Send((void *)&sum, size, MPI_BYTE, proc, tag, comm_service::comm());
00244 if ( MPI_SUCCESS != R )
00245 comm_service::error_die( "SumCombine", "MPI_Send", R );
00246 }
00247 else {
00248 R = MPI_Recv((void *)&sum, size, MPI_BYTE, VizServer, tag, comm_service::comm(), &status);
00249 if ( MPI_SUCCESS != R )
00250 comm_service::error_die( "ArrayCombine", "MPI_Recv", R );
00251 }
00252 }
00253 #endif
00254 }
00255
00256 protected:
00257 int OutputEvery, Nxc;
00258 point_type xc[OUTPUTPOINTSMAX];
00259 interpolation_type* _Interpolation;