Пример #1
0
        /// <summary>
        /// Fogg's information for this routine came from Dole "Habitable Planets
        /// for Man", Blaisdell Publishing Company, NY, 1964.  From this, he came
        /// up with his eq.12, which is the equation for the base_angular_velocity
        /// below.  Going a bit further, he found an equation for the change in
        /// angular velocity per time (dw/dt) from P. Goldreich and S. Soter's paper
        /// "Q in the Solar System" in Icarus, vol 5, pp.375-389 (1966).  Comparing
        /// to the change in angular velocity for the Earth, we can come up with an
        /// approximation for our new planet (his eq.13) and take that into account.
        /// </summary>
        public static Double DayLength(ref SolarSystem system, Double mass, Double radius, Double orbital_period, Double eccentricity, Boolean giant)
        {
            system.spin_resonance = false;
            Double k2 = giant ? 0.24 : 0.33;
            Double planetary_mass_in_grams = mass * Constants.SOLAR_MASS_IN_GRAMS;
            Double equatorial_radius_in_cm = radius * Constants.CM_PER_KM;
            Double base_angular_velocity   = Math.Sqrt(2.0 * Constants.J * (planetary_mass_in_grams) / (k2 * Math.Pow(equatorial_radius_in_cm, 2.0)));
            /*   This next term describes how much a planet's rotation is slowed by    */
            /*  it's moons.  Find out what dw/dt is after figuring out Goldreich and   */
            /*  Soter's Q'.                                                            */
            Double change_in_angular_velocity = 0.0;
            Double temp = base_angular_velocity + (change_in_angular_velocity * system.age);

            /*   'temp' is now the angular velocity. Now we change from rad/sec to     */
            /*  hours/rotation.                               */
            temp = 1.0 / ((temp / SolarSystem.radians_per_rotation) * Constants.SECONDS_PER_HOUR);
            if (!(temp >= orbital_period))
            {
                return(temp);
            }
            Double spin_resonance_period = ((1.0 - eccentricity) / (1.0 + eccentricity)) * orbital_period;

            system.Callback("...maybe: " + spin_resonance_period + "\n");
            if (eccentricity > 0.01)
            {
                system.Callback("...resonance...\n");
                temp = spin_resonance_period;
                system.spin_resonance = true;
            }
            else
            {
                temp = orbital_period;
            }
            return(temp);
        }
Пример #2
0
        public static Planet DistributePlanetaryMasses(ref SolarSystem system, Double stellar_mass_ratio, Double stellar_luminosity_ratio, Double inner_dust, Double outer_dust)
        {
            SetInitialConditions(system, inner_dust, outer_dust);
            Double planetesimal_inner_bound = InnermostPlanet(stellar_mass_ratio);
            Double planetesimal_outer_bound = OutermostPlanet(stellar_mass_ratio);

            while (system.dust_left)
            {
                Double a    = system.random.Range(planetesimal_inner_bound, planetesimal_outer_bound);
                Double e    = system.random.Eccentricity();
                Double mass = Constants.PROTOPLANET_MASS;
                if (system.verbose)
                {
                    system.Callback("Checking " + a + " AU.\n");
                }
                if (!DustAvailable(system, InnerEffectLimit(system, a, e, mass), OuterEffectLimit(system, a, e, mass)))
                {
                    if (system.verbose)
                    {
                        system.Callback(".. failed.\n");
                    }
                    continue;
                }
                system.Callback(".. Injecting protoplanet.\n");
                system.dust_density = Constants.DUST_DENSITY_COEFF * Math.Sqrt(stellar_mass_ratio) * Math.Exp(-Constants.ALPHA * Math.Pow(a, 1.0 / Constants.N));
                Double crit_mass = CriticalLimit(a, e, stellar_luminosity_ratio);
                AccreteDust(ref system, ref mass, a, e, crit_mass, planetesimal_inner_bound, planetesimal_outer_bound);
                if ((mass != 0.0) && (mass != Constants.PROTOPLANET_MASS))
                {
                    CoalescePlanetesimals(ref system, a, e, mass, crit_mass, stellar_luminosity_ratio, planetesimal_inner_bound, planetesimal_outer_bound);
                }
                else
                {
                    system.Callback(".. failed due to large neighbor.\n");
                }
            }
            return(system.planet_head);
        }
