From 9a29607b3edd00d9cfb45e2e13f5974e212b1e59 Mon Sep 17 00:00:00 2001
From: Robert Izzard <r.izzard@surrey.ac.uk>
Date: Fri, 30 Jul 2021 00:12:41 +0100
Subject: [PATCH] improved how memory is allocated and freed in MINT

fixed issue where max_stellar_type are not checked before an event
---
 src/MINT/MINT_alloc.c                         |   1 -
 src/MINT/MINT_call_BSE_stellar_structure.c    |  19 ++-
 src/MINT/MINT_copy_star.c                     | 117 ++++++++++++++++++
 src/MINT/MINT_free.c                          |   4 +
 src/MINT/MINT_free_star.c                     |  18 +++
 src/MINT/MINT_function_macros.h               |   6 +
 src/MINT/MINT_generic_data_types.def          |   4 +-
 src/MINT/MINT_init.c                          |   1 -
 src/MINT/MINT_init_stars.c                    |   2 +-
 src/MINT/MINT_load_CHeB_grid.c                |   2 +-
 src/MINT/MINT_make_CHeB_TA_table.c            |   2 +-
 src/MINT/MINT_make_CHeB_ZA_table.c            |   2 +-
 src/MINT/MINT_make_generic_map.c              |  58 ++++++++-
 src/MINT/MINT_prototypes.h                    |   6 +
 src/MINT/MINT_stellar_structure.c             |  24 ++--
 src/MINT/MINT_table_loader.c                  |   2 +-
 src/binary_c_debug.h                          |   2 +-
 src/evolution/check_for_evolution_stop.c      |  15 +--
 src/evolution/evolve_system_binary_c.c        | 115 +++++++++--------
 src/evolution/start_of_evolution.c            |   2 -
 src/evolution/update_system_by_dt.c           |   2 +-
 src/interface/interface_stellar_structure.c   |   5 +-
 src/memory/clean_star.c                       |   3 +
 src/memory/free_star_contents.c               |   6 +-
 src/memory/free_stardata_stack.c              |   3 +-
 src/setup/derived_arguments.c                 |  11 --
 src/stellar_structure/stellar_structure_BSE.c |  17 ++-
 src/stellar_structure/stellar_structure_HG.c  |   9 +-
 .../stellar_timescales_high_mass_GB.c         |   4 +-
 .../stellar_timescales_low_mass_GB.c          |   2 +-
 src/timestep/timestep_CHeB.c                  |   2 +-
 31 files changed, 338 insertions(+), 128 deletions(-)
 create mode 100644 src/MINT/MINT_copy_star.c
 create mode 100644 src/MINT/MINT_free_star.c

diff --git a/src/MINT/MINT_alloc.c b/src/MINT/MINT_alloc.c
index de4872e4b..b66fdaaf7 100644
--- a/src/MINT/MINT_alloc.c
+++ b/src/MINT/MINT_alloc.c
@@ -2,7 +2,6 @@
 No_empty_translation_unit_warning;
 
 #ifdef MINT
-
 void MINT_alloc(struct stardata_t * const stardata)
 {
     /*
diff --git a/src/MINT/MINT_call_BSE_stellar_structure.c b/src/MINT/MINT_call_BSE_stellar_structure.c
index e18d7969c..becfe72ac 100644
--- a/src/MINT/MINT_call_BSE_stellar_structure.c
+++ b/src/MINT/MINT_call_BSE_stellar_structure.c
@@ -32,13 +32,26 @@ int MINT_call_BSE_stellar_structure(struct stardata_t * const stardata,
             newstar->derivative[DERIVATIVE_STELLAR_CENTRAL_CARBON] = 0.0;
         }
 
+        printf("MINT call BSE stellar structure %p \n",
+               (void*)newstar->luminosities);
+
+        stellar_timescales(newstar->stellar_type,
+                           newstar->phase_start_mass,
+                           newstar->mass,
+                           &newstar->tm,
+                           &newstar->tn,
+                           newstar->timescales,
+                           newstar->luminosities,
+                           newstar->GB,
+                           stardata,
+                           newstar);
         ret = stellar_structure_BSE_with_newstar(stardata,
                                                  STELLAR_STRUCTURE_CALLER_MINT,
                                                  oldstar,
                                                  newstar,
-                                                 NULL,
-                                                 NULL,
-                                                 NULL);
+                                                 newstar->timescales,
+                                                 newstar->luminosities,
+                                                 newstar->GB);
     }
     return ret;
 }
diff --git a/src/MINT/MINT_copy_star.c b/src/MINT/MINT_copy_star.c
new file mode 100644
index 000000000..8e6a34b6a
--- /dev/null
+++ b/src/MINT/MINT_copy_star.c
@@ -0,0 +1,117 @@
+#include "../binary_c.h"
+No_empty_translation_unit_warning;
+
+#ifdef MINT
+
+/*
+ * Copy the MINT data in star in src to dest, which
+ * should already be allocated memory.
+ *
+ * To be called from copy_star()
+ */
+void MINT_copy_star(const struct star_t * const RESTRICT src,
+                    struct star_t * const RESTRICT dest,
+                    struct mint_shell_t * const mint_shells_p,
+                    const Shell_index mint_nshells)
+{
+    /*
+     * Copy MINT structures
+     */
+    if(src->mint != dest->mint &&
+       src->mint != NULL)
+    {
+        if(dest->mint == NULL)
+        {
+            dest->mint = Malloc(sizeof(struct mint_t));
+            Cprint("dest->mint is NULL, alloced to %p\n",
+                   (void*)dest->mint);
+        }
+
+        Cprint("memcpy mint %p %p\n",
+               (void*)dest->mint,
+               (void*)src->mint);
+
+        /*
+         * Copy main MINT pointer
+         */
+        memcpy(dest->mint,
+               src->mint,
+               sizeof(struct mint_t));
+
+        /*
+         * Restore shells
+         */
+        Cprint("restore mint->shells from %p to %p\n",
+               (void*)dest->mint->shells,
+               (void*)mint_shells_p);
+        dest->mint->shells = mint_shells_p;
+
+        if(src->mint->shells == NULL)
+        {
+            /*
+             * No shells to copy
+             */
+            Safe_free(dest->mint->shells);
+        }
+        else
+        {
+            /*
+             * Copy shells
+             */
+            const size_t shellssize = sizeof(struct mint_shell_t)*
+                src->mint->nshells;
+
+            if(dest->mint->shells == NULL &&
+               dest->mint->nshells > 0)
+            {
+                /*
+                 * Require new memory for shells
+                 */
+                dest->mint->shells = Malloc(shellssize);
+                Cprint("MINT shells Malloc at %p\n",
+                       (void*)dest->mint->shells);
+            }
+            else if(dest->mint->shells != NULL &&
+                    mint_nshells != dest->mint->nshells)
+            {
+                /*
+                 * Shell number has changed, realloc
+                 * or free (if new shell number is zero).
+                 */
+                if(shellssize == 0)
+                {
+                    Safe_free(dest->mint->shells);
+                    Cprint("MINT shells set to %p\n",
+                           (void*)dest->mint->shells);
+                }
+                else
+                {
+                    Cprint("realloc MINT shells to size %zu, was %p\n",
+                           shellssize,
+                           (void*)dest->mint->shells);
+                    dest->mint->shells = Realloc(dest->mint->shells,
+                                                 shellssize);
+                }
+            }
+
+            Cprint("copy MINT shells %p to %p size %zu\n",
+                   (void*)src->mint->shells,
+                   (void*)dest->mint->shells,
+                   shellssize);
+
+            /*
+             * Copy shells' contents if required
+             */
+            if(shellssize > 0 &&
+               src->mint->shells != NULL &&
+               dest->mint->shells != NULL)
+            {
+                memcpy(dest->mint->shells,
+                       src->mint->shells,
+                       shellssize);
+            }
+        }
+    }
+}
+
+#endif//MINT
diff --git a/src/MINT/MINT_free.c b/src/MINT/MINT_free.c
index d0d9f805b..e9e8f7c32 100644
--- a/src/MINT/MINT_free.c
+++ b/src/MINT/MINT_free.c
@@ -10,6 +10,10 @@ void MINT_free(struct stardata_t * const RESTRICT stardata MAYBE_UNUSED)
      * binary_c stardata but that's not the store
      * (see MINT_free_store for that).
      */
+    Foreach_star(star)
+    {
+        MINT_free_star(star);
+    }
 }
 
 #endif//MINT
diff --git a/src/MINT/MINT_free_star.c b/src/MINT/MINT_free_star.c
new file mode 100644
index 000000000..e8635490b
--- /dev/null
+++ b/src/MINT/MINT_free_star.c
@@ -0,0 +1,18 @@
+#include "../binary_c.h"
+No_empty_translation_unit_warning;
+
+#ifdef MINT
+
+void MINT_free_star(struct star_t * const RESTRICT star)
+{
+    /*
+     * Free memory allocated for MINT in each star struct
+     */
+    if(star->mint != NULL)
+    {
+        Safe_free(star->mint->shells);
+        Safe_free(star->mint);
+    }
+}
+
+#endif//MINT
diff --git a/src/MINT/MINT_function_macros.h b/src/MINT/MINT_function_macros.h
index 560c158ac..b4a716fba 100644
--- a/src/MINT/MINT_function_macros.h
+++ b/src/MINT/MINT_function_macros.h
@@ -244,4 +244,10 @@
         (STAR)->mint->nshells > 0               \
     )
 
