From 07517df411e118da0cb7a244ffc8e59b0389afb5 Mon Sep 17 00:00:00 2001
From: Robert Izzard <r.izzard@surrey.ac.uk>
Date: Wed, 14 Jul 2021 18:56:43 +0100
Subject: [PATCH] add strip_trailing function to strip a given char from the
 end of a string

updated CHeB loading logic
---
 src/MINT/MINT_CHeB_data_columns.h        | 38 ++++++++++
 src/MINT/MINT_data_columns_CHeB_list.def | 92 ++++++++++++++++++++++++
 src/MINT/MINT_load_CHeB_grid.c           | 44 ++++++++++++
 src/MINT/MINT_load_grid.c                |  5 ++
 src/MINT/MINT_table_loader.c             | 40 +++++++----
 src/string/string_prototypes.h           |  2 +
 src/string/strip_trailing.c              | 24 +++++++
 tbse.mint                                |  2 +
 8 files changed, 232 insertions(+), 15 deletions(-)
 create mode 100644 src/MINT/MINT_CHeB_data_columns.h
 create mode 100644 src/MINT/MINT_data_columns_CHeB_list.def
 create mode 100644 src/MINT/MINT_load_CHeB_grid.c
 create mode 100644 src/string/strip_trailing.c

diff --git a/src/MINT/MINT_CHeB_data_columns.h b/src/MINT/MINT_CHeB_data_columns.h
new file mode 100644
index 000000000..1937b468a
--- /dev/null
+++ b/src/MINT/MINT_CHeB_data_columns.h
@@ -0,0 +1,38 @@
+#pragma once
+#ifndef MINT_CHeB_DATA_COLUMNS_H
+#define MINT_CHeB_DATA_COLUMNS_H
+
+/*
+ * Define the MINT data columns.
+ */
+
+#include "MINT_data_columns_CHeB_list.def"
+#undef X
+
+/* loading actions */
+#define X(NAME) MINT_CHeB_ACTION_##NAME,
+enum { MINT_ACTIONS_LIST };
+#undef X
+
+/* MS parameter items list */
+#define X(NAME,ACTION) MINT_CHeB_##NAME,
+enum { MINT_CHeB_PARAMETER_ITEMS_LIST };
+#undef X
+
+/* parameter items actions */
+#define X(NAME,ACTION) MINT_CHeB_ACTION_##ACTION,
+static int MINT_CHeB_parameter_actions[] MAYBE_UNUSED = { MINT_CHeB_PARAMETER_ITEMS_LIST };
+#undef X
+
+/* data items list */
+#define X(NAME,ACTION) MINT_CHeB_##NAME,
+enum { MINT_CHeB_DATA_ITEMS_LIST };
+#undef X
+
+/* data items actions */
+#define X(NAME,ACTION) MINT_CHeB_ACTION_##ACTION,
+static int MINT_CHeB_data_actions[] MAYBE_UNUSED = { MINT_CHeB_DATA_ITEMS_LIST };
+#undef X
+
+
+#endif // MINT_CHeB_DATA_COLUMMNS_H
diff --git a/src/MINT/MINT_data_columns_CHeB_list.def b/src/MINT/MINT_data_columns_CHeB_list.def
new file mode 100644
index 000000000..411116c29
--- /dev/null
+++ b/src/MINT/MINT_data_columns_CHeB_list.def
@@ -0,0 +1,92 @@
+#pragma once
+#ifndef MINT_DATA_COLUMNS_CHeB_LIST_DEF
+#define MINT_DATA_COLUMNS_CHeB_LIST_DEF
+
+/*
+ * Define the MINT core-helium burning table.
+ *
+ * These are the order in which columns are
+ * set in the MINT interpolation table.
+ *
+ * Each column name should be in CAPTIALS with
+ * underscores (_) as word separators,
+ * and wrapped in an X(...), e.g.,
+ *
+ * #define MINT_CHeB_PARAMETER_ITEMS    \
+ *         X(MASS),           \
+ *         X(CENTRAL_HELIUM)
+ *
+ * And note that in the code, these are prefixed
+ * automatically with MINT_CHeB_, e.g. to make
+ * MINT_CHeB_MASS, MINT_CHeB_CENTRAL_HELIUM, etc.
+ *
+ * Scalar items should be listed first,
+ * with items on Chebyshev lists coming last
+ * with CHEBYSHEV in their names.
+ *
+ * The column names listed here should each
+ * match a column of the input data file, as
+ * specified in the header of that file. If they
+ * do not, you probably will not be able to
+ * get things to run as you'd like... so you'll
+ * have to take some kind of executive action
+ * to fix this, or fill the data from some other
+ * source (e.g. BSE's fitting functions).
+ *
+ * The ..._PARAMETER_ITEMS must be scalars only.
+ *
+ * The lengths of the Chebyshev lists are automatically
+ * calculated based on the data file contents.
+ */
+
+
+/*
+ * The MINT_CHeB_PARAMETER_ITEMS are prefixed by MINT_CHeB_
+ *
+ * The table has two columns: first the identifier
+ * which is used in the code and in the data file.
+ * Second is the "action" which is one of the
+ * MINT_ACTIONS_LIST
+ */
+#define MINT_CHeB_PARAMETER_ITEMS_LIST            \
+    X(MASS, LOG10)                              \
+        X(CENTRAL_HELIUM, NOTHING)
+
+/*
+ * The MINT_CHeB_DATA_ITEMS are prefixed by MINT_CHeB_
+ *
+ * The table has two columns: first the identifier
+ * which is used in the code and in the data file.
+ * Second is the "action" which is one of the
+ * MINT_ACTIONS_LIST
+ */
+#define MINT_CHeB_DATA_ITEMS_LIST                         \
+    X(RADIUS, LOG10)                                    \
+        X(LUMINOSITY, LOG10)                            \
+        X(AGE, NOTHING)                                 \
+        X(CONVECTIVE_CORE_MASS, NOTHING)                \
+        X(CONVECTIVE_CORE_RADIUS, NOTHING)              \
+        X(CONVECTIVE_CORE_MASS_OVERSHOOT, NOTHING)      \
+        X(CONVECTIVE_CORE_RADIUS_OVERSHOOT, NOTHING)    \
+        X(CONVECTIVE_ENVELOPE_MASS, NOTHING)            \
+    X(CONVECTIVE_ENVELOPE_RADIUS, NOTHING)              \
+    X(CONVECTIVE_ENVELOPE_MASS_SIMPLIFIED, NOTHING)     \
+    X(CONVECTIVE_ENVELOPE_RADIUS_SIMPLIFIED, NOTHING)   \
+    X(K2, NOTHING)                                      \
+    X(TIDAL_E2, NOTHING)                                \
+    X(TIDAL_E_FOR_LAMBDA, NOTHING)                      \
+    X(TIMESCALE_KELVIN_HELMHOLTZ, NOTHING)              \
+    X(TIMESCALE_DYNAMICAL, NOTHING)                     \
+    X(TIMESCALE_NUCLEAR, NOTHING)                       \
+    X(MEAN_MOLECULAR_WEIGHT_CORE, NOTHING)              \
+    X(MEAN_MOLECULAR_WEIGHT_AVERAGE, NOTHING)           \
+    X(FIRST_DERIVATIVE_CENTRAL_HELIUM, LOG10NEGATIVE) \
+    X(SECOND_DERIVATIVE_CENTRAL_HELIUM, NOTHING)      \
+    X(CHEBYSHEV_TEMPERATURE, NOTHING)                   \
+    X(CHEBYSHEV_DENSITY, NOTHING)                       \
+    X(CHEBYSHEV_TOTAL_PRESSURE, NOTHING)                \
+    X(CHEBYSHEV_GAS_PRESSURE, NOTHING)                  \
+    X(CHEBYSHEV_RADIUS, NOTHING)                        \
+    X(CHEBYSHEV_GAMMA1, NOTHING)                        \
+    X(CHEBYSHEV_PRESSURE_SCALE_HEIGHT, NOTHING)
+#endif // MINT_DATA_COLUMNS_CHeB_LIST_DEF
diff --git a/src/MINT/MINT_load_CHeB_grid.c b/src/MINT/MINT_load_CHeB_grid.c
new file mode 100644
index 000000000..88dcf362a
--- /dev/null
+++ b/src/MINT/MINT_load_CHeB_grid.c
@@ -0,0 +1,44 @@
+#include "../binary_c.h"
+No_empty_translation_unit_warning;
+
+#ifdef MINT
+#include "MINT.h"
+#include "MINT_load_grid.h"
+
+/*
+ * Subroutine to load CHeB data
+ * for MINT.
+ *
+ * Return TRUE on success, FALSE on failure.
+ */
+
+Boolean MINT_load_CHeB_grid(struct stardata_t * const stardata)
+{
+    const Boolean vb = FALSE; /* set vb=TRUE for lots of verbose output */
+
+
+    /*
+     * Make lists of parameter and data item names
+     * we require in our table of scalars
+     */
+#undef X
+#define X(NAME,ACTION) Stringify_expanded(NAME),
+    static const char * parameter_names[] =
+        { MINT_CHeB_PARAMETER_ITEMS_LIST };
+    static const char * data_names[] =
+        { MINT_CHeB_DATA_ITEMS_LIST };
+#undef X
+
+    return MINT_Load_Table(
+        stardata,
+        MINT_TABLE_CHeB,
+        NULL,
+        "MINT_CHeB",
+        parameter_names,
+        data_names,
+        MINT_CHeB_parameter_actions,
+        MINT_CHeB_data_actions,
+        vb);
+}
+
+#endif // MINT
diff --git a/src/MINT/MINT_load_grid.c b/src/MINT/MINT_load_grid.c
index 3db1d5575..dc5bfd215 100644
--- a/src/MINT/MINT_load_grid.c
+++ b/src/MINT/MINT_load_grid.c
@@ -36,6 +36,11 @@ int MINT_load_grid(struct stardata_t * const stardata)
                       "MINT_dir is empty : probably you need to set the MINT_dir environment variable\n");
     }
 
