Ejemplo n.º 1
0
        public static void absorbCO2(TClima clima, TWorld w, TSolarSurface s, long i, long j)
        {
            double absorption, rain_times;

            if (clima.isIce[i, j] || clima.co2_tons[i, j] == 0 || !statechanges.isInSunlight(i, j, s))
            {
                return;
            }

            if (w.isOcean[i, j])
            {
                // absorption scaled over 12 h per day and over 3 quarters of earth surface
                absorption = TSimConst.co2_absorption_ocean / (365 / 12 / 15 * TSimConst.degree_step) / (360 * 180 * 3 / 4);
            }
            else
            {
                // absorption scaled over 12 h per day and over 1 quarter of earth surface
                absorption = TSimConst.co2_absorption_vegetation / (365 / 12 / 15 * TSimConst.degree_step) / (360 * 180 * 1 / 4);
                // jungle absorbs more than desert
                rain_times = clima.rain_times[i, j];
                if (rain_times > 5)
                {
                    rain_times = 5;
                }

                absorption = absorption * rain_times;
            }

            clima.co2_tons[i, j] = clima.co2_tons[i, j] - absorption;
            if (clima.co2_tons[i, j] < 0)
            {
                clima.co2_tons[i, j] = 0;
            }
        }
Ejemplo n.º 2
0
        public static void moveSteamDown(TClima clima, TWorld w, TSolarSurface s, int l, long i, long j)
        {
            double
                transferSteam,
                maxSteam,
                transferEnergy;

            // recalculate temperature
            clima.T_atmosphere[l, i, j] = statechanges.thermicGradient(w, clima, l * TMdlConst.distance_atm_layers, clima.T_atmosphere[0, i, j], i, j);
            if (clima.steam[l, i, j] == 0)
            {
                return;
            }

            // how much steam could stay in the upper layer l
            maxSteam = statechanges.maxWaterInSteam(clima, w, l, i, j);
            // how much steam has to be transferred down
            transferSteam = (clima.steam[l, i, j] - maxSteam) * (1 / TSimConst.steam_hours);
            if (transferSteam < 0)
            {
                return;
            }
            // energy which is given back to atmosphere
            transferEnergy = transferSteam * TPhysConst.grav_acc * TMdlConst.distance_atm_layers;

            // let's move it dowm
            clima.energy_atmosphere[i, j] = clima.energy_atmosphere[i, j] + transferEnergy;
            clima.steam[l, i, j]          = clima.steam[l, i, j] - transferSteam;
            clima.steam[l - 1, i, j]      = clima.steam[l - 1, i, j] + transferSteam;
        }
Ejemplo n.º 3
0
        public static void moveSteamUp(TClima clima, TWorld w, TSolarSurface s, int l, long i, long j)
        {
            double availableSteam,
                   maxSteam,
                   transferEnergy,
                   evaporationPct;

            // let's compute first the temperature on the upper layer based on the thermic gradient
            clima.T_atmosphere[l, i, j] = statechanges.thermicGradient(w, clima, l * TMdlConst.distance_atm_layers, clima.T_atmosphere[0, i, j], i, j);
            // we do not add altitude here, as altitude is already in clima.T_atmosphere[0, i, j]
            // if there is ice on ground or no steam to push up we exit
            if (clima.isIce[i, j] || clima.steam[l - 1, i, j] == 0)
            {
                return;
            }
            evaporationPct = statechanges.evaporatePercentage(clima, clima.T_atmosphere[l - 1, i, j], i, j);
            if (evaporationPct == 0)
            {
                return;
            }

            // how much steam could stay in the upper layer l?
            maxSteam = statechanges.maxWaterInSteam(clima, w, l, i, j);
            // how much steam is available for transfer
            availableSteam = Math.Min(clima.steam[l - 1, i, j], maxSteam) * (1 / TSimConst.steam_hours) * evaporationPct;
            // is there enough energy to perform the transfer to the upper layer?
            transferEnergy = availableSteam * TPhysConst.grav_acc * TMdlConst.distance_atm_layers;
            if (clima.energy_atmosphere[i, j] > transferEnergy)
            {
                // let's move it up
                clima.energy_atmosphere[i, j] = clima.energy_atmosphere[i, j] - transferEnergy;
                clima.steam[l - 1, i, j]      = clima.steam[l - 1, i, j] - availableSteam;
                clima.steam[l, i, j]          = clima.steam[l, i, j] + availableSteam;
            }
        }
