Advertisement
bolverk

wd_nova

Jun 18th, 2015
491
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 22.74 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include "polyfit.hpp"
  4. #include "source/newtonian/two_dimensional/physical_geometry.hpp"
  5. #include "source/newtonian/two_dimensional/geometric_outer_boundaries/SquareBox.hpp"
  6. #include "source/tessellation/VoronoiMesh.hpp"
  7. #include "source/misc/mesh_generator.hpp"
  8. #include "fermi_table.hpp"
  9. #include "source/newtonian/common/hllc.hpp"
  10. #include "source/newtonian/two_dimensional/point_motions/eulerian.hpp"
  11. #include "source/newtonian/two_dimensional/source_terms/CenterGravity.hpp"
  12. #include "source/newtonian/two_dimensional/source_terms/cylindrical_complementary.hpp"
  13. #include "source/newtonian/two_dimensional/source_terms/SeveralSources.hpp"
  14. #include "source/misc/vector_initialiser.hpp"
  15. #include "source/newtonian/two_dimensional/simple_cfl.hpp"
  16. #include "source/newtonian/two_dimensional/simple_flux_calculator.hpp"
  17. #include "source/newtonian/two_dimensional/simple_extensive_updater.hpp"
  18. #include "source/newtonian/two_dimensional/simple_cell_updater.hpp"
  19. #include "source/newtonian/two_dimensional/hdf5_diagnostics.hpp"
  20.  
  21. using namespace std;
  22.  
  23. namespace units {
  24.  
  25.   // Metric prefixes
  26.   //  const double kilo = 1e3;
  27.   //  const double centi = 1e-2;
  28.  
  29.   // Length
  30.   //  const double meter = 1e-2;
  31.  
  32.   // Time
  33.   //  const double second = 1;
  34.  
  35.   // Mass
  36.   const double gram = 1;
  37.  
  38.   // Degree
  39.   //  const double kelvin = 1;
  40.  
  41.   // Constants
  42.   //  const double solar_mass = 1.99e33;
  43.   const double gravitation_constant = 6.67e-8;
  44. }
  45.  
  46. namespace {
  47.  
  48.   bool bracketed(int low, int arg, int high)
  49.   {
  50.     return arg>=low && high>arg;
  51.   }
  52.  
  53.   map<string,pair<double,double> > generate_atomic_properties(void)
  54.   {
  55.     map<string,pair<double,double> > res;
  56.     res["He4"] = pair<double,double>(4,2);
  57.     res["C12"] = pair<double,double>(12,6);
  58.     res["O16"] = pair<double,double>(16,8);
  59.     res["Ne20"] = pair<double,double>(20,10);
  60.     res["Mg24"] = pair<double,double>(24,12);
  61.     res["Si28"] = pair<double,double>(28,14);
  62.     res["S32"] = pair<double,double>(32,16);
  63.     res["Ar36"] = pair<double,double>(36,18);
  64.     res["Ca40"] = pair<double,double>(40,20);
  65.     res["Ti44"] = pair<double,double>(44,22);
  66.     res["Cr48"] = pair<double,double>(48,44);
  67.     res["Fe52"] = pair<double,double>(52,26);
  68.     res["Ni56"] = pair<double,double>(56,28);
  69.     return res;
  70.   }
  71.  
  72.   template<class S, class T> const T& safe_map_read(const map<S,T>& m,
  73.                             const S& s)
  74.   {
  75.     assert(m.count(s)==1);
  76.     return m.find(s)->second;
  77.   }
  78.  
  79.   vector<double> load_txt(const string& fname)
  80.   {
  81.     vector<double> res;
  82.  
  83.     ifstream f(fname.c_str());
  84.     assert(f);
  85.     double buf = 0;
  86.     while(f>>buf)
  87.       res.push_back(buf);
  88.     f.close();
  89.     return res;
  90.   }
  91.  
  92.   void save_txt(const string& fname, const vector<double>& v)
  93.   {
  94.     ofstream f(fname.c_str());
  95.     assert(f);
  96.     const size_t v_size = v.size();
  97.     for(size_t i=0;i<v_size;++i)
  98.       f << v.at(i) << endl;
  99.     f.close();
  100.   }
  101.  
  102.   map<string,vector<double> > get_composition_data(void)
  103.   {
  104.     map<string,vector<double> > res;
  105.     const map<string,pair<double,double> > atomic_properties = generate_atomic_properties();
  106.     for(map<string,pair<double,double> >::const_iterator it =
  107.       atomic_properties.begin();
  108.     it != atomic_properties.end(); ++it)
  109.       res[it->first] = load_txt(string("tracer_")+it->first+".txt");
  110.     return res;
  111.   }
  112.  
  113.   bool is_strictly_increasing(const vector<double>& v)
  114.   {
  115.     for(size_t i=1;i<v.size();++i){
  116.       if(v.at(i)<=v.at(i-1))
  117.     return false;
  118.     }
  119.     return true;
  120.   }
  121.  
  122.   class Interpolator
  123.   {
  124.   public:
  125.  
  126.     Interpolator(const vector<double>& x_list,
  127.          const vector<double>& y_list):
  128.       x_list_(x_list), y_list_(y_list)
  129.     {
  130.       assert(is_strictly_increasing(x_list_));
  131.       assert(x_list_.size()==y_list_.size());
  132.     }
  133.  
  134.     double operator()(double x) const
  135.     {
  136.       const double x_list_front = x_list_.front();
  137.       const double x_list_back = x_list_.back();
  138.       assert(x>x_list_front);
  139.       assert(x<x_list_back);      
  140.       //      assert(x>x_list_.front());
  141.       //      assert(x<x_list_.back());
  142.       for(size_t i=1;i<x_list_.size();++i){
  143.     if(x_list_.at(i)>x)
  144.       return y_list_.at(i-1) + (y_list_.at(i)-y_list_.at(i-1))*
  145.         (x-x_list_.at(i-1))/(x_list_.at(i)-x_list_.at(i-1));
  146.       }
  147.       throw "point outside bound";
  148.     }
  149.  
  150.   private:
  151.     const vector<double> x_list_;
  152.     const vector<double> y_list_;
  153.   };
  154.  
  155.   class InitialData
  156.   {
  157.   public:
  158.  
  159.     const vector<double> radius_list;
  160.     const vector<double> density_list;
  161.     const vector<double> temperature_list;
  162.     const vector<double> velocity_list;
  163.     const map<string,vector<double> > tracers_list;
  164.  
  165.     InitialData(const string& radius_file,
  166.         const string& density_file,
  167.         const string& temperature_file,
  168.         const string& velocity_file):
  169.       radius_list(load_txt(radius_file)),
  170.       density_list(load_txt(density_file)),
  171.       temperature_list(load_txt(temperature_file)),
  172.       velocity_list(load_txt(velocity_file)),
  173.       tracers_list(get_composition_data()) {}
  174.   };
  175.  
  176.   vector<double> create_pressure_reference(const FermiTable& eos,
  177.                        const InitialData& id)
  178.   {
  179.     vector<double> res(id.radius_list.size());
  180.     for(size_t i=0;i<id.radius_list.size();++i){
  181.       map<string,double> tracer;
  182.       for(map<string,vector<double> >::const_iterator it=
  183.         id.tracers_list.begin();
  184.       it!=id.tracers_list.end();
  185.       ++it)
  186.     tracer[it->first] = (it->second).at(i);
  187.       res[i] = eos.dt2p(id.density_list.at(i),
  188.             id.temperature_list.at(i),
  189.             tracer);
  190.     }
  191.     return res;
  192.   }
  193.  
  194.   pair<Vector2D, Vector2D> stretch(const pair<Vector2D,Vector2D>& boundaries,
  195.                    double ratio)
  196.   {
  197.     const Vector2D centre = 0.5*(boundaries.first + boundaries.second);
  198.     return pair<Vector2D,Vector2D>(centre+ratio*(boundaries.first-centre),
  199.                    centre+ratio*(boundaries.second-centre));
  200.   }
  201.  
  202.   bool is_in(const Vector2D& point,
  203.          const pair<Vector2D,Vector2D>& boundaries)
  204.   {
  205.     return ((boundaries.first.x<point.x) &&
  206.         (boundaries.second.x>point.x) &&
  207.         (boundaries.first.y<point.y) &&
  208.         (boundaries.second.y>point.y));
  209.      
  210.   }
  211.  
  212.   vector<Vector2D> rectangular_clip(const vector<Vector2D>& point_list,
  213.                     const pair<Vector2D,Vector2D>& boundaries)
  214.   {
  215.     vector<Vector2D> res;
  216.     for(size_t i=0;i<point_list.size();++i){
  217.       if(is_in(point_list.at(i),boundaries))
  218.     res.push_back(point_list.at(i));
  219.     }
  220.     return res;
  221.   }
  222.  
  223.   vector<Vector2D> create_grid(const pair<Vector2D,Vector2D>& boundaries,
  224.                    const double dq,
  225.                    const double r_min)
  226.   {
  227.     vector<Vector2D> res;
  228.     //   const double r_min = 0.1*boundaries.first.y;
  229.     const double r_max = boundaries.second.y;
  230.     for(double r=r_min;
  231.     r<r_max;
  232.     r*=(1+dq)){
  233.       for(double q=0;q<2*M_PI;q+=dq)
  234.     res.push_back(Vector2D(r*cos(q),r*sin(q)));
  235.     }
  236.     res = rectangular_clip(res,stretch(boundaries,0.99));
  237.     ofstream f("mesh_points.txt");
  238.     for(size_t i=0;i<res.size();++i)
  239.       f << res.at(i).x << " " << res.at(i).y << endl;
  240.     f.close();
  241.     return res;
  242.   }
  243.  
  244.   double calc_tracer_flux(const Edge& edge,
  245.               const Tessellation& tess,
  246.               const vector<ComputationalCell>& cells,
  247.               const string& name,
  248.               const Conserved& hf)
  249.   {
  250.     if(hf.Mass>0 &&
  251.        edge.neighbors.first>0 &&
  252.        edge.neighbors.first<tess.GetPointNo()){
  253.       assert(cells.at(static_cast<size_t>(edge.neighbors.first)).tracers.count(name)==1);
  254.       return hf.Mass*
  255.     cells.at(static_cast<size_t>(edge.neighbors.first)).tracers.find(name)->second;
  256.     }
  257.     if(hf.Mass<0 &&
  258.        edge.neighbors.second>0 &&
  259.        edge.neighbors.second<tess.GetPointNo()){
  260.       assert(cells.at(static_cast<size_t>(edge.neighbors.second)).tracers.count(name)==1);
  261.       return hf.Mass*
  262.     cells.at(static_cast<size_t>(edge.neighbors.second)).tracers.find(name)->second;
  263.     }
  264.     return 0;    
  265.   }
  266.  
  267.   class InnerBC: public FluxCalculator
  268.   {
  269.   public:
  270.  
  271.     InnerBC(const RiemannSolver& rs,
  272.         const string& ghost,
  273.         const double radius):
  274.       rs_(rs), ghost_(ghost), radius_(radius) {}
  275.  
  276.     vector<Extensive> operator()
  277.     (const Tessellation& tess,
  278.      const vector<Vector2D>& point_velocities,
  279.      const vector<ComputationalCell>& cells,
  280.      const EquationOfState& eos,
  281.      const double /*time*/,
  282.      const double /*dt*/) const
  283.     {
  284.       vector<Extensive> res(tess.getAllEdges().size());
  285.       for(size_t i=0;i<tess.getAllEdges().size();++i){
  286.     const Conserved hydro_flux =
  287.       calcHydroFlux(tess,point_velocities,
  288.             cells, eos, i);
  289.     res.at(i).mass = hydro_flux.Mass;
  290.     res.at(i).momentum = hydro_flux.Momentum;
  291.     res.at(i).energy = hydro_flux.Energy;
  292.     for(map<string,double>::const_iterator it =
  293.           cells.front().tracers.begin();
  294.         it!=cells.front().tracers.end();
  295.         ++it)
  296.       res.at(i).tracers[it->first] =
  297.         calc_tracer_flux(tess.getAllEdges().at(i),
  298.                  tess,cells,it->first,hydro_flux);
  299.       }
  300.       return res;
  301.     }
  302.  
  303.   private:
  304.     const RiemannSolver& rs_;
  305.     const string ghost_;
  306.     const double radius_;
  307.  
  308.     const Conserved calcHydroFlux
  309.     (const Tessellation& tess,
  310.      const vector<Vector2D>& point_velocities,
  311.      const vector<ComputationalCell>& cells,
  312.      const EquationOfState& eos,
  313.      const size_t i) const
  314.     {
  315.       const Edge& edge = tess.GetEdge(static_cast<int>(i));
  316.       const pair<bool,bool> flags
  317.     (edge.neighbors.first>=0 && edge.neighbors.first<tess.GetPointNo(),
  318.      edge.neighbors.second>=0 && edge.neighbors.second<tess.GetPointNo());
  319.       assert(flags.first || flags.second);
  320.       if(!flags.first){
  321.     const size_t right_index = static_cast<size_t>(edge.neighbors.second);
  322.     const ComputationalCell& right_cell = cells.at(right_index);
  323.     if(right_cell.stickers.find(ghost_)->second)
  324.       return Conserved();
  325.     const Vector2D p = Parallel(edge);
  326.     const Primitive right = convert_to_primitive(right_cell, eos);
  327.     const Primitive left = reflect(right,p);
  328.     const Vector2D n = remove_parallel_component
  329.       (tess.GetMeshPoint(edge.neighbors.second)-
  330.        edge.vertices.first,p);
  331.     return rotate_solve_rotate_back
  332.       (rs_, left, right, 0, n, p);
  333.       }
  334.       if(!flags.second){
  335.     const size_t left_index =
  336.       static_cast<size_t>(edge.neighbors.first);
  337.     const ComputationalCell& left_cell = cells.at(left_index);
  338.     if(left_cell.stickers.find(ghost_)->second)
  339.       return Conserved();
  340.     const Primitive left = convert_to_primitive(left_cell, eos);
  341.     const Vector2D p = Parallel(edge);
  342.     const Primitive right = reflect(left, p);
  343.     const Vector2D n = remove_parallel_component
  344.       (edge.vertices.second -
  345.        tess.GetMeshPoint(edge.neighbors.first),p);
  346.     return rotate_solve_rotate_back
  347.       (rs_, left, right, 0, n, p);
  348.       }
  349.       const size_t left_index =
  350.     static_cast<size_t>(edge.neighbors.first);
  351.       const size_t right_index =
  352.     static_cast<size_t>(edge.neighbors.second);
  353.       const ComputationalCell& left_cell = cells.at(left_index);
  354.       const ComputationalCell& right_cell = cells.at(right_index);
  355.       if(left_cell.stickers.find(ghost_)->second &&
  356.      right_cell.stickers.find(ghost_)->second)
  357.     return Conserved();
  358.       const Vector2D p = Parallel(edge);
  359.       const Vector2D n =
  360.     tess.GetMeshPoint(edge.neighbors.second) -
  361.     tess.GetMeshPoint(edge.neighbors.first);
  362.       const double velocity = Projection
  363.     (tess.CalcFaceVelocity
  364.      (point_velocities.at(left_index),
  365.       point_velocities.at(right_index),
  366.       tess.GetCellCM(edge.neighbors.first),
  367.       tess.GetCellCM(edge.neighbors.second),
  368.       calc_centroid(edge)),n);
  369.       if(left_cell.stickers.find(ghost_)->second){
  370.     const Primitive right =
  371.       convert_to_primitive(right_cell, eos);
  372.     const Primitive left =
  373.       (abs(tess.GetMeshPoint(static_cast<int>(right_index)))>radius_) ?
  374.       right : reflect(right,p);
  375.     return rotate_solve_rotate_back
  376.       (rs_,left,right,velocity,n,p);
  377.       }
  378.       if(right_cell.stickers.find(ghost_)->second){
  379.     const Primitive left =
  380.       convert_to_primitive(left_cell, eos);
  381.     const Primitive right =
  382.       (abs(tess.GetMeshPoint(static_cast<int>(left_index)))>radius_) ?
  383.       left : reflect(left,p);
  384.     return rotate_solve_rotate_back
  385.       (rs_,left,right,velocity,n,p);
  386.       }
  387.       const Primitive left =
  388.     convert_to_primitive(left_cell, eos);
  389.       const Primitive right =
  390.     convert_to_primitive(right_cell, eos);
  391.       return rotate_solve_rotate_back
  392.     (rs_,left,right,velocity,n,p);
  393.     }
  394.   };
  395.  
  396.   class LazyCellUpdater: public CellUpdater
  397.   {
  398.   public:
  399.  
  400.     LazyCellUpdater(void) {}
  401.  
  402.     vector<ComputationalCell> operator()
  403.     (const Tessellation& /*tess*/,
  404.      const PhysicalGeometry& /*pg*/,
  405.      const EquationOfState& eos,
  406.      const vector<Extensive>& extensives,
  407.      const vector<ComputationalCell>& old,
  408.      const CacheData& cd) const
  409.     {
  410.       vector<ComputationalCell> res = old;
  411.       for(size_t i=0;i<extensives.size();++i){
  412.     if(old.at(i).stickers.find("ghost")->second)
  413.       continue;
  414.     const double volume = cd.volumes[i];
  415.     res.at(i).density = extensives.at(i).mass/volume;
  416.     res.at(i).velocity = extensives.at(i).momentum/extensives.at(i).mass;
  417.     const double total_energy = extensives.at(i).energy/extensives.at(i).mass;
  418.     const double kinetic_energy = 0.5*ScalarProd(res.at(i).velocity, res.at(i).velocity);
  419.     const double thermal_energy = total_energy - kinetic_energy;
  420.     for(map<string,double>::const_iterator it =
  421.           extensives.at(i).tracers.begin();
  422.         it!=extensives.at(i).tracers.end();
  423.         ++it)
  424.       res.at(i).tracers[it->first] = it->second/extensives.at(i).mass;
  425.     res.at(i).pressure = eos.de2p(res.at(i).density, thermal_energy, res.at(i).tracers);
  426.       }
  427.       return res;
  428.     }
  429.   };
  430.  
  431.   vector<ComputationalCell> calc_init_cond(const Tessellation& tess,
  432.                        const FermiTable& eos,
  433.                        const InitialData& id,
  434.                        const Shape2D& cd)
  435.   {
  436.     save_txt("pressure_reference.txt",create_pressure_reference(eos,id));
  437.     vector<ComputationalCell> res(static_cast<size_t>(tess.GetPointNo()));
  438.     const Interpolator density_interpolator(id.radius_list,
  439.                         id.density_list);
  440.     const Interpolator temperature_interpolator(id.radius_list,
  441.                         id.temperature_list);
  442.     const Interpolator velocity_interpolator(id.radius_list,
  443.                          id.velocity_list);
  444.     map<string,Interpolator*> tracer_intepolators;
  445.     for(map<string,vector<double> >::const_iterator it=
  446.       id.tracers_list.begin();
  447.     it!=id.tracers_list.end(); ++it)
  448.       tracer_intepolators[it->first] = new Interpolator(id.radius_list,
  449.                             it->second);
  450.     for(size_t i=0;i<res.size();++i){
  451.       res.at(i).density = id.density_list.back();
  452.       res.at(i).velocity = Vector2D(0,0);
  453.       res.at(i).stickers["ghost"] = true;
  454.       for(map<string,Interpolator*>::const_iterator it=
  455.         tracer_intepolators.begin();
  456.       it!=tracer_intepolators.end();
  457.       ++it)
  458.     res.at(i).tracers[it->first] = 0;
  459.       res.at(i).tracers["He4"] = 1;
  460.       res.at(i).pressure = eos.dt2p(res.at(i).density,
  461.                     id.temperature_list.back(),
  462.                     res.at(i).tracers);
  463.       const Vector2D r = tess.GetMeshPoint(static_cast<int>(i));
  464.       const double radius = abs(r);
  465.       /*
  466.     if(radius<id.radius_list.front() || radius>id.radius_list.back())
  467.     continue;
  468.       */
  469.       if(!cd(r))
  470.     continue;
  471.       res.at(i).stickers["ghost"] = false;
  472.       const double density = density_interpolator(radius);
  473.       const double temperature = temperature_interpolator(radius);
  474.       const double velocity = velocity_interpolator(radius);
  475.       for(map<string,Interpolator*>::const_iterator it=
  476.         tracer_intepolators.begin();
  477.       it!=tracer_intepolators.end();
  478.       ++it)
  479.     res.at(i).tracers[it->first] = (*(it->second))(radius);
  480.       const double pressure = eos.dt2p(density, temperature, res.at(i).tracers);
  481.       res.at(i).density = density;
  482.       res.at(i).pressure = pressure;
  483.       res.at(i).velocity = r*velocity/radius;
  484.     }
  485.     for(map<string,Interpolator*>::iterator it=
  486.       tracer_intepolators.begin();
  487.     it!=tracer_intepolators.end();
  488.     ++it)
  489.       delete it->second;
  490.     return res;
  491.   }
  492.  
  493.   class CircularSection: public Shape2D
  494.   {
  495.   public:
  496.  
  497.     CircularSection(const double radius_in,
  498.             const double radius_out,
  499.             const double angle_left,
  500.             const double angle_right):
  501.       radius_in_(radius_in),
  502.       radius_out_(radius_out),
  503.       angle_left_(angle_left),
  504.       angle_right_(angle_right) {}
  505.  
  506.     bool operator()(const Vector2D& r) const
  507.     {
  508.       const double radius = abs(r);
  509.       const double angle = atan2(r.y,r.x);
  510.       return (radius_in_<radius &&
  511.           radius_out_>radius &&
  512.           angle_left_<angle &&
  513.           angle_right_>angle);
  514.     }
  515.  
  516.   private:
  517.     const double radius_in_;
  518.     const double radius_out_;
  519.     const double angle_left_;
  520.     const double angle_right_;
  521.   };
  522.  
  523.   class LazyExtensiveUpdater: public ExtensiveUpdater
  524.   {
  525.   public:
  526.  
  527.     LazyExtensiveUpdater(void) {}
  528.  
  529.     void operator()
  530.     (const vector<Extensive>& fluxes,
  531.      const PhysicalGeometry& /*pg*/,
  532.      const Tessellation& tess,
  533.      const double dt,
  534.      const CacheData& cd,
  535.      const vector<ComputationalCell>& cells,
  536.      vector<Extensive>& extensive) const
  537.     {
  538.       const vector<Edge>& edge_list = tess.getAllEdges();
  539.       for(size_t i=0;i<edge_list.size();++i){
  540.     const Edge& edge = edge_list.at(i);
  541.     const Extensive delta = dt*cd.areas[i]*fluxes.at(i);
  542.     if(bracketed(0,edge.neighbors.first,tess.GetPointNo()) &&
  543.        !safe_map_read
  544.        (cells.at(static_cast<size_t>(edge.neighbors.first)).stickers,string("ghost")))
  545.       extensive.at(static_cast<size_t>(edge.neighbors.first)) -= delta;
  546.     if(bracketed(0,edge.neighbors.second,tess.GetPointNo()) &&
  547.        !safe_map_read
  548.        (cells.at(static_cast<size_t>(edge.neighbors.second)).stickers,string("ghost")))
  549.       extensive.at(static_cast<size_t>(edge.neighbors.second)) += delta;
  550.       }
  551.     }
  552.   };
  553.  
  554.   template<typename T> vector<T> polyfit_sc(const pair<vector<T>,vector<T> >& x_y, int deg)
  555.   {
  556.     return polyfit(x_y.first, x_y.second, deg);
  557.   }
  558.  
  559.   vector<pair<double,double> > calc_mass_radius_list(const Tessellation& tess,
  560.                              const vector<ComputationalCell>& cells,
  561.                              const CacheData& cd)
  562.   {
  563.     vector<pair<double, double> > res;
  564.     for(size_t i=0;i<cells.size();++i){
  565.       if(cells[i].stickers.find("ghost")->second)
  566.     continue;
  567.       const double radius = abs(tess.GetMeshPoint(static_cast<int>(i)));
  568.       const double mass = cd.volumes[i]*cells[i].density;
  569.       res.push_back(pair<double,double>(radius,mass));
  570.     }
  571.     return res;
  572.   }
  573.  
  574.   vector<double> calc_mass_in_shells(const vector<pair<double,double> >& mass_radius_list,
  575.                      const vector<double>& sample_points)
  576.   {
  577.     vector<double> res(sample_points.size(),0);
  578.     for(vector<pair<double,double> >::const_iterator it=
  579.       mass_radius_list.begin();
  580.     it!=mass_radius_list.end();
  581.     ++it){
  582.       for(size_t i=0;i<sample_points.size();++i){
  583.     if(sample_points[i]>it->first)
  584.       res[i] += it->second;
  585.     else
  586.       break;
  587.       }
  588.     }
  589.     return res;
  590.   }
  591.  
  592.   class MonopoleSelfGravity: public SourceTerm
  593.   {
  594.   public:
  595.  
  596.     MonopoleSelfGravity(const vector<double>& sample_radii,
  597.             double gravitation_constant,
  598.             const pair<double,double>& section_angles):
  599.       sample_radii_(sample_radii),
  600.       gravitation_constant_(gravitation_constant),
  601.       section2shell_(2./(cos(section_angles.second)-cos(section_angles.first))) {}
  602.  
  603.     vector<Extensive> operator()
  604.     (const Tessellation& tess,
  605.      const PhysicalGeometry& /*pg*/,
  606.      const CacheData& cd,
  607.      const vector<ComputationalCell>& cells,
  608.      const vector<Extensive>& /*fluxes*/,
  609.      const vector<Vector2D>& /*point_velocities*/,
  610.      const double /*t*/) const
  611.     {
  612.       const vector<double> mass_sample =
  613.     calc_mass_in_shells(calc_mass_radius_list(tess,cells,cd),
  614.                 sample_radii_);
  615.       const Interpolator radius_mass_interp(sample_radii_,
  616.                         mass_sample);
  617.       vector<Extensive> res(static_cast<size_t>(tess.GetPointNo()));
  618.       for(size_t i=0;i<res.size();++i){
  619.     if(cells[i].stickers.find("ghost")->second)
  620.       continue;
  621.     const Vector2D r = tess.GetCellCM(static_cast<int>(i));
  622.     const double radius = abs(r);
  623.     const double mass = radius_mass_interp(radius)*section2shell_;
  624.     const Vector2D acc = (-1)*gravitation_constant_*r*mass/pow(radius,3);
  625.     const double volume = cd.volumes[i];
  626.     res[i].mass = 0;
  627.     res[i].momentum = volume*cells[i].density*acc;
  628.     res[i].energy = volume*cells[i].density*ScalarProd(acc,cells[i].velocity);
  629.       }
  630.       return res;
  631.     }
  632.  
  633.   private:
  634.     const vector<double> sample_radii_;
  635.     const double gravitation_constant_;
  636.     const double section2shell_;
  637.   };
  638. }
  639.  
  640. class SimData
  641. {
  642. public:
  643.  
  644.   SimData(const InitialData& id):
  645.     pg_(Vector2D(0,0), Vector2D(1,0)),
  646.     outer_(Vector2D(-0.5*id.radius_list.front(),0.9*id.radius_list.front()),
  647.        Vector2D(0.5*id.radius_list.front(),1.2*id.radius_list.back())),
  648.     //  tess_(cartesian_mesh(100,100,outer_.getBoundary().first,outer_.getBoundary().second),
  649.     tess_(create_grid(outer_.getBoundary(),1e-2,0.9*id.radius_list.front()),
  650.       outer_),
  651.     eos_("eos_tab.coded",1,1,0,generate_atomic_properties()),
  652.     rs_(),
  653.     point_motion_(),
  654.     gravity_acc_(units::gravitation_constant*1.816490e33*units::gram,
  655.          1, Vector2D(0,0)),
  656.     gravity_force_(gravity_acc_),
  657.     msg_(linspace(id.radius_list.front(),id.radius_list.back(),100),
  658.      units::gravitation_constant,
  659.      pair<double,double>(M_PI*0.46,M_PI*0.54)),
  660.     geom_force_(pg_.getAxis()),
  661.     force_(VectorInitialiser<SourceTerm*>(&gravity_force_)
  662.        (&geom_force_)(&msg_)()),
  663.     tsf_(0.3),
  664.     fc_(rs_,string("ghost"),2*id.radius_list.back()),
  665.     eu_(),
  666.     cu_(),
  667.     sim_(tess_,
  668.      outer_,
  669.      pg_,
  670.      calc_init_cond(tess_,eos_,id,CircularSection(id.radius_list.front(),
  671.                               id.radius_list.back(),
  672.                               0.46*M_PI,
  673.                               0.54*M_PI)),
  674.      eos_,
  675.      point_motion_,
  676.      force_,
  677.      tsf_,
  678.      fc_,
  679.      eu_,
  680.      cu_) {}
  681.  
  682.   hdsim& getSim(void)
  683.   {
  684.     return sim_;
  685.   }
  686.  
  687. private:
  688.   const CylindricalSymmetry pg_;
  689.   const SquareBox outer_;
  690.   VoronoiMesh tess_;
  691.   const FermiTable eos_;
  692.   const Hllc rs_;
  693.   Eulerian point_motion_;
  694.   CenterGravity gravity_acc_;
  695.   ConservativeForce gravity_force_;
  696.   MonopoleSelfGravity msg_;
  697.   CylindricalComplementary geom_force_;
  698.   SeveralSources force_;
  699.   const SimpleCFL tsf_;
  700.   //  const SimpleFluxCalculator fc_;
  701.   const InnerBC fc_;
  702.   //  const SimpleExtensiveUpdater eu_;
  703.   const LazyExtensiveUpdater eu_;
  704.   //  const SimpleCellUpdater cu_;
  705.   const LazyCellUpdater cu_;
  706.   hdsim sim_;
  707. };
  708.  
  709. int main(void)
  710. {
  711.   SimData sim_data(InitialData("radius_list.txt",
  712.                    "density_list.txt",
  713.                    "temperature_list.txt",
  714.                    "velocity_list.txt"));
  715.   hdsim& sim = sim_data.getSim();
  716.   write_snapshot_to_hdf5(sim,"initial.h5");
  717.   while(sim.getTime()<1e-1){
  718.     cout << sim.getTime() << endl;
  719.     sim.TimeAdvance();
  720.   }
  721.   //  sim.TimeAdvance();
  722.   write_snapshot_to_hdf5(sim,"final.h5");
  723.   return 0;
  724. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement