rendered paste bodyvoid generate_planets(primary* sun,
int random_tilt,
char flag_char,
int sys_no,
char* system_name,
int do_gases,
int do_moons)
{
planet_pointer planet;
int planet_no = 0;
for (planet = innermost_planet, planet_no = 1;
planet != NULL;
planet = planet->next_planet, planet_no++)
{
planet->first_moon = NULL;
planet->atmosphere = NULL;
planet->gases = 0;
planet->high_temp = 0;
planet->low_temp = 0;
planet->max_temp = 0;
planet->min_temp = 0;
planet->greenhs_rise = 0;
planet->planet_no = planet_no;
planet->primary_body = sun;
planet->resonant_period = FALSE;
#ifdef MOONS
if (do_moons)
{
long double m1 = planet->mass;
long double m2 = sun->mass;
long double mu = m2 / (m1 + m2);
long double e = planet->e;
long double a = planet->a;
long double outer_limit = (0.464 + (-0.380 * mu) + (-0.631 * e) +
(0.586 * mu * e) + (0.150 * pow2(e)) +
(-0.198 * mu * pow2(e))) * a;
// long double farthest = farthest_planet(planet->mass);
long double outer_dust = stellar_dust_limit(planet->mass);
// if (outer_limit > farthest)
// outer_limit = farthest;
planet->first_moon = dist_moon_masses (planet->mass,
sun->luminosity,
planet->a,
planet->e,
0.0,
outer_dust,
1.0,
outer_limit);
if (planet->first_moon)
{
int n;
planet_pointer ptr;
for (n=0, ptr=planet->first_moon;
ptr != NULL;
ptr=ptr->next_planet)
{
if (ptr->mass * SUN_MASS_IN_EARTH_MASSES > .0001)
{
n++;
fprintf (stderr, "%d: %d %6.3Lg %6.3Lg\n",
planet_no,
n,
ptr->mass * SUN_MASS_IN_EARTH_MASSES,
ptr->mass / planet->mass);
}
}
}
}
#endif
planet->orbit_zone = orb_zone(sun->luminosity, planet->a);
planet->orb_period = period(planet->a,planet->mass,sun->mass);
if (random_tilt)
planet->axial_tilt = inclination(planet->a);
planet->exospheric_temp = EARTH_EXOSPHERE_TEMP / pow2(planet->a / sun->r_ecosphere);
planet->rms_velocity = rms_vel(MOL_NITROGEN,planet->exospheric_temp);
planet->core_radius = kothari_radius(planet->dust_mass,FALSE,planet->orbit_zone);
// Calculate the radius as a gas giant, to verify it will retain gas.
// Then if mass > Earth, it's at least 5% gas and retains He, it's
// some flavor of gas giant.
planet->density = empirical_density(planet->mass,planet->a, sun->r_ecosphere, TRUE);
planet->radius = volume_radius(planet->mass,planet->density);
planet->surf_accel = acceleration(planet->mass,planet->radius);
planet->surf_grav = gravity(planet->surf_accel);
planet->molec_weight = min_molec_weight(planet);
if (((planet->mass * SUN_MASS_IN_EARTH_MASSES) > 1.0)
&& ((planet->gas_mass / planet->mass) > 0.05)
&& (min_molec_weight(planet) <= 4.0))
{
if ((planet->gas_mass / planet->mass) < 0.20)
planet->type = tSubSubGasGiant;
else if ((planet->mass * SUN_MASS_IN_EARTH_MASSES) < 20.0)
planet->type = tSubGasGiant;
else
planet->type = tGasGiant;
}
else // If not, it's rocky.
{
planet->radius = kothari_radius(planet->mass,FALSE,planet->orbit_zone);
planet->density = volume_density(planet->mass,planet->radius);
planet->surf_accel = acceleration(planet->mass,planet->radius);
planet->surf_grav = gravity(planet->surf_accel);
if ((planet->gas_mass / planet->mass) > 0.000001)
{
long double h2_mass = planet->gas_mass * 0.85;
long double he_mass = (planet->gas_mass - h2_mass) * 0.999;
long double h2_loss = 0.0;
long double he_loss = 0.0;
long double h2_life = gas_life(MOL_HYDROGEN, planet);
long double he_life = gas_life(HELIUM, planet);
if (h2_life < sun->age)
{
h2_loss = ((1.0 - (1.0 / exp(sun->age / h2_life))) * h2_mass);
planet->gas_mass -= h2_loss;
planet->mass -= h2_loss;
planet->surf_accel = acceleration(planet->mass,planet->radius);
planet->surf_grav = gravity(planet->surf_accel);
}
if (he_life < sun->age)
{
he_loss = ((1.0 - (1.0 / exp(sun->age / he_life))) * he_mass);
planet->gas_mass -= he_loss;
planet->mass -= he_loss;
planet->surf_accel = acceleration(planet->mass,planet->radius);
planet->surf_grav = gravity(planet->surf_accel);
}
if (((h2_loss + he_loss) > .000001) && (flag_verbose & 0x0080))
fprintf (stderr, "%s (-s%ld -%c%d) %d\tLosing gas: H2: %5.3Lf EM, He: %5.3Lf EM\n",
system_name,
flag_seed, flag_char, sys_no,
planet_no,
h2_loss * SUN_MASS_IN_EARTH_MASSES, he_loss * SUN_MASS_IN_EARTH_MASSES);
}
}
planet->day = day_length(planet); /* Modifies planet->resonant_period */
planet->esc_velocity = escape_vel(planet->mass,planet->radius);
if ((planet->type == tGasGiant)
|| (planet->type == tSubGasGiant)
|| (planet->type == tSubSubGasGiant))
{
planet->greenhouse_effect = FALSE;
planet->volatile_gas_inventory = INCREDIBLY_LARGE_NUMBER;
planet->surf_pressure = INCREDIBLY_LARGE_NUMBER;
planet->boil_point = INCREDIBLY_LARGE_NUMBER;
planet->surf_temp = INCREDIBLY_LARGE_NUMBER;
planet->greenhs_rise = 0;
planet->albedo = about(GAS_GIANT_ALBEDO,0.1);
planet->hydrosphere = 1.0;
planet->cloud_cover = 1.0;
planet->ice_cover = 0.0;
planet->surf_grav = gravity(planet->surf_accel);
planet->molec_weight = min_molec_weight(planet);
planet->surf_grav = INCREDIBLY_LARGE_NUMBER;
planet->estimated_temp = est_temp(sun->r_ecosphere, planet->a, planet->albedo);
planet->estimated_terr_temp = est_temp(sun->r_ecosphere, planet->a, EARTH_ALBEDO);
{
long double temp = planet->estimated_terr_temp;
if ((temp >= FREEZING_POINT_OF_WATER)
&& (temp <= EARTH_AVERAGE_KELVIN + 10.)
&& (sun->age > 2.0E9))
{
habitable_jovians++;
if (flag_verbose & 0x8000)
{
fprintf (stderr, "%s (-s%ld -%c%d) %d\t%s (%4.2LfEM %5.3Lf By) with earth-like temperature (%.1Lf C, %.1Lf F, %+.1Lf C Earth).\n",
system_name,
flag_seed, flag_char, sys_no,
planet_no,
planet->type == tGasGiant ? "Jovian" :
planet->type == tSubGasGiant ? "Sub-Jovian" :
planet->type == tSubSubGasGiant ? "Gas Dwarf" :
"Big",
planet->mass * SUN_MASS_IN_EARTH_MASSES,
sun->age /1.0E9,
temp - FREEZING_POINT_OF_WATER,
32 + ((temp - FREEZING_POINT_OF_WATER) * 1.8),
temp - EARTH_AVERAGE_KELVIN);
}
}
}
}
else
{
planet->estimated_temp = est_temp(sun->r_ecosphere, planet->a, EARTH_ALBEDO);
planet->estimated_terr_temp = est_temp(sun->r_ecosphere, planet->a, EARTH_ALBEDO);
planet->surf_grav = gravity(planet->surf_accel);
planet->molec_weight = min_molec_weight(planet);
planet->greenhouse_effect = grnhouse(sun->r_ecosphere, planet->a);
planet->volatile_gas_inventory = vol_inventory(planet->mass,
planet->esc_velocity,
planet->rms_velocity,
sun->mass,
planet->orbit_zone,
planet->greenhouse_effect,
(planet->gas_mass
/ planet->mass) > 0.000001);
planet->surf_pressure = pressure(planet->volatile_gas_inventory,
planet->radius,
planet->surf_grav);
if ((planet->surf_pressure == 0.0))
planet->boil_point = 0.0;
else
planet->boil_point = boiling_point(planet->surf_pressure);
iterate_surface_temp(planet); /* Sets:
* planet->surf_temp
* planet->greenhs_rise
* planet->albedo
* planet->hydrosphere
* planet->cloud_cover
* planet->ice_cover
*/
if (do_gases &&
(planet->max_temp >= FREEZING_POINT_OF_WATER) &&
(planet->min_temp <= planet->boil_point))
calculate_gases(sun, planet, flag_char, sys_no, planet_no, system_name);
/*
* Next we assign a type to the planet.
*/
if (planet->surf_pressure < 1.0)
{
if ((planet->mass * SUN_MASS_IN_EARTH_MASSES) < ASTEROID_MASS_LIMIT)
planet->type = tAsteroids;
else
planet->type = tRock;
}
else if ((planet->surf_pressure > 6000.0) &&
(planet->molec_weight <= 2.0)) // Retains Hydrogen
{
planet->type = tSubSubGasGiant;
planet->gases = 0;
free(planet->atmosphere);
planet->atmosphere = NULL;
}
else
{ // Atmospheres:
if (((int)planet->day == (int)(planet->orb_period * 24.0) ||
(planet->resonant_period)))
planet->type = t1Face;
else if (planet->hydrosphere >= 0.95)
planet->type = tWater; // >95% water
else if (planet->ice_cover >= 0.95)
planet->type = tIce; // >95% ice
else if (planet->hydrosphere > 0.05)
planet->type = tTerrestrial; // Terrestrial
// else <5% water
else if (planet->max_temp > planet->boil_point)
planet->type = tVenusian; // Hot = Venusian
else if ((planet->gas_mass / planet->mass) > 0.0001)
{ // Accreted gas
planet->type = tIce; // But no Greenhouse
planet->ice_cover = 1.0; // or liquid water
} // Make it an Ice World
else if (planet->surf_pressure <= 250.0)// Thin air = Martian
planet->type = tMartian;
else if (planet->surf_temp < FREEZING_POINT_OF_WATER)
planet->type = tIce;
else
{
planet->type = tUnknown;
if (flag_verbose & 0x0001)
fprintf (stderr, "%12s\tp=%4.2Lf\tm=%4.2Lf\tg=%4.2Lf\tt=%+.1Lf\t-s%ld -%c%d\t%s %d\t Unknown %s\n",
type_string (planet->type),
planet->surf_pressure,
planet->mass * SUN_MASS_IN_EARTH_MASSES,
planet->surf_grav,
planet->surf_temp - EARTH_AVERAGE_KELVIN,
flag_seed,
flag_char,
sys_no,
system_name,
planet_no,
((int)planet->day == (int)(planet->orb_period * 24.0) ||
(planet->resonant_period)) ? "(1-Face)" : ""
);
}
}
}
/*
* Now we're ready to test for habitable planets,
* so we can count and log them and such
*/
{
int tIndex = 0;
switch (planet->type)
{
case tUnknown: tIndex = 0; break;
case tRock: tIndex = 1; break;
case tVenusian: tIndex = 2; break;
case tTerrestrial: tIndex = 3; break;
case tSubSubGasGiant: tIndex = 4; break;
case tSubGasGiant: tIndex = 5; break;
case tGasGiant: tIndex = 6; break;
case tMartian: tIndex = 7; break;
case tWater: tIndex = 8; break;
case tIce: tIndex = 9; break;
case tAsteroids: tIndex = 10; break;
case t1Face: tIndex = 11; break;
}
if (type_counts[tIndex] == 0)
++type_count;
++type_counts[tIndex];
}
{
unsigned int breathe = breathability (planet);
if ((breathe == BREATHABLE) &&
(!planet->resonant_period) && // Option needed?
((int)planet->day != (int)(planet->orb_period * 24.0)))
{
int list_it = FALSE;
habitable++;
if (min_breathable_temp > planet->surf_temp)
{
min_breathable_temp = planet->surf_temp;
if (flag_verbose & 0x0002)
list_it = TRUE;
}
if (max_breathable_temp < planet->surf_temp)
{
max_breathable_temp = planet->surf_temp;
if (flag_verbose & 0x0002)
list_it = TRUE;
}
if (min_breathable_g > planet->surf_grav)
{
min_breathable_g = planet->surf_grav;
if (flag_verbose & 0x0002)
list_it = TRUE;
}
if (max_breathable_g < planet->surf_grav)
{
max_breathable_g = planet->surf_grav;
if (flag_verbose & 0x0002)
list_it = TRUE;
}
if (planet->type == tTerrestrial)
{
if (min_breathable_terrestrial_g > planet->surf_grav)
{
min_breathable_terrestrial_g = planet->surf_grav;
if (flag_verbose & 0x0002)
list_it = TRUE;
}
if (max_breathable_terrestrial_g < planet->surf_grav)
{
max_breathable_terrestrial_g = planet->surf_grav;
if (flag_verbose & 0x0002)
list_it = TRUE;
}
}
if (min_breathable_p > planet->surf_pressure)
{
min_breathable_p = planet->surf_pressure;
if (flag_verbose & 0x0002)
list_it = TRUE;
}
if (max_breathable_p < planet->surf_pressure)
{
max_breathable_p = planet->surf_pressure;
if (flag_verbose & 0x0002)
list_it = TRUE;
}
if (flag_verbose & 0x0004)
list_it = TRUE;
if (list_it)
fprintf (stderr, "%12s\tp=%4.2Lf\tm=%4.2Lf\tg=%4.2Lf\tt=%+.1Lf\t-s%ld -%c%d\t%s %d\n",
type_string (planet->type),
planet->surf_pressure,
planet->mass * SUN_MASS_IN_EARTH_MASSES,
planet->surf_grav,
planet->surf_temp - EARTH_AVERAGE_KELVIN,
flag_seed,
flag_char,
sys_no,
system_name,
planet_no);
}
}
if ((flag_verbose & 0x0800)
&& (planet->dust_mass * SUN_MASS_IN_EARTH_MASSES >= 0.0006)
&& (planet->gas_mass * SUN_MASS_IN_EARTH_MASSES >= 0.0006)
&& (planet->type != tGasGiant)
&& (planet->type != tSubGasGiant)
)
{
int core_size = (int)((50. * planet->core_radius) / planet->radius);
if (core_size <= 49)
{
fprintf (stderr, "%12s\tp=%4.2Lf\tr=%4.2Lf\tm=%4.2Lf\t-s%ld -%c%d\t%d\t%s %d\n",
type_string (planet->type),
planet->core_radius,
planet->radius,
planet->mass * SUN_MASS_IN_EARTH_MASSES,
flag_seed,
flag_char,
sys_no,
50-core_size,
system_name,
planet_no);
}
}
{
long double rel_temp = (planet->surf_temp - FREEZING_POINT_OF_WATER) -
EARTH_AVERAGE_CELSIUS;
long double seas = (planet->hydrosphere * 100.0);
long double clouds = (planet->cloud_cover * 100.0);
long double pressure = (planet->surf_pressure /
EARTH_SURF_PRES_IN_MILLIBARS);
long double ice = (planet->ice_cover * 100.0);
long double gravity = planet->surf_grav;
unsigned int breathe = breathability (planet);
if ((gravity >= .8) &&
(gravity <= 1.2) &&
(rel_temp >= -2.0) &&
(rel_temp <= 3.0) &&
(ice <= 10.) &&
(pressure >= 0.5) &&
(pressure <= 2.0) &&
(clouds >= 40.) &&
(clouds <= 80.) &&
(seas >= 50.) &&
(seas <= 80.) &&
(planet->type != tWater) &&
(breathe == BREATHABLE))
{
earthlike++;
if (flag_verbose & 0x0008)
fprintf (stderr, "%12s\tp=%4.2Lf\tm=%4.2Lf\tg=%4.2Lf\tt=%+.1Lf\t%d -s%ld -%c%d\t%s %d\tEarth-like\n",
type_string (planet->type),
planet->surf_pressure,
planet->mass * SUN_MASS_IN_EARTH_MASSES,
planet->surf_grav,
planet->surf_temp - EARTH_AVERAGE_KELVIN,
habitable,
flag_seed,
flag_char,
sys_no,
system_name,
planet_no);
} else if ((flag_verbose & 0x0008) &&
(breathe == BREATHABLE) &&
(gravity > 1.3) &&
(habitable > 1) &&
((rel_temp < -2.0) ||
(ice > 10.))
)
{
fprintf (stderr, "%12s\tp=%4.2Lf\tm=%4.2Lf\tg=%4.2Lf\tt=%+.1Lf\t%d -s%ld -%c%d\t%s %d\tSphinx-like\n",
type_string (planet->type),
planet->surf_pressure,
planet->mass * SUN_MASS_IN_EARTH_MASSES,
planet->surf_grav,
planet->surf_temp - EARTH_AVERAGE_KELVIN,
habitable,
flag_seed,
flag_char,
sys_no,
system_name,
planet_no);
}
}
}
}