Ejemplo n.º 4
0
        public static void computeSolarSurface(TSolarSurface s, TTime t, double earthDeclination)
        {
            int    j, shift;
            double daylengthhour;

            for (j = 0; j < 180; j++)
            {
                daylengthhour = computeDayLenghtDuration(earthDeclination, j, t); // for fix daylength 12;
                if (daylengthhour == Constants.FULL_NIGHT)
                {
                    s.degstart[j] = Constants.FULL_NIGHT;
                    s.degend[j]   = Constants.FULL_NIGHT;
                }
                else
                {
                    shift         = (int)Math.Round(daylengthhour * 15 / 2); // each hour are 15 degrees (360/24)
                    s.degstart[j] = 179 - shift;
                    s.degend[j]   = 179 + shift;

                    s.degstart[j] = s.degstart[j] + TMdlConst.initDegreeSunlight;
                    s.degend[j]   = s.degend[j] + TMdlConst.initDegreeSunlight; // 12 hours which are 15 degrees a part
                    if (s.degstart[j] >= 360)
                    {
                        s.degstart[j] = s.degstart[j] - 360;
                    }
                    if (s.degend[j] >= 360)
                    {
                        s.degend[j] = s.degend[j] - 360;
                    }
                } // else FULL_NIGHT
            }     // for
        }
Ejemplo n.º 5
0
 public static void updateOutgoingEnergyOnCellGrid(TClima clima, TWorld w, TSolarSurface sSurface, double earthInclination, int i, int j)
 {
     updateTemperature(clima, w, i, j);
     exchangeEnergyBetweenAtmAndTerrain(clima, w, i, j);
     updateTemperature(clima, w, i, j);
     radiateEnergyIntoSpace(clima, w, i, j);
     updateTemperature(clima, w, i, j);
 }
Ejemplo n.º 6
0
        static void TestTwoDays()
        {
            double[,] tmpGrid      = new double[360, 180];
            short[,] wind          = new short[360, 180];
            double[,] T_atmosphere = new double[360, 180];

            TWorld world = new TWorld();

            Debug.WriteLine("Init World");
            initmodel.initWorld(world);

            TClima clima = new TClima();

            Debug.WriteLine("Init Clima");
            initmodel.initClima(world, clima, 16, 16);

            TTime         t = new TTime();
            TSolarSurface s = new TSolarSurface();

            Debug.WriteLine("Init time and solar surface");
            initmodel.initTime(t, s);
            Debug.WriteLine("Initial conditions created");

            Debug.WriteLine("Simulating 3 days of weather including energy cycle, winds,");
            Debug.WriteLine("marine currents, steam generation and rain");
            for (int day = 170; day < 173; day++)
            {
                Debug.Write("Simulating day = " + day + " ");

                for (int hour = 0; hour < 24; hour++)
                {
                    Debug.Write(".");
                    riverandlakes.clearRain(clima);
                    double earthInclination = energyfunctions.computeEarthDeclination(day);
                    for (int j = 0; j < 180; j++)
                    {
                        for (int i = 0; i < 360; i++)
                        {
                            energyfunctions.updateIncomingEnergyOnCellGrid(clima, world, s, earthInclination, i, j);
                            watercycle.formSteam(clima, world, s, i, j, t.day);
                        }
                    }

                    flux.moveEnergy(clima, clima.energy_atmosphere, tmpGrid, T_atmosphere, wind, flux.WIND, world, true);
#if TODO
                    flux.moveEnergy(clima, clima.energy_ocean_terr, tmpGrid, clima.T_ocean_terr, clima.surfaceTransfer, flux.SURFACE_AND_MARINE_CURRENT, world, true);
                    //printPlanet(2000, day, hour, clima, world, true, false);
                    watercycle.moveSteam(clima.wind, clima.steam, tmpGrid);
#endif
                }
            }
        }
Ejemplo n.º 7
0
        public static void mainSimDayLoop(TWorld world, TClima clima, TSolarSurface s, TTime t, double[,] tmpGrid, double earthDeclination)
        {
#if TODO
            computeSolarSurface(s, t, earthDeclination);
            increasePopulation(clima, 1);
            printEarthStatus(t.year, t.day, Round(t.hour), clima, world);
            printPlanet(t.year, t.day, Round(t.hour), clima, world, false, true);
            if (t.day % TSimConst.decrease_rain_times == 0)
            {
                decreaseRainTimes(clima);
            }
#endif
            throw new NotImplementedException();
        }
