コード例 #1
0
        private void DistMoonMasses(ProtoStar star, ProtoPlanet planet)
        {
            planet.initDisc(0.0D, star.StellarDustLimit, true);
            int counter = 0;

            do
            {
                counter++;

                ProtoPlanet moon = new ProtoPlanet(star.Star, planet.Planet)
                {
                    SemiMajorAxis = rnd.NextDouble(planet.PlanetInnerBound, planet.PlanetOuterBound),
                    Eccentricity  = rnd.RandomEccentricity(),
                    DustMass      = Constants.Stargen.PROTOPLANET_MASS,
                    Star          = star.Star,
                    IsMoon        = true,
                    MoonOf        = planet,
                };
                moon.init();

                if (planet.IsDustAvailable(moon))
                {
                    //var criticalMass = protoPlanet.CriticalLimit;
                    AccreteDust(planet, moon);

                    if (moon.Mass > Constants.Stargen.PROTOPLANET_MASS)
                    {
                        CoalescePlanetesimals(planet, moon);
                    }
                    else
                    {
#if LOG4NET_ENABLED
                        logger.Debug("Moon at " + moon.SemiMajorAxis + " failed due to large neighbor!");
#endif
                    }
                }

                if (counter == 10000)
                {
#if LOG4NET_ENABLED
                    logger.Debug("Exceeded 10000 attempts to create a planet! Will not continue!");
#endif
                }
            }while (planet.DustAvailable && counter < 10000);

            planet.Planets = new List <ProtoPlanet>(planet.Planets.OrderBy(x => x.SemiMajorAxis));

            planet.Planets.ForEach(moon =>
            {
                moon.Planet.Primary = planet.Star;
                planet.Planet.Moons.Add(moon.Planet);
            });
        }
コード例 #2
0
        public void CollectDust(AccreteDisc Disc, ProtoPlanet p, double inner, double outer, double lastMass)
        {
            //ProtoStar star = p.Star;
            // declear working vars:
            double bandwidth = 0.0;
            double temp = 0.0;
            double temp1 = 0.0;
            double temp2 = 0.0;
            double width = 0.0;
            double volume = 0.0;
            double dustdensity, gasdensity, massdensity;

            foreach (AccreteBand band in Disc.Bands)
            {
                if (band.Intersect(inner, outer) && band.DustPresent)
                {
                    bandwidth = outer - inner;
                    temp1     = Math.Max(outer - band.OuterEdge, 0.0);
                    temp2     = Math.Max(band.InnerEdge - inner, 0.0);
                    width     = bandwidth - temp1 - temp2;

                    if (!band.DustPresent)
                    {
                        dustdensity = 0.0;
                        gasdensity  = 0.0;
                    }
                    else
                    {
                        if ((lastMass > p.CriticalLimit) && band.GasPresent)
                        {
                            massdensity = p.CloudDensity;
                            gasdensity  = massdensity - (Constants.Stargen.K * massdensity) / (1.0 + (Math.Sqrt(p.CriticalLimit / p.Mass) * (Constants.Stargen.K - 1.0)));
                            dustdensity = massdensity - gasdensity;
                        }
                        else
                        {
                            dustdensity = p.CloudDensity;
                            gasdensity  = 0.0;
                        }
                    }

                    temp   = 4.0 * Math.PI * Math.Pow(p.SemiMajorAxis, 2.0) * p.ReducedMass * (1.0 - (p.Eccentricity * (temp1 - temp2) / bandwidth));
                    volume = temp * width;


                    p.DustMass += volume * dustdensity;
                    p.GasMass  += volume * gasdensity;
                }
            }
        }
コード例 #3
0
        private void AccreteDust(AccreteDisc Disc, ProtoPlanet p)
        {
            //ProtoStar star = p.Star;

            double startDustMass = p.DustMass;
            double startGasMass  = p.GasMass;
            //double minAccretion = 0.0001 * startMass;

            double gatherLast = 0.0;

            double rInner = 0;
            double rOuter = 0;

            do
            {
                //gatherLast = gatherNow;
                gatherLast = p.Mass;

                p.ReduceMass();
                rInner = p.InnerEffectLimit;
                rOuter = p.OuterEffectLimit;

                p.DustMass = startDustMass;
                p.GasMass  = startGasMass;

                //foreach (AccreteBand band in Disc.Bands)
                {
                    //if(band.Intersect(rInner, rOuter))
                    {
                        CollectDust(Disc, p, rInner, rOuter, gatherLast);
                    }
                    //band.CollectDust(rInner, rOuter, p, gatherLast);
                }
            }while ((p.Mass - gatherLast) >= (0.0001 * p.Mass));

            Disc.UpdateDust(p); // Clear dust only on reduced mass?
        }
コード例 #4
0
 public bool Intersect(ProtoPlanet p)
 {
     return(Intersect(p.InnerEffectLimit, p.OuterEffectLimit));
 }