+    /*
+     * Strip trailing slashes from the MINT directory name
+     */
+    strip_trailing(stardata->preferences->MINT_dir,'/');
+
     /*
      * Load data tables from the functions
      * set in MINT_data_tables.def
diff --git a/src/MINT/MINT_table_loader.c b/src/MINT/MINT_table_loader.c
index 1eeea76c4..2c4e1f746 100644
--- a/src/MINT/MINT_table_loader.c
+++ b/src/MINT/MINT_table_loader.c
@@ -17,7 +17,8 @@ static char * automatically_generate_filename(
     struct stardata_t * const stardata,
     const char * header_string,
     const unsigned int MINT_table_id,
-    Boolean * const allocated);
+    Boolean * const allocated,
+    Boolean * const using_test_data);
 
 Boolean MINT_table_loader(struct stardata_t * const stardata,
                           const unsigned int MINT_table_id,
@@ -34,6 +35,7 @@ Boolean MINT_table_loader(struct stardata_t * const stardata,
     Boolean warned_ncols_in_file1 = FALSE;
     Boolean warned_ncols_in_file2 = FALSE;
     Boolean filename_allocated = FALSE;
+    Boolean using_test_data = FALSE;
 
     if(vb)printf("MINT load table %s from %s, function %p, MINT_dir %s\n",
                  header_string,
@@ -55,7 +57,8 @@ Boolean MINT_table_loader(struct stardata_t * const stardata,
                 automatically_generate_filename(stardata,
                                                 header_string,
                                                 MINT_table_id,
-                                                &filename_allocated);
+                                                &filename_allocated,
+                                                &using_test_data);
         }
 
         /*
@@ -98,6 +101,18 @@ Boolean MINT_table_loader(struct stardata_t * const stardata,
             }
             else
             {
+                /*
+                 * Warn if we're using test_data directory
+                 */
+                if(using_test_data == TRUE
+                   &&
+                   stardata->preferences->MINT_disable_grid_load_warnings == FALSE)
+                {
+                    fprintf(stderr,
+                            "Warning: using a test_data file at \"%s\"\n",
+                            filename);
+                }
+
                 /*
                  * Get the number of lines of data : we need
                  * this to allocate memory for the data table.
@@ -717,7 +732,8 @@ static char * automatically_generate_filename(
     struct stardata_t * const stardata,
     const char * header_string,
     const unsigned int MINT_table_id,
-    Boolean * const allocated)
+    Boolean * const allocated,
+    Boolean * const using_test_data)
 {
     char * filename = NULL;
 
@@ -783,7 +799,7 @@ static char * automatically_generate_filename(
      */
     const size_t len = strlen(stardata->preferences->MINT_dir);
     const size_t offset = 4;