Ejemplo n.º 8
0
        public static void updateIncomingEnergyOnCellGrid(TClima clima, TWorld w, TSolarSurface sSurface, double earthInclination, int i, int j)
        {
            double energyIn;

            if (statechanges.isInSunlight(i, j, sSurface))
            {
                energyIn = computeEnergyFromSunOnSquare(i, j, earthInclination, clima, w);
                spreadEnergyOnAtmosphereAndTerrain(clima, energyIn, i, j);
                updateTemperature(clima, w, i, j);
            }

            radiateTerrestrialEnergy(clima, w, i, j);
            updateTemperature(clima, w, i, j);
        }
Ejemplo n.º 9
0
        public static bool isInSunlight(long i, long j, TSolarSurface sSurface)
        {
            if (sSurface.degstart[j] == Constants.FULL_NIGHT)
            {
                return(false);
            }

            if (sSurface.degend[j] > sSurface.degstart[j])
            {
                return((i >= sSurface.degstart[j]) && (i <= sSurface.degend[j]));
            }
            else
            {
                return((i <= sSurface.degend[j]) || (i >= sSurface.degstart[j]));
            }
        }
Ejemplo n.º 10
0
        public static void stepTime(TTime t, TSolarSurface sSurface)
        {
            long j;

            t.hour = t.hour + TSimConst.degree_step / 15;
            if (t.hour >= 24)
            {
                t.hour = 0;
                t.day  = t.day + 1;
                if (t.day > 365)
                {
                    t.day  = 1;
                    t.year = t.year + 1;
                }
            }

            if (TMdlConst.rotation)
            {
                for (j = 90; j < 180; j++)
                {
                    if (sSurface.degstart[j] == Constants.FULL_NIGHT)
                    {
                        continue;
                    }

                    sSurface.degstart[j] = sSurface.degstart[j] - TSimConst.degree_step * TMdlConst.inverse_rotation;
                    if (sSurface.degstart[j] < 0)
                    {
                        sSurface.degstart[j] = sSurface.degstart[j] + 360;
                    }
                    if (sSurface.degstart[j] >= 360)
                    {
                        sSurface.degstart[j] = sSurface.degstart[j] - 360;
                    }

                    sSurface.degend[j] = sSurface.degend[j] - TSimConst.degree_step * TMdlConst.inverse_rotation;
                    if (sSurface.degend[j] < 0)
                    {
                        sSurface.degend[j] = sSurface.degend[j] + 360;
                    }
                    if (sSurface.degend[j] >= 360)
                    {
                        sSurface.degend[j] = sSurface.degend[j] - 360;
                    }
                }
            }
        }
Ejemplo n.º 11
0
        public static void initTimeHDY(long hour, long day, long year, TTime t, TSolarSurface sSurface)
        {
            if ((hour < 0) || (hour > 23))
            {
                throw new Exception("Hour has to lie between 0 and 23");
            }
            if ((day < 1) || (day > 365))
            {
                throw new Exception("Day has to lie between 1 and 365");
            }
            if ((year < 0) || (year > 10000))
            {
                throw new Exception("Year has to lie between 0 and 10000");
            }

            t.hour = hour;
            t.day  = day;
            t.year = year;
        }
