From d220e07aabaf86136e376d73c28a5fe38476a09a Mon Sep 17 00:00:00 2001 From: kar <kas2020@protonmail.com> Date: Thu, 21 Apr 2022 17:11:53 -0400 Subject: [PATCH] added support for custom values and more modularity --- src/Science.hpp | 2 + src/Science/QSPCount.cpp | 55 +++++++++++++++++++++------ src/cases/qsp/qsp.cpp | 82 +++++++++++++++++++++++++++------------- src/cases/qsp/spins.conf | 47 +++++++++++++++++++++-- 4 files changed, 145 insertions(+), 41 deletions(-) diff --git a/src/Science.hpp b/src/Science.hpp index f429ffa..cd5c38f 100644 --- a/src/Science.hpp +++ b/src/Science.hpp @@ -272,6 +272,8 @@ struct QSPData { TArrayn::DTArray *temp; TArrayn::DTArray *rho; TArrayn::DTArray *salinity; + TArrayn::DTArray *custom_T1; + TArrayn::DTArray *custom_S1; TArrayn::DTArray *xgrid; TArrayn::DTArray *ygrid; TArrayn::DTArray *zgrid; diff --git a/src/Science/QSPCount.cpp b/src/Science/QSPCount.cpp index 358eeaa..25fdae0 100644 --- a/src/Science/QSPCount.cpp +++ b/src/Science/QSPCount.cpp @@ -66,6 +66,7 @@ enum QSPType { QSP_temp, QSP_rho, QSP_salinity, + QSP_custom, }; void QSP_write(int local_rank, const QSPVector &local_hist, @@ -121,6 +122,8 @@ QSPType QSPConvert(const std::string &name) { converted_type = QSP_rho; } else if (name.compare("salinity") == 0) { converted_type = QSP_salinity; + } else if (name.compare("custom") == 0) { + converted_type = QSP_custom; } return converted_type; } @@ -149,11 +152,15 @@ TArrayn::DTArray *QSPPtr(const QSPData &qsp_data, const QSPType &type) { case QSP_salinity: ptr = qsp_data.salinity; break; + case QSP_custom: // Make sure to set the pointer yourself. Can't do it here. + break; } return ptr; } +// compute the minimum and maximum values for either tracer, then substitute +// any default values of +- infinity with the global min/max values instead. void QSPMaxMin(const QSPType &T1_type, const QSPType &S1_type, TArrayn::DTArray *T1_ptr, TArrayn::DTArray *S1_ptr, QSPOptions &qsp_options, const QSPData &qsp_data, int i_low, @@ -214,30 +221,46 @@ void QSPMaxMin(const QSPType &T1_type, const QSPType &S1_type, MPI_COMM_WORLD); switch (T1_type) { case QSP_ke: - qsp_options.T1_max = glob_ke_max; - qsp_options.T1_min = glob_ke_min; + qsp_options.T1_max = + qsp_options.T1_max == double_max ? glob_ke_max : qsp_options.T1_max; + qsp_options.T1_min = + qsp_options.T1_min == -double_max ? glob_ke_min : qsp_options.T1_min; break; case QSP_rho: - qsp_options.T1_max = glob_rho_max; - qsp_options.T1_min = glob_rho_min; + qsp_options.T1_max = + qsp_options.T1_max == double_max ? glob_rho_max : qsp_options.T1_max; + qsp_options.T1_min = + qsp_options.T1_min == -double_max ? glob_rho_min : qsp_options.T1_min; break; default: - qsp_options.T1_max = psmax(max(*T1_ptr)); - qsp_options.T1_min = psmin(min(*T1_ptr)); + qsp_options.T1_max = qsp_options.T1_max == double_max + ? psmax(max(*T1_ptr)) + : qsp_options.T1_max; + qsp_options.T1_min = qsp_options.T1_min == -double_max + ? psmin(min(*T1_ptr)) + : qsp_options.T1_min; break; } switch (S1_type) { case QSP_ke: - qsp_options.S1_max = glob_ke_max; - qsp_options.S1_min = glob_ke_min; + qsp_options.S1_max = + qsp_options.S1_max == double_max ? glob_ke_max : qsp_options.S1_max; + qsp_options.S1_min = + qsp_options.S1_min == -double_max ? glob_ke_min : qsp_options.S1_min; break; case QSP_rho: - qsp_options.S1_max = glob_rho_max; - qsp_options.S1_min = glob_rho_min; + qsp_options.S1_max = + qsp_options.S1_max == double_max ? glob_rho_max : qsp_options.S1_max; + qsp_options.S1_min = + qsp_options.S1_min == -double_max ? glob_rho_min : qsp_options.S1_min; break; default: - qsp_options.S1_max = psmax(max(*S1_ptr)); - qsp_options.S1_min = psmin(min(*S1_ptr)); + qsp_options.S1_max = qsp_options.S1_max == double_max + ? psmax(max(*S1_ptr)) + : qsp_options.S1_max; + qsp_options.S1_min = qsp_options.S1_min == -double_max + ? psmin(min(*S1_ptr)) + : qsp_options.S1_min; break; } } else { // !(cond1 || cond2) == !cond1 && !cond2 @@ -259,6 +282,14 @@ void QSPCount(QSPOptions qsp_options, QSPData qsp_data) { TArrayn::DTArray *S1_ptr = QSPPtr(qsp_data, S1_type); TArrayn::DTArray *T1_ptr = QSPPtr(qsp_data, T1_type); + if (T1_type == QSP_custom) { + T1_ptr = qsp_data.custom_T1; + } + + if (S1_type == QSP_custom) { + S1_ptr = qsp_data.custom_S1; + } + if ((!S1_ptr && S1_type != QSP_ke) || (!T1_ptr && T1_type != QSP_ke)) { std::cout << "Not enough data was provided for the requested tracer. " "Aborting...\n"; diff --git a/src/cases/qsp/qsp.cpp b/src/cases/qsp/qsp.cpp index f2cccdf..3dca040 100644 --- a/src/cases/qsp/qsp.cpp +++ b/src/cases/qsp/qsp.cpp @@ -8,10 +8,9 @@ #include "../../Options.hpp" // config-file parser #include "../../Science.hpp" // Science content -// Defines limits of intrinsic types. Used as default values for -// T1_max, T1_min, S1_max and/orS1_min #include <cassert> #include <limits> +#include <string> // Tensor variables for indexing blitz::firstIndex ii; @@ -36,21 +35,23 @@ const int z_ind = 2; // QSP variables double T1_max, S1_max, T1_min, S1_min; -string T1_name, S1_name; +std::string T1_name, S1_name; int NT, NS; -string QSP_filename; -bool use_salinity; +std::string QSP_filename; +bool use_salinity, read_rho; +std::string salinity_filename, temp_filename, rho_filename; +std::string custom_T1_filename, custom_S1_filename; +const double double_max = std::numeric_limits<double>::max(); // current output number int plotnum; // Derivative options -string deriv_filenames; // file name to take derivative of -int start_sequence; // output number to start taking derivatives at -int final_sequence; // output number to stop taking derivatives at -int step_sequence; // step between outputs to take derivatives - // streching/tilting? -bool v_exist; // Does the v field exist? +int start_sequence; // output number to start taking derivatives at +int final_sequence; // output number to stop taking derivatives at +int step_sequence; // step between outputs to take derivatives + // streching/tilting? +bool v_exist; // Does the v field exist? /* ------------------ Adjust the class --------------------- */ @@ -152,22 +153,39 @@ public: qsp_data.temp = NULL; qsp_data.rho = NULL; qsp_data.salinity = NULL; + qsp_data.custom_T1 = NULL; + qsp_data.custom_S1 = NULL; + + DTArray *arr_salinity, *arr_temperature, *arr_rho, *custom_T1, *custom_S1; - DTArray *arr_salinity, *arr_temperature, *arr_rho; if (use_salinity) { arr_salinity = alloc_array(Nx, Ny, Nz); - init_tracer_restart("s", *arr_salinity); + init_tracer_restart(salinity_filename, *arr_salinity); qsp_data.salinity = arr_salinity; } + + if (read_rho) { + arr_rho = alloc_array(Nx, Ny, Nz); + init_tracer_restart(rho_filename, *arr_rho); + qsp_data.rho = arr_rho; + } + if (T1_name.compare("temp") == 0 || S1_name.compare("temp") == 0) { arr_temperature = alloc_array(Nx, Ny, Nz); - init_tracer_restart("t", *arr_temperature); + init_tracer_restart(temp_filename, *arr_temperature); qsp_data.temp = arr_temperature; } - if (T1_name.compare("rho") == 0 || S1_name.compare("rho") == 0) { - arr_rho = alloc_array(Nx, Ny, Nz); - init_tracer_restart("rho", *arr_rho); - qsp_data.rho = arr_rho; + + if (T1_name.compare("custom") == 0) { + custom_T1 = alloc_array(Nx, Ny, Nz); + init_tracer_restart(custom_T1_filename, *custom_T1); + qsp_data.custom_T1 = custom_T1; + } + + if (S1_name.compare("custom") == 0) { + custom_S1 = alloc_array(Nx, Ny, Nz); + init_tracer_restart(custom_S1_filename, *custom_S1); + qsp_data.custom_S1 = custom_S1; } QSPCount(qsp_opts, qsp_data); @@ -216,27 +234,39 @@ int main(int argc, char **argv) { add_option("type_y", &ygrid_type, "FOURIER", "Grid type in Y"); add_option("type_z", &zgrid_type, "Grid type in Z"); - option_category("Derivative options"); + option_category("QSP options"); add_option("start_sequence", &start_sequence, "Sequence number to start taking derivatives at"); add_option("final_sequence", &final_sequence, "Sequence number to stop taking derivatives at"); add_option("step_sequence", &step_sequence, 1, "Step between outputs to take derivatives"); + add_option("salinity_filename", &salinity_filename, + "Base Filename of Salinity data (optional)."); + add_option("temp_filename", &temp_filename, + "Base Filename of temperature data (optional)."); + add_option("T1_filename", &custom_T1_filename, + "Base Filename of custom tracer for T1."); + add_option("S1_filename", &custom_S1_filename, + "Base Filename of custom tracer for S1."); add_option("T1", &T1_name, "u", - "Name of tracer 1 for QSP. Valid values are rho,u,v,w,temp or ke"); + "Name of tracer 1 for QSP. Valid values are rho,u,v,w,temp, " + "salinity or ke"); add_option("S1", &S1_name, "w", - "Name of tracer 2 for QSP. Valid values are rho,u,v,w,temp or ke"); - add_option("T1_max", &T1_max, std::numeric_limits<double>::max(), + "Name of tracer 2 for QSP. Valid values are rho,u,v,w,temp, " + "salinity or ke"); + add_option("T1_max", &T1_max, double_max, "Maximum explicit bin for T1 in QSP."); - add_option("T1_min", &T1_min, std::numeric_limits<double>::min(), + add_option("T1_min", &T1_min, -double_max, "Minimum explicit bin for T1 in QSP."); - add_option("S1_max", &S1_max, std::numeric_limits<double>::max(), + add_option("S1_max", &S1_max, double_max, "Maximum explicit bin for S1 in QSP."); - add_option("S1_min", &S1_min, std::numeric_limits<double>::min(), + add_option("S1_min", &S1_min, -double_max, "Minimum explicit bin for S1 in QSP."); add_option("salinity", &use_salinity, false, - "Should salinity be read in from filename s?."); + "Should salinity be read in from a file?."); + add_option("read_rho", &read_rho, false, + "Should rho be read in from a file?."); add_option("QSP_filename", &QSP_filename, "QSP_default", "Filename to save data to. Don't include file extension."); add_option("NS", &NS, 10, "Number of bins for tracer S"); diff --git a/src/cases/qsp/spins.conf b/src/cases/qsp/spins.conf index b25d2b6..dd65a3b 100644 --- a/src/cases/qsp/spins.conf +++ b/src/cases/qsp/spins.conf @@ -15,14 +15,55 @@ type_z = NO_SLIP mapped_grid = false v_exist = false -# Derivative Options +# If salinity is needed (directly or indirectly) set this to true +salinity = false +salinity_filename = s + +# If you already pre-computed rho (the equation of state) and saved it to a +# file, then set this to true. If this is false, and QSP can find the +# temperature data but not rho, it will use the equation of state function from +# Science.hpp, and if it also finds salinity it will add that to the equation +# of state calculation too. +read_rho = false +rho_filename = rho + +# Sequence Options start_sequence = 0 final_sequence = 0 step_sequence = 1 -# QSP Parameters +# Choose what tracers you want to use. T1 and S1 have no distinguishable +# meaning, just stay consistent with NT and NS. Do note that if you pick ke +# then QSP will compute it in-place. If you already pre-computed ke and have a +# saved file for it, use the custom property explained below instead. +# Tracer options: rho, temp, salinity, u, v, w, ke +# +# Note: If you need to use a custom tracer (i.e. not one of the above), set the +# tracer name to "custom." If you do this however, it is your responsability to +# ensure that: +# a) you provide a valid custom filename too and +# b) all prepocessing is already completed and the data in the file is exactly +# what you want to use T1 = temp S1 = ke -QSP_filename = QSP + +# Tracer base filenames. These are only relevent parameters IFF you set the +# according tracer name to "custom" above. Otherwise, these are ignored. +T1_filename = vorticity +S1_filename = vorticity + +# Set the min/max values of the first/last bin in each dimension respectively. +# These are optional parameters. If you remove these lines from the config QSP +# will find the global min/max values for each timestep and use that instead. +# So if you need fixed values for these make sure to include them! +T1_min = 1 +T1_max = 1 +S1_min = 1 +S1_max = 1 + +# Number of bins for T1 and S1 chosen above. NT = 10 NS = 10 + +# Base filename to save results +QSP_filename = QSP -- GitLab