diff --git a/matlab/spins_QSP_csv.m b/matlab/spins_QSP_csv.m new file mode 100644 index 0000000000000000000000000000000000000000..63f60d07bd5011503a0587b9d266f0edfb3e7bd9 --- /dev/null +++ b/matlab/spins_QSP_csv.m @@ -0,0 +1,15 @@ +function [T1_max, T1_min, S1_max, S1_min, pdfCount] = spins_QSP_reader(filename) + % Reads in the csv file and interprets it in the correct way for the user. + % + % Input: Filename (string) name of csv file. + % + % Output: Returns the max/min values for T1 and S1 (as specified in + % spins.conf) and the (normalized) pdfCount histogram. + A = importdata(filename); + T1_max = A(1, 1); + T1_min = A(1, 2); + S1_max = A(1, 3); + S1_min = A(1, 4); + pdfCount = A(2:end, :); + pdfCount /= sum(sum(pdfCount)); +end diff --git a/src/Science.hpp b/src/Science.hpp index 24b459c0b039755d14cb37db5eec7fa9ead1b304..fb54033a5ee0319deec510c765a344621a100317 100644 --- a/src/Science.hpp +++ b/src/Science.hpp @@ -13,12 +13,12 @@ extern Array<double,1> _quadw_x, _quadw_y, _quadw_z; // Marek's Overturning Diagnostic -blitz::Array<double,3> overturning_2d(blitz::Array<double,3> const & rho, +blitz::Array<double,3> overturning_2d(blitz::Array<double,3> const & rho, blitz::Array<double,1> const & zgrid, TArrayn::Dimension reduce = TArrayn::thirdDim ); // Read in a 2D file and interpret it as a 2D slice of a 3D array, for // initialization with read-in-data from a program like MATLAB -void read_2d_slice(blitz::Array<double,3> & fillme, const char * filename, +void read_2d_slice(blitz::Array<double,3> & fillme, const char * filename, int Nx, int Ny); void read_2d_restart(blitz::Array<double,3>& fillme, const char* filename, @@ -40,7 +40,7 @@ void compute_baroclinic_vort_x(TArrayn::DTArray & barovortx, TArrayn::DTArray & TArrayn::Grad * gradient_op, const string * grid_type); void compute_baroclinic_vort_y(TArrayn::DTArray & barovorty, TArrayn::DTArray & T, TArrayn::Grad * gradient_op, const string * grid_type); -void compute_baroclinic_vort(TArrayn::DTArray & barovort, TArrayn::DTArray & temp, +void compute_baroclinic_vort(TArrayn::DTArray & barovort, TArrayn::DTArray & temp, TArrayn::DTArray & T, TArrayn::Grad * gradient_op, const string * grid_type, bool v_exist); // Enstrophy density @@ -63,7 +63,7 @@ void compute_BPE_from_internal(double & phi_i, TArrayn::DTArray & rho, double kappa_rho, double rho_0, double g, int Nz, bool dimensional_rho = false); // Quadrature weights -void compute_quadweights(int szx, int szy, int szz, +void compute_quadweights(int szx, int szy, int szz, double Lx, double Ly, double Lz, NSIntegrator::DIMTYPE DIM_X, NSIntegrator::DIMTYPE DIM_Y, NSIntegrator::DIMTYPE DIM_Z); @@ -132,20 +132,20 @@ void R_invt(TArrayn::DTArray & R, TArrayn::DTArray & u, inline double nleos_inline(double T, double S){ - // Returns the density (kg/m^3) + // Returns the density (kg/m^3) // MacDougall et. al. 2003 (JAOT 20) // // This EOS is a rational function taken at pressure = 0 // // Constants for Numerator - + // First find any regions of negative salinity and set them to zero for this operation. - - if (S < 0) { + + if (S < 0) { S = 0; }; - const double N0 = 9.99843699e+02; + const double N0 = 9.99843699e+02; const double N1 = 7.35212840e+00; const double N2 = -5.45928211e-02; const double N3 = 3.98476704e-04; @@ -162,7 +162,7 @@ inline double nleos_inline(double T, double S){ double numerator = N0 + T*(N1 + T*(N2 + N3*T)) + S*(N4 + N5*T + N6*S) + p*(N7 + N8*T*T + N9*S + p*(N10 + N11*T*T)); - // Constants for denominator + // Constants for denominator const double D0 = 1.00000000e+00; const double D1 = 7.28606739e-03; const double D2 = -4.60835542e-05; @@ -176,7 +176,7 @@ inline double nleos_inline(double T, double S){ const double D10 = 5.30848875e-06; const double D11 = -3.03175128e-16; const double D12 = -1.27934137e-17; - + double denominator = D0 + T*(D1 + T*(D2 + T*(D3 + D4*T))) + S*(D5 + T*(D6 + D7*T*T) + sqrt(S)*(D8 + D9*T*T)) + p*(D10 + p*T*(D11*T*T + D12*p)); return numerator/denominator; @@ -187,12 +187,12 @@ void nleos(TArrayn::DTArray & rho, TArrayn::DTArray & T, TArrayn::DTArray & S); inline double compute_alpha(double T0, double S0){ - // Computes the thermal expansion coefficient at S0 and T0 + // Computes the thermal expansion coefficient at S0 and T0 // Derivative is a finite difference for simplicity // Does not divide by rho_0, that is done in lineos() const double dT = 1e-08; double TpdT = T0 + dT; - + double alpha = (nleos_inline(TpdT,S0) - nleos_inline(T0,S0))/dT; return alpha; @@ -200,7 +200,7 @@ inline double compute_alpha(double T0, double S0){ BZ_DECLARE_FUNCTION(compute_alpha) inline double compute_beta(double T0, double S0){ - // Computes the haline contraction coefficient at S0 and T0 + // Computes the haline contraction coefficient at S0 and T0 // Derivative is a finite difference for simplicity // Does not divide by rho_0, that is done in lineos() const double dS = 1e-08; @@ -211,9 +211,9 @@ inline double compute_beta(double T0, double S0){ return beta; } BZ_DECLARE_FUNCTION(compute_beta) - + inline double compute_rho0(double T0, double S0){ - // Computes the reference density at S0 and T0 + // Computes the reference density at S0 and T0 double rho_0 = nleos_inline(T0,S0); return rho_0; @@ -229,7 +229,7 @@ void eos(const string eos_type, TArrayn::DTArray & rho, TArrayn::DTArray & T, TA /* inline double fresh_quad(double T){ - // Returns the density (kg/m^3) for water using simple quadratic fit to + // Returns the density (kg/m^3) for water using simple quadratic fit to // MacDougall et. al. 2003 (JAOT 20) // Constants are determined via a quadratic fit preserving the Temperature of maximum density const double rho_max = 9.999744074665388e+02; // Density of freshwater at Tmd (deg C) @@ -248,7 +248,17 @@ void compute_lambda2(TArrayn::DTArray & lambda2, TArrayn::DTArray & u, TArrayn::DTArray & temp2, TArrayn::Grad * gradient_op, const string * grid_type, TArrayn::DTArray & A11, TArrayn::DTArray & A12, TArrayn::DTArray & A13, TArrayn::DTArray & A22, TArrayn::DTArray & A23, - TArrayn::DTArray & A33); + TArrayn::DTArray & A33); + +/* Creates and outputs data for plotting a bivariate histogram with NS*NT bins + * between tracers S1 and T1 to "filename.csv" (don't include file extension). + */ +void QSPCount(const TArrayn::DTArray &t, const TArrayn::DTArray &u, + const TArrayn::DTArray &v, const TArrayn::DTArray &w, + const char T1_name, const char S1_name, const int NS, + const int NT, double T1_max, double S1_max, double T1_min, + double S1_min, const int Nx, const int Ny, const int Nz, + string filename, const int plotnum); // Equation of state for seawater, polynomial fit from // Brydon, Sun, Bleck (1999) (JGR) @@ -283,7 +293,7 @@ inline double eqn_of_state_dT(double T){ // Constants are from table 4 of the above paper, at pressure 0 // (This is appropriate since this is currently an incompressible // model) - + // Kept the same names for these constants as in eqn_of_state const double c2 = 5.10768e-2; // T term, constant after derivative const double c4 = -7.40849e-3; // T^2 term, 2T after derivative diff --git a/src/Science/QSPCount.cpp b/src/Science/QSPCount.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c2d2df524437e0fd2bea3d8485cfae37a9cfcc02 --- /dev/null +++ b/src/Science/QSPCount.cpp @@ -0,0 +1,287 @@ +#include "../Science.hpp" +#include "boost/lexical_cast.hpp" +#include <algorithm> +#include <blitz/array.h> +#include <cmath> +#include <cstdlib> +#include <fstream> +#include <ios> +#include <iostream> +#include <limits> +#include <mpi.h> +#include <string> +#include <vector> + +using namespace Transformer; +using namespace blitz; + +int index(int row, int col, int rows, int cols) { + assert(row >= 0 && row < rows); + assert(col >= 0 && col < cols); + return (row * cols) + col; +} + +void QSPCount(const TArrayn::DTArray &t, const TArrayn::DTArray &u, + const TArrayn::DTArray &v, const TArrayn::DTArray &w, + const char T1_name, const char S1_name, const int NS, + const int NT, double T1_max, double S1_max, double T1_min, + double S1_min, const int Nx, const int Ny, const int Nz, + string filename, const int plotnum) { + + int local_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &local_rank); + const TArrayn::DTArray *T1_ptr = NULL, *S1_ptr = NULL; + + switch (T1_name) { + case 'u': + T1_ptr = &u; + break; + case 'v': + T1_ptr = &v; + break; + case 'w': + T1_ptr = &w; + break; + case 'k': + break; + case 't': + T1_ptr = &t; + break; + case 'T': + T1_ptr = &t; + break; + default: + return; + } + + switch (S1_name) { + case 'u': + S1_ptr = &u; + break; + case 'v': + S1_ptr = &v; + break; + case 'w': + S1_ptr = &w; + break; + case 'k': + break; + case 't': + S1_ptr = &t; + break; + case 'T': + S1_ptr = &t; + break; + default: + return; + } + + int i_low = u.lbound(blitz::firstDim); + int j_low = u.lbound(blitz::secondDim); + int k_low = u.lbound(blitz::thirdDim); + int i_high = u.ubound(blitz::firstDim); + int j_high = u.ubound(blitz::secondDim); + int k_high = u.ubound(blitz::thirdDim); + + // This block calculates the global min/max values, in case the user + // didn't want to specify them. + double double_max = std::numeric_limits<double>::max(); + double double_min = std::numeric_limits<double>::min(); + if (T1_max == double_max || S1_max == double_max || S1_max == double_min || + S1_min == double_min) { + + // If One of the variables is K.E or rho, we need to hand-roll the max/min + // since, in general, the index of max(u) is the same as the index of max(v) + if (T1_name == 'k' || T1_name == 't' || S1_name == 'k' || S1_name == 't') { + double ke_max = -double_max, ke_min = double_max; + double rho_max = -double_max, rho_min = double_max; + + // Main hand-rolled loop + for (int i = i_low; i <= i_high; i++) { + for (int j = j_low; j <= j_high; j++) { + for (int k = k_low; k <= k_high; k++) { + double ke_current = 0, tmp = 0; + if (Nx > 1) { + tmp = u(i, j, k); + ke_current += tmp * tmp; + } + if (Ny > 1) { + tmp = v(i, j, k); + ke_current += tmp * tmp; + } + if (Nz > 1) { + tmp = w(i, j, k); + ke_current += tmp * tmp; + } + ke_current = 0.5 * ke_current; + double rho_current = eqn_of_state_t(t(i, j, k)); + ke_max = ke_current > ke_max ? ke_current : ke_max; + ke_min = ke_current < ke_min ? ke_current : ke_min; + rho_max = rho_current > rho_max ? rho_current : rho_max; + rho_min = rho_current < rho_min ? rho_current : rho_min; + } + } + } + + double glob_ke_max, glob_ke_min, glob_rho_max, glob_rho_min; + MPI_Allreduce(&ke_max, &glob_ke_max, 1, MPI_DOUBLE, MPI_MAX, + MPI_COMM_WORLD); + MPI_Allreduce(&ke_min, &glob_ke_min, 1, MPI_DOUBLE, MPI_MIN, + MPI_COMM_WORLD); + MPI_Allreduce(&rho_max, &glob_rho_max, 1, MPI_DOUBLE, MPI_MAX, + MPI_COMM_WORLD); + MPI_Allreduce(&rho_min, &glob_rho_min, 1, MPI_DOUBLE, MPI_MIN, + MPI_COMM_WORLD); + + switch (T1_name) { + case 'k': + T1_max = glob_ke_max; + T1_min = glob_ke_min; + break; + case 't': + T1_max = glob_rho_max; + T1_min = glob_rho_min; + break; + default: + T1_max = psmax(max(*T1_ptr)); + T1_min = psmin(min(*T1_ptr)); + break; + } + + switch (S1_name) { + case 'k': + S1_max = glob_ke_max; + S1_min = glob_ke_min; + break; + case 't': + S1_max = glob_rho_max; + S1_min = glob_rho_min; + break; + default: + S1_max = psmax(max(*S1_ptr)); + S1_min = psmin(min(*S1_ptr)); + break; + } + } else { // !(cond1 || cond2) == !cond1 && !cond2 + S1_max = psmax(max(*S1_ptr)); + S1_min = psmin(min(*S1_ptr)); + T1_max = psmax(max(*T1_ptr)); + T1_min = psmin(min(*T1_ptr)); + } + } + + double hS = (S1_max - S1_min) / (double)NS; + double hT = (T1_max - T1_min) / (double)NT; + double hS_inv = 1 / hS; + double hT_inv = 1 / hT; + + int *local_hist = (int *)calloc(NS * NT, sizeof(int)); + if (!local_hist) { + std::cout << "Bad memory allocation. Exiting QSPCount" << std::endl; + return; + } + + // Main loop for QSP + double Tval, Sval, tmp; + for (int i = i_low; i <= i_high; i++) { + for (int j = j_low; j <= j_high; j++) { + for (int k = k_low; k <= k_high; k++) { + + if (T1_name == 'k') { + Tval = 0; + if (Nx > 1) { + tmp = u(i, j, k); + Tval += tmp * tmp; + } + if (Ny > 1) { + tmp = v(i, j, k); + Tval += tmp * tmp; + } + if (Nz > 1) { + tmp = w(i, j, k); + Tval += tmp * tmp; + } + Tval = 0.5 * Tval; + } else if (T1_name == 't') { + tmp = (*T1_ptr)(i, j, k); + Tval = eqn_of_state_t(tmp); + } else { + Tval = (*T1_ptr)(i, j, k); + } + int idxT = floor((Tval - T1_min) * hT_inv); + if (idxT < 0) { + idxT = 0; + } else if (idxT >= NT) { + idxT = 0; + } + + if (S1_name == 'k') { + Sval = 0; + if (Nx > 1) { + tmp = u(i, j, k); + Sval += tmp * tmp; + } + if (Ny > 1) { + tmp = v(i, j, k); + Sval += tmp * tmp; + } + if (Nz > 1) { + tmp = w(i, j, k); + Sval += tmp * tmp; + } + Sval = 0.5 * Sval; + } else if (S1_name == 't') { + tmp = (*S1_ptr)(i, j, k); + Sval = eqn_of_state_t(tmp); + } else { + Sval = (*S1_ptr)(i, j, k); + } + int idxS = floor((Sval - S1_min) * hS_inv); + if (idxS < 0) { + idxS = 0; + } else if (idxS >= NS) { + idxS = 0; + } + local_hist[index(idxS, idxT, NS, NT)] += 1; + } + } + } + + MPI_Barrier(MPI_COMM_WORLD); // Wait for everyone to finish + if (local_rank == 0) { + int *glob_hist = (int *)calloc(NS * NT, sizeof(int)); + if (!glob_hist) { + std::cout << "Bad memory allocation. Exiting QSPCount" << std::endl; + free(local_hist); + return; + } + MPI_Reduce(local_hist, glob_hist, // send and receive buffers + NS * NT, MPI_INT, // count and datatype + MPI_SUM, 0, // Reduction operator and root process # + MPI_COMM_WORLD); // Communicator + filename = filename + "." + boost::lexical_cast<string>(plotnum) + ".csv"; + std::fstream outfile; + outfile.open(filename.c_str(), std::ios_base::out); + if (outfile.is_open()) { + outfile << T1_max << ',' << T1_min << ',' << S1_max << ',' << S1_min; + for (int i = 4; i < NT; i++) { + outfile << ',' << 0; + } + outfile << std::endl; + for (int ii = 0; ii < NS; ii++) { + outfile << glob_hist[index(ii, 0, NS, NT)]; + for (int jj = 1; jj < NT; jj++) { + outfile << ',' << glob_hist[index(ii, jj, NS, NT)]; + } + outfile << std::endl; + } + } + free(glob_hist); + } else { + MPI_Reduce(local_hist, NULL, // send and receive buffers + NS * NT, MPI_INT, // count and datatype + MPI_SUM, 0, // Reduction operator and root process # + MPI_COMM_WORLD); // Communicator + } + free(local_hist); +} diff --git a/src/VERSION b/src/VERSION index ae8b19475b67f0169e4f6057b5c5728ce674b540..81e4488aef22f8c969bdd8aada2b50890c93a412 100644 --- a/src/VERSION +++ b/src/VERSION @@ -1,3 +1,3 @@ MAJOR_VERSION=2 MINOR_VERSION=1 -PATCH_VERSION=8 +PATCH_VERSION=9 diff --git a/src/cases/derivatives/derivatives.cpp b/src/cases/derivatives/derivatives.cpp index e34cf225c1f576bd8c7423d00db8723d79d3b4fb..99b158abab73d374d9a00df52328ea5a1cbe9dcd 100644 --- a/src/cases/derivatives/derivatives.cpp +++ b/src/cases/derivatives/derivatives.cpp @@ -8,6 +8,10 @@ #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 <limits> + // Tensor variables for indexing blitz::firstIndex ii; blitz::secondIndex jj; @@ -29,6 +33,12 @@ const int x_ind = 0; const int y_ind = 1; const int z_ind = 2; +// QSP variables +double T1_max, S1_max, T1_min, S1_min; +char T1_name, S1_name; +int NT, NS; +string QSP_filename; + // physical parameters double visco; // viscosity (m^2/s) double rho_0; // reference density (kg/m^3) @@ -38,7 +48,7 @@ double g; // acceleration due to gravity (m/s^2) int plotnum; // Derivative options -string deriv_filenames; // file name to take derivative of +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 @@ -52,8 +62,9 @@ bool do_enst_stretch; // Do enstrophy production term from vortex bool do_Q; // Do second invariant of grad(u,v,w)? bool do_R; // Do third invariant/det of grad(u,v,w)? bool do_Q_and_R; // Do the second and third invariants? -bool do_lambda2; // Do lambda2/Hussain's Lambda? +bool do_lambda2; // Do lambda2/Hussain's Lambda? bool v_exist; // Does the v field exist? +bool do_hist; // Create QSP data? /* ------------------ Adjust the class --------------------- */ @@ -87,7 +98,7 @@ class userControl : public BaseCase { /* Set other things */ double get_visco() const { return visco; } int get_restart_sequence() const { return plotnum; } - + /* Read grid (if mapped) */ bool is_mapped() const { return mapped; } void do_mapping(DTArray & xg, DTArray & yg, DTArray & zg) { @@ -116,24 +127,25 @@ class userControl : public BaseCase { //string prev_deriv, base_field; vector<string> fields; // vector of fields to take derivatives split(deriv_filenames.c_str(), ' ', fields); // populate that vector - if ( do_vort_stretch or do_enst_stretch or do_Q or do_R or do_Q_and_R or do_lambda2 ) { + if ( do_vort_stretch or do_enst_stretch or do_Q or do_R or + do_Q_and_R or do_lambda2 or do_hist ) { temp1 = alloc_array(Nx,Ny,Nz); temp2 = alloc_array(Nx,Ny,Nz); - if ( do_enst_stretch ) + if ( do_enst_stretch ) temp3 = alloc_array(Nx,Ny,Nz); } - - if ( do_barvor ) { + + if ( do_barvor ) { temp4 = alloc_array(Nx,Ny,Nz); } if ( do_lambda2 ) { - A11 = alloc_array(Nx,Ny,Nz); - A12 = alloc_array(Nx,Ny,Nz); - A13 = alloc_array(Nx,Ny,Nz); - A22 = alloc_array(Nx,Ny,Nz); - A23 = alloc_array(Nx,Ny,Nz); - A33 = alloc_array(Nx,Ny,Nz); + A11 = alloc_array(Nx,Ny,Nz); + A12 = alloc_array(Nx,Ny,Nz); + A13 = alloc_array(Nx,Ny,Nz); + A22 = alloc_array(Nx,Ny,Nz); + A23 = alloc_array(Nx,Ny,Nz); + A33 = alloc_array(Nx,Ny,Nz); } // Compute derivatives at each requested output for ( plotnum = start_sequence; plotnum <= final_sequence; @@ -154,7 +166,7 @@ class userControl : public BaseCase { // parse for expansion type find_expansion(grid_type, expan, fields[var_num]); - // read the field and setup for derivative + // read the field and setup for derivative if ( fields[var_num] == "v" ) { saved_v = true; init_tracer_restart(fields[var_num],v); @@ -224,7 +236,7 @@ class userControl : public BaseCase { } } } - + // Baroclinic vorticity if ( do_barvor ) { @@ -239,23 +251,23 @@ class userControl : public BaseCase { compute_baroclinic_vort_x(deriv_var, u, gradient_op, grid_type); deriv_var=deriv_var*g; write_array(deriv_var,"barx",plotnum); - if (master()) fprintf(stdout,"Completed the write for barx.%d\n",plotnum); + if (master()) fprintf(stdout,"Completed the write for barx.%d\n",plotnum); } - + compute_baroclinic_vort_y(deriv_var, u, gradient_op, grid_type); deriv_var=deriv_var*g; write_array(deriv_var,"bary",plotnum); if (master()) fprintf(stdout,"Completed the write for bary.%d\n",plotnum); - + // Restart u u = 0; } - // read in fields (if not already stored in memory) + // read in fields (if not already stored in memory) if ( do_vor_x or do_vor_y or do_vor_z or - do_enstrophy or do_dissipation or - do_vort_stretch or do_enst_stretch or - do_Q or do_R or do_Q_and_R or do_lambda2 ) { + do_enstrophy or do_dissipation or + do_vort_stretch or do_enst_stretch or + do_Q or do_R or do_Q_and_R or do_lambda2 or do_hist ) { // u init_tracer_restart("u",u); // v @@ -299,7 +311,7 @@ class userControl : public BaseCase { write_array(deriv_var,"vortz",plotnum); if (master()) fprintf(stdout,"Completed the write for vortz.%d\n",plotnum); - } + } // Calculate Enstrophy if ( do_enstrophy ) { @@ -373,7 +385,7 @@ class userControl : public BaseCase { write_array(deriv_var,"Q",plotnum); if (master()) fprintf(stdout,"Completed the write for Q.%d\n",plotnum); } - + // Calculate R/third invariant of grad(u,v,w) if ( do_R or do_Q_and_R ) { R_invt(deriv_var, u, v, w, *temp1, *temp2, gradient_op, grid_type, v_exist); @@ -385,13 +397,29 @@ class userControl : public BaseCase { // Calculate lambda2/second eigenvalue of S^2+Omega^2 if ( do_lambda2 ){ - compute_lambda2( deriv_var, u, v, w, *temp1, *temp2, gradient_op, + compute_lambda2( deriv_var, u, v, w, *temp1, *temp2, gradient_op, grid_type, *A11, *A12, *A13, *A22, *A23, *A33); double max_var = psmax(max(abs(deriv_var))); if (master()) fprintf(stdout,"Max lam2: %.6g\n",max_var); write_array(deriv_var,"lam2",plotnum); if (master()) fprintf(stdout,"Completed the write for lam2.%d\n",plotnum); - + + } + + // Compute QSP data. The code promises to not mutate the arrays, + // nor to make deep copies of them + if ( do_hist ){ + // Read in T to temp1 if required. + if (T1_name == 't' || S1_name == 't' || T1_name == 'T' || + S1_name == 'T') { + init_tracer_restart("t", *temp1); + } + QSPCount(*temp1, u, v, w, T1_name, S1_name, NS, NT, + T1_max, S1_max, T1_min, S1_min, + Nx, Ny, Nz, QSP_filename, plotnum); + if (master()) { + fprintf(stdout, "Completed the write for QSP.%d\n", plotnum); + } } } } @@ -465,6 +493,16 @@ int main(int argc, char ** argv) { add_option("do_R",&do_R,false,"Calculate R?"); add_option("do_Q_and_R",&do_Q_and_R,false,"Calculate Q and R?"); add_option("do_lambda2",&do_lambda2,false,"Calculate Lambda2?"); + add_option("do_hist",&do_hist,false,"Create QSP Data?"); + add_option("T1",&T1_name,'t', "Name of tracer 1 for QSP. Valid values are t (for rho),u,v,w,T (for temp) or k for K.E."); + add_option("S1",&S1_name,'w', "Name of tracer 2 for QSP. Valid values are t (for rho),u,v,w,T (for temp) or k for K.E."); + add_option("T1_max",&T1_max,std::numeric_limits<double>::max(), "Maximum explicit bin for T1 in QSP."); + add_option("T1_min",&T1_min,std::numeric_limits<double>::min(), "Minimum explicit bin for T1 in QSP."); + add_option("S1_max",&S1_max,std::numeric_limits<double>::max(), "Maximum explicit bin for S1 in QSP."); + add_option("S1_min",&S1_min,std::numeric_limits<double>::min(), "Minimum explicit bin for S1 in QSP."); + 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"); + add_option("NT",&NT,10,"Number of bins for tracer T"); add_option("v_exist",&v_exist,"Does the v field exist?"); // Parse the options from the command line and config file options_parse(argc,argv); @@ -489,13 +527,13 @@ int main(int argc, char ** argv) { } if (visco==1.0){ if (master()) - fprintf(stdout,"You may have forgotten to specify viscosity, " + fprintf(stdout,"You may have forgotten to specify viscosity, " "Using default value visco = 1.\n"); } if (rho_0==1000.0){ if (master()) - fprintf(stdout,"You may have forgotten to specify reference density, " + fprintf(stdout,"You may have forgotten to specify reference density, " "Using default value rho_0 = 1000.\n"); } diff --git a/src/cases/derivatives/spins.conf b/src/cases/derivatives/spins.conf index 8b53d2d202b4df0f4f8e2952e8768967c15ba688..9e9304c8f827a3a96740c154769aa2182d8c29a5 100644 --- a/src/cases/derivatives/spins.conf +++ b/src/cases/derivatives/spins.conf @@ -42,3 +42,11 @@ do_Q = false do_R = false do_Q_and_R = false do_lambda2 = false +do_hist = false + +# QSP Parameters +T1 = t +S1 = k +QSP_filename = QSP +NT = 10 +NS = 10