Ejemplo n.º 12
0
        public static void formSteam(TClima clima, TWorld w, TSolarSurface s, long i, long j, long day)
        {
            double energyToBoil, evaporationPct, evaporationQty;

            if (clima.isIce[i, j] || statechanges.isInSunlight(i, j, s))
            {
                return;
            }

            evaporationPct = statechanges.evaporatePercentage(clima, clima.T_ocean_terr[i, j], i, j);
            if (evaporationPct == 0)
            {
                return;
            }

            // steam over ocean
            if (w.isOcean[i, j])
            {
                // check how much steam we could form
                evaporationQty = (statechanges.maxWaterInSteam(clima, w, 0, i, j) - clima.steam[0, i, j]) * (1 / TSimConst.steam_hours)
                                 * evaporationPct;
            }
            else
            // steam produced by river and lakes
            {
                if (clima.water_surface[i, j] == 0)
                {
                    return;
                }

                // vegetation (where it rains more than one time, slows down evaporation)
                if (clima.rain_times[i, j] > 0)
                {
                    evaporationQty = clima.water_surface[i, j] / clima.rain_times[i, j] * evaporationPct * (1 / TSimConst.steam_hours);
                }
                else
                {
                    evaporationQty = clima.water_surface[i, j] * evaporationPct * (1 / TSimConst.steam_hours);
                }

                if (day % TSimConst.decrease_rain_times == 0)
                {
                    clima.rain_times[i, j]--;
                    if (clima.rain_times[i, j] < 0)
                    {
                        clima.rain_times[i, j] = 0;
                    }
                }
            }


            if (evaporationQty > 0) // here we will rain in a later public static void  call
            {
                // energy to boil the steam
                if (TPhysConst.kT_boil - clima.T_atmosphere[0, i, j] > 0)
                {
                    energyToBoil = TPhysConst.cp_steam * evaporationQty * (TPhysConst.kT_boil - clima.T_atmosphere[0, i, j]);
                }
                else
                {
                    energyToBoil = 0;
                }


                if (clima.energy_ocean_terr[i, j] >= energyToBoil)
                // the atmosphere has enough energy to carry the steam
                {
                    clima.steam[0, i, j]          = clima.steam[0, i, j] + evaporationQty;
                    clima.energy_ocean_terr[i, j] = clima.energy_ocean_terr[i, j] - energyToBoil;

                    if (!w.isOcean[i, j])
                    {
                        clima.water_surface[i, j] = clima.water_surface[i, j] - evaporationQty;
                    }
                }
            }
        }
Ejemplo n.º 13
0
        public static void mainSimTimestepLoop(TWorld world, TClima clima, TSolarSurface s, TTime t, double[,] tmpGrid, double arthDeclination)
        {
            long l, i, j;

#if TODO
            clearRain(clima);
            for (j = 0; j < 180; j++)
            {
                for (i = 0; i < 360; i++)
                {
                    updateIncomingEnergyOnCellGrid(clima, world, s, earthDeclination, i, j);
                    formSteam(clima, world, s, i, j, t.day);           // add steam to layer 0
                    for (l = 1; l < TMdlConst.atmospheric_layers; l++) // move steam from layer l-1 to layer l
                    {
                        moveSteamUp(clima, world, s, l, i, j);
                    }
                    formCO2(clima, world, i, j);
                }
            }

            moveEnergy(clima, clima.energy_ocean_terr, tmpGrid, clima.T_ocean_terr, clima.surfaceTransfer, SURFACE_AND_MARINE_CURRENT, world, true);
            moveEnergy(clima, clima.energy_atmosphere, tmpGrid, clima.T_atmosphere[0, 0, 0], clima.wind[0, 0, 0], WIND, world, true);

            flux.applyCoriolis(clima.wind[0], clima.wind[0], TMdlConst.rotation);
            for (l = 1; l < TMdlConst.atmospheric_layers; l++)
            {
                flux.applyCoriolis(clima.wind[l - 1], clima.wind[l], TMdlConst.rotation);
            }

            followSurface(world, clima.wind[0]);

            for (l = 0; l < TMdlConst.atmospheric_layers; l++)
            {
                moveSteam(clima.wind[l], clima.steam[l], tmpGrid);
            }

            moveCO2(clima.wind[0], clima.co2_tons[0], tmpGrid);

            vulcanoEruption(world, clima);
            singleNuclearBomb(world, clima);
            nuclearWar(world, clima);
            moveAshes(clima.wind[0, 0, 0], clima.ashes_pct[0, 0], tmpGrid);
            ashesFallDown(world, clima);

            for (j = 0; j < 180; j++)
            {
                for (i = 0; i < 360; i++)
                {
                    for (l = TMdlConst.atmospheric_layers - 1; l > 0; l--)    // move steam from layer l to layer l-1
                    {
                        moveSteamDown(clima, world, s, l, i, j);
                    }
                    rainSteam(clima, world, i, j);
                    waterOrIce(clima, world, i, j);
                    absorbCO2(clima, world, s, i, j);
                    updateOutgoingEnergyOnCellGrid(clima, world, s, earthDeclination, i, j);
                }
            }

            moveWaterDownToOcean(world, clima, clima.water_surface, tmpGrid);
            stepTime(t, s);
#endif
            throw new NotImplementedException();
        }
Ejemplo n.º 14
0
 public static void initTime(TTime t, TSolarSurface sSurface)
 {
     initTimeHDY(0, 1, 2000, t, sSurface);
 }