/// <summary> Planetary system contructor. Builds an accretion disc for the /// specified planet around the specified star. This has not been /// exercised to any significant degree, because moon formation /// doesn't seem to follow Dole's model quite as well. /// </summary> /// <param name="s">Primary for this system. /// </param> /// <param name="p">Planet around which these moons will form. /// </param> public Protosystem(Star s, Planet p) { star = s; planet = p; body_inner_bound = planet.nearest_moon(); body_outer_bound = planet.farthest_moon(); disc = new DustDisc(0.0, star.stellar_dust_limit(), planet.nearest_moon(), planet.farthest_moon()); disc.cloud_eccentricity = 0.2; }
/// <summary> Star system contructor. Builds an accretion disc for the /// specified star. /// </summary> /// <param name="s">Primary for this system. /// </param> public Protosystem(Star s) { star = s; planet = null; //planet_head = null; body_inner_bound = star.nearest_planet(); body_outer_bound = star.farthest_planet(); disc = new DustDisc(0.0, star.stellar_dust_limit(), star.nearest_planet(), star.farthest_planet()); disc.cloud_eccentricity = 0.2; }
/// <summary> Creates the planets of this system using Dole's accretion algorithm.</summary> private void Initialize() { PlanetClassifier pc = new PlanetClassifier(); Planet last_planet = null, cur_planet = null; //Protoplanet p; ArrayList protoplanetsList = new ArrayList(); //int I; Protosystem ps = new Protosystem(Primary); ps.dist_planetary_masses(); //p = ps.planet_head; foreach (Protoplanet p in ps.protoplanetsList) { if (p.mass > 0.0) { cur_planet = new Planet(p); cur_planet.age = Primary.age; // not sure why, but planets are missing age when generated, so i'll put this here cur_planet.orbit_zone = Primary.orb_zone(cur_planet.a); cur_planet.set_vital_stats(Primary.SM, Primary.r_greenhouse, Primary.r_ecosphere, Primary.age); cur_planet.description = pc.planetType(cur_planet); // could generate moons here // 1. generate a new protosystem based on the planet and star // 2. pull out all of the protoplanets and create moons from them // 3. delete the protosystem #region Added: moons [Yan] //not sure if it's ok to calculate this way, satellites can be created individually as planets and then get snatched by bigger planet but it works this way too //planet migration due to orbital drag not calculated too Protosystem ps_moons = new Protosystem(Primary, cur_planet); ps_moons.dist_moon_masses(); Planet last_moon = null, cur_moon = null; foreach (Protoplanet p_moon in ps_moons.protoplanetsList) { if (p_moon.mass > 0.0) { cur_moon = new Planet(p_moon); if (last_moon != null) { if (cur_moon.mass > 0.0000001) // fine-tweaked to give some moons, but not too many { cur_planet.moons.Add(cur_moon); } } last_moon = cur_moon; } } #endregion if (last_planet != null) { this.planetsList.Add(cur_planet); } last_planet = cur_planet; } } ps = null; planetsList.Sort(new PlanetSort(SortDirection.Ascending)); }
/// <summary> Returns a string describing the planet in general terms.</summary> /// <param name="p">Planet object to be described /// </param> /// <returns>s Constant string description /// </returns> public virtual System.String planetType(Planet p) { if (p.mass < 0.01) return "Asteroidal"; if (p.gas_giant) { //I use effective temp based on distance from sun, becuse gas giants don't //have a surface, and thus don't have surface temperature string hot = (p.eff_temp(p.r_ecosphere) > 500) ? "Hot, " : ""; if (p.mass < 50.0) return hot + "Small gas giant"; else if (p.mass > 1000.0) return hot + "Brown dwarf"; else return hot + "Large gas giant"; } else { if ((p.age > 1e+9) // changed from 2.7, it's in megayears && (p.a > 0.8 * p.r_ecosphere) && (p.a < 1.2 * p.r_ecosphere) && (p.day < 96.0) && (p.surf_temp > (273.15 - 30.0)) //changed from -1 Even if average temp not suitable, on equator/poles can be habitable && (p.surf_temp < (273.15 + 40.0)) //changed from +30 && (p.surf_pressure > 360) //changed from 0.36 ? && (p.surf_pressure < 2600.0) && ((p.ice_cover + p.hydrosphere < 1.0) && (p.hydrosphere > 0.0))) return "Habitable"; if ((p.mass > 0.4) && (p.a > 0.65 * p.r_ecosphere) && (p.a < 1.35 * p.r_ecosphere) && (p.surf_temp > (273.15 - 45.0)) && (p.surf_pressure > 0.05) && (p.surf_pressure < 8000.0) && ((p.ice_cover > 0.0) || (p.hydrosphere > 0.0))) return "Marginally habitable"; if (p.ice_cover > 0.95) return "Iceworld"; if (p.hydro_fraction() > 0.95 && p.avg_temp > PhysicalConstants.FREEZING_POINT_OF_WATER && p.avg_temp < p.boil_point) return "Waterworld"; if (p.surf_temp < 100.0) return "Frigid airless rock"; if (p.surf_pressure < 0.01) { if (p.surf_temp < 273.0) return "Cold airless rock"; return "Hot airless rock"; } else if (p.surf_pressure > 10000.0) { if (p.surf_temp > 273.0) return "Hot, dense atmosphere"; else return "Cold, dense atmosphere"; } else { if (p.surf_temp > (((p.boil_point - 273.0) / 2.0) + 273.0)) return "Hot terrestrial"; if (p.surf_temp < 273.0) return "Frozen terrestrial"; return "Terrestrial"; } } }
public virtual double roche_limit(Star primary, Planet innermost_planet) { double d; d = primary.radius * Math.Pow( ((primary.MASS() * PhysicalConstants.SUN_MASS_IN_EARTH_MASSES / (4 / 3 * Math.PI * Math.Pow(primary.radius, 3))) / innermost_planet.density) , 1 / 3); return d; }