+#define MINT_has_table(TABLE) (                     \
+        stardata != NULL &&                         \
+        stardata->store != NULL &&                  \
+        stardata->store->MINT_tables[TABLE] != NULL \
+        )
+
 #endif // MINT_FUNCTION_MACROS_H
diff --git a/src/MINT/MINT_generic_data_types.def b/src/MINT/MINT_generic_data_types.def
index bed00ac55..ac1cd6ace 100644
--- a/src/MINT/MINT_generic_data_types.def
+++ b/src/MINT/MINT_generic_data_types.def
@@ -20,7 +20,7 @@
         X(CONVECTIVE_CORE_RADIUS)               \
         X(CONVECTIVE_CORE_MASS_OVERSHOOT)       \
         X(CONVECTIVE_CORE_RADIUS_OVERSHOOT)     \
-        X(CONVECTIVE_ENVELOPE_MASS)             \
+    X(CONVECTIVE_ENVELOPE_MASS)                 \
     X(CONVECTIVE_ENVELOPE_RADIUS)               \
     X(CONVECTIVE_ENVELOPE_MASS_SIMPLIFIED)      \
     X(CONVECTIVE_ENVELOPE_RADIUS_SIMPLIFIED)    \
@@ -35,6 +35,8 @@
     X(TESTPANTS)                                \
     X(FIRST_DERIVATIVE_CENTRAL_HYDROGEN)        \
     X(SECOND_DERIVATIVE_CENTRAL_HYDROGEN)       \
+    X(FIRST_DERIVATIVE_CENTRAL_HELIUM)          \
+    X(SECOND_DERIVATIVE_CENTRAL_HELIUM)         \
     X(CHEBYSHEV_TEMPERATURE)                    \
     X(CHEBYSHEV_DENSITY)                        \
     X(CHEBYSHEV_TOTAL_PRESSURE)                 \
diff --git a/src/MINT/MINT_init.c b/src/MINT/MINT_init.c
index 849c5f804..98ca8be6a 100644
--- a/src/MINT/MINT_init.c
+++ b/src/MINT/MINT_init.c
@@ -27,7 +27,6 @@ void MINT_init(struct stardata_t * const stardata)
          */
         MINT_alloc(stardata);
 
-
         /*
          * Initialize the MINT data if required
          */
diff --git a/src/MINT/MINT_init_stars.c b/src/MINT/MINT_init_stars.c
index 74a788aab..886768352 100644
--- a/src/MINT/MINT_init_stars.c
+++ b/src/MINT/MINT_init_stars.c
@@ -48,7 +48,7 @@ void MINT_init_stars(struct stardata_t * const stardata)
 
 #ifdef NUCSYN
     if(stardata->preferences->MINT_use_ZAMS_profiles == TRUE &&
-       stardata->store->MINT_tables[MINT_TABLE_ZAMS_COMPOSITION] != NULL)
+       MINT_has_table(MINT_TABLE_ZAMS_COMPOSITION))
     {
         double * result_cheb = Malloc(MINT_result_size(MINT_TABLE_ZAMS_COMPOSITION));
         unsigned int n;
diff --git a/src/MINT/MINT_load_CHeB_grid.c b/src/MINT/MINT_load_CHeB_grid.c
index 11d604764..7732f48b2 100644
--- a/src/MINT/MINT_load_CHeB_grid.c
+++ b/src/MINT/MINT_load_CHeB_grid.c
@@ -39,7 +39,7 @@ Boolean MINT_load_CHeB_grid(struct stardata_t * const stardata)
         MINT_CHeB_data_actions,
         vb);
 
