00001
00002
00003 #ifndef AMROC_FLUIDPROBLEM_H
00004 #define AMROC_FLUIDPROBLEM_H
00005 #define DIM 3
00006
00007 #include "LBMProblem.h"
00008 #include "LBMD3Q19.h"
00009
00010 typedef double DataType;
00011 typedef LBMD3Q19<DataType> LBMType;
00012
00013 #define OWN_LBMSCHEME
00014 #define OWN_AMRSOLVER
00015 #include "LBMStdProblem.h"
00016 #include "F77Interfaces/F77GFMBoundary.h"
00017 #include "AMRELCGFMSolver.h"
00018 #include "LBMGFMBoundary.h"
00019 #include "Interfaces/SchemeGFMFileOutput.h"
00020
00021 class LBMSpecific : public LBMType {
00022 typedef LBMType base;
00023 public:
00024 LBMSpecific() : base(), omega(1.) {}
00025
00026 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00027 base::register_at(Ctrl,prefix);
00028 RegisterAt(base::LocCtrl,"Omega",omega);
00029 }
00030
00031 virtual void SetupData(GridHierarchy* gh, const int& ghosts) {
00032 base::SetupData(gh,ghosts);
00033 if (base::LengthScale()!=DataType(1.) || base::TimeScale()!=DataType(1.)) {
00034 std::cerr << "dx(0) and dt(0) need to be equal to 1.0!" << std::endl;
00035 std::exit(-1);
00036 }
00037 if (omega<0.5 || omega>2.) {
00038 std::cerr << "0.5 <= omega <= 2 required." << std::endl;
00039 std::exit(-1);
00040 }
00041 base::SetGas(1.,base::LatticeViscosity(omega),base::LatticeSpeedOfSound());
00042 std::cout << "D3Q19: Gas_rho=" << base::GasDensity() << " Gas_Cs=" << base::GasSpeedofSound()
00043 << " Gas_nu=" << base::GasViscosity() << std::endl;
00044 }
00045
00046 private:
00047 DataType omega;
00048 };
00049
00050
00051 template <class LBMType, int dim>
00052 class LBMELCGFMBoundary : public LBMGFMBoundary<LBMType,dim> {
00053 typedef typename LBMType::MicroType MicroType;
00054 typedef typename MicroType::InternalDataType DataType;
00055 typedef LBMGFMBoundary<LBMType,dim> base;
00056 public:
00057 typedef typename base::vec_grid_data_type vec_grid_data_type;
00058 typedef typename base::grid_data_type grid_data_type;
00059 typedef typename base::point_type point_type;
00060 typedef AMRELCGFMSolver<MicroType,FixupType,FlagType,dim> amr_elc_solver;
00061
00062 LBMELCGFMBoundary(LBMType &scheme, amr_elc_solver& solver) : base(scheme), _solver(solver) {
00063 base::SetNAux(base::Dim());
00064 }
00065
00066 virtual void SetBndryAux(vec_grid_data_type& gdu, grid_data_type& gdphi,
00067 const MicroType* u, DataType* aux, const int& Level,
00068 double t, const int& nc, const int* idx,
00069 const point_type* xc, const DataType* distance,
00070 const point_type* normal) {
00071 _solver.ExtractBoundaryVelocities(gdu.bbox(),nc,xc,reinterpret_cast<point_type *>(aux));
00072 }
00073
00074 protected:
00075 amr_elc_solver& _solver;
00076 };
00077
00078 class SolverObjects {
00079 public:
00080 SolverObjects() {
00081 _LBMSpecific = new LBMSpecific();
00082 _IntegratorSpecific = new IntegratorSpecific(*_LBMSpecific);
00083 _InitialConditionSpecific = new InitialConditionSpecific(*_LBMSpecific);
00084 _BoundaryConditionsSpecific = new BoundaryConditionsSpecific(*_LBMSpecific);
00085 }
00086
00087 ~SolverObjects() {
00088 delete _BoundaryConditionsSpecific;
00089 delete _InitialConditionSpecific;
00090 delete _IntegratorSpecific;
00091 delete _LBMSpecific;
00092 }
00093
00094 protected:
00095 LBMSpecific *_LBMSpecific;
00096 IntegratorSpecific *_IntegratorSpecific;
00097 InitialConditionSpecific *_InitialConditionSpecific;
00098 BoundaryConditionsSpecific *_BoundaryConditionsSpecific;
00099 };
00100
00101 class FluidSolverSpecific : protected SolverObjects,
00102 public AMRELCGFMSolver<MicroType,FixupType,FlagType,DIM> {
00103 typedef MicroType::InternalDataType DataType;
00104 typedef AMRELCGFMSolver<MicroType,FixupType,FlagType,DIM> base;
00105 typedef SchemeGFMFileOutput<LBMType,FixupType,FlagType,DIM> output_type;
00106 public:
00107 FluidSolverSpecific() : SolverObjects(), base(*SolverObjects::_IntegratorSpecific,
00108 *SolverObjects::_InitialConditionSpecific,
00109 *SolverObjects::_BoundaryConditionsSpecific) {
00110 SetLevelTransfer(new LBMF77LevelTransfer<LBMType,DIM>(SolverObjects::_IntegratorSpecific->Scheme(), f_prolong, f_restrict));
00111 SetFileOutput(new output_type(*this,SolverObjects::_IntegratorSpecific->Scheme()));
00112 SetFixup(new FixupSpecific(SolverObjects::_IntegratorSpecific->Scheme()));
00113 SetFlagging(new FlaggingSpecific(*this,SolverObjects::_IntegratorSpecific->Scheme()));
00114 AddGFM(new GhostFluidMethod<MicroType,DIM>( new LBMELCGFMBoundary<LBMType,DIM>(SolverObjects::_IntegratorSpecific->LBM(),*this),
00115 new CPTLevelSet<DataType,DIM>()));
00116 SetCoupleGFM(0);
00117 }
00118
00119 ~FluidSolverSpecific() {
00120 DeleteGFM(_GFM[0]);
00121 delete _LevelTransfer;
00122 delete _Flagging;
00123 delete _Fixup;
00124 delete _FileOutput;
00125 }
00126
00127 virtual void SendBoundaryData() {
00128 START_WATCH
00129 for (register int l=0; l<=FineLevel(base::GH()); l++) {
00130 int Time = CurrentTime(base::GH(),l);
00131 ((output_type*) _FileOutput)->Transform(base::U(), base::Work(), Time,
00132 l, base::Dim()+4, base::t[l]);
00133 if (CurrentTime(base::GH(),base::CouplingLevel) != Time)
00134 ((output_type*) _FileOutput)->Transform(base::U(), base::Work(), Time+TimeStep(base::U(),l),
00135 l, base::Dim()+4, base::t[l]+base::dt[l]);
00136 }
00137 END_WATCH(FLUID_CPL_PRESSURE_CALCULATE)
00138 base::SendBoundaryData();
00139 }
00140
00141 virtual void SetupData() {
00142 base::SetupData();
00143 base::NAMRTimeSteps = 1;
00144 base::AdaptBndTimeInterpolate = 0;
00145 base::Step[0].LastTime = 1.e37;
00146 base::Step[0].VariableTimeStepping = -1;
00147 base::Step[0].dtv[0] = ((LBMIntegrator<LBMType,DIM> &)Integrator_()).LBM().TimeScale();
00148 }