#include #include #include #include "source/tessellation/VoronoiMesh.hpp" #include "source/newtonian/two_dimensional/hdsim2d.hpp" #include "source/newtonian/two_dimensional/interpolations/pcm2d.hpp" #include "source/newtonian/two_dimensional/spatial_distributions/uniform2d.hpp" #include "source/newtonian/common/ideal_gas.hpp" #include "source/newtonian/two_dimensional/geometric_outer_boundaries/SquareBox.hpp" #include "source/newtonian/two_dimensional/hydro_boundary_conditions/RigidWallHydro.hpp" #include "source/newtonian/common/hllc.hpp" #include "source/newtonian/two_dimensional/source_terms/zero_force.hpp" #include "source/newtonian/two_dimensional/point_motions/eulerian.hpp" #include "source/newtonian/two_dimensional/point_motions/lagrangian.hpp" #include "source/newtonian/two_dimensional/point_motions/eulerian.hpp" #include "source/newtonian/two_dimensional/point_motions/round_cells.hpp" #include "source/newtonian/two_dimensional/diagnostics.hpp" #include "source/newtonian/two_dimensional/source_terms/cylindrical_complementary.hpp" #include "source/newtonian/two_dimensional/source_terms/CenterGravity.hpp" #include "source/newtonian/two_dimensional/source_terms/SeveralSources.hpp" #include "source/misc/simple_io.hpp" #include "source/newtonian/test_2d/main_loop_2d.hpp" #include "source/newtonian/test_2d/kill_switch.hpp" #include "source/newtonian/two_dimensional/hdf5_diagnostics.hpp" #include "source/misc/mesh_generator.hpp" #include "source/tessellation/RoundGrid.hpp" #include "source/misc/int2str.hpp" #include "source/newtonian/two_dimensional/interpolations/linear_gauss_consistent.hpp" #include "source/newtonian/test_2d/consecutive_snapshots.hpp" #include #include "source/newtonian/two_dimensional/hydro_boundary_conditions/FreeFlow.hpp" #include "source/misc/utils.hpp" #include "source/tessellation/shape_2d.hpp" #include "source/newtonian/test_2d/piecewise.hpp" #include "source/mpi/MeshPointsMPI.hpp" #include "source/mpi/mpi_macro.hpp" #include "source/mpi/ConstNumberPerProc.hpp" #include "source/misc/hdf5_utils.hpp" #include "source/newtonian/test_2d/contour.hpp" #include "source/newtonian/two_dimensional/custom_evolutions/Ratchet.cpp" #include "source/newtonian/two_dimensional/diagnostics.hpp" #include using namespace std; using namespace simulation2d; namespace { class WriteConserved: public DiagnosticFunction { public: WriteConserved(string const& fname): tracer_(), cons_(), fname_(fname) {} void operator()(hdsim const& sim) { tracer_.push_back(total_tracer(sim,0)); cons_.push_back(total_conserved(sim)); time_.push_back(sim.GetTime()); } ~WriteConserved(void) { ofstream f(fname_.c_str()); for(size_t i=0;i tracer_; mutable vector cons_; mutable vector time_; const string fname_; }; /* class Veil: public Acceleration { public: Veil(Acceleration& full): full_(full) {} Vector2D Calculate (Tessellation const & tess, vector< Primitive > const & cells, int point, vector< Conserved > const & fluxes, vector< Vector2D > const & point_velocity, HydroBoundaryConditions const & hbc, vector< vector< double > > const & tracers, double time, double dt) { const Primitive& cell = cells[static_cast(point)]; if(abs(cell.Velocity.x)::epsilon()&& abs(cell.Velocity.y)::epsilon()) return Vector2D(0,0); else return full_.Calculate(tess,cells,point,fluxes,point_velocity,hbc,tracers, time,dt); } private: Acceleration& full_; };*/ double calc_mach_number(const Primitive& p) { return abs(p.Velocity)/p.SoundSpeed; } Vector2D find_pos_on_line(const Vector2D& p1, double v1, const Vector2D& p2, double v2, double vt) { return p1+((vt-v1)/(v2-v1))*(p2-p1); } /* vector process_positions(const Index2Member& gg) { vector res(get_mpi_size()); for(size_t i=0;i lower_left.x) && (point.x < upper_right.x) && (point.y > lower_left.y) && (point.y < upper_right.y)); } vector rectangle_clip(const vector& grid, const Vector2D& lower_left, const Vector2D& upper_right) { vector res; for(size_t i=0, endp=grid.size();i calc_radius_list(void) { const double rmin = 1e-4; const double q = 1.01; const size_t n = 200; vector res(n); for(size_t i=0;i create_grid(Vector2D const& lower_left, Vector2D const& upper_right, double dx2x) { vector res; for(double x = lower_left.x*(1+0.5*dx2x); x centered_hexagonal_grid(double r_min, double r_max) { const vector r_list = arange(0,r_max,r_min); vector res; for(size_t i=0;i(6*i,1); vector angle_list(angle_num,0); for(size_t j=0;j centered_logarithmic_spiral(double r_min, double r_max, double alpha, const Vector2D& center) { const double theta_max = log(r_max/r_min)/alpha; const vector theta_list = arange(0,theta_max,2*M_PI*alpha); vector r_list(theta_list.size(),0); for(size_t i=0;i res(r_list.size()); for(size_t i=0;i complete_grid(double r_inner, double r_outer, double alpha) { const vector inner = centered_hexagonal_grid(r_inner*alpha*2*M_PI, r_inner); const vector outer = centered_logarithmic_spiral(r_inner, r_outer, alpha); return join(inner, outer); } */ template class VectorInitializer { public: VectorInitializer(const T& t): buf_(1,t) {} VectorInitializer& operator()(const T& t) { buf_.push_back(t); return *this; } vector operator()(void) { return buf_; } private: vector buf_; }; } class SimData { public: SimData(const Constants& c): pg_(Vector2D(0,0), Vector2D(0,1)), outer_(c.lower_left, c.upper_right), // init_points_(cartesian_mesh(300,450,c.lower_left,c.upper_right)), //cgg_(11+2*150,7+2*300,lower_left, upper_right), init_points_(rectangle_clip (centered_logarithmic_spiral(0.01, abs(c.upper_right-c.lower_left), 0.002, Vector2D(-0.2,-1)), c.lower_left, c.upper_right)), /* init_points_(create_grid(lower_left, upper_right, 0.1)), */ tess_(), //proc_tess_(process_positions(Echo(init_points_)),outer_), eos_(adiabatic_index), rs_(), hbc_(rs_), //interpm_(eos_,outer_,hbc_,true,false), interpm_(), raw_point_motion_(), point_motion_(raw_point_motion_,hbc_, 0.15, 0.02, false,0,&outer_), alt_point_motion_(), gravity_acc_(c.gravitation_constant*c.black_hole_mass, 0.1*c.parsec, c.parsec*Vector2D(-0.05,0)), // veil_(gravity_acc_), gravity_force_(gravity_acc_), geom_force_(pg_.getAxis()), force_(VectorInitializer(&gravity_force_) (&geom_force_)()), ce_(Ratchet::in), sim_(init_points_, //distribute_grid(proc_tess_,Echo(init_points_)), tess_, // proc_tess_, interpm_, Piecewise (Circle(Vector2D(0,-c.offset),c.supernova_radius), Uniform2D(c.supernova_density), Piecewise (Circle(Vector2D(0,0),c.R_b), BoundedRadialPowerLaw(Vector2D(0,0), -omega_in, c.inner_density_prefactor, 1e-6, 10), BoundedRadialPowerLaw(Vector2D(0,0), -omega_out, c.outer_density_prefactor, 1e-6, 10))), Piecewise(Circle(Vector2D(0,-c.offset),c.supernova_radius), Uniform2D(c.supernova_pressure), HydrostaticPressure(c.gravitation_constant*c.black_hole_mass, c.R_0, c.rho_0, c.omega_in, c.R_b, c.omega_out)), Uniform2D(0), Uniform2D(0), eos_, rs_, alt_point_motion_, // point_motion_, force_, outer_, hbc_) { sim_.SetColdFlows(0.01,0.01); sim_.SetDensityFloor(1e-6,1e-23); sim_.changePhysicalGeometry(&pg_); sim_.custom_evolution_manager.addCustomEvolution(&ce_); for(int i=0;i(i)] = 1; } } hdsim& getSim(void) { return sim_; } private: const CylindricalSymmetry pg_; const SquareBox outer_; // const CartesianGridGenerator cgg_; const vector init_points_; VoronoiMesh tess_; VoronoiMesh proc_tess_; const IdealGas eos_; const Hllc rs_; const RigidWallHydro hbc_; //const FreeFlow hbc_; // LinearGaussConsistent interpm_; PCM2D interpm_; Lagrangian raw_point_motion_; RoundCells point_motion_; Eulerian alt_point_motion_; CenterGravity gravity_acc_; // Veil veil_; ConservativeForce gravity_force_; CylindricalComplementary geom_force_; SeveralSources force_; Ratchet ce_; hdsim sim_; }; namespace { /* class HighestShockedPoint: public TerminationCondition { public: HighestShockedPoint(double position): position_(position) {} bool operator()(hdsim const& sim) { const double mn_thres = 0.01; double ys = -10; for(int i=0;imn_thres){ ys = max(ys, sim.GetMeshPoint(i).y); } } cout << ys << endl; return ys < position_; } private: const double position_; }; */ } class CustomDiagnostic { public: CustomDiagnostic(double dt, double t_start): dt_(dt), t_next_(t_start), counter_(0) {} void operator()(const hdsim& sim) { if(sim.GetTime()>t_next_){ write_snapshot_to_hdf5(sim, "snapshot_"+int2str(counter_)+".h5"); t_next_ += dt_; ++counter_; } } private: const double dt_; double t_next_; int counter_; }; namespace { /* vector calc_decade_vector(double val, size_t decades) { vector res; for(size_t i=0;i(i)+1)); return res; } */ } namespace { /* double highest_shocked_point(const hdsim& sim) { const double mn_thres = 0.01; double ys = -10; for(int i=0;imn_thres){ ys = max(ys,sim.GetMeshPoint(i).y); } } return ys; } */ } namespace { /* class MyDiagnostic: public DiagnosticFunction { public: MyDiagnostic(double y_start, size_t decades): snapshot_times_(calc_decade_vector(y_start, decades)), y_next_(y_start), counter_(0), active_(true) {} void operator()(const hdsim& sim) { if(!active_) return; if(highest_shocked_point(sim)>y_next_){ write_snapshot_to_hdf5(sim,"snapshot_"+int2str(counter_)+".h5"); if(static_cast(counter_)>snapshot_times_.size()-1) active_ = false; else{ y_next_ = snapshot_times_.at(static_cast(counter_)); ++counter_; } } } private: const vector snapshot_times_; mutable double y_next_; mutable int counter_; mutable bool active_; }; */ } namespace { class MultipleDiagnostics: public DiagnosticFunction { public: MultipleDiagnostics(const vector& diag_list): diag_list_(diag_list) {} void operator()(const hdsim& sim) { BOOST_FOREACH(DiagnosticFunction* df, diag_list_) { (*df)(sim); } } private: const vector diag_list_; }; } namespace { class ShockFrontDetector: public LocalContourCriterion { public: ShockFrontDetector(const Vector2D& center, double mn_thres): center_(center), mn_thres_(mn_thres) {} std::pair operator()(const Edge& edge, const hdsim& sim) const { if(sim.getHydroBoundaryCondition().IsBoundary(edge, sim.GetTessellation())) return std::pair(false,Vector2D(0,0)); if(edge.neighbors.first>sim.GetCellNo() || edge.neighbors.second>sim.GetCellNo()) return std::pair(false,Vector2D(0,0)); const std::pair mach_numbers (calc_mach_number(sim.GetCell(edge.neighbors.first)), calc_mach_number(sim.GetCell(edge.neighbors.second))); if((mach_numbers.first-mn_thres_)*(mach_numbers.second-mn_thres_)>0 || (mach_numbers.second-mach_numbers.first)* (abs(sim.GetMeshPoint(edge.neighbors.second)-center_)- abs(sim.GetMeshPoint(edge.neighbors.first)-center_))>0) return std::pair(false,Vector2D(0,0)); else return std::pair (true,find_pos_on_line(sim.GetMeshPoint(edge.neighbors.first), mach_numbers.first, sim.GetMeshPoint(edge.neighbors.second), mach_numbers.second, mn_thres_)); } private: const Vector2D center_; const double mn_thres_; }; /* class CellEdgesGetter: public Index2Member { public: CellEdgesGetter(const Tessellation& tess, const int n): tess_(tess), edge_indices_(tess_.GetCellEdges(n)) {} size_t getLength(void) const { return edge_indices_.size(); } Edge operator()(size_t i) const { return tess_.GetEdge(edge_indices_[i]); } private: const Tessellation& tess_; const vector edge_indices_; }; */ /* class EnforceRigidWall: public Manipulate { public: EnforceRigidWall(void) {} void operator()(hdsim& sim) { const PhysicalGeometry& pg = sim.getPhysicalGeometry(); const Tessellation& tess = sim.GetTessellation(); for(size_t i=0;i diag_list; diag_list.push_back(&diag1); diag_list.push_back(&diag2); diag_list.push_back(&diag3); diag_list.push_back(&diag4); MultipleDiagnostics diag(diag_list); main_loop(sim, term_cond_raw, &hdsim::TimeAdvance, &diag); } } namespace { void report_error(UniversalError const& eo) { cout << eo.GetErrorMessage() << endl; cout.precision(14); for(size_t i=0;i(1,c.year)) ("solar mass",vector(1,c.solar_mass)) ("parsec",vector(1,c.parsec)); write_snapshot_to_hdf5(sim, "initial.h5"); my_main_loop(sim,c); write_snapshot_to_hdf5(sim, "final.h5"); } catch(const UniversalError& eo){ report_error(eo); throw; } return 0; }