-    const char * const stub = (char*)(stardata->preferences->MINT_dir + len - offset -1);
+    const char * const stub = (char*)(stardata->preferences->MINT_dir + len - offset - 1);
     char * test = check_file_exists(filename);
 
     if(test == NULL
@@ -795,7 +811,9 @@ static char * automatically_generate_filename(
        Strings_equal(stub,"/data"))
     {
         const char was = stub[0];
-        stardata->preferences->MINT_dir[len - offset] = '\0';
+        char * replace_location =
+            stardata->preferences->MINT_dir + len - offset - (was == '/' ? 1 : 0);
+        *replace_location = '\0';
         char * fallback_dir = NULL;
         if(asprintf(&fallback_dir,
                     "%s/%s",
@@ -825,9 +843,7 @@ static char * automatically_generate_filename(
         /*
          * Restore the directory
          */
-        stardata->preferences->MINT_dir[len - offset] = was;
-
-
+        *replace_location = was;
 
         /*
          * Check if the file is there but with a zipped extension,
@@ -841,16 +857,10 @@ static char * automatically_generate_filename(
             filename = filename_alt;
         }
 
-        if(stardata->preferences->MINT_disable_grid_load_warnings == FALSE)
-        {
-            fprintf(stderr,
-                    "Warning: using a test_data file at \"%s\"\n",
-                    filename);
-        }
+        *using_test_data = TRUE;
     }
 
     Safe_free(test);
-
     return filename;
 }
 
diff --git a/src/string/string_prototypes.h b/src/string/string_prototypes.h
index a4a65e48d..8e96cb89f 100644
--- a/src/string/string_prototypes.h
+++ b/src/string/string_prototypes.h
@@ -64,5 +64,7 @@ char * fast_double_parser(const char *p,
                           double * const outDouble);
 double fast_strtod(const char * nptr,
                    char ** endptr);
+void strip_trailing(char * const string,
+                    const char c);
 
 #endif // STRING_PROTOTYPES_H
diff --git a/src/string/strip_trailing.c b/src/string/strip_trailing.c
new file mode 100644
index 000000000..b893952c4
--- /dev/null
+++ b/src/string/strip_trailing.c
@@ -0,0 +1,24 @@
+#include "../binary_c.h"
+No_empty_translation_unit_warning;
+
+
+/*
+ * Function to strip a trailing character (c) from a *string.
+ *
+ * Does not change the amount of memory located at *string
+ *
+ * c should not be \0 (NULL char)
+ */
+void strip_trailing(char * const string,
+                    const char c)
+{
+    if(string != NULL)
+    {
+        size_t len;
+        while ((len = strlen(string)) &&
+               string[strlen(string)-1] == c)
+        {
+            string[strlen(string)-1] = '\0';
+        }
+    }
+}
diff --git a/tbse.mint b/tbse.mint
index 09d8c16eb..1ecbd41b3 100755
--- a/tbse.mint
+++ b/tbse.mint
@@ -30,6 +30,7 @@ MINT_DISABLE_GRID_LOAD_WARNINGS=False
 MINT_DATA_CLEANUP=True
 MINT_USE_ZAMS_PROFILES=True
 MINT_FALLBACK_TO_TEST_DATA=True
+MINT_DIR=$HOME/data/MINT/data
 
 # RUN tbse
 tbse \
@@ -38,6 +39,7 @@ tbse \
     --maximum_timestep $MAXIMUM_TIMESTEP \
     --stellar_structure_algorithm STELLAR_STRUCTURE_ALGORITHM_MINT \
     --metallicity $METALLICITY \
+    --MINT_dir $MINT_DIR/ \
     --MINT_metallicity $MINT_METALLICITY \
     --MINT_Kippenhahn $MINT_KIPPENHAHN \
     --MINT_Kippenhahn_stellar_type $MINT_KIPPENHAHN_STELLAR_TYPE \
-- 
GitLab