Ejemplo n.º 1
0
 public void SimulateRule(FactorRule rule)
 {
     //Are the requirements met?
     if (rule.EvaluateRequirements())
     {
         //If they are, do what the rule wants.
         rule.ApplyResults();
     }
 }
Ejemplo n.º 2
0
 private void AddRule(FactorRule rule)
 {
     //Add the rule to the list for updating
     AllFactorRules.Add(rule);
 }
Ejemplo n.º 3
0
    /// <summary>
    /// Create the rules that govern our early earth environment
    /// </summary>
    public void PopulateRules()
    {
        //The purpose of these rules is to force several events to occur that simulate approximately what happens in Early Earth during Great Oxygen Extinction.
        //These rules aren't highly accurate or anything. I pulled the data together in a few hours of Wikipedia/other site searching
        //The goal was to create a base system that has factors that influence one another according to defined rules.

        FactorRule rule;

        //All of these could be loaded from a file in the future (and saved to files for later simulation/debugging)

        #region Water Boiling
        rule = new FactorRule("Water Boiling",

                              //Hotter than boiling point
                              new Requirement(ref factors[Temperature]._stats, new GreaterThan(373.2f)),
                              //There's 1% surface water left
                              new Requirement(ref factors[LiquidH20]._stats, new GreaterThan(1)),

                              //Likely wouldn't be that big of a temperature drop
                              //The temperature goes down because now the gaseous H20 is more energetic.
                              new Result(ref factors[Temperature]._stats, new AdjustByFixedValue(-.25f)),

                              //When there is that much heat, it evaporates the water into gaseous form
                              new Result(ref factors[LiquidH20]._stats, new AdjustByFixedValue(-.1f)),
                              new Result(ref factors[GaseousH20]._stats, new AdjustByFixedValue(.1f))
                              );
        AddRule(rule);
        #endregion

        #region Water Freezing
        rule = new FactorRule("Water Freezing",

                              //Colder than freezing point
                              new Requirement(ref factors[Temperature]._stats, new LessThan(273.2f)),

                              //There's 1% surface water left
                              new Requirement(ref factors[LiquidH20]._stats, new GreaterThan(1)),

                              //I doubt the temperature raise would be ANYWHERE near this significant.
                              //Temperature goes up because the energy is now in the form of the bonds holding the water into a frozen form.
                              new Result(ref factors[Temperature]._stats, new AdjustByFixedValue(.25f)),

                              //Lets get a little more solid water.
                              new Result(ref factors[LiquidH20]._stats, new AdjustValueDeltaTime(-.1f)),
                              new Result(ref factors[SolidH20]._stats, new AdjustValueDeltaTime(.1f))
                              );
        AddRule(rule);
        #endregion

        #region Ice Melting [Not implemented]
        //I chose not to implement this rule deliberately.
        //MY simulation does not yet support segregation of temperatures or factors.
        //This means most simulations would immediately force the temperature just around freezing point, rather than maintaining a near earth temperature.
        //Earth's ice is usually maintained through uneven distribution of the temperature.

        //Condensation would likely fit in the same boat here.
        #endregion

        #region Sun Heating the Planet
        rule = new FactorRule("Sun Heating Planet",

                              //Based on what the University of Tennesse's Agriculture Solar/Sunstainable Energy page says:
                              //https://ag.tennessee.edu/solar/Pages/What%20Is%20Solar%20Energy/Sun%27s%20Energy.aspx
                              //Earth is soaking up heat by 1368 W/m^2. However only about 1000 of it reaches it to the earth's surface.
                              //Earth is 510.1 trillion m^2. Let's cut this in half to represent the 'Day' side of the planet.
                              //This means that the earth is soaking up 255.1 PetaWatts of energy
                              //Another resource, Wikipedia, gives us a smaller number of 174 PW (https://en.wikipedia.org/wiki/Watt#Petawatt) - Wolfram also backs this number up.
                              //Note to self: Read about the Solar Constant, because that looks cool.

                              //I'd like to dig into this deeper and calculate how much temperature differential is caused by 174 PetaWatts pouring into earth, but I want to tie up these comments.

                              //The sun will attempt to heat us to the temperature of the sun.
                              new Requirement(ref factors[Temperature]._stats, new LessThan(5778)),

                              //So I'll say it is .174 degrees kelvin per 'time interval' of every second of simulation.
                              new Result(ref factors[Temperature]._stats, new AdjustValueDeltaTime(.174f))
                              );
        AddRule(rule);
        #endregion

        #region Nocturnal Cooling of Earth
        rule = new FactorRule("Sun Heating Planet",

                              //Doing some math
                              //https://upload.wikimedia.org/wikipedia/commons/8/8f/Erbe.gif
                              //Assume we're cooling 225 Watts / m^2.
                              //Earth is 510.1 trillion m^2. Let's cut this in half to represent the 'Night' side of the planet.
                              //This means we	are losing 57.39 PetaWatts of energy every 'time interval'
                              //I'll say a single second is a time interval so our Rule can have some numerical basis.

                              //The sun will attempt to heat us to the temperature of the sun.
                              new Requirement(ref factors[Temperature]._stats, new LessThan(5778)),

                              //When there is that much heat, it evaporates the water into gaseous form
                              new Result(ref factors[Temperature]._stats, new AdjustValueDeltaTime(.05739f))
                              );
        AddRule(rule);
        #endregion

        #region Huronian Glaciation
        //Oxygen + Methane = CO2 + Water - Temperature
        //https://en.wikipedia.org/wiki/Huronian_glaciation
        rule = new FactorRule("Huronian Glaciation",
                              //If too much O2 and CH4, and it isn't too cold
                              new Requirement(ref factors[Temperature]._stats, new GreaterThan(270)),
                              new Requirement(ref factors[O2]._stats, new GreaterThan(20.78f)),
                              new Requirement(ref factors[CH4]._stats, new GreaterThan(.05f)),

                              //CH4 and O2 form into CO2
                              new Result(ref factors[O2]._stats, new AdjustValueDeltaTime(-.1f)),
                              new Result(ref factors[CH4]._stats, new AdjustValueDeltaTime(-.1f)),

                              new Result(ref factors[CO2]._stats, new AdjustValueDeltaTime(.05f)),

                              //We see high temperature drops (which will drive the freezing of liquid water)
                              new Result(ref factors[Temperature]._stats, new AdjustValueDeltaTime(-2.5f))
                              );
        AddRule(rule);
        #endregion

        #region Anaerobic corrosion
        //Fe + 2H2O -> Fe(OH)2 + H2
        //https://en.wikipedia.org/wiki/Hydrogen#Anaerobic_corrosion
        //We want to represent (however inaccurately) some introduction of hydrogen into the system.
        //I choose to represent this because it's a good candidate for it's interaction with water.
        //I did chunk both parts of anaerobic corrosion of iron together into one rule.
        rule = new FactorRule("Anaerobic Corrosion",
                              //Need some metal to break apart the rust into more stable Iron compounds and H2.
                              new Requirement(ref factors[UnrustedMetals]._stats, new GreaterThan(5.0f)),
                              //Metal rusts. This involves water (ideally this could be an OR of liquid or gas)
                              new Requirement(ref factors[LiquidH20]._stats, new GreaterThan(1.0f)),
                              //Anaerobic Corrosion doesn't occur when there's lots of O2
                              new Requirement(ref factors[O2]._stats, new LessThan(15f)),

                              //We consume some of the un-rusted metals. (I didn't represent a new creation that they make.
                              new Result(ref factors[UnrustedMetals]._stats, new AdjustValueDeltaTime(-.1f)),
                              //Yield!
                              new Result(ref factors[LiquidH20]._stats, new AdjustValueDeltaTime(-.1f)),
                              new Result(ref factors[H2]._stats, new AdjustValueDeltaTime(.25f))
                              );
        AddRule(rule);
        #endregion

        #region Methanogenesis
        //CO2 + 4 H2 = CH4 + 2 H20
        //https://en.wikipedia.org/wiki/Methanogen
        rule = new FactorRule("Methanogenesis",
                              //We don't want lots of O2 to do this.
                              new Requirement(ref factors[CO2]._stats, new GreaterThan(5.0f)),
                              //We need some carbon. (specifically glucose, but we aren't simulating that fine grain)
                              new Requirement(ref factors[H2]._stats, new GreaterThan(1.0f)),
                              //We need some heat (a bit above freezing)
                              new Requirement(ref factors[Temperature]._stats, new GreaterThan(280f)),
                              //Methanogens are required for this process
                              //new Requirement(ref factors[Methanogens]._stats, new GreaterThan(2)),

                              //More Methanogens.
                              new Result(ref factors[Methanogens]._stats, new AdjustValueDeltaTime(.25f)),
                              //Consume our components.
                              new Result(ref factors[H2]._stats, new AdjustValueDeltaTime(-.8f)),
                              new Result(ref factors[CO2]._stats, new AdjustValueDeltaTime(-.1f)),
                              //Product yield.
                              new Result(ref factors[CH4]._stats, new AdjustValueDeltaTime(.5f)),
                              new Result(ref factors[LiquidH20]._stats, new AdjustValueDeltaTime(.5f))
                              );
        AddRule(rule);
        #endregion

        #region Cyanobacteria Photosynthesis
        //Cyanobacteria Photosynthesis works well in high CO2 environments
        //https://en.wikipedia.org/wiki/Obligate_anaerobe
        rule = new FactorRule("Cyanobacteria Photosynthesis",

                              //Eat that CO2
                              new Requirement(ref factors[CO2]._stats, new GreaterThan(.5f)),
                              //We need some carbon. (specifically glucose, but we aren't simulating that fine grain)
                              new Requirement(ref factors[O2]._stats, new LessThan(60.0f)),
                              //We need some heat (a bit above freezing)
                              new Requirement(ref factors[Temperature]._stats, new GreaterThan(295f)),

                              //More Cyanobacteria.
                              new Result(ref factors[Cyanobacteria]._stats, new AdjustValueDeltaTime(2f)),
                              //Absorb JUST a bit of heat
                              new Result(ref factors[Temperature]._stats, new AdjustValueDeltaTime(-0.002f)),
                              //Eat some CO2
                              new Result(ref factors[CO2]._stats, new AdjustValueDeltaTime(-.75f)),
                              //Make O2
                              new Result(ref factors[O2]._stats, new AdjustValueDeltaTime(.6f))
                              );

        AddRule(rule);
        #endregion

        #region Anaerobic Fermentation
        //Anaerobes like low oxygen environments and produce CO2 off of heat and solid carbon.
        //https://en.wikipedia.org/wiki/Obligate_anaerobe
        rule = new FactorRule("Anaerobic Fermentation",
                              //We don't want lots of O2 to do this.
                              new Requirement(ref factors[O2]._stats, new LessThan(14.0f)),
                              //We need some carbon. (specifically glucose, but we aren't simulating that fine grain)
                              new Requirement(ref factors[SolidCarbon]._stats, new GreaterThan(2.0f)),
                              //We need some heat (I assume they stop if its freezing)
                              new Requirement(ref factors[Temperature]._stats, new GreaterThan(275f)),

                              //More Anaerobes.
                              new Result(ref factors[Anaerobes]._stats, new AdjustValueDeltaTime(.4f)),
                              //new Result(ref factors[CH4]._stats, new AdjustValueByDeltaTime(.1f)));
                              //Make some CO2
                              new Result(ref factors[CO2]._stats, new AdjustValueDeltaTime(.75f))
                              );
        AddRule(rule);
        #endregion

        #region Obligate Anaerobes Death
        //Obligate Anaerobes die if they hit 20% oxygen
        //https://en.wikipedia.org/wiki/Obligate_anaerobe
        rule = new FactorRule("Obligate Anaerobes Death",

                              //Too much O2
                              new Requirement(ref factors[O2]._stats, new GreaterThan(20.78f)),

                              //And Anaerobes die off (not changing the constraints of what is going on)
                              new Result(ref factors[Anaerobes]._stats, new MultiplyByPercentAndDeltaTime(.15f))

                              //Maybe they'd add to the 'carbo-matter' available?
                              );
        AddRule(rule);
        #endregion

        #region Cyanobacteria Death
        //Cyanobacteria likely need continuous CO2 and heat to survive. Here's a pair of rules to kill them.
        rule = new FactorRule("Cyanobacteria Death",

                              //Too little CO2
                              new Requirement(ref factors[CO2]._stats, new LessThan(1)),

                              //MASS STARVATION!
                              new Result(ref factors[Cyanobacteria]._stats, new MultiplyByPercentAndDeltaTime(.15f))
                              );
        AddRule(rule);

        rule = new FactorRule("Cyanobacteria Freeze",

                              //Too cold (not enough sun)
                              new Requirement(ref factors[Temperature]._stats, new LessThan(260)),

                              //MASS DEATH!
                              new Result(ref factors[Cyanobacteria]._stats, new MultiplyByPercentAndDeltaTime(.15f))
                              );
        AddRule(rule);
        #endregion

        #region Obligate Anaerobes Death
        //Obligate Anaerobes die if they hit 20% oxygen
        //https://en.wikipedia.org/wiki/Obligate_anaerobe
        rule = new FactorRule("Obligate Anaerobes Death",

                              //Too much O2
                              new Requirement(ref factors[O2]._stats, new GreaterThan(20.78f)),

                              //And Anaerobes die off (not changing the constraints of what is going on)
                              new Result(ref factors[Anaerobes]._stats, new MultiplyByPercentAndDeltaTime(.15f))

                              //Maybe they'd add to the 'carbo-matter' available?
                              );
        AddRule(rule);
        #endregion
    }