Пример #3
0
        /// <summary>
        ///  This implements Fogg's eq.17.  The 'inventory' returned is unitless.
        /// </summary>
        public static Double VolInventory(SolarSystem system, Double mass, Double escape_vel, Double rms_vel, Double stellar_mass, Int32 zone, Boolean greenhouse_effect)
        {
            Double proportion_const;
            Double velocity_ratio = escape_vel / rms_vel;

            if (!(velocity_ratio >= Constants.GAS_RETENTION_THRESHOLD))
            {
                return(0.0);
            }
            switch (zone)
            {
            case 1:
                proportion_const = 100000.0;
                break;

            case 2:
                proportion_const = 75000.0;
                break;

            case 3:
                proportion_const = 250.0;
                break;

            default:
                proportion_const = 10.0;
                system.Callback("Error: orbital zone not initialized correctly!\n");
                break;
            }
            Double mass_in_earth_units = mass * Constants.EARTH_MASSES_PER_SOLAR_MASS;
            Double temp1 = (proportion_const * mass_in_earth_units) / stellar_mass;
            Double temp2 = system.random.About(temp1, 0.2);

            if (greenhouse_effect)
            {
                return(temp2);
            }
            return(temp2 / 100.0);
        }
Пример #4
0
        public static void CoalescePlanetesimals(ref SolarSystem system, Double a, Double e, Double mass, Double crit_mass, Double stellar_luminosity_ratio, Double body_inner_bound, Double body_outer_bound)
        {
            Boolean coalesced = false;
            Planet  node1     = system.planet_head;
            Planet  node2     = null;
            Planet  node3     = null;

            while (node1 != null)
            {
                node2 = node1;
                Double temp = node1.a - a;
                Double dist1;
                Double dist2;
                if (temp > 0.0)
                {
                    dist1 = a * (1.0 + e) * (1.0 + system.reduced_mass) - a;
                    /* x aphelion   */
                    system.reduced_mass = Math.Pow(node1.mass / (1.0 + node1.mass), 1.0 / 4.0);
                    dist2 = node1.a
                            - node1.a * (1.0 - node1.e) * (1.0 - system.reduced_mass);
                }
                else
                {
                    dist1 = a - a * (1.0 - e) * (1.0 - system.reduced_mass);
                    /* x perihelion */
                    system.reduced_mass = Math.Pow(node1.mass / (1.0 + node1.mass), 1.0 / 4.0);
                    dist2 = node1.a * (1.0 + node1.e) * (1.0 + system.reduced_mass)
                            - node1.a;
                }
                if ((Math.Abs(temp) <= Math.Abs(dist1)) || (Math.Abs(temp) <= Math.Abs(dist2)))
                {
                    system.Callback("Collision between two planetesimals!\n");
                    Double a3 = (node1.mass + mass) / (node1.mass / node1.a + mass / a);
                    temp = node1.mass * Math.Sqrt(node1.a) * Math.Sqrt(1.0 - Math.Pow(node1.e, 2.0));
                    temp = temp + mass * Math.Sqrt(a) * Math.Sqrt(Math.Sqrt(1.0 - Math.Pow(e, 2.0)));
                    temp = temp / ((node1.mass + mass) * Math.Sqrt(a3));
                    temp = 1.0 - Math.Pow(temp, 2.0);
                    if ((temp < 0.0) || (temp >= 1.0))
                    {
                        temp = 0.0;
                    }
                    e    = Math.Sqrt(temp);
                    temp = node1.mass + mass;
                    AccreteDust(ref system, ref temp, a3, e, stellar_luminosity_ratio, body_inner_bound, body_outer_bound);
                    node1.a    = a3;
                    node1.e    = e;
                    node1.mass = temp;
                    node1      = null;
                    coalesced  = true;
                }
                else
                {
                    node1 = node1.next_planet;
                }
            }
            if (coalesced)
            {
                return;
            }
            node3 = new Planet
            {
                a         = a,
                e         = e,
                gas_giant = mass >= crit_mass,
                mass      = mass
            };
            system.bodies.Add(node3);
            if (system.planet_head == null)
            {
                system.planet_head = node3;
                node3.next_planet  = null;
            }
            else
            {
                node1 = system.planet_head;
                if (a < node1.a)
                {
                    node3.next_planet  = node1;
                    system.planet_head = node3;
                }
                else if (system.planet_head.next_planet == null)
                {
                    system.planet_head.next_planet = node3;
                    node3.next_planet = null;
                }
                else
                {
                    while ((node1 != null) && (node1.a < a))
                    {
                        node2 = node1;
                        node1 = node1.next_planet;
                    }
                    node3.next_planet = node1;
                    node2.next_planet = node3;
                }
            }
        }