Program Listing for File main.cpp
↰ Return to documentation for file (src/main.cpp)
#include "define.h"
#include "EOS.h"
#include "EOSmodify.h"
#include "phase.h"
#include "hydro.h"
#include "compfind.h"
#include "parser.h"
struct timeval start_time, end_time;
//Global Parameter Defaults
double rho_eps_rel = 1E-11; // relative error tolerance of the density solver
double T_eps_rel = 1E-11; // relative error tolerance of the temperature solver for the adiabatic profile
double ode_eps_rel0 = 1E-7; // relative error tolerance for first round ode integrator (1E-7) used in mode 0
double ode_eps_rel1 = 1E-10; // relative error tolerance for second round ode integrator (1E-10) used in mode 0
int fit_iter;
double R_eps_rel = 2E-5; // relative error tolerance in mode 0 first round radius determination (5E-5). Should be around sqrt(ode_eps_rel0).
double ode_eps_rel2 = 1E-10; // relative error tolerance for ode integrator (1E-10) used in mode 1
double P_eps_rel = 1E-10; // relative error tolerance in mode 1 central pressure determination (1E-10). Should not be more restrict than ode_eps_rel.
double fit_eps_rel = 1E-4; // the relative error tolerance at the fitting point in mode 0 round 2 (1E-4). Should be four orders of magnitudes larger than ode_eps_rel1.
vector<double> ave_rho = {15, 5, 2, 1E-3};// Assuming the density of the core is 15, mantle is 5, water is 2, and gas is 1E-3.
bool verbose = false; // Whether print warnings.
double P_surface = 1E5; // The pressure level that the broad band optical transit radius probes. (in microbar)
int count_shoot = 0; // used to count the total number of shootings per each solution
int count_step = 0; // used to count the sum of integral steps in all shooting results.
int main(int argc, char* argv[])
{
gsl_set_error_handler_off(); //Dismiss the abortion from execution, which is designed for code testing.
hydro* planet;
ifstream fin;
int n_settings;
//Initialize all the parameters, will throw error later if missing
int input_mode=0;
string core_phasedgm="Fe_default";
string mantle_phasedgm="Si_default";
string hydro_phasedgm="water_default";
string atm_phasedgm="gas_default";
vector<double> Mcomp={0,0,0,0};
vector<double> Tgap = {0,0,0,0};
string outputfile=" ";
int layer_index=0;
float mass_frac=0;
float min_mass=0;
float max_mass=0;
float step_mass=0;
string inputfile=" ";
int solver=1;
int findlayer=1;
float minPMR=0;
float maxPMR=0;
float step=0;
vector<int> layers={1,1,0,0};
float rerr=0;
float MassPrior=0;
float MUncPrior=0;
float RadPrior=0;
float RUncPrior=0;
int numlayers=2;
int numchains=1;
int chainsteps=10;
Water_sc_Mazevet -> modify_dTdP(dTdP_S_H2OSC);
//Parse input file
try{
Settings options(argv[1]); // Will throw an exception if the file couldn't be opened.
n_settings = options.LoadSettings(); // Load settings from the file and return the number of options found.
std::cout << "Loaded " << n_settings << " settings.\n";
//Error Tolerances
rho_eps_rel = options.GetOptionDouble("rho_eps_rel");
T_eps_rel = options.GetOptionDouble("T_eps_rel");
ode_eps_rel0 = options.GetOptionDouble("ode_eps_rel0");
ode_eps_rel1 = options.GetOptionDouble("ode_eps_rel1");
R_eps_rel = options.GetOptionDouble("R_eps_rel");
ode_eps_rel2 = options.GetOptionDouble("ode_eps_rel2");
P_eps_rel = options.GetOptionDouble("P_eps_rel");
fit_eps_rel = options.GetOptionDouble("fit_eps_rel");
//Global Run Options
verbose = options.GetOptionBool("verbose");
P_surface = options.GetOptionDouble("P_surface");
vector<double> ave_rho = {options.GetOptionDouble("ave_rho_core"), options.GetOptionDouble("ave_rho_mantle"), options.GetOptionDouble("ave_rho_hydro"), options.GetOptionDouble("ave_rho_atm")};
//Mode Options
// Choose between the 8 available input_mode values:
// 0: regular solver, 1: temperature-free solver, 2: two-layer solver,
// 3: bulk input mode with regular solver
// 4: composition finder, finds third layer mass to match a mass and radius measurement
// 5: modify a built-in EOS on they fly,
// 6: iterate over EOS modifications with two-layer solver, 5: iterate over EOS with regular solver
input_mode = options.GetOptionDouble("input_mode");
//Get Phase Diagrams for modes which require
if (input_mode==0 or input_mode==3 or input_mode==4 or input_mode==7 or input_mode==8)
{
core_phasedgm=options.GetOptionString("core_phasedgm");
mantle_phasedgm=options.GetOptionString("mantle_phasedgm");
hydro_phasedgm=options.GetOptionString("hydro_phasedgm");
atm_phasedgm=options.GetOptionString("atm_phasedgm");
}
//Get parameters specific to each mode
switch (input_mode){
case 0:
Mcomp[0]=options.GetOptionDouble("mass_of_core");
Mcomp[1]=options.GetOptionDouble("mass_of_mantle");
Mcomp[2]=options.GetOptionDouble("mass_of_hydro");
Mcomp[3]=options.GetOptionDouble("mass_of_atm");
Tgap[0]=options.GetOptionDouble("temp_jump_3");
Tgap[1]=options.GetOptionDouble("temp_jump_2");
Tgap[2]=options.GetOptionDouble("temp_jump_1");
Tgap[3]=options.GetOptionDouble("surface_temp");
outputfile=options.GetOptionString("output_file");
break;
case 1:
Mcomp[0]=options.GetOptionDouble("mass_of_core");
Mcomp[1]=options.GetOptionDouble("mass_of_mantle");
Mcomp[2]=options.GetOptionDouble("mass_of_hydro");
outputfile=options.GetOptionString("output_file");
break;
case 2:
layer_index=options.GetOptionDouble("layer_index");
mass_frac=options.GetOptionDouble("mass_frac");
min_mass=options.GetOptionDouble("min_mass");
max_mass=options.GetOptionDouble("max_mass");
step_mass=options.GetOptionDouble("step_mass");
break;
case 3:
inputfile=options.GetOptionString("input_file");
solver=options.GetOptionDouble("solver");
Tgap[0]=options.GetOptionDouble("temp_jump_3");
Tgap[1]=options.GetOptionDouble("temp_jump_2");
Tgap[2]=options.GetOptionDouble("temp_jump_1");
Tgap[3]=options.GetOptionDouble("surface_temp");
outputfile=options.GetOptionString("output_file");
break;
case 4:
inputfile=options.GetOptionString("input_file");
outputfile=options.GetOptionString("output_file");
findlayer=options.GetOptionDouble("find_layer");
layers[options.GetOptionDouble("layer_inner")-1]=1;
layers[options.GetOptionDouble("layer_outer")-1]=1;
minPMR=options.GetOptionDouble("PMR_min");
maxPMR=options.GetOptionDouble("PMR_max");
step=options.GetOptionDouble("PMR_step");
rerr=options.GetOptionDouble("R_error");
Tgap[0]=options.GetOptionDouble("temp_jump_3");
Tgap[1]=options.GetOptionDouble("temp_jump_2");
Tgap[2]=options.GetOptionDouble("temp_jump_1");
Tgap[3]=options.GetOptionDouble("surface_temp");
break;
case 5:
break; //must be run from main.cpp
case 6:
inputfile=options.GetOptionString("input_file");
outputfile=options.GetOptionString("output_file");
layer_index=options.GetOptionDouble("layer_index");
mass_frac=options.GetOptionDouble("mass_frac");
break;
case 7:
inputfile=options.GetOptionString("input_file");
outputfile=options.GetOptionString("output_file");
Mcomp[0]=options.GetOptionDouble("mass_of_core");
Mcomp[1]=options.GetOptionDouble("mass_of_mantle");
Mcomp[2]=options.GetOptionDouble("mass_of_hydro");
Mcomp[3]=options.GetOptionDouble("mass_of_atm");
Tgap[0]=options.GetOptionDouble("temp_jump_3");
Tgap[1]=options.GetOptionDouble("temp_jump_2");
Tgap[2]=options.GetOptionDouble("temp_jump_1");
Tgap[3]=options.GetOptionDouble("surface_temp");
break;
case 8:
MassPrior=options.GetOptionDouble("mass_prior");
MUncPrior=options.GetOptionDouble("mass_unc");
RadPrior=options.GetOptionDouble("radius_prior");
RUncPrior=options.GetOptionDouble("radius_unc");
numlayers=options.GetOptionDouble("num_layers");
numchains=options.GetOptionDouble("num_chains");
chainsteps=options.GetOptionDouble("chain_steps");
outputfile=options.GetOptionString("output_file");
Tgap[0]=options.GetOptionDouble("temp_jump_3");
Tgap[1]=options.GetOptionDouble("temp_jump_2");
Tgap[2]=options.GetOptionDouble("temp_jump_1");
Tgap[3]=options.GetOptionDouble("surface_temp");
break;
}
} catch (SettingsParserException& e) { // This will be triggered if an exception is thrown above.
std::cout << "\nException: " << e.what() << "\n"; // e.what() prints the exception message.
return EXIT_FAILURE;
}
//Set Phase Diagrams from string in config
vector<PhaseDgm> Comp = {core, mant, water, atm};
if (core_phasedgm=="Fe_default")
Comp[0]=core;
else if (core_phasedgm=="Fe_fccbcc")
Comp[0]=core1;
else
cout<<"core_phasedgm does not exist, using default"<<endl;
if (mantle_phasedgm=="Si_default")
Comp[1]=mant;
else if (mantle_phasedgm=="Si_simple")
Comp[1]=mant1;
else if (mantle_phasedgm=="PREM")
Comp[1]=mant2;
else if (mantle_phasedgm=="C_simple")
Comp[1]=mant3;
else if (mantle_phasedgm=="SiC")
Comp[1]=mant4;
else
cout<<"mant_phasedgm does not exist, using default"<<endl;
if (hydro_phasedgm=="water_default")
Comp[2]=water;
else if (hydro_phasedgm=="water_tabulated")
Comp[2]=water1;
else if (hydro_phasedgm=="water_legacy")
Comp[2]=water2;
else
cout<<"hydro_phasedgm does not exist, using default"<<endl;
if (atm_phasedgm=="gas_default")
Comp[3]=atm;
else if (atm_phasedgm=="HHe_tabulated")
Comp[3]=atm1;
else
cout<<"atm_phasedgm does not exist, using default"<<endl;
//START main code for the 9 input modes
// 0: regular solver, 1: temperature-free solver, 2: two-layer solver,
// 3: bulk input mode with regular solver
// 4: composition finder, finds third layer mass to match a mass and radius measurement
// 5: modify a built-in EOS on they fly,
// 6: iterate over EOS modifications with two-layer solver, 7: iterate over EOS with regular solver
// 8: MCMC mass fraction finder
if (input_mode == 0)
{
double deltat;
gettimeofday(&start_time,NULL);
planet=fitting_method(Comp, Mcomp, Tgap, ave_rho, P_surface, false);
cout<<"# of shots "<<count_shoot<<", # of total steps "<<count_step<<endl;
gettimeofday(&end_time, NULL);
deltat = ((end_time.tv_sec - start_time.tv_sec) * 1000000u + end_time.tv_usec - start_time.tv_usec) / 1.e6;
cout<<"run time "<<deltat<<'s'<<endl;
if (!planet)
{
for (unsigned int i=0; i < Mcomp.size(); i++)
cout<<Mcomp[i]<<", ";
cout<<"\t No solution found."<<endl;
}
else
{
planet->print(outputfile, false); // Save the result in an asc file with this name.
cout<<"Planet saved: "<<outputfile<<endl;
}
delete planet;
}
else if(input_mode == 1)
{
double deltat;
gettimeofday(&start_time,NULL);
planet=getmass(Mcomp[0],Mcomp[1],Mcomp[2],P_surface);
// Mass in Earth Masses of Core, Mantle, Hydrosphere
gettimeofday(&end_time, NULL);
deltat = ((end_time.tv_sec - start_time.tv_sec) * 1000000u + end_time.tv_usec - start_time.tv_usec) / 1.e6;
cout<<"run time "<<deltat<<'s'<<endl;
if (planet)
{
planet->print(outputfile);
cout<<"Planet saved: "<<outputfile<<endl;
}
// Save the result in an asc file with this name.
delete planet;
}
else if(input_mode == 2)
{
vector<double> Mp,Rp;
double deltat;
for (float value = min_mass; value <= max_mass; value += step_mass) {
Mp.push_back(value);
}
gettimeofday(&start_time,NULL);
twolayer(layer_index,mass_frac,Mp,Rp,P_surface,true);
for(int i=0; i < int(Mp.size()); i++)
cout<<Mp[i]<<" \t"<<Rp[i]<<endl;
gettimeofday(&end_time, NULL);
deltat = ((end_time.tv_sec - start_time.tv_sec) * 1000000u + end_time.tv_usec - start_time.tv_usec) / 1.e6;
cout<<"run time "<<deltat<<'s'<<endl;
}
else if(input_mode == 3)
{
multiplanet(Comp, Tgap, solver, ave_rho, P_surface, false, inputfile, outputfile);
}
else if(input_mode == 4)
{
//Multi-threading is commented out by default for easy install
//Must uncomment Line 2 in Makefile and all occurences of "pragma..." in comfind.cpp
int num_threads=0;
compfinder(Comp,findlayer,layers,minPMR,maxPMR,step,rerr,num_threads,Tgap,ave_rho,P_surface,false,inputfile,outputfile);
}
else if(input_mode == 5)
{
vector<double> Mp,Rp;
double fraction = 0;
int nPhases=3;
EOS **highEOSs = new EOS*[nPhases];
for(int i=0; i<nPhases; i++)
highEOSs[i] = new EOS();
highEOSs[0] -> setphasename("Ice VII");
highEOSs[1] -> setphasename("Ice VII'");
highEOSs[2] -> setphasename("Ice X");
double IceVII_Grande[5][2]={{0.,0.},{1.,13.62},{2.,10.48},{3.,4.},{5.,18.01528}};
double IceVIIp_Grande[5][2]={{0.,0.},{1.,12.32},{2.,22.36},{3.,4.},{5.,18.01528}};
double IceX_Grande[5][2]={{0.,0.},{1.,11.0},{2.,38.6},{3.,4.},{5.,18.01528}};
double start_P[2]={4.76,34.14};
highEOSs[0] -> modifyEOS(IceVII_Grande,5);
highEOSs[1] -> modifyEOS(IceVIIp_Grande,5);
highEOSs[2] -> modifyEOS(IceX_Grande,5);
water.set_phase_highP(nPhases, start_P, highEOSs);
planet = getmass(0,0,0.0999968,P_surface);
if (planet)
planet->print("./result/Structure.txt");
twolayer(0,fraction,Mp,Rp,P_surface);
for(int i=0; i < int(Mp.size()); i++)
cout<<Mp[i]<<" \t"<<Rp[i]<<endl;
for(int i=0; i<nPhases; i++)
delete highEOSs[i];
delete[] highEOSs;
}
else if(input_mode == 6)
{
double deltat;
gettimeofday(&start_time,NULL);
twolayer(layer_index,mass_frac,P_surface,1,inputfile, outputfile);
gettimeofday(&end_time, NULL);
deltat = ((end_time.tv_sec - start_time.tv_sec) * 1000000u + end_time.tv_usec - start_time.tv_usec) / 1.e6;
cout<<"run time "<<deltat<<'s'<<endl;
}
else if(input_mode == 7)
{
double deltat;
gettimeofday(&start_time,NULL);
fullmodel(Comp,Mcomp,Tgap,ave_rho,P_surface,false,2,inputfile,outputfile);
gettimeofday(&end_time, NULL);
deltat = ((end_time.tv_sec - start_time.tv_sec) * 1000000u + end_time.tv_usec - start_time.tv_usec) / 1.e6;
cout<<"run time "<<deltat<<'s'<<endl;
}
else if(input_mode == 8)
{
double deltat;
gettimeofday(&start_time,NULL);
mcmcsample(Comp,MassPrior,MUncPrior,RadPrior,RUncPrior,Tgap,ave_rho,P_surface,false,outputfile,numchains,chainsteps,numlayers);
gettimeofday(&end_time, NULL);
deltat = ((end_time.tv_sec - start_time.tv_sec) * 1000000u + end_time.tv_usec - start_time.tv_usec) / 1.e6;
cout<<"run time "<<deltat<<'s'<<endl;
}
// ============================
delete Fe_liquid;
delete Fe_liquid2;
delete Fe_fcc;
delete Fe_bcc;
delete Fe_hcp;
delete Fe_hcp2;
delete Fe_hcp3;
delete Fe_Dummy;
delete Fe_7Si;
delete Fe_15Si;
delete Fe_Seager;
delete Si_Pv_Shim;
delete Si_Pv;
delete Si_PPv;
delete Si_PPv_Sakai;
delete Si_PREM;
delete Si_BM2fit;
delete Si_Seager;
delete Si_liquid;
delete Si_Liquid_Wolf;
delete Si_Dummy;
delete Fo;
delete Wds;
delete Rwd;
delete Akm;
delete Pv_Doro;
delete PPv_Doro;
delete Fo_Sotin;
delete En;
delete Mw;
delete Ice_Seager;
delete H2O_AQUA;
delete H2O_SeaFreeze;
delete Water_SF;
delete Water_Brown;
delete Water_IAPWS;
delete Water_ExoPlex;
delete Water;
delete Water_sc_Mazevet;
delete IceIh_SF;
delete IceII_SF;
delete IceIII_SF;
delete IceV_SF;
delete IceVI_SF;
delete IceIh;
delete IceIh_ExoPlex;
delete IceVI_ExoPlex;
delete IceVI_Bezacier;
delete IceVII_ExoPlex;
delete IceVII_Bezacier;
delete IceVII;
delete IceVIIp;
delete IceVII_FFH2004;
delete IceVII_FFH2004fit;
delete IceVII_Fei;
delete IceVII_FFH2004BM;
delete IceX_HS;
delete IceX;
delete IceZeng2013FFH;
delete IceZeng2013FMNR;
delete Ice_Dummy;
delete Gas;
delete Gas_iso;
delete Gas_hhe;
delete watervapor;
delete Water_Vap_IAPWS;
delete Gold;
delete Plat;
delete Graph;
delete Diam;
delete BC8;
delete SiC_B3_Vinet;
delete SiC_B1_Vinet;
delete vdW_H2;
delete vdW_He;
delete vdW_H2O;
delete vdW_CH4;
delete vdW_NH3;
delete vdW_CO2;
delete Anorthite;
delete Spinel;
delete Fayalite;
delete Fe_Wadsleyite;
delete Fe_Ringwoodite;
delete Enstatite;
delete Ferrosilite;
delete Diopside;
delete Hedenbergite;
delete HP_clinopyroxene;
delete Mg_Akimotoite;
delete Fe_Akimotoite;
delete Pyrope;
delete Mg_Majorite;
delete Almandine;
delete Grossular;
delete Quartz;
delete Coesite;
delete Stishovite;
delete Seifertite;
delete Fe_Post_Perovskite;
delete Fe_Perovskite;
delete HP_Clinoferrosilite;
delete Periclase;
delete Wustite;
delete Kyanite;
delete Nepheline;
return 0;
}