コード例 #5
0
 public bool IsDustAvailable(ProtoPlanet p)
 {
     p.ReduceMass();
     return(IsDustLeftRange(p.InnerEffectLimit, p.OuterEffectLimit));
 }
コード例 #6
0
 public void UpdateDust(ProtoPlanet p)
 {
     UpdateDust(p.InnerEffectLimit, p.OuterEffectLimit, p.Mass > p.CriticalLimit);
 }
コード例 #7
0
 public bool IsGasAvailable(ProtoPlanet p)
 {
     return(IsGasLeftRange(p.InnerEffectLimit, p.OuterEffectLimit));
 }
コード例 #8
0
        public StarSystem Create(string name)
        {
            //create the starsystem
            var starSystem = new StarSystem(name);

            _starFactory.Create(name).ForEach(star =>
            {
                star.StarSystem = starSystem;
                starSystem.Stars.Add(star);
            });

            // Create some working Vars:
            double inner = 0.0;
            double outer = 0.0;

            for (var i = 0; i < starSystem.Stars.Count; i++)
            {
                var star      = starSystem.Stars[i];
                var protoStar = new ProtoStar(star);

                for (int j = 0; j < starSystem.Stars.Count; j++)
                {
                    if (i != j)
                    {
                        var starB = starSystem.Stars[j];
                        // Forbidden zone inner is 1/3 of the minimum seperation
                        // Forbidden zone outer is 3x the maximum seperation
                        // TODO: Add in effect of eccentricities
                        double minseperation, maxseperation;
                        if (star.SemiMajorAxis > starB.SemiMajorAxis)
                        {
                            // Orbits beyond other star
                            minseperation = Math.Abs(star.SemiMajorAxis * (1.0 - star.Eccentricity) - starB.SemiMajorAxis * (1.0 + starB.Eccentricity));
                            if (i == 0)
                            {
                                maxseperation = Math.Abs(star.SemiMajorAxis * (1.0 + star.Eccentricity) - starB.SemiMajorAxis * (1.0 - starB.Eccentricity));
                            }
                            else
                            {
                                maxseperation = 200;
                            }
                        }
                        else
                        {
                            // Orbits inside other star
                            minseperation = Math.Abs(star.SemiMajorAxis * (1.0 + star.Eccentricity) - starB.SemiMajorAxis * (1.0 - starB.Eccentricity));
                            if (i == 0)
                            {
                                maxseperation = Math.Abs(star.SemiMajorAxis * (1.0 - star.Eccentricity) - starB.SemiMajorAxis * (1.0 + starB.Eccentricity));
                            }
                            else
                            {
                                maxseperation = 200;
                            }
                        }

                        /*minseperation = Math.Abs(starSystem.Stars[j].SemiMajorAxis - starSystem.Stars[i].SemiMajorAxis);
                         * double maxseperation;
                         * if (i == 0)
                         *  maxseperation = Math.Abs(starSystem.Stars[j].SemiMajorAxis + starSystem.Stars[i].SemiMajorAxis);
                         * else
                         *  maxseperation = 200;*/
                        inner = minseperation / 3.0;
                        outer = maxseperation * 3.0;
                        protoStar.UpdateDust(inner, outer, false);
                    }
                    initOrbitPosition(star);
                }

                //protoStar.DistributePlanetaryMasses(rnd);
                int counter = 0;
                while (protoStar.DustAvailable)
                {
                    counter++;
                    var protoPlanet = new ProtoPlanet(protoStar.Star, protoStar.Star)
                    {
                        Star          = star,
                        SemiMajorAxis = rnd.NextDouble(protoStar.PlanetInnerBound, protoStar.PlanetOuterBound),
                        Eccentricity  = rnd.RandomEccentricity(),
                        //Eccentricity = 0.99,
                        DustMass = Constants.Stargen.PROTOPLANET_MASS,
                    };
                    protoPlanet.init();


                    if (protoStar.IsDustAvailable(protoPlanet))
                    {
                        //var criticalMass = protoPlanet.CriticalLimit;
                        AccreteDust(protoStar, protoPlanet);

                        if (protoPlanet.Mass > Constants.Stargen.PROTOPLANET_MASS)
                        {
                            CoalescePlanetesimals(protoStar, protoPlanet);
                        }
                        else
                        {
#if LOG4NET_ENABLED
                            logger.Debug("Planet at " + protoPlanet.SemiMajorAxis + " failed due to large neighbor!");
#endif
                        }
                    }
                    if (counter == 10000)
                    {
#if LOG4NET_ENABLED
                        logger.Debug("Exceeded 10000 attempts to create a planet! Will not continue!");
#endif
                    }
                }
                while (protoStar.DustAvailable && counter < 10000)
                {
                    ;
                }

                //populate the Star from the protoStar
                protoStar.Planets.ForEach(planet =>
                {
                    planet.Planet.Primary = star;
                    if (_generateMoons)
                    {
                        DistMoonMasses(protoStar, planet);
                    }
                    star.Planets.Add(planet.Planet);
                });
                star.Planets = new BindingList <Planet>(star.Planets.OrderBy(x => x.SemiMajorAxis).ToList());
                GeneratePlanets(star);
            }

            return(starSystem);
        }
