/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2012 Pedro Gonnet (pedro.gonnet@durham.ac.uk),
* Matthieu Schaller (schaller@strw.leidenuniv.nl)
* 2018 Jacob Kegerreis (jacob.kegerreis@durham.ac.uk)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
******************************************************************************/
/* Config parameters. */
#include
/* Some standard headers. */
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* Conditional headers. */
#ifdef HAVE_LIBZ
#include
#endif
/* Local headers. */
#include "equation_of_state.h"
#include "swift.h"
/* Engine policy flags. */
#ifndef ENGINE_POLICY
#define ENGINE_POLICY engine_policy_none
#endif
/**
* @brief Write a list of densities, energies, and resulting pressures to file
* from an equation of state.
*
* WORK IN PROGRESS
*
* So far only does the Hubbard & MacFarlane (1980) equations of state.
*
* Usage:
* $ ./testEOS (mat_id) (do_output)
*
* Sys args (optional):
* mat_id | int | Material ID, see equation_of_state.h for the options.
* Default: 201 (= id_HM80_ice).
*
* do_output | int | Set 1 to write the output file of rho, u, P values,
* set 0 for no output. Default: 0.
*
* Output text file contains:
* header
* num_rho num_u mat_id # Header values
* rho_0 rho_1 rho_2 ... rho_num_rho # Array of densities, rho
* u_0 u_1 u_2 ... u_num_u # Array of energies, u
* P_0_0 P_0_1 ... P_0_num_u # Array of pressures, P(rho, u)
* P_1_0 ... ... P_1_num_u
* ... ... ... ...
* P_num_rho_0 ... P_num_rho_num_u
* c_0_0 c_0_1 ... c_0_num_u # Array of sound speeds, c(rho,
* u)
* c_1_0 ... ... c_1_num_u
* ... ... ... ...
* c_num_rho_0 ... c_num_rho_num_u
*
* Note that the values tested extend beyond the range that most EOS are
* designed for (e.g. outside table limits), to help test the EOS in case of
* unexpected particle behaviour.
*
*/
#ifdef EOS_PLANETARY
int main(int argc, char *argv[]) {
float rho, u, log_rho, log_u, P, c;
struct unit_system us;
struct swift_params *params =
(struct swift_params *)malloc(sizeof(struct swift_params));
if (params == NULL) error("Error allocating memory for the parameter file.");
const struct phys_const *phys_const = 0; // Unused placeholder
const float J_kg_to_erg_g = 1e4; // Convert J/kg to erg/g
char filename[64];
// Output table params
const int num_rho = 100, num_u = 100;
float log_rho_min = logf(1e-4f), log_rho_max = logf(1e3f), // Densities (cgs)
log_u_min = logf(1e4f),
log_u_max = logf(1e13f), // Sp. int. energies (SI)
log_rho_step = (log_rho_max - log_rho_min) / (num_rho - 1.f),
log_u_step = (log_u_max - log_u_min) / (num_u - 1.f);
float A1_rho[num_rho], A1_u[num_u];
// Sys args
int mat_id_in, do_output;
// Default sys args
const int mat_id_def = eos_planetary_id_HM80_ice;
const int do_output_def = 0;
// Check the number of system arguments and use defaults if not provided
switch (argc) {
case 1:
// Default both
mat_id_in = mat_id_def;
do_output = do_output_def;
break;
case 2:
// Read mat_id, default do_output
mat_id_in = atoi(argv[1]);
do_output = do_output_def;
break;
case 3:
// Read both
mat_id_in = atoi(argv[1]);
do_output = atoi(argv[2]);
break;
default:
error("Invalid number of system arguments!\n");
mat_id_in = mat_id_def; // Ignored, just here to keep the compiler happy
do_output = do_output_def;
};
enum eos_planetary_material_id mat_id =
(enum eos_planetary_material_id)mat_id_in;
/* Greeting message */
printf("This is %s\n", package_description());
// Check material ID
const enum eos_planetary_type_id type =
(enum eos_planetary_type_id)(mat_id / eos_planetary_type_factor);
// Select the material base type
switch (type) {
// Tillotson
case eos_planetary_type_Til:
switch (mat_id) {
case eos_planetary_id_Til_iron:
printf(" Tillotson iron \n");
break;
case eos_planetary_id_Til_granite:
printf(" Tillotson granite \n");
break;
case eos_planetary_id_Til_water:
printf(" Tillotson water \n");
break;
default:
error("Unknown material ID! mat_id = %d \n", mat_id);
};
break;
// Hubbard & MacFarlane (1980)
case eos_planetary_type_HM80:
switch (mat_id) {
case eos_planetary_id_HM80_HHe:
printf(" Hubbard & MacFarlane (1980) hydrogen-helium atmosphere \n");
break;
case eos_planetary_id_HM80_ice:
printf(" Hubbard & MacFarlane (1980) ice mix \n");
break;
case eos_planetary_id_HM80_rock:
printf(" Hubbard & MacFarlane (1980) rock mix \n");
break;
default:
error("Unknown material ID! mat_id = %d \n", mat_id);
};
break;
// SESAME
case eos_planetary_type_SESAME:
switch (mat_id) {
case eos_planetary_id_SESAME_iron:
printf(" SESAME basalt 7530 \n");
break;
case eos_planetary_id_SESAME_basalt:
printf(" SESAME basalt 7530 \n");
break;
case eos_planetary_id_SESAME_water:
printf(" SESAME water 7154 \n");
break;
case eos_planetary_id_SS08_water:
printf(" Senft & Stewart (2008) SESAME-like water \n");
break;
default:
error("Unknown material ID! mat_id = %d \n", mat_id);
};
break;
default:
error("Unknown material type! mat_id = %d \n", mat_id);
}
// Convert to internal units
// Earth masses and radii
// units_init(&us, 5.9724e27, 6.3710e8, 1.f, 1.f, 1.f);
// SI
units_init(&us, 1000.f, 100.f, 1.f, 1.f, 1.f);
log_rho_min -= logf(units_cgs_conversion_factor(&us, UNIT_CONV_DENSITY));
log_rho_max -= logf(units_cgs_conversion_factor(&us, UNIT_CONV_DENSITY));
log_u_min += logf(J_kg_to_erg_g / units_cgs_conversion_factor(
&us, UNIT_CONV_ENERGY_PER_UNIT_MASS));
log_u_max += logf(J_kg_to_erg_g / units_cgs_conversion_factor(
&us, UNIT_CONV_ENERGY_PER_UNIT_MASS));
// Set the input parameters
// Which EOS to initialise
parser_set_param(params, "EoS:planetary_use_Til:1");
parser_set_param(params, "EoS:planetary_use_HM80:1");
parser_set_param(params, "EoS:planetary_use_SESAME:1");
// Table file names
parser_set_param(params,
"EoS:planetary_HM80_HHe_table_file:"
"../examples/planetary_HM80_HHe.txt");
parser_set_param(params,
"EoS:planetary_HM80_ice_table_file:"
"../examples/planetary_HM80_ice.txt");
parser_set_param(params,
"EoS:planetary_HM80_rock_table_file:"
"../examples/planetary_HM80_rock.txt");
parser_set_param(params,
"EoS:planetary_SESAME_iron_table_file:"
"../examples/planetary_SESAME_iron_2140.txt");
parser_set_param(params,
"EoS:planetary_SESAME_basalt_table_file:"
"../examples/planetary_SESAME_basalt_7530.txt");
parser_set_param(params,
"EoS:planetary_SESAME_water_table_file:"
"../examples/planetary_SESAME_water_7154.txt");
parser_set_param(params,
"EoS:planetary_SS08_water_table_file:"
"../examples/planetary_SS08_water.txt");
// Initialise the EOS materials
eos_init(&eos, phys_const, &us, params);
// Manual debug testing
if (1) {
printf("\n ### MANUAL DEBUG TESTING ### \n");
rho = 5960;
u = 1.7e8;
P = gas_pressure_from_internal_energy(rho, u, eos_planetary_id_HM80_ice);
printf("u = %.2e, rho = %.2e, P = %.2e \n", u, rho, P);
return 0;
}
// Output file
sprintf(filename, "testEOS_rho_u_P_c_%d.txt", mat_id);
FILE *f = fopen(filename, "w");
if (f == NULL) {
printf("Could not open output file!\n");
exit(EXIT_FAILURE);
}
if (do_output == 1) {
fprintf(f, "Density Sp.Int.Energy mat_id \n");
fprintf(f, "%d %d %d \n", num_rho, num_u, mat_id);
}
// Densities
log_rho = log_rho_min;
for (int i = 0; i < num_rho; i++) {
A1_rho[i] = exp(log_rho);
log_rho += log_rho_step;
if (do_output == 1)
fprintf(f, "%.6e ",
A1_rho[i] * units_cgs_conversion_factor(&us, UNIT_CONV_DENSITY));
}
if (do_output == 1) fprintf(f, "\n");
// Sp. int. energies
log_u = log_u_min;
for (int i = 0; i < num_u; i++) {
A1_u[i] = exp(log_u);
log_u += log_u_step;
if (do_output == 1)
fprintf(f, "%.6e ",
A1_u[i] * units_cgs_conversion_factor(
&us, UNIT_CONV_ENERGY_PER_UNIT_MASS));
}
if (do_output == 1) fprintf(f, "\n");
// Pressures
for (int i = 0; i < num_rho; i++) {
rho = A1_rho[i];
for (int j = 0; j < num_u; j++) {
P = gas_pressure_from_internal_energy(rho, A1_u[j], mat_id);
if (do_output == 1)
fprintf(f, "%.6e ",
P * units_cgs_conversion_factor(&us, UNIT_CONV_PRESSURE));
}
if (do_output == 1) fprintf(f, "\n");
}
// Sound speeds
for (int i = 0; i < num_rho; i++) {
rho = A1_rho[i];
for (int j = 0; j < num_u; j++) {
c = gas_soundspeed_from_internal_energy(rho, A1_u[j], mat_id);
if (do_output == 1)
fprintf(f, "%.6e ",
c * units_cgs_conversion_factor(&us, UNIT_CONV_SPEED));
}
if (do_output == 1) fprintf(f, "\n");
}
fclose(f);
return 0;
}
#else
int main(int argc, char *argv[]) { return 0; }
#endif