Advertisement
bolverk

rich_v2_offset_supernova

Mar 25th, 2015
419
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 25.59 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <limits>
  4. #include "tessellation/VoronoiMesh.hpp"
  5. #include "newtonian/two_dimensional/hdsim2d.hpp"
  6. #include "newtonian/two_dimensional/interpolations/pcm2d.hpp"
  7. #include "newtonian/two_dimensional/spatial_distributions/uniform2d.hpp"
  8. #include "newtonian/common/ideal_gas.hpp"
  9. #include "newtonian/two_dimensional/geometric_outer_boundaries/SquareBox.hpp"
  10. #include "newtonian/two_dimensional/hydro_boundary_conditions/RigidWallHydro.hpp"
  11. #include "newtonian/common/hllc.hpp"
  12. #include "newtonian/two_dimensional/source_terms/zero_force.hpp"
  13. #include "newtonian/two_dimensional/point_motions/eulerian.hpp"
  14. #include "newtonian/two_dimensional/point_motions/lagrangian.hpp"
  15. #include "newtonian/two_dimensional/point_motions/eulerian.hpp"
  16. #include "newtonian/two_dimensional/point_motions/round_cells.hpp"
  17. #include "newtonian/two_dimensional/diagnostics.hpp"
  18. #include "newtonian/two_dimensional/source_terms/cylindrical_complementary.hpp"
  19. #include "newtonian/two_dimensional/source_terms/CenterGravity.hpp"
  20. #include "newtonian/two_dimensional/source_terms/SeveralSources.hpp"
  21. #include "misc/simple_io.hpp"
  22. #include "newtonian/test_2d/main_loop_2d.hpp"
  23. #include "newtonian/test_2d/kill_switch.hpp"
  24. #include "newtonian/two_dimensional/hdf5_diagnostics.hpp"
  25. #include "misc/mesh_generator.hpp"
  26. #include "tessellation/RoundGrid.hpp"
  27. #include "misc/int2str.hpp"
  28. #include "newtonian/two_dimensional/interpolations/linear_gauss_consistent.hpp"
  29. #include "newtonian/test_2d/consecutive_snapshots.hpp"
  30. #include <boost/foreach.hpp>
  31. #include "newtonian/two_dimensional/hydro_boundary_conditions/FreeFlow.hpp"
  32. #include "misc/utils.hpp"
  33. #include "tessellation/shape_2d.hpp"
  34. #include "newtonian/test_2d/piecewise.hpp"
  35. #include "mpi/MeshPointsMPI.hpp"
  36. #include "mpi/mpi_macro.hpp"
  37. #include "mpi/ConstNumberPerProc.hpp"
  38. #include "misc/hdf5_utils.hpp"
  39. #include "newtonian/test_2d/contour.hpp"
  40. #include "newtonian/two_dimensional/custom_evolutions/Ratchet.cpp"
  41. #include "newtonian/two_dimensional/diagnostics.hpp"
  42. #include "newtonian/two_dimensional/simple_flux_calculator.hpp"
  43. #include "newtonian/two_dimensional/simple_cell_updater.hpp"
  44. #include <fenv.h>
  45.  
  46. using namespace std;
  47. using namespace simulation2d;
  48.  
  49. namespace {
  50.  
  51.   class CellEdgesGetter: public Index2Member<Edge>
  52.   {
  53.   public:
  54.     CellEdgesGetter(const Tessellation& tess,
  55.             const int n):
  56.       tess_(tess), edge_indices_(tess_.GetCellEdges(n)) {}
  57.  
  58.     size_t getLength(void) const
  59.     {
  60.       return edge_indices_.size();
  61.     }
  62.  
  63.     Edge operator()(size_t i) const
  64.     {
  65.       return tess_.GetEdge(edge_indices_[i]);
  66.     }
  67.  
  68.   private:
  69.     const Tessellation& tess_;
  70.     const vector<int> edge_indices_;
  71.   };
  72.  
  73.   class WriteConserved: public DiagnosticFunction
  74.   {
  75.   public:
  76.  
  77.     WriteConserved(const string& fname):
  78.       cons_(), fname_(fname) {}
  79.  
  80.     void operator()(const hdsim& sim)
  81.     {
  82.       cons_.push_back(total_conserved(sim));
  83.       time_.push_back(sim.getTime());
  84.     }
  85.  
  86.     ~WriteConserved(void)
  87.     {
  88.       ofstream f(fname_.c_str());
  89.       for(size_t i=0;i<cons_.size();++i)
  90.     f << time_[i] << " "
  91.       << cons_[i].mass << " "
  92.       << cons_[i].momentum.x << " "
  93.       << cons_[i].momentum.y << " "
  94.       << cons_[i].energy << " "
  95.       << cons_[i].tracers["ejecta"] << "\n";
  96.       f.close();
  97.     }
  98.  
  99.   private:
  100.     mutable vector<Extensive> cons_;
  101.     mutable vector<double> time_;
  102.     const string fname_;
  103.   };
  104.  
  105.   class Constants
  106.   {
  107.   public:
  108.  
  109.     // Metric prefix
  110.     const double kilo;
  111.     const double centi;
  112.  
  113.     // Length / distance
  114.     const double parsec;
  115.     const double meter;
  116.  
  117.     // Time
  118.     const double year;
  119.     const double second;
  120.  
  121.     // Mass
  122.     const double solar_mass;
  123.     const double gram;
  124.  
  125.     // Energy
  126.     const double erg;
  127.  
  128.     // Force
  129.     const double newton;
  130.  
  131.     // Parameters
  132.     const double black_hole_mass;
  133.     const double zeta;
  134.     const double adiabatic_index;
  135.     const double gravitation_constant;
  136.     const double rho_0;
  137.     const double R_0;
  138.     const double omega_in;
  139.     const double inner_density_prefactor;
  140.     const double R_b;
  141.     const double omega_out;
  142.     const double outer_density_prefactor;
  143.     const double offset;
  144.     const double supernova_energy;
  145.     const double supernova_radius;
  146.     const double supernova_volume;
  147.     const double supernova_mass;
  148.     const double supernova_density;
  149.     const double supernova_pressure;
  150.     const Vector2D lower_left;
  151.     const Vector2D upper_right;
  152.  
  153.     Constants(void):
  154.       kilo(1e3),
  155.       centi(1e-2),
  156.       parsec(1),
  157.       meter(3.24e-17*parsec),
  158.       year(1),
  159.       second(year/3.16e7),
  160.       solar_mass(1),
  161.       gram(5.03e-34*solar_mass),
  162.       erg(gram*pow(centi*meter/second,2)),
  163.       newton(kilo*gram*meter/pow(second,2)),
  164.       black_hole_mass(1e6*solar_mass),
  165.       zeta(pow(black_hole_mass/(4.3e6*solar_mass),7./15.)),
  166.       adiabatic_index(5./3.),
  167.       gravitation_constant(6.673e-11*newton*pow(meter/(kilo*gram),2)),
  168.       rho_0(2.2e-22*gram/pow(centi*meter,3)),
  169.       R_0(0.04*parsec*zeta),
  170.       omega_in(1),
  171.       inner_density_prefactor(rho_0*pow(R_0,omega_in)),
  172.       R_b(0.4*parsec*zeta),
  173.       omega_out(3),
  174.       outer_density_prefactor
  175.       (inner_density_prefactor*pow(R_b,omega_out-omega_in)),
  176.       offset(0.24*R_b),
  177.       supernova_energy(1e51*erg),
  178.       supernova_radius(0.2*offset),
  179.       supernova_volume((4.*M_PI/3)*pow(supernova_radius,3)),
  180.       supernova_mass(5*solar_mass),
  181.       supernova_density(supernova_mass/supernova_volume),
  182.       supernova_pressure((adiabatic_index-1)*supernova_energy/supernova_volume),
  183.       lower_left(parsec*Vector2D(0,-5*offset)),
  184.       upper_right(parsec*Vector2D(5*offset,5*offset)) {}
  185.   };
  186.  
  187.   class Bremsstrahlung: public DiagnosticFunction
  188.   {
  189.   public:
  190.  
  191.     Bremsstrahlung(const string& fname, const Constants& c):
  192.       fname_(fname),
  193.       // Coefficient is taken from Rybicki and Lightman 1979, page 162 equation 5.15b
  194.       boltzmann_constant_(1.38e-16*c.erg),
  195.       coefficient_(1.4e-27*c.erg/pow(c.centi*c.meter,3)/c.second),
  196.       particle_mass_(1.67e-24*c.gram),
  197.       cc_(pow(c.centi*c.meter,3)) {}
  198.  
  199.     void operator()(const hdsim& sim)
  200.     {
  201.       double total_luminosity = 0;
  202.       const PhysicalGeometry& pg = sim.getPhysicalGeometry();
  203.       const Tessellation& tess = sim.getTessellation();
  204.       for(int i=0;i<static_cast<int>(sim.getAllCells().size());++i)
  205.     total_luminosity += pg.calcVolume(serial_generate(CellEdgesGetter(tess,i)))*
  206.       calcEmissivity(sim.getAllCells()[static_cast<size_t>(i)].density,
  207.              sim.getAllCells()[static_cast<size_t>(i)].pressure);
  208.       time_luminosity_.push_back(std::pair<double,double>(sim.getTime(),total_luminosity));
  209.     }
  210.  
  211.     ~Bremsstrahlung(void)
  212.     {
  213.       ofstream f(fname_.c_str());
  214.       for(size_t i=0;i<time_luminosity_.size();++i)
  215.     f << time_luminosity_[i].first << " "
  216.       << time_luminosity_[i].second << endl;
  217.       f.close();
  218.     }
  219.  
  220.   private:
  221.  
  222.     double calcTemperature(double density, double pressure)
  223.     {
  224.       return particle_mass_*(pressure/density)/boltzmann_constant_;
  225.     }
  226.  
  227.     double calcEmissivity(double density, double pressure)
  228.     {
  229.       const double T = calcTemperature(density, pressure);
  230.       const double n = (density/particle_mass_)*cc_;
  231.       return coefficient_*sqrt(T)*pow(n,2);
  232.     }
  233.  
  234.     const string fname_;
  235.     const double boltzmann_constant_;
  236.     const double coefficient_;
  237.     const double particle_mass_;
  238.     const double cc_;
  239.     mutable vector<std::pair<double,double> > time_luminosity_;
  240.   };
  241.  
  242.   class HydrostaticPressure: public SpatialDistribution
  243.   {
  244.   public:
  245.  
  246.     HydrostaticPressure(double gm,
  247.             double r0,
  248.             double rho_0,
  249.             double omega_1,
  250.             double R_b,
  251.             double omega_2):
  252.       gm_(gm), r0_(r0), rho_0_(rho_0),
  253.       omega_1_(omega_1), R_b_(R_b), omega_2_(omega_2) {}
  254.  
  255.     double operator()(const Vector2D& r) const
  256.     {
  257.       if(abs(r)<R_b_)
  258.     return (gm_/r0_)*(rho_0_/(omega_1_+1))*pow(abs(r)/r0_,-omega_1_-1)-
  259.       (gm_/r0_)*(rho_0_/(omega_1_+1))*pow(R_b_/r0_,-omega_1_-1)+
  260.       (gm_/r0_)*(rho_0_/(omega_2_+1))*pow(R_b_/r0_,-omega_1_-1);
  261.       else
  262.     return (gm_/r0_)*(rho_0_/(omega_2_+1))*
  263.       pow(R_b_/r0_,-omega_1_-1)*
  264.       pow(abs(r)/R_b_,-omega_2_-1);
  265.     }
  266.  
  267.   private:
  268.     const double gm_;
  269.     const double r0_;
  270.     const double rho_0_;
  271.     const double omega_1_;
  272.     const double R_b_;
  273.     const double omega_2_;
  274.   };
  275.  
  276.   class BoundedRadialPowerLaw: public SpatialDistribution
  277.   {
  278.   public:
  279.  
  280.     BoundedRadialPowerLaw(const Vector2D& center,
  281.               double index,
  282.               double prefactor,
  283.               double lower_bound,
  284.               double upper_bound):
  285.       center_(center),
  286.       index_(index),
  287.       prefactor_(prefactor),
  288.       lower_bound_(lower_bound),
  289.       upper_bound_(upper_bound) {}
  290.  
  291.     double operator()(const Vector2D& r) const
  292.     {
  293.       const double radius = max(min(abs(r-center_),
  294.                     upper_bound_),
  295.                 lower_bound_);
  296.       return prefactor_*pow(radius,index_);
  297.     }
  298.  
  299.   private:
  300.     const Vector2D center_;
  301.     const double index_;
  302.     const double prefactor_;
  303.     const double lower_bound_;
  304.     const double upper_bound_;
  305.   };
  306.  
  307.   bool is_inside_rectangle(const Vector2D& point,
  308.                const Vector2D& lower_left,
  309.                const Vector2D& upper_right)
  310.   {
  311.     return ((point.x > lower_left.x) &&
  312.         (point.x < upper_right.x) &&
  313.         (point.y > lower_left.y) &&
  314.         (point.y < upper_right.y));
  315.   }
  316.  
  317.   vector<Vector2D> rectangle_clip(const vector<Vector2D>& grid,
  318.                   const Vector2D& lower_left,
  319.                   const Vector2D& upper_right)
  320.   {
  321.     vector<Vector2D> res;
  322.     for(size_t i=0, endp=grid.size();i<endp;++i){
  323.       const Vector2D& point = grid[i];
  324.       if(is_inside_rectangle(point,lower_left,upper_right))
  325.     res.push_back(point);    
  326.     }
  327.     return res;
  328.   }
  329.  
  330.   /*
  331.     vector<double> calc_radius_list(void)
  332.     {
  333.     const double rmin = 1e-4;
  334.     const double q = 1.01;
  335.     const size_t n = 200;
  336.     vector<double> res(n);
  337.     for(size_t i=0;i<n;++i)
  338.     res[i] = rmin*pow(q,i);
  339.     write_number(0,"finished_calc_radius_list.txt");
  340.     return res;
  341.     }
  342.   */
  343.  
  344.   /*
  345.     vector<Vector2D> create_grid(Vector2D const& lower_left,
  346.     Vector2D const& upper_right,
  347.     double dx2x)
  348.     {
  349.     vector<Vector2D> res;
  350.     for(double x = lower_left.x*(1+0.5*dx2x);
  351.     x<upper_right.x; x*=(1+dx2x)){
  352.     const double dx = x*dx2x;
  353.     for(double y=lower_left.y+dx/2;
  354.     y<upper_right.y; y += dx)
  355.     res.push_back(Vector2D(x,y));
  356.     }
  357.     return res;
  358.     }
  359.   */
  360.  
  361.   /*
  362.     vector<Vector2D> centered_hexagonal_grid(double r_min,
  363.     double r_max)
  364.     {
  365.     const vector<double> r_list = arange(0,r_max,r_min);
  366.     vector<Vector2D> res;
  367.     for(size_t i=0;i<r_list.size();++i){
  368.     const size_t angle_num = max<size_t>(6*i,1);
  369.     vector<double> angle_list(angle_num,0);
  370.     for(size_t j=0;j<angle_num;++j)
  371.     angle_list.at(j) = 2*M_PI*(double)j/(double)(angle_num);
  372.     for(size_t j=0;j<angle_num;++j)
  373.     res.push_back(r_list.at(i)*Vector2D(cos(angle_list.at(j)),
  374.     sin(angle_list.at(j))));
  375.     }
  376.     return res;
  377.     }
  378.   */
  379.  
  380.   vector<Vector2D> centered_logarithmic_spiral(double r_min,
  381.                            double r_max,
  382.                            double alpha,
  383.                            const Vector2D& center)
  384.   {
  385.     const double theta_max = log(r_max/r_min)/alpha;
  386.     const vector<double> theta_list =
  387.       arange(0,theta_max,2*M_PI*alpha/(1-0.5*alpha));
  388.  
  389.     vector<double> r_list(theta_list.size(),0);
  390.     for(size_t i=0;i<r_list.size();++i)
  391.       r_list.at(i) = r_min*exp(alpha*theta_list.at(i));
  392.  
  393.     vector<Vector2D> res(r_list.size());
  394.     for(size_t i=0;i<res.size();++i)
  395.       res[i] = center+r_list[i]*Vector2D(cos(theta_list.at(i)),
  396.                      sin(theta_list.at(i)));
  397.     return res;
  398.   }
  399.  
  400.   /*
  401.     vector<Vector2D> complete_grid(double r_inner,
  402.     double r_outer,
  403.     double alpha)
  404.     {
  405.     const vector<Vector2D> inner =
  406.     centered_hexagonal_grid(r_inner*alpha*2*M_PI,
  407.     r_inner);
  408.     const vector<Vector2D> outer =
  409.     centered_logarithmic_spiral(r_inner,
  410.     r_outer,
  411.     alpha);
  412.     return join(inner, outer);
  413.     }
  414.   */
  415.  
  416.   template<class T> class VectorInitializer
  417.   {
  418.   public:
  419.  
  420.     VectorInitializer(const T& t):
  421.       buf_(1,t) {}
  422.  
  423.     VectorInitializer& operator()(const T& t)
  424.     {
  425.       buf_.push_back(t);
  426.       return *this;
  427.     }
  428.  
  429.     vector<T> operator()(void)
  430.     {
  431.       return buf_;
  432.     }
  433.  
  434.   private:
  435.     vector<T> buf_;
  436.   };
  437.  
  438.   vector<ComputationalCell> calc_init_cond(const Tessellation& tess,
  439.                        const Constants& c)
  440.   {
  441.     vector<ComputationalCell> res(static_cast<size_t>(tess.GetPointNo()));
  442.     for(size_t i=0;i<res.size();++i){
  443.       const Vector2D r = tess.GetMeshPoint(static_cast<int>(i));
  444.       res[i].density = Piecewise(Circle(Vector2D(0,-c.offset),c.supernova_radius),
  445.                  Uniform2D(c.supernova_radius),
  446.                  Piecewise(Circle(Vector2D(0,0), c.R_b),
  447.                        BoundedRadialPowerLaw(Vector2D(0,0),
  448.                                  -c.omega_in,
  449.                                  c.inner_density_prefactor,
  450.                                  1e-6, 10),
  451.                        BoundedRadialPowerLaw(Vector2D(0,0),
  452.                                  -c.omega_out,
  453.                                  c.outer_density_prefactor,
  454.                                  1e-6,10)))(r);
  455.       res[i].pressure = Piecewise(Circle(Vector2D(0,-c.offset),c.supernova_radius),
  456.                   Uniform2D(c.supernova_pressure),
  457.                   HydrostaticPressure(c.gravitation_constant*c.black_hole_mass,
  458.                               c.R_0,
  459.                               c.rho_0,
  460.                               c.omega_in,
  461.                               c.R_b,
  462.                               c.omega_out))(r);
  463.       res[i].velocity = Vector2D(0,0);
  464.       res[i].tracers["ejecta"] = Piecewise
  465.     (Circle(Vector2D(0,-c.offset),c.supernova_radius),
  466.      Uniform2D(1), Uniform2D(0))(r);
  467.       res[i].stickers["dummy"] = Circle(Vector2D(0,0),c.supernova_radius)(r);
  468.     }
  469.     return res;
  470.   }
  471.  
  472.   class SinkFlux: public FluxCalculator
  473.   {
  474.   public:
  475.  
  476.     SinkFlux(const RiemannSolver& rs):
  477.       rs_(rs) {}
  478.  
  479.     vector<Extensive> operator()
  480.     (const Tessellation& tess,
  481.      const vector<Vector2D>& point_velocities,
  482.      const vector<ComputationalCell>& cells,
  483.      const EquationOfState& eos,
  484.      const double /*time*/,
  485.      const double /*dt*/) const
  486.     {
  487.       vector<Extensive> res(tess.getAllEdges().size());
  488.       for(size_t i=0;i<tess.getAllEdges().size();++i){
  489.     const Conserved hydro_flux =
  490.       calcHydroFlux(tess, point_velocities,
  491.             cells, eos, i);
  492.     res[i].mass = hydro_flux.Mass;
  493.     res[i].momentum = hydro_flux.Momentum;
  494.     res[i].energy = hydro_flux.Energy;
  495.     for(std::map<std::string,double>::const_iterator it =
  496.           cells.front().tracers.begin();
  497.         it!=cells.front().tracers.end();++it)
  498.       res[i].tracers[it->first] = (it->second)*hydro_flux.Mass;
  499.       }
  500.       return res;
  501.     }
  502.  
  503.   private:
  504.     const RiemannSolver& rs_;
  505.  
  506.     const Conserved calcHydroFlux
  507.     (const Tessellation& tess,
  508.      const vector<Vector2D>& point_velocities,
  509.      const vector<ComputationalCell>& cells,
  510.      const EquationOfState& eos,
  511.      const size_t i) const
  512.     {
  513.       const Edge& edge = tess.GetEdge(static_cast<int>(i));
  514.       const std::pair<bool,bool> flags
  515.     (edge.neighbors.first>=0 && edge.neighbors.first<tess.GetPointNo(),
  516.      edge.neighbors.second>=0 && edge.neighbors.second<tess.GetPointNo());
  517.       assert(flags.first || flags.second);
  518.       if(!flags.first){
  519.     const size_t right_index =
  520.       static_cast<size_t>(edge.neighbors.second);
  521.     const ComputationalCell& right_cell = cells[right_index];
  522.     if(right_cell.stickers.find("dummy")->second)
  523.       return Conserved();
  524.     const Vector2D p = Parallel(edge);
  525.     const Primitive right = convert_to_primitive(right_cell,eos);
  526.     const Primitive left = reflect(right,p);
  527.     const Vector2D n = remove_parallel_component
  528.       (tess.GetMeshPoint(edge.neighbors.second) -
  529.        edge.vertices.first, p);
  530.     return rotate_solve_rotate_back
  531.       (rs_, left, right, 0, n, p);
  532.       }
  533.       if(!flags.second){
  534.     const size_t left_index =
  535.       static_cast<size_t>(edge.neighbors.first);
  536.     const ComputationalCell& left_cell = cells[left_index];
  537.     if(left_cell.stickers.find("dummy")->second)
  538.       return Conserved();
  539.     const Primitive left = convert_to_primitive(left_cell, eos);
  540.     const Vector2D p = Parallel(edge);
  541.     const Primitive right = reflect(left,p);
  542.     const Vector2D n = remove_parallel_component
  543.       (edge.vertices.second -
  544.        tess.GetMeshPoint(edge.neighbors.first), p);
  545.     return rotate_solve_rotate_back
  546.       (rs_, left, right, 0, n, p);
  547.       }
  548.       const size_t left_index =
  549.     static_cast<size_t>(edge.neighbors.first);
  550.       const size_t right_index =
  551.     static_cast<size_t>(edge.neighbors.second);
  552.       const ComputationalCell& left_cell = cells[left_index];
  553.       const ComputationalCell& right_cell = cells[right_index];
  554.       if(left_cell.stickers.find("dummy")->second &&
  555.      right_cell.stickers.find("dummy")->second)
  556.     return Conserved();
  557.       const Vector2D p = Parallel(edge);
  558.       const Vector2D n =
  559.     tess.GetMeshPoint(edge.neighbors.second) -
  560.     tess.GetMeshPoint(edge.neighbors.first);
  561.       const double velocity = Projection
  562.     (tess.CalcFaceVelocity
  563.      (point_velocities[left_index],
  564.       point_velocities[right_index],
  565.       tess.GetCellCM(edge.neighbors.first),
  566.       tess.GetCellCM(edge.neighbors.second),
  567.       calc_centroid(edge)),n);             
  568.       if(left_cell.stickers.find("dummy")->second){
  569.     const Primitive right =
  570.       convert_to_primitive(right_cell, eos);
  571.     const Primitive left =
  572.       ScalarProd(n,right.Velocity) < 0 ? right :
  573.       reflect(right,p);
  574.     return rotate_solve_rotate_back
  575.                      (rs_,left,right,velocity,n,p);
  576.       }
  577.       if(right_cell.stickers.find("dummy")->second){
  578.     const Primitive left =
  579.       convert_to_primitive(left_cell, eos);
  580.     const Primitive right =
  581.       ScalarProd(n,left.Velocity)>0 ?
  582.       left : reflect(left,p);
  583.     return rotate_solve_rotate_back
  584.       (rs_,left,right,velocity,n,p);
  585.       }
  586.       const Primitive left =
  587.     convert_to_primitive(left_cell, eos);
  588.       const Primitive right =
  589.     convert_to_primitive(right_cell, eos);
  590.       return rotate_solve_rotate_back
  591.     (rs_,left,right,velocity,n,p);
  592.     }
  593.   };
  594.  
  595.   class TimeStepCalculator: public Index2Member<double>
  596.   {
  597.   public:
  598.  
  599.     TimeStepCalculator(const Tessellation& tess,
  600.                const vector<ComputationalCell>& cells,
  601.                const EquationOfState& eos,
  602.                const vector<Vector2D>& point_velocities):
  603.       tess_(tess), cells_(cells),
  604.       point_velocities_(point_velocities), eos_(eos) {}
  605.  
  606.     size_t getLength(void) const
  607.     {
  608.       return cells_.size();
  609.     }
  610.  
  611.     double operator()(size_t i) const
  612.     {
  613.       return tess_.GetWidth(static_cast<int>(i))/
  614.     (eos_.dp2c(cells_[i].density, cells_[i].pressure)+
  615.      abs(cells_[i].velocity)+
  616.      abs(point_velocities_[i]));
  617.     }
  618.  
  619.   private:
  620.     const Tessellation& tess_;
  621.     const vector<ComputationalCell>& cells_;
  622.     const vector<Vector2D>& point_velocities_;
  623.     const EquationOfState& eos_;
  624.   };
  625.  
  626.   class LogCFL: public TimeStepFunction
  627.   {
  628.   public:
  629.  
  630.     LogCFL(double cfl, const string& fname):
  631.       cfl_(cfl), fname_(fname) {}
  632.  
  633.     double operator()
  634.     (const Tessellation& tess,
  635.      const vector<ComputationalCell>& cells,
  636.      const EquationOfState& eos,
  637.      const vector<Vector2D>& point_velocities,
  638.      const double /*time*/) const
  639.     {
  640.       const TimeStepCalculator tsc(tess,cells,eos,point_velocities);
  641.       double res = tsc(0);
  642.       size_t argmin = 0;
  643.       for(size_t i=1;i<tsc.getLength();++i){
  644.     const double candidate = tsc(i);
  645.     if(candidate<res && !cells[i].stickers.find("dummy")->second){
  646.       res = candidate;
  647.       argmin = i;
  648.     }  
  649.       }
  650.       ofstream f(fname_.c_str());
  651.       f << argmin << endl;
  652.       f << tess.GetMeshPoint(static_cast<int>(argmin)).x << ", ";
  653.       f << tess.GetMeshPoint(static_cast<int>(argmin)).y << endl;
  654.       f << tess.GetWidth(static_cast<int>(argmin)) << endl;
  655.       f << eos.dp2c(cells[argmin].density, cells[argmin].pressure) << endl;
  656.       f << cells[argmin].velocity.x << ", ";
  657.       f << cells[argmin].velocity.y << endl;
  658.       f << point_velocities[argmin].x << ", ";
  659.       f << point_velocities[argmin].y << endl;
  660.       f.close();
  661.       return cfl_*res;
  662.     }
  663.  
  664.   private:
  665.     const double cfl_;
  666.     const string fname_;
  667.   };
  668. }
  669.  
  670. class SimData
  671. {
  672.  
  673. public:
  674.  
  675.   SimData(const Constants& c):
  676.     pg_(Vector2D(0,0), Vector2D(0,1)),
  677.     outer_(c.lower_left, c.upper_right),
  678.     init_points_(rectangle_clip
  679.          (centered_logarithmic_spiral(0.001,
  680.                           abs(c.upper_right-c.lower_left),
  681.                           0.005,
  682.                           Vector2D(-0.1*c.offset,0)),
  683.           c.lower_left, c.upper_right)),
  684.     tess_(init_points_, outer_),
  685.     eos_(c.adiabatic_index),
  686.     rs_(),
  687.     hbc_(rs_),
  688.     interpm_(),
  689.     raw_point_motion_(),
  690.     point_motion_(raw_point_motion_,eos_),
  691.     alt_point_motion_(),
  692.     gravity_acc_(c.gravitation_constant*c.black_hole_mass,
  693.          0.01*c.parsec,
  694.          c.parsec*Vector2D(-0.01*c.offset,0)),
  695.     gravity_force_(gravity_acc_),
  696.     geom_force_(pg_.getAxis()),
  697.     force_(VectorInitializer<SourceTerm*>(&gravity_force_)
  698.        (&geom_force_)()),
  699.     tsf_(0.3, "dt_log.txt"),
  700.     fc_(rs_),
  701.     cu_(),
  702.     sim_(tess_,
  703.      outer_,
  704.      pg_,
  705.      calc_init_cond(tess_,c),
  706.      eos_,
  707.      alt_point_motion_,
  708.      force_,
  709.      tsf_,
  710.      fc_,
  711.      cu_) {}
  712.  
  713.   hdsim& getSim(void)
  714.   {
  715.     return sim_;
  716.   }
  717.  
  718. private:
  719.   const CylindricalSymmetry pg_;
  720.   const SquareBox outer_;
  721.   const vector<Vector2D> init_points_;
  722.   VoronoiMesh tess_;
  723.   VoronoiMesh proc_tess_;
  724.   const IdealGas eos_;
  725.   const Hllc rs_;
  726.   const RigidWallHydro hbc_;
  727.   PCM2D interpm_;
  728.   Lagrangian raw_point_motion_;
  729.   RoundCells point_motion_;
  730.   Eulerian alt_point_motion_;
  731.   CenterGravity gravity_acc_;
  732.   ConservativeForce gravity_force_;
  733.   CylindricalComplementary geom_force_;
  734.   SeveralSources force_;
  735.   //  const SimpleCFL tsf_;
  736.   const LogCFL tsf_;
  737.   const SinkFlux fc_;
  738.   const SimpleCellUpdater cu_;
  739.   hdsim sim_;
  740. };
  741.  
  742. class CustomDiagnostic
  743. {
  744. public:
  745.  
  746.   CustomDiagnostic(double dt,
  747.            double t_start):
  748.     dt_(dt),
  749.     t_next_(t_start),
  750.     counter_(0) {}
  751.  
  752.   void operator()(const hdsim& sim)
  753.   {
  754.     if(sim.getTime()>t_next_){
  755.       write_snapshot_to_hdf5(sim, "snapshot_"+int2str(counter_)+".h5");
  756.  
  757.       t_next_ += dt_;
  758.       ++counter_;
  759.     }
  760.   }
  761.  
  762. private:
  763.   const double dt_;
  764.   double t_next_;
  765.   int counter_;
  766. };
  767.  
  768. namespace {
  769.   /*
  770.     vector<double> calc_decade_vector(double val, size_t decades)
  771.     {
  772.     vector<double> res;
  773.     for(size_t i=0;i<decades;++i)
  774.     res.push_back(val/pow(2.0,static_cast<double>(i)+1));
  775.     return res;
  776.     }
  777.   */
  778. }
  779.  
  780. namespace {
  781.  
  782.   /*
  783.     double highest_shocked_point(const hdsim& sim)
  784.     {
  785.     const double mn_thres = 0.01;
  786.     double ys = -10;
  787.     for(int i=0;i<sim.GetCellNo();++i){
  788.     if(sim.GetCell(i).Velocity.y/sim.GetCell(i).SoundSpeed>mn_thres){
  789.     ys = max(ys,sim.GetMeshPoint(i).y);
  790.     }
  791.     }
  792.     return ys;
  793.     }
  794.   */
  795. }
  796.  
  797. namespace {
  798.   /*
  799.     class MyDiagnostic: public DiagnosticFunction
  800.     {
  801.     public:
  802.  
  803.     MyDiagnostic(double y_start,
  804.     size_t decades):
  805.     snapshot_times_(calc_decade_vector(y_start, decades)),
  806.     y_next_(y_start), counter_(0), active_(true) {}
  807.  
  808.     void operator()(const hdsim& sim)
  809.     {
  810.     if(!active_)
  811.     return;
  812.  
  813.     if(highest_shocked_point(sim)>y_next_){
  814.     write_snapshot_to_hdf5(sim,"snapshot_"+int2str(counter_)+".h5");
  815.     if(static_cast<size_t>(counter_)>snapshot_times_.size()-1)
  816.     active_ = false;
  817.     else{
  818.     y_next_ = snapshot_times_.at(static_cast<size_t>(counter_));
  819.     ++counter_;
  820.     }
  821.     }
  822.     }
  823.  
  824.     private:
  825.     const vector<double> snapshot_times_;
  826.     mutable double y_next_;
  827.     mutable int counter_;
  828.     mutable bool active_;
  829.     };
  830.   */
  831. }
  832.  
  833. namespace {
  834.   class MultipleDiagnostics: public DiagnosticFunction
  835.   {
  836.   public:
  837.  
  838.     MultipleDiagnostics(const vector<DiagnosticFunction*>& diag_list):
  839.       diag_list_(diag_list) {}
  840.  
  841.     void operator()(const hdsim& sim)
  842.     {
  843.       BOOST_FOREACH(DiagnosticFunction* df, diag_list_)
  844.     {
  845.       (*df)(sim);
  846.     }
  847.     }
  848.  
  849.   private:
  850.     const vector<DiagnosticFunction*> diag_list_;
  851.   };
  852. }
  853.  
  854. namespace {
  855.  
  856.   class WriteCycle: public DiagnosticFunction
  857.   {
  858.   public:
  859.  
  860.     WriteCycle(const string& fname):
  861.       fname_(fname) {}
  862.  
  863.     void operator()(const hdsim& sim)
  864.     {
  865.       write_number(sim.getCycle(),fname_);
  866.     }
  867.  
  868.   private:
  869.     const string fname_;
  870.   };
  871.  
  872.   void my_main_loop(hdsim& sim, const Constants& c)
  873.   {
  874.     //  sim.SetCfl(0.1);
  875.     const double tf = 400*c.year;
  876.     SafeTimeTermination term_cond_raw(tf,1e6);
  877.     ConsecutiveSnapshots diag1(new ConstantTimeInterval(1*c.year),
  878.                    new Rubric("snapshot_",".h5"));
  879.     WriteTime diag2("time.txt");
  880.     WriteConserved diag4("conserved.txt");
  881.     Bremsstrahlung diag5("luminosity_history.txt",c);
  882.     WriteCycle diag6("cycle.txt");
  883.     vector<DiagnosticFunction*> diag_list;
  884.     diag_list.push_back(&diag1);
  885.     diag_list.push_back(&diag2);
  886.     //    diag_list.push_back(&diag3);
  887.     diag_list.push_back(&diag4);
  888.     diag_list.push_back(&diag5);
  889.     diag_list.push_back(&diag6);
  890.     MultipleDiagnostics diag(diag_list);
  891.  
  892.     main_loop(sim,
  893.           term_cond_raw,
  894.           &hdsim::TimeAdvance,
  895.           &diag);
  896.   }
  897. }
  898.  
  899. namespace {
  900.   void report_error(UniversalError const& eo)
  901.   {
  902.     cout << eo.GetErrorMessage() << endl;
  903.     cout.precision(14);
  904.     for(size_t i=0;i<eo.GetFields().size();++i)
  905.       cout << eo.GetFields()[i] << " = "
  906.        << eo.GetValues()[i] << endl;
  907.   }
  908. }
  909.  
  910. int main(void)
  911. {
  912.   feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
  913.   //  MPI_Init(NULL, NULL);
  914.  
  915.   try{
  916.  
  917.     Constants c;
  918.  
  919.     SimData sim_data(c);
  920.     hdsim& sim = sim_data.getSim();
  921.  
  922.     write_snapshot_to_hdf5(sim,
  923.                "initial.h5");
  924.  
  925.     my_main_loop(sim,c);
  926.  
  927.     write_snapshot_to_hdf5(sim,
  928.                "final.h5");
  929.  
  930.   }
  931.   catch(const UniversalError& eo){
  932.     report_error(eo);
  933.     throw;
  934.   }
  935.  
  936.   return 0;
  937. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement