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 }
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 } } }
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; } } } }
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; }
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(); }
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(); }
public static double computeDayLenghtDuration(double earthDeclination, int j, TTime t) { double lat, latdeg, A, B, C, d, minusboverc; // from // http://mathforum.org/library/drmath/view/56478.html //Date: 09/22/98 at 12:40:09 //From: Doctor Rick //Subject: Re: Geometry, hours of daylight //Hi, Hilde. What you"re asking for isn"t simple. I can show you the //geometry of the hours of daylight, but it won"t be complete, and //sunrise and sunset times involve additional complications. //The Analemma Web site gives explanations and math for the declination //of the sun (which you will need for my calculation below) and for the //"equation of time," which tells when noon really occurs. Sunrise and //sunset will be equal time intervals before and after noon, but noon is //not at 12:00: // http://www.analemma.com/Pages/framesPage.html //Here is a brief explanation of the length of the day. //On any given day, the sun is at a particular declination (which is the //latitude of the point on earth where the sun is directly overhead). //The terminator (the line connecting all places where the sun is //setting or rising) is a circle that is tilted from a north-south plane //by an angle equal to the declination. Here is a side view: // ****|**** Terminator SUN // *\* | *** // ** \ dec| ** // ** \ B | C ** // *--------\--+-----------o You // * \ |A / * // * \| / lat * // * +-------------- // * |\ * // * | \ * // * | \ * // ** | \ ** // ** | \ ** // *** | *\* // ****|**** //The terminator is shown edge-on, at the angle of declination from the //vertical. Your latitude is shown as a horizontal line. We are //interested in the point of intersection of the terminator and your //latitude, because that is where you experience sunrise or sunset. //If we call the radius of the earth 1 unit, then distance A is sin(lat). //Therefore distance B is sin(lat)*tan(dec). Distance C, the radius of //the latitude circle, is cos(lat). //Now look down from the north on your latitude circle: // oooo|oooo // **o | ooo // **| \ | oo // ** | \C | oo // * | \ | o // * | \ | o // * | B \| o // * night+------+ day o // * | /| o // * | / | o // * | / | o // ** | / | oo // **| / | oo // **o | ooo // oooo|oooo //The angle between sunrise and sunset (on the day side of the angle) is // d = 2 cos^-1(-B/C) // = 2 cos^-1(-tan(dec)tan(lat)) //The length of the day is 24 hours * d/360. But remember to consult the //Web site above to see why this isn"t quite right. //- Doctor Rick, The Math Forum // http://mathforum.org/dr.math/ lat = Conversion.YtoLat(j); latdeg = lat * Math.PI / 180; try { d = 2 * Math.Acos(-Math.Tan(earthDeclination * Math.PI / 180) * Math.Tan(latdeg)); d = d / Math.PI * 180; return(24 * d / 360); } catch (Exception e) { // TODO: could be done at the hourly level here if (t.day >= 79 && t.day <= 262) { // Winter in South Hemisphere if (lat > 0) { return(0); // whole day sun } else { return(Constants.FULL_NIGHT); // to trick it into deep night } } else { // Winter in North Hemisphere if (lat > 0) { return(Constants.FULL_NIGHT); } else { return(0); // whole day sun } } } }
public static void initTime(TTime t, TSolarSurface sSurface) { initTimeHDY(0, 1, 2000, t, sSurface); }