-    if(stardata->store->MINT_tables[MINT_TABLE_CHeB] != NULL)
+    if(MINT_has_table(MINT_TABLE_CHeB))
     {
         /*
          * Check derivative
diff --git a/src/MINT/MINT_make_CHeB_TA_table.c b/src/MINT/MINT_make_CHeB_TA_table.c
index b0314fd58..d71d424fb 100644
--- a/src/MINT/MINT_make_CHeB_TA_table.c
+++ b/src/MINT/MINT_make_CHeB_TA_table.c
@@ -15,7 +15,7 @@ Boolean MINT_make_CHeB_TA_table(struct stardata_t * const stardata)
      */
     const Boolean vb = FALSE;
 
-    if(stardata->store->MINT_tables[MINT_TABLE_CHeB] != NULL)
+    if(MINT_has_table(MINT_TABLE_CHeB))
     {
         double logM;
         const int N = 1000;
diff --git a/src/MINT/MINT_make_CHeB_ZA_table.c b/src/MINT/MINT_make_CHeB_ZA_table.c
index 83ca113bc..182aaac12 100644
--- a/src/MINT/MINT_make_CHeB_ZA_table.c
+++ b/src/MINT/MINT_make_CHeB_ZA_table.c
@@ -14,7 +14,7 @@ Boolean MINT_make_CHeB_ZA_table(struct stardata_t * const stardata)
      * Return TRUE on success, FALSE on failure.
      */
     const Boolean vb = FALSE;
-    if(stardata->store->MINT_tables[MINT_TABLE_CHeB] != NULL)
+    if(MINT_has_table(MINT_TABLE_CHeB))
     {
         double logM;
         const int N = 1000;
diff --git a/src/MINT/MINT_make_generic_map.c b/src/MINT/MINT_make_generic_map.c
index b056a893b..572ac2875 100644
--- a/src/MINT/MINT_make_generic_map.c
+++ b/src/MINT/MINT_make_generic_map.c
@@ -7,14 +7,19 @@ No_empty_translation_unit_warning;
 #include "MINT_data_columns.h"
 void MINT_make_generic_map(struct stardata_t * const stardata)
 {
+
     /*
      * We want to map each MINT variable type in the generic list to
      * the variable type in the stellar type's list.
+     *
+     * When first called, the store should all be memset(0)
+     * so all the mint_generic_map pointers are NULL.
      */
-    for(Stellar_type s=0; s<NUMBER_OF_STELLAR_TYPES; s++)
-    {
-        stardata->store->mint_generic_map[s] = NULL;
-    }
+
+    /*
+     * If the map is already set, just return.
+     */
+    if(stardata->store->mint_generic_map[0]) return;
 
     /*
      * Make list of generic items as strings
@@ -68,5 +73,50 @@ void MINT_make_generic_map(struct stardata_t * const stardata)
         }
 #undef X
     }
+
+
+    /*
+     * Core-helium burning
+     */
+    {
+        const Stellar_type s = CHeB;
+        {
+            stardata->store->mint_generic_map[s] =
+                Malloc(n_generic_strings * sizeof(int));
+
+            /*
+             * Set the map to -1 (no map) by default
+             */
+            for(size_t i=0; i<n_generic_strings; i++)
+            {
+                stardata->store->mint_generic_map[s][i] = -1;
+            }
+
+            /*
+             * Check each generic type with each CHeB type:
+             * if they match, the type is in both lists, so
+             * set the map
+             */
+#define X(NAME,ACTION)                                                  \
+            for(size_t i=0; i<n_generic_strings; i++)                   \
+            {                                                           \
+                if(Strings_equal(#NAME,                                 \
+                                 generic_strings[i]))                   \
+                {                                                       \
+                    stardata->store->mint_generic_map[s][MINT_##NAME] = \
+                        MINT_CHeB_##NAME;                               \
+                    Dprint(                                             \
+                        "map generic stellar_type %d : %s = %d to MINT_MS = %d\n", \
+                        s,                                              \
+                        #NAME,                                          \
+                        MINT_##NAME,                                    \
+                        MINT_CHeB_##NAME);                              \
+                }                                                       \
+            }
+
+            MINT_CHeB_DATA_ITEMS_LIST;
+        }
+#undef X
+    }
 }
 #endif//MINT
diff --git a/src/MINT/MINT_prototypes.h b/src/MINT/MINT_prototypes.h
index 46782d4b3..275d629f5 100644
--- a/src/MINT/MINT_prototypes.h
+++ b/src/MINT/MINT_prototypes.h
@@ -21,7 +21,13 @@ void MINT_clear(struct stardata_t * const stardata);
 int MINT_load_grid(struct stardata_t * const stardata);
 void MINT_init_store(struct store_t * store);
 void MINT_free(struct stardata_t * const RESTRICT stardata);
+void MINT_free_star(struct star_t * const RESTRICT star);
 void MINT_free_store(struct store_t * const store);
+void MINT_copy_star(const struct star_t * const RESTRICT src,
+                    struct star_t * const RESTRICT dest,
+                    struct mint_shell_t * const mint_shells_p,
+                    const Shell_index mint_nshells);
+
 void MINT_load_data(struct stardata_t * const stardata);
 void MINT_label_shell_masses(struct stardata_t * const stardata MAYBE_UNUSED,
                              struct star_t * const star);
diff --git a/src/MINT/MINT_stellar_structure.c b/src/MINT/MINT_stellar_structure.c
index b88e5824e..e237ef41f 100644
--- a/src/MINT/MINT_stellar_structure.c
+++ b/src/MINT/MINT_stellar_structure.c
@@ -66,15 +66,11 @@ int MINT_stellar_structure(struct stardata_t * const stardata,
                 newstar->age = newstar->tms;
                 newstar->TAMS_luminosity = newstar->luminosity;
                 newstar->TAMS_radius = newstar->radius;
+
 #ifdef NUCSYN
-                if(MINT_has_shells(newstar))
-                {
-                    newstar->TAMS_core_mass = MINT_core(newstar,XHe4,0.9);
-                }
-                else
-                {
-                    newstar->TAMS_core_mass = 0.0;
-                }
+                newstar->TAMS_core_mass =
+                    MINT_has_shells(newstar) ?
+                    MINT_core(newstar,XHe4,0.9) : 0.0;
 #else
                 newstar->TAMS_core_mass = 0.0;
 #endif// NUCSYN
@@ -93,15 +89,8 @@ int MINT_stellar_structure(struct stardata_t * const stardata,
                 /*
                  * Finished CHeB
                  */
-                static int count = 0;
                 newstar->stellar_type = EAGB;
                 newstar->mint->XHec = 0.0;
-                if(vb)printf("MINT to EAGB %d\n",count++);
-                if(count>0)
-                {
-                    Backtrace;
-                    //Flexit;
-                }
             }
         }
     }
@@ -154,6 +143,11 @@ int MINT_stellar_structure(struct stardata_t * const stardata,
                                                caller_id);
     }
 
+    if(newstar->stellar_type > stardata->preferences->max_stellar_type[newstar->starnum])
+    {
+        return ret;
+    }
+
     /*
      * Call BSE after MINT?
      */
diff --git a/src/MINT/MINT_table_loader.c b/src/MINT/MINT_table_loader.c
index 2c4e1f746..5c7ae2ad2 100644
--- a/src/MINT/MINT_table_loader.c
+++ b/src/MINT/MINT_table_loader.c
@@ -44,7 +44,7 @@ Boolean MINT_table_loader(struct stardata_t * const stardata,
                  stardata->preferences->MINT_dir);
 
 
-    if(stardata->store->MINT_tables[MINT_table_id] == NULL)
+    if(MINT_has_table(MINT_table_id) == FALSE)
     {
         /*
          * If filename is NULL, generate the filename
diff --git a/src/binary_c_debug.h b/src/binary_c_debug.h
index 15ac142d7..092f34a16 100644
--- a/src/binary_c_debug.h
+++ b/src/binary_c_debug.h
@@ -106,7 +106,7 @@
  * this is not shown.
  */
 
-#define Debug_show_expression " %d %d ",stardata->model.model_number,stardata->star[0].mint ? stardata->star[0].mint->nshells : -1
+#define Debug_show_expression " %d %d ",stardata->star[0].stellar_type,stardata->star[1].stellar_type
 //#undef Debug_show_expression
 
 /*
diff --git a/src/evolution/check_for_evolution_stop.c b/src/evolution/check_for_evolution_stop.c
index f47404955..827230649 100644
--- a/src/evolution/check_for_evolution_stop.c
+++ b/src/evolution/check_for_evolution_stop.c
@@ -8,18 +8,19 @@ No_empty_translation_unit_warning;
 
 Boolean Pure_function check_for_evolution_stop(struct stardata_t * const stardata)
 {
-    Star_number i;
-    Starloop(i)
+    Foreach_star(star)
     {
         /*
          * Check stellar type does not exceed the max stellar type
          * but skip if MASSLESS_REMNANT and the max_stellar_type is negative
          */
-        if(
-            (stardata->star[i].stellar_type != MASSLESS_REMNANT ||
-             stardata->preferences->max_stellar_type[i] > 0)
-            &&
-            stardata->star[i].stellar_type > abs(stardata->preferences->max_stellar_type[i]))
+        const Stellar_type max =
+            stardata->preferences->max_stellar_type[star->starnum];
+
+        if((star->stellar_type != MASSLESS_REMNANT ||
+            max > 0)
+           &&
+           star->stellar_type > abs(max))
         {
             return TRUE;
         }
diff --git a/src/evolution/evolve_system_binary_c.c b/src/evolution/evolve_system_binary_c.c
index 7c3382f81..1fe8da26e 100644
--- a/src/evolution/evolve_system_binary_c.c
+++ b/src/evolution/evolve_system_binary_c.c
@@ -256,70 +256,85 @@ int evolve_system_binary_c(struct stardata_t * RESTRICT const stardata)
         else
         {
             /*
-             * catch events, e.g. supernovae, unstable RLOF,
-             * common-envelope evolution
+             * Check if evolution needs to stop: if so, don't
+             * catch events and stop evolving, but do log so
+             * we know what happened.
              */
-            if(events_pending(stardata))
+            const Boolean evstop = check_for_evolution_stop(stardata);
+            if(evstop == TRUE)
             {
-                eprint("\n\n\n\n>>>>>  EVENTS t=%30.20e <<<<<\n\n\n\n",
-                       stardata->model.time);
-                catch_events(stardata);
-            }
-
-            /*
-             * Check for floating-point exceptions
-             */
-            if(stardata->preferences->float_overflow_checks > 0)
-            {
-                floating_point_exception_checks(stardata);
-            }
-
-            /*
-             * Check for evolution split before
-             * we save_to_previous. If evolution_split
-             * does not return EVOLUTION_SPLIT_CONTINUE, it
-             * either splits the evolution here or restores
-             * the previously saved.
-             */
-#ifdef EVOLUTION_SPLITTING
-            if(unlikely(evolution_split(stardata,&evstatus) !=
-                        EVOLUTION_SPLIT_CONTINUE))
-            {
-                /*
-                 * Keep evolving, but do nothing else: evolution_split
-                 * does the administration of the splitting algorithm
-                 */
-                evolving = TRUE;
+                evolving = FALSE;
+                erase_events(stardata);
+                Evolution_logging;
             }
             else
-#endif // EVOLUTION_SPLITTING
             {
                 /*
-                 * Do logging
+                 * catch events, e.g. supernovae, unstable RLOF,
+                 * common-envelope evolution
                  */
-                Evolution_logging;
-
-                /*
-                 * Update timestep triggers
-                 */
-                timestep_increment_fixed_timesteps(stardata);
+                if(events_pending(stardata))
+                {
+                    eprint("\n\n\n\n>>>>>  EVENTS t=%30.20e <<<<<\n\n\n\n",
+                           stardata->model.time);
+                    catch_events(stardata);
+                }
 
                 /*
-                 * Calculate the next timestep
+                 * Check for floating-point exceptions
                  */
-                set_next_timestep(stardata);
+                if(stardata->preferences->float_overflow_checks > 0)
+                {
+                    floating_point_exception_checks(stardata);
+                }
 
                 /*
-                 * Save the stardata to previous_stardata, unless evolving is FALSE,
-                 * in which case we want to keep the previous in place
-                 * just in case there is a stardata dump to follow
+                 * Check for evolution split before
+                 * we save_to_previous. If evolution_split
+                 * does not return EVOLUTION_SPLIT_CONTINUE, it
+                 * either splits the evolution here or restores
+                 * the previously saved.
                  */
-                if(evolving)
+#ifdef EVOLUTION_SPLITTING
+                if(unlikely(evolution_split(stardata,&evstatus) !=
+                            EVOLUTION_SPLIT_CONTINUE))
                 {
-                    eprint("LOOP this %d prev %d\n",
-                           stardata->model.model_number,
-                           stardata->previous_stardata->model.model_number);
-                    evolution_save_to_previous(stardata);
+                    /*
+                     * Keep evolving, but do nothing else: evolution_split
+                     * does the administration of the splitting algorithm
+                     */
+                    evolving = TRUE;
+                }
+                else
+#endif // EVOLUTION_SPLITTING
+                {
+                    /*
+                     * Do logging
+                     */
+                    Evolution_logging;
+
+                    /*
+                     * Update timestep triggers
+                     */
+                    timestep_increment_fixed_timesteps(stardata);
+
+                    /*
+                     * Calculate the next timestep
+                     */
+                    set_next_timestep(stardata);
+
+                    /*
+                     * Save the stardata to previous_stardata, unless evolving is FALSE,
+                     * in which case we want to keep the previous in place
+                     * just in case there is a stardata dump to follow
+                     */
+                    if(evolving)
+                    {
+                        eprint("LOOP this %d prev %d\n",
+                               stardata->model.model_number,
+                               stardata->previous_stardata->model.model_number);
+                        evolution_save_to_previous(stardata);
+                    }
                 }
             }
         }
diff --git a/src/evolution/start_of_evolution.c b/src/evolution/start_of_evolution.c
index a9d37b7cf..487fe311d 100644
--- a/src/evolution/start_of_evolution.c
+++ b/src/evolution/start_of_evolution.c
@@ -17,12 +17,10 @@ void start_of_evolution(struct stardata_t *stardata)
 
     Dprint("First run\n");
 
-
     /*************************************/
     /** set up variables and parameters **/
     /*************************************/
 
-
     /*
      * Initialize the stellar structure algorithm(s)
      * data. Note that MINT must be initialized first.
diff --git a/src/evolution/update_system_by_dt.c b/src/evolution/update_system_by_dt.c
index ae49d54c0..c76be0a5c 100644
--- a/src/evolution/update_system_by_dt.c
+++ b/src/evolution/update_system_by_dt.c
@@ -386,7 +386,7 @@ int update_system_by_dt(struct stardata_t * RESTRICT const stardata,
             update_phase_variables(stardata);
 
             const Boolean exhausted = check_for_time_exhaustion(stardata,
-                                                          stardata->model.intpol);
+                                                                stardata->model.intpol);
             const Boolean explicit_stop = check_for_evolution_stop(stardata);
 
             retval = (exhausted == TRUE || explicit_stop == TRUE)
diff --git a/src/interface/interface_stellar_structure.c b/src/interface/interface_stellar_structure.c
index a08969e35..bb36401b7 100644
--- a/src/interface/interface_stellar_structure.c
+++ b/src/interface/interface_stellar_structure.c
@@ -99,6 +99,7 @@ int vinterface_stellar_structure(struct stardata_t * const stardata,
                                     newstar->timescales,
                                     newstar->luminosities,
                                     newstar->GB);
+
         Dprint("Allow SN %d  : SN type %d, NONE %d != none? %d \n",
                allow_SN,
                newstar->SN_type,
@@ -155,9 +156,7 @@ int vinterface_stellar_structure(struct stardata_t * const stardata,
         }
         Exit_binary_c(BINARY_C_ALGORITHM_OUT_OF_RANGE,
                       "Unknown stellar structure algorithm %d\n",
-                      stardata->preferences->stellar_structure_algorithm//,
-                      //stellar_structure_algorithm_strings[
-                          );
+                      stardata->preferences->stellar_structure_algorithm);
     }
 
     /*
diff --git a/src/memory/clean_star.c b/src/memory/clean_star.c
index d56091198..d7d54c815 100644
--- a/src/memory/clean_star.c
+++ b/src/memory/clean_star.c
@@ -12,5 +12,8 @@ void clean_star(struct star_t * RESTRICT const star)
     Safe_free(star->luminosities);
     Safe_free(star->GB);
 #endif //BSE
+#ifdef MINT
+    MINT_free_star(star);
+#endif//MINT
     memset(star,0,sizeof(struct star_t));
 }
diff --git a/src/memory/free_star_contents.c b/src/memory/free_star_contents.c
index 3c52f10c0..52f9ea93f 100644
--- a/src/memory/free_star_contents.c
+++ b/src/memory/free_star_contents.c
@@ -11,11 +11,7 @@ void free_star_contents(struct star_t * const RESTRICT star)
     if(star != NULL)
     {
 #ifdef MINT
-        if(star->mint != NULL)
-        {
-            Safe_free(star->mint->shells);
-            Safe_free(star->mint);
-        }
+        MINT_free_star(star);
 #endif//MINT
     }
 }
diff --git a/src/memory/free_stardata_stack.c b/src/memory/free_stardata_stack.c
index f7a287c78..99be4c202 100644
--- a/src/memory/free_stardata_stack.c
+++ b/src/memory/free_stardata_stack.c
@@ -5,8 +5,7 @@ void free_stardata_stack(struct stardata_t * RESTRICT const stardata)
     /*
      * Free the stardata stack
      */
-    unsigned int i;
-    for(i=0;i<stardata->n_stardata_stack;i++)
+    for(unsigned int i=0;i<stardata->n_stardata_stack;i++)
     {
         free_stardata(&stardata->stardata_stack[i]);
     }
diff --git a/src/setup/derived_arguments.c b/src/setup/derived_arguments.c
index a11045355..d22410f07 100644
--- a/src/setup/derived_arguments.c
+++ b/src/setup/derived_arguments.c
@@ -220,17 +220,6 @@ void derived_arguments(struct stardata_t * stardata)
             Max(p->MINT_minimum_nshells,
                 MINT_HARD_MIN_NSHELLS);
 
-        struct stardata_t * s = stardata;
-        Foreach_star(star)
-        {
-            star->mint = Calloc(sizeof(struct mint_t),1);
-        }
-        stardata = stardata->previous_stardata;
-        Foreach_star(star)
-        {
-            star->mint = Calloc(sizeof(struct mint_t),1);
-        }
-        stardata = s;
         if(p->MINT_metallicity < -TINY)
         {
             p->MINT_metallicity =
diff --git a/src/stellar_structure/stellar_structure_BSE.c b/src/stellar_structure/stellar_structure_BSE.c
index 5573f5f13..3ce03ba4e 100644
--- a/src/stellar_structure/stellar_structure_BSE.c
+++ b/src/stellar_structure/stellar_structure_BSE.c
@@ -17,9 +17,9 @@ No_empty_translation_unit_warning;
 int stellar_structure_BSE(struct stardata_t * const stardata,
                           const Caller_id caller_id,
                           struct star_t * const star,
-                          double *  const timescales,
-                          double *  const luminosities,
-                          double *  const GB)
+                          double * const timescales,
+                          double * const luminosities,
+                          double * const GB)
 {
     Dprint("stellar structure called from %s with age %g (star %d, type %d, timescales %p, luminosities %p, GB %p)\n",
            Stellar_structure_caller_string(caller_id),
@@ -40,8 +40,9 @@ int stellar_structure_BSE(struct stardata_t * const stardata,
         Dprint("Made stellar_structure_newstar at %p\n",
                (void*)stardata->tmpstore->stellar_structure_newstar);
     }
-    struct star_t * newstar = stardata->tmpstore->stellar_structure_newstar;
+    struct star_t * const newstar = stardata->tmpstore->stellar_structure_newstar;
     copy_star(star,newstar);
+
     Dprint("newstar = %p\n",(void*)newstar);
 
     return stellar_structure_BSE_with_newstar(stardata,
@@ -51,16 +52,15 @@ int stellar_structure_BSE(struct stardata_t * const stardata,
                                               timescales,
                                               luminosities,
                                               GB);
-
 }
 
 int stellar_structure_BSE_with_newstar(struct stardata_t * const stardata,
                                        const Caller_id caller_id,
                                        struct star_t * const oldstar,
                                        struct star_t * const newstar,
-                                       double *  const timescales,
-                                       double *  const luminosities,
-                                       double *  const GB)
+                                       double * const timescales,
+                                       double * const luminosities,
+                                       double * const GB)
 {
     Dprint("oldstar %p newstar %p timescales %p luminosities %p GB %p\n",
            (void*)oldstar,
@@ -72,7 +72,6 @@ int stellar_structure_BSE_with_newstar(struct stardata_t * const stardata,
     Supernova_type new_SN_type = SN_NONE;
 
     Boolean alloc_timescales, alloc_luminosities, alloc_GB;
-
     if(timescales != NULL)
     {
         newstar->timescales = timescales;
diff --git a/src/stellar_structure/stellar_structure_HG.c b/src/stellar_structure/stellar_structure_HG.c
index a59b39819..03cb1e110 100644
--- a/src/stellar_structure/stellar_structure_HG.c
+++ b/src/stellar_structure/stellar_structure_HG.c
@@ -35,7 +35,9 @@ Stellar_type stellar_structure_HG(struct star_t * RESTRICT const newstar,
 
 #ifdef NUCSYN
         mcbgbf =
-            stardata->preferences->MINT_nuclear_burning == TRUE
+            (MINT_has_shells(newstar)
+             &&
+             stardata->preferences->MINT_nuclear_burning == TRUE)
             ? MINT_core(newstar,XHe4,0.9)
             : mcbgb(newstar,stardata);
 #else
@@ -58,11 +60,12 @@ Stellar_type stellar_structure_HG(struct star_t * RESTRICT const newstar,
      */
     rho = mctmsf(newstar->phase_start_mass);
 
-    Dprint("age = %g, tm = %g, thg = %g, rho = %g\n",
+    Dprint("age = %g, tm = %g, thg = %g, rho = %g, mcbgbf = %g\n",
            newstar->age,
            newstar->tm,
            thg,
-           rho);
+           rho,
+           mcbgbf);
 
     tau = (newstar->age - newstar->tm) / thg;
 
diff --git a/src/stellar_timescales/stellar_timescales_high_mass_GB.c b/src/stellar_timescales/stellar_timescales_high_mass_GB.c
index 23b6eee81..011639dd4 100644
--- a/src/stellar_timescales/stellar_timescales_high_mass_GB.c
+++ b/src/stellar_timescales/stellar_timescales_high_mass_GB.c
@@ -27,8 +27,8 @@ void stellar_timescales_high_mass_GB(struct stardata_t * const stardata,
 
     Boolean have_set = FALSE;
 #ifdef MINT
-    if(stardata->preferences->stellar_structure_algorithm ==
-       STELLAR_STRUCTURE_ALGORITHM_MINT)
+    if(stardata->preferences->stellar_structure_algorithm == STELLAR_STRUCTURE_ALGORITHM_MINT &&
+       MINT_has_table(MINT_TABLE_CHeB))
     {
         have_set = TRUE;
 
diff --git a/src/stellar_timescales/stellar_timescales_low_mass_GB.c b/src/stellar_timescales/stellar_timescales_low_mass_GB.c
index 66e282cb5..560360d88 100644
--- a/src/stellar_timescales/stellar_timescales_low_mass_GB.c
+++ b/src/stellar_timescales/stellar_timescales_low_mass_GB.c
@@ -100,7 +100,7 @@ void stellar_timescales_low_mass_GB(const double GBp,
 #ifdef MINT
     if(stardata->preferences->stellar_structure_algorithm ==
        STELLAR_STRUCTURE_ALGORITHM_MINT &&
-       stardata->store->MINT_tables[MINT_TABLE_CHeB] != NULL)
+       MINT_has_table(MINT_TABLE_CHeB))
     {
         have_set = TRUE;
         MINT_CHeB_ZA(stardata,
diff --git a/src/timestep/timestep_CHeB.c b/src/timestep/timestep_CHeB.c
index 31d291ba4..bb7319eae 100644
--- a/src/timestep/timestep_CHeB.c
+++ b/src/timestep/timestep_CHeB.c
@@ -6,7 +6,7 @@ No_empty_translation_unit_warning;
 void timestep_CHeB(Timestep_prototype_args)
 {
     if(stardata->preferences->stellar_structure_algorithm == STELLAR_STRUCTURE_ALGORITHM_MINT &&
-       stardata->store->MINT_tables[MINT_TABLE_CHeB_TA] != NULL)
+       MINT_has_table(MINT_TABLE_CHeB_TA))
     {
 #ifdef MINT
         double phase_lifetime;
-- 
GitLab