コード例 #9
0
 private bool GeneratePlanet(ProtoPlanet protoplanet)
 {
     return(GeneratePlanet(protoplanet.Planet));
 }
コード例 #10
0
        private void doCollisions(AccreteDisc Disc)
        {
            // create working vars:
            double miu1, miu2;
            double delta = 1, deltaMin = 0;
            double newE, newA;
            double temp;

            bool collision;

            do
            {
                collision    = false;
                Disc.Planets = new List <ProtoPlanet>(Disc.Planets.OrderBy(x => x.SemiMajorAxis));
                for (int i = 0; i < Disc.Planets.Count - 1; i++)
                {
                    ProtoPlanet aPlanet = Disc.Planets[i];
                    ProtoPlanet bPlanet = Disc.Planets[i + 1];

                    miu1 = aPlanet.Mass / Disc.Mass;
                    miu2 = bPlanet.Mass / Disc.Mass;

                    deltaMin = 2.4 * (Math.Pow(miu1 + miu2, 1.0 / 3.0));
                    delta    = Math.Abs((bPlanet.SemiMajorAxis - aPlanet.SemiMajorAxis) / aPlanet.SemiMajorAxis);

                    if (delta <= deltaMin && !Disc.isMoonDisc)
                    {
                        // New orbital distance
                        newA = (aPlanet.Mass + bPlanet.Mass) / ((aPlanet.Mass / aPlanet.SemiMajorAxis) + (bPlanet.Mass / bPlanet.SemiMajorAxis));

//#if LOG4NET_ENABLED
                        //logger.Debug(String.Format("Collision between two planetesimals! {0:N4} AU ({1:N5}) + {2:N4} AU ({3:N5}) -> {4:N4} AU", bPlanet.SemiMajorAxis, bPlanet.MassInEarthMasses, aPlanet.SemiMajorAxis, aPlanet.MassInEarthMasses, newA));
//#endif
                        // Compute new eccentricity
                        temp = aPlanet.Mass * Math.Sqrt(aPlanet.SemiMajorAxis) * Math.Sqrt(1.0 - Math.Pow(aPlanet.Eccentricity, 2.0));
                        temp = temp + (bPlanet.Mass * Math.Sqrt(bPlanet.SemiMajorAxis) * Math.Sqrt(Math.Sqrt(1.0 - Math.Pow(bPlanet.Eccentricity, 2.0))));
                        temp = temp / ((aPlanet.Mass + bPlanet.Mass) * Math.Sqrt(newA));
                        temp = 1.0 - Math.Pow(temp, 2.0);

                        temp = Math.Min(Math.Max(temp, 0.0), 1.0);

                        newE = Math.Sqrt(temp);

                        // Create a new Protoplanet to accrete additional material
                        var newP = new ProtoPlanet(Disc.Star, Disc.Star)
                        {
                            SemiMajorAxis = newA,
                            Eccentricity  = newE,
                            DustMass      = aPlanet.DustMass + bPlanet.DustMass,
                            GasMass       = aPlanet.GasMass + bPlanet.GasMass,
                            Star          = Disc.Star,
                            IsMoon        = aPlanet.IsMoon,
                            MoonOf        = aPlanet.MoonOf
                        };
                        newP.init();
                        //newP.CritMass = getCriticalMass(newP);
                        //newP.CloudDensity = getCloudDensity(newP);

                        //double startmass = newP.Mass;
                        AccreteDust(Disc, newP);

                        /*
                         #if LOG4NET_ENABLED
                         * if (newP.Mass < startmass)
                         *  logger.Debug("Accretion reduced mass, something is wrong!");
                         * else if (newP.Mass > startmass)
                         *  logger.Debug("Accretion increased mass!");
                         * else
                         *  logger.Debug("Accretion did not change mass!");
                         #endif
                         */

                        //#if LOG4NET_ENABLED
                        //logger.Debug(string.Format("New planet at {0:N4} AU with mass {1:N5}!", newP.SemiMajorAxis, newP.MassInEarthMasses));
                        //#endif

                        Disc.Planets.Remove(aPlanet);
                        Disc.Planets.Remove(bPlanet);
                        Disc.Planets.Add(newP);

                        collision = true;
                        break;
                    }
                }
            }while (collision == true);
        }
コード例 #11
0
 private void CoalescePlanetesimals(AccreteDisc Disc, ProtoPlanet p)
 {
     Disc.Planets.Add(p);
     doCollisions(Disc);
 }