From ce26bdaf8dc3658bde3aed663a9d46011dde4666 Mon Sep 17 00:00:00 2001 From: Andreas Gattringer <andreas.gattringer@univie.ac.at> Date: Thu, 27 Jul 2023 11:34:15 +0200 Subject: [PATCH] cats: no longer directly access seed data structures, use new getter/setter functions instead --- .../actions/process_inter_period_survival.c | 6 +- src/cats/actions/process_seed_dispersal.c | 9 +- src/cats/dispersal/dispersal.c | 3 +- src/cats/dispersal/local_dispersal.c | 8 +- src/cats/grids/cats_grid.c | 2 +- src/cats/grids/gdal_save.c | 6 +- src/cats/grids/grid_setup.c | 2 +- src/cats/inline.h | 109 ++++++++++++++++-- src/cats/misc/debug.c | 6 +- src/cats/mpi/mpi_save.c | 3 +- src/cats/mpi/mpi_seeds.c | 5 +- src/cats/plants/inter_period.c | 41 ++++--- src/cats/plants/long_range_dispersal.c | 2 +- src/cats/plants/plant_structures.c | 36 +++--- src/cats/plants/seeds.c | 43 +++---- 15 files changed, 192 insertions(+), 89 deletions(-) diff --git a/src/cats/actions/process_inter_period_survival.c b/src/cats/actions/process_inter_period_survival.c index 479385a..0f6d050 100644 --- a/src/cats/actions/process_inter_period_survival.c +++ b/src/cats/actions/process_inter_period_survival.c @@ -57,10 +57,10 @@ void write_stats(struct cats_grid *grid, const struct cats_configuration *conf, j_sum_weighted, get_seed_sum(g, 0, 0)); - fprintf(f, ",%f", g->dispersed_seeds[0][0]); + fprintf(f, ",%f", get_dispersed_seeds(grid, 0, 0)); for (int32_t i = 0; i < seed_persistence; i++) { - if (g->seed_bank[0][0]) { - fprintf(f, ",%f", g->seed_bank[0][0][i]); + if (seed_bank_exists(g, 0, 0)) { + fprintf(f, ",%f", get_seed_bank_seeds(g, 0, 0, i)); } else { fprintf(f, ",%f", 0.0); diff --git a/src/cats/actions/process_seed_dispersal.c b/src/cats/actions/process_seed_dispersal.c index 8157c95..ab47e31 100644 --- a/src/cats/actions/process_seed_dispersal.c +++ b/src/cats/actions/process_seed_dispersal.c @@ -43,6 +43,7 @@ #include "inline_overlays.h" #include "actions/cats_actions.h" #include "temporal/years.h" +#include "inline.h" void area_post_process_seeds(struct cats_grid *grid, struct cats_thread_info *ts); @@ -106,7 +107,7 @@ enum action_status process_disperse_seeds(struct cats_grid *grid, struct cats_co if (conf->command_line_options.lambda_test) { disperse_seeds(grid, 0, 0, grid->single_thread); - grid->seeds_produced[0][0] = 0.0f; + set_produced_seeds(grid, 0, 0, 0.0f); cell_post_process_seeds(grid, conf, 0, 0, grid->single_thread); return ACTION_RUN; } @@ -172,7 +173,7 @@ void area_post_process_seeds(struct cats_grid *grid, struct cats_thread_info *ts mark_cell_done(&debug, row, col); #endif if (cell_excluded_by_overlay(conf, row, col)) { - grid->dispersed_seeds[row][col] = 0; + set_dispersed_seeds(grid, row, col, 0.0f); } else { cell_post_process_seeds(grid, conf, row, col, ts); } @@ -194,8 +195,8 @@ void dispersal_wrapper(struct cats_grid *grid, struct cats_thread_info *ts) mark_cell_done(&debug, row, col); #endif if (cell_excluded_by_overlay(conf, row, col)) { continue; } - if (grid->seeds_produced[row][col] > 0.0) disperse_seeds(grid, row, col, ts); - grid->seeds_produced[row][col] = 0.0f; + if (get_produced_seeds(grid, row, col) > 0.0) disperse_seeds(grid, row, col, ts); + set_produced_seeds(grid, row, col, 0.0f); } } } diff --git a/src/cats/dispersal/dispersal.c b/src/cats/dispersal/dispersal.c index 938c362..4f13f4a 100644 --- a/src/cats/dispersal/dispersal.c +++ b/src/cats/dispersal/dispersal.c @@ -51,6 +51,7 @@ #include "memory/cats_memory.h" #include "inline_overlays.h" +#include "inline.h" // ANSATZPUNKTE // 3 verschiedene dispersals: @@ -153,7 +154,7 @@ void disperse_seeds(const struct cats_grid *restrict grid, cats_dt_coord s_row, assert(s_col < grid->dimension.cols); - float seeds = grid->seeds_produced[s_row][s_col]; + float seeds = get_produced_seeds(grid, s_row, s_col); assert(seeds >= 0.0); if (seeds < 1.0) return; diff --git a/src/cats/dispersal/local_dispersal.c b/src/cats/dispersal/local_dispersal.c index c91fd54..14c4191 100644 --- a/src/cats/dispersal/local_dispersal.c +++ b/src/cats/dispersal/local_dispersal.c @@ -29,6 +29,7 @@ #include "configuration/configuration.h" #include "data/cats_grid.h" #include "local_dispersal.h" +#include "inline.h" void cell_local_dispersal(struct cats_configuration *conf, struct cats_grid *grid, cats_dt_coord row, @@ -37,11 +38,12 @@ void cell_local_dispersal(struct cats_configuration *conf, struct cats_grid *gri const struct cats_dispersal *const dispersal = grid->dispersal; if (dispersal->local_dispersal <= 0.0) return; - float seeds = grid->seeds_produced[row][col]; + float seeds = get_produced_seeds(grid, row, col); cats_dt_seeds self = (float) (seeds * dispersal->local_dispersal); self = min_float(seeds, self); - grid->dispersed_seeds[row][col] += self; - grid->seeds_produced[row][col] -= self; + increase_dispersed_seeds(grid, row, col, self); + decrease_produced_seeds(grid, row, col, self); + } \ No newline at end of file diff --git a/src/cats/grids/cats_grid.c b/src/cats/grids/cats_grid.c index 8814d97..3ddb38e 100644 --- a/src/cats/grids/cats_grid.c +++ b/src/cats/grids/cats_grid.c @@ -255,7 +255,7 @@ void cleanup_grid_seeds_and_juveniles(struct cats_grid *grid) for (cats_dt_coord col = 0; col < grid->dimension.cols; col++) { destroy_seed_structure(grid, row, col); } - free(grid->seed_bank[row]); + free(grid->seed_bank[row]); // clean-up [cleanup_grid_seeds_and_juveniles] } } diff --git a/src/cats/grids/gdal_save.c b/src/cats/grids/gdal_save.c index ba02526..89d05a6 100644 --- a/src/cats/grids/gdal_save.c +++ b/src/cats/grids/gdal_save.c @@ -173,13 +173,13 @@ void *save_seeds_to_gdal(struct cats_grid *grid, struct cats_configuration *conf for (cats_dt_coord col = 0; col < cols; col++) { if (i > 0) { int year = i - 1; - if (grid->seed_bank[row][col]) { - seeds[row][col] = (int32_t) grid->seed_bank[row][col][year]; + if (seed_bank_exists(grid, row, col)) { + seeds[row][col] = (int32_t) get_seed_bank_seeds(grid, row, col, year); } else { seeds[row][col] = 0; } } else { - seeds[row][col] = (int32_t) grid->dispersed_seeds[row][col]; + seeds[row][col] = (int32_t) get_dispersed_seeds(grid, row, col); } } } diff --git a/src/cats/grids/grid_setup.c b/src/cats/grids/grid_setup.c index 5c31dcd..899ce48 100644 --- a/src/cats/grids/grid_setup.c +++ b/src/cats/grids/grid_setup.c @@ -53,7 +53,7 @@ void setup_grid_seed_structures(const struct cats_configuration *conf, struct ca grid->seed_bank = calloc_or_die(rows, sizeof(cats_dt_seeds **)); for (cats_dt_coord row = 0; row < rows; row++) { - grid->seed_bank[row] = calloc_or_die(cols, sizeof(cats_dt_seeds *)); + grid->seed_bank[row] = calloc_or_die(cols, sizeof(cats_dt_seeds *)); // initialisation [setup_grid_seed_structure] for (cats_dt_coord col = 0; col < cols; col++) { grid->seed_bank[row][col] = NULL; // initialisation [setup_grid_seed_structure] diff --git a/src/cats/inline.h b/src/cats/inline.h index 5c17dc4..fe3ae80 100644 --- a/src/cats/inline.h +++ b/src/cats/inline.h @@ -44,14 +44,15 @@ #include "inline_vital_ages.h" #include "grids/dimensions.h" -static inline bool valid_dispersed_seed_grid(const struct cats_grid *grid, cats_dt_coord row) +static inline bool valid_dispersed_seeds_grid(const struct cats_grid *grid, cats_dt_coord row) { if (grid == NULL) return false; if (grid->dispersed_seeds == NULL) return false; - if (grid->dispersed_seeds[row] == NULL) return false; // validator [valid_population_grid] + if (grid->dispersed_seeds[row] == NULL) return false; // validator [valid_dispersed_seeds_grid] return true; } + static inline bool valid_produced_seed_grid(const struct cats_grid *grid, cats_dt_coord row) { if (grid == NULL) return false; @@ -75,18 +76,109 @@ static inline cats_dt_seeds get_dispersed_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col) { assert(valid_coordinates(&grid->dimension, row, col)); - assert(valid_dispersed_seed_grid(grid, row)); - return grid->dispersed_seeds[row][col]; // get [get_dispersed_seeds] + assert(valid_dispersed_seeds_grid(grid, row)); + return grid->dispersed_seeds[row][col]; // getter [get_dispersed_seeds] +} + +static inline void +set_dispersed_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_seeds seeds) +{ + assert(valid_coordinates(&grid->dimension, row, col)); + assert(valid_dispersed_seeds_grid(grid, row)); + assert(seeds >= 0); + grid->dispersed_seeds[row][col] = seeds; // setter [set_dispersed_seeds] +} + +static inline void +increase_dispersed_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_seeds by) +{ + assert(valid_coordinates(&grid->dimension, row, col)); + assert(valid_dispersed_seeds_grid(grid, row)); + assert(by >= 0); + grid->dispersed_seeds[row][col] += by; // setter [increase_dispersed_seeds] +} + +static inline void +decrease_dispersed_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_seeds by) +{ + assert(valid_coordinates(&grid->dimension, row, col)); + assert(valid_dispersed_seeds_grid(grid, row)); + assert(by >= 0); + grid->dispersed_seeds[row][col] -= by; // setter [decrease_dispersed_seeds] + assert(grid->dispersed_seeds[row][col] >= 0); // setter [decrease_dispersed_seeds] } + + static inline cats_dt_seeds get_produced_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col) { assert(valid_coordinates(&grid->dimension, row, col)); assert(valid_produced_seed_grid(grid, row)); - return grid->seeds_produced[row][col]; // get [get_produced_seeds] + return grid->seeds_produced[row][col]; // getter [get_produced_seeds] +} + +static inline bool valid_seed_bank_grid(const struct cats_grid *grid, cats_dt_coord row) +{ + if (grid == NULL || grid->seed_bank == NULL || grid->seed_bank[row] == NULL) return false; // validator [valid_seed_bank_grid] + return true; } +static inline bool seed_bank_exists(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col) +{ + assert(valid_coordinates(&grid->dimension, row, col)); + assert(valid_seed_bank_grid(grid, row)); + return grid->seed_bank[row][col] != NULL; // validator [seed_bank_exists] +} + +static inline cats_dt_seeds get_seed_bank_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, int32_t year) +{ + assert(seed_bank_exists(grid, row, col)); + assert(year < get_vital_age(grid, VA_SEED_PERSISTENCE)); + assert(year >= 0); + return grid->seed_bank[row][col][year]; // getter [get_seed_bank_seeds] +} + +static inline void set_seed_bank_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, int32_t year, cats_dt_seeds seeds) +{ + assert(seed_bank_exists(grid, row, col)); + assert(year < get_vital_age(grid, VA_SEED_PERSISTENCE)); + assert(seeds >= 0.0f); + grid->seed_bank[row][col][year] = seeds; // setter [set_seed_bank_seeds] +} + + + +static inline void +set_produced_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_seeds seeds) +{ + assert(valid_coordinates(&grid->dimension, row, col)); + assert(valid_produced_seed_grid(grid, row)); + assert(seeds >= 0); + grid->seeds_produced[row][col] = seeds; // setter [set_produced_seeds] +} + +static inline void +increase_produced_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_seeds by) +{ + assert(valid_coordinates(&grid->dimension, row, col)); + assert(valid_produced_seed_grid(grid, row)); + assert(by > 0); + grid->seeds_produced[row][col] += by; // setter [increase_produced_seeds] +} + + +static inline void +decrease_produced_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_seeds by) +{ + assert(valid_coordinates(&grid->dimension, row, col)); + assert(valid_produced_seed_grid(grid, row)); + assert(by > 0); + grid->seeds_produced[row][col] -= by; // setter [decrease_produced_seeds] + assert(grid->seeds_produced[row][col] >= 0); // setter [decrease_produced_seeds] +} + + static inline void set_suitability(struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_environment value) @@ -213,10 +305,11 @@ static inline double get_seed_sum(const struct cats_grid *grid, cats_dt_coord ro assert(grid != NULL && grid->juveniles != NULL); assert(valid_coordinates(&grid->dimension, row, col)); const int32_t max_sp = get_vital_age(grid, VA_SEED_PERSISTENCE); //grid->param.seed_persistence; - double sum = grid->dispersed_seeds[row][col]; - if (grid->seed_bank[row][col] == NULL) return sum; + double sum = get_dispersed_seeds(grid, row, col); + + if (!seed_bank_exists(grid, row, col)) return sum; for (int32_t i = 0; i < max_sp; i++) { - sum += grid->seed_bank[row][col][i]; + sum += get_seed_bank_seeds(grid, row, col, i); } return sum; } diff --git a/src/cats/misc/debug.c b/src/cats/misc/debug.c index 4900cc3..9683654 100644 --- a/src/cats/misc/debug.c +++ b/src/cats/misc/debug.c @@ -57,11 +57,11 @@ void debug_seeds(struct cats_grid *grid, const struct cats_configuration *conf, { if (row == cats_debug.misc_debug_coords.row && col == cats_debug.misc_debug_coords.col) { fprintf(cats_debug.misc_debug_file, "%d,%d,%s,seeds,%f", grid->id, conf->time.year_current, action, - grid->dispersed_seeds[row][col]); // debug [debug_seeds] + get_dispersed_seeds(grid, row, col)); const int32_t seed_persistence = get_vital_age(grid, VA_SEED_PERSISTENCE); for (int32_t i = 0; i < seed_persistence; i++) { - if (grid->seed_bank[row][col]) { // debug [debug_seeds] - fprintf(cats_debug.misc_debug_file, ",%f", grid->seed_bank[row][col][i]); // debug [debug_seeds] + if (seed_bank_exists(grid, row, col)) { + fprintf(cats_debug.misc_debug_file, ",%f", get_seed_bank_seeds(grid, row, col, i)); } else { fprintf(cats_debug.misc_debug_file, ",%d", 0); } diff --git a/src/cats/mpi/mpi_save.c b/src/cats/mpi/mpi_save.c index 3af93da..c667d1e 100644 --- a/src/cats/mpi/mpi_save.c +++ b/src/cats/mpi/mpi_save.c @@ -35,6 +35,7 @@ #include "memory/cats_memory.h" #include "mpi/mpi_grid_helpers.h" #include "paths/output_paths.h" +#include "inline.h" /* @@ -80,7 +81,7 @@ void *save_seeds0_to_gdal_mpi(struct cats_grid *grid, struct cats_configuration for (int r = 0; r < grid->dimension.rows; r++) { for (int c = 0; c < grid->dimension.cols; c++) { - seeds0[r * grid->dimension.cols + c] = grid->dispersed_seeds[r][c]; + seeds0[r * grid->dimension.cols + c] = get_dispersed_seeds(grid, r, c); } } diff --git a/src/cats/mpi/mpi_seeds.c b/src/cats/mpi/mpi_seeds.c index 9b3f153..89bb25d 100644 --- a/src/cats/mpi/mpi_seeds.c +++ b/src/cats/mpi/mpi_seeds.c @@ -29,6 +29,7 @@ #include "mpi_grid_helpers.h" #include "memory/raw_arrays.h" #include "mpi_seeds.h" +#include "inline.h" void send_and_receive_dispersed_seeds_mpi(struct cats_grid *grid, struct cats_configuration *conf) @@ -143,7 +144,7 @@ void add_seeds0_from_below(const struct cats_configuration *conf, struct cats_gr for (int r = 0; r < radius; r++) { for (int c = 0; c < cols; c++) { - grid->dispersed_seeds[start_row + r][c] += from_below[r * cols + c]; + increase_dispersed_seeds(grid, start_row + r, c, (cats_dt_seeds) from_below[r * cols + c]); } } } @@ -159,7 +160,7 @@ void add_seeds0_from_above(const struct cats_configuration *conf, struct cats_gr for (int r = 0; r < radius; r++) { for (int c = 0; c < cols; c++) { - grid->dispersed_seeds[r][c] += from_above[r * cols + c]; + increase_dispersed_seeds(grid, r, c, (cats_dt_seeds) from_above[r * cols + c]); } } } \ No newline at end of file diff --git a/src/cats/plants/inter_period.c b/src/cats/plants/inter_period.c index 2c6ae48..267c288 100644 --- a/src/cats/plants/inter_period.c +++ b/src/cats/plants/inter_period.c @@ -35,46 +35,55 @@ void inter_period_survival_seeds(struct cats_grid *grid, struct cats_configurati cats_dt_coord col, struct cats_thread_info *ts) { // if we have no seeds, we are done - if (grid->dispersed_seeds[row][col] == 0.0 && grid->seed_bank[row][col] == NULL) return; + cats_dt_seeds disp_seeds = get_dispersed_seeds(grid, row, col); + if (disp_seeds == 0.0 && seed_bank_exists(grid, row, col) == false) return; cats_dt_rates seed_survival_rate; + bool have_seed_bank = seed_bank_exists(grid, row, col); const struct cats_vital_rate *rate_link_surv = get_default_vital_rate(grid, VR_SEED_SURVIVAL); seed_survival_rate = calculate_rate(rate_link_surv, NAN, &grid->param, grid, row, col, NULL); - if (grid->dispersed_seeds[row][col] > 0) { - cats_dt_seeds dying_0 = poisson_seeds_capped(ts->rng, grid->dispersed_seeds[row][col] * + if (disp_seeds > 0) { + cats_dt_seeds dying_0 = poisson_seeds_capped(ts->rng, disp_seeds * (1.0 - seed_survival_rate), - grid->dispersed_seeds[row][col]); + disp_seeds); - grid->dispersed_seeds[row][col] = grid->dispersed_seeds[row][col] - dying_0; + disp_seeds = disp_seeds - dying_0; + set_dispersed_seeds(grid, row, col, disp_seeds); - if (grid->dispersed_seeds[row][col] > 0.0 && grid->seed_bank[row][col] == NULL) { + + if (disp_seeds > 0.0 && have_seed_bank == false) { create_seed_structure(grid, row, col); } } - if (grid->dispersed_seeds[row][col] == 0.0 && grid->seed_bank[row][col] == NULL) return; + + if (disp_seeds == 0.0 && have_seed_bank == false) return; + + if (have_seed_bank == false) create_seed_structure(grid, row, col); const int32_t seed_persistence = get_vital_age(grid, VA_SEED_PERSISTENCE); - for (int32_t stage = 0; stage < seed_persistence - 0; stage++) { // -1 + for (int32_t stage = 0; stage < seed_persistence; stage++) { + cats_dt_seeds seeds_i = get_seed_bank_seeds(grid, row, col, stage); cats_dt_seeds dying = poisson_seeds_capped(ts->rng, - grid->seed_bank[row][col][stage] * + seeds_i * (1.0 - seed_survival_rate), - grid->seed_bank[row][col][stage]); - grid->seed_bank[row][col][stage] = grid->seed_bank[row][col][stage] - dying; + seeds_i); + set_seed_bank_seeds(grid, row, col, stage, seeds_i - dying); } - for (int32_t k = seed_persistence - 1; k >= 1; k--) { // -2 - grid->seed_bank[row][col][k] = grid->seed_bank[row][col][k - 1]; + for (int32_t k = seed_persistence - 1; k >= 1; k--) { + cats_dt_seeds s = get_seed_bank_seeds(grid, row, col, k - 1); + set_seed_bank_seeds(grid, row, col, k, s); } - grid->seed_bank[row][col][0] = grid->dispersed_seeds[row][col]; - assert(grid->seed_bank[row][col][0] >= 0.0); - grid->dispersed_seeds[row][col] = 0.0f; + set_seed_bank_seeds(grid, row, col, 0, get_dispersed_seeds(grid, row, col)); + assert(get_seed_bank_seeds(grid, row, col, 0) >= 0); + set_dispersed_seeds(grid, row, col, 0.0f); } diff --git a/src/cats/plants/long_range_dispersal.c b/src/cats/plants/long_range_dispersal.c index 6168429..eb6d86d 100644 --- a/src/cats/plants/long_range_dispersal.c +++ b/src/cats/plants/long_range_dispersal.c @@ -87,7 +87,7 @@ void disperse_long_range(struct cats_grid *grid) } // disperse seeds and reduce number of local seeds - grid->dispersed_seeds[trow][tcol] += (cats_dt_seeds) package; + increase_dispersed_seeds(grid, trow, tcol, (cats_dt_seeds) package); grid->seeds_produced[row][col] -= (cats_dt_seeds) package; // stop if no more seeds are left to distribute diff --git a/src/cats/plants/plant_structures.c b/src/cats/plants/plant_structures.c index 8d1378c..cd36a39 100644 --- a/src/cats/plants/plant_structures.c +++ b/src/cats/plants/plant_structures.c @@ -40,50 +40,42 @@ void destroy_plant_cell(struct cats_grid *grid, const cats_dt_coord row, const c assert(col >= 0 && col < grid->dimension.cols); destroy_juveniles(grid, row, col); destroy_seed_structure(grid, row, col); - grid->dispersed_seeds[row][col] = 0.0f; - grid->seeds_produced[row][col] = 0.0f; + set_dispersed_seeds(grid, row, col, 0.0f); + set_produced_seeds(grid, row, col, 0.0f); set_population_ignore_cc(grid, row, col, 0); } void create_seed_structure(const struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col) { - assert(grid != NULL); - if (grid->seed_bank[row][col] != NULL) return; + + assert(valid_seed_bank_grid(grid, row)); + if (seed_bank_exists(grid, row, col) == true) return; const int32_t seed_persistence = get_vital_age(grid, VA_SEED_PERSISTENCE); - const int32_t size = seed_persistence - 0; // - 1); + const int32_t size = seed_persistence; if (size <= 0) return; // no seed persistence - assert(grid->seed_bank != NULL); - assert(row >= 0 && row < grid->dimension.rows); - assert(col >= 0 && col < grid->dimension.cols); - assert(grid->seed_bank[row][col] == NULL); - - grid->seed_bank[row][col] = calloc_or_die(size, sizeof(cats_dt_seeds)); - - + grid->seed_bank[row][col] = calloc_or_die(size, sizeof(cats_dt_seeds)); // initialisation [create_seed_structure] } void destroy_seed_structure(const struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col) { assert(grid != NULL); - assert(grid->seed_bank != NULL); - assert(row >= 0 && row < grid->dimension.rows); - assert(col >= 0 && col < grid->dimension.cols); + const int32_t seed_persistence = get_vital_age(grid, VA_SEED_PERSISTENCE); - const int size = (seed_persistence - 0); // -1 + const int size = (seed_persistence - 0); // do we actually have seeds in the ground? - if (size <= 0 || grid->seed_bank[row][col] == NULL) return; + if (size <= 0 || seed_bank_exists(grid, row, col) == false) return; - for (uint32_t i = 0; i < size; i++) { - grid->seed_bank[row][col][i] = 0.0f; + for (int32_t i = 0; i < size; i++) { + set_seed_bank_seeds(grid, row, col, i, 0.0f); // clean-up [destroy_seed_structure] } - free(grid->seed_bank[row][col]); - grid->seed_bank[row][col] = NULL; + free(grid->seed_bank[row][col]); // clean-up [destroy_seed_structure] + grid->seed_bank[row][col] = NULL; // clean-up [destroy_seed_structure] } diff --git a/src/cats/plants/seeds.c b/src/cats/plants/seeds.c index c4cb44d..0cd63b9 100644 --- a/src/cats/plants/seeds.c +++ b/src/cats/plants/seeds.c @@ -87,9 +87,8 @@ void cell_seed_production(struct cats_grid *grid, cats_dt_coord row, cats_dt_coo assert(grid->seeds_produced != NULL); // ensure that no seeds are left-over in the cell - assert(grid->seeds_produced[row][col] == 0.0); - - grid->seeds_produced[row][col] = 0.0f; + assert(get_produced_seeds(grid, row, col) == 0.0f); + set_produced_seeds(grid, row, col, 0.0f); // no population -> no seeds cats_dt_rates N = get_adult_population(grid, row, col); @@ -124,10 +123,11 @@ void cell_seed_production(struct cats_grid *grid, cats_dt_coord row, cats_dt_coo const cats_dt_rates total_seeds = N * flowering_frequency * seed_yield * pollination_rate; assert(total_seeds >= 0.0); + cats_dt_seeds seeds = poisson_seeds(ts->rng, total_seeds); // we don't cap + set_produced_seeds(grid, row, col, seeds); - grid->seeds_produced[row][col] = poisson_seeds(ts->rng, total_seeds); // we don't cap - if (grid->seeds_produced[row][col] > 0) ts->stats[grid->id].stats[CS_SEEDS_PRODUCED] += 1; + if (seeds > 0) ts->stats[grid->id].stats[CS_SEEDS_PRODUCED] += 1; cats_dt_rates hapaxanth = grid->param.hapaxanthy; @@ -167,17 +167,19 @@ germinate_seeds_in_ground(struct cats_thread_info *ts, struct cats_grid *grid, c for (int32_t k = 0; k < max_k; k++) { - cats_dt_population germinated = poisson(ts->rng, grid->seed_bank[row][col][k] * germination_rate); + cats_dt_seeds seeds_k = get_seed_bank_seeds(grid, row, col, k); + cats_dt_population germinated = poisson(ts->rng, seeds_k * germination_rate); if (germinated <= 0) continue; add_germinated(ts, grid, row, col, germinated, K_class); - grid->seed_bank[row][col][k] = max_float(grid->seed_bank[row][col][k] - (float) germinated, 0.0f); - + seeds_k = max_float(seeds_k - (float) germinated, 0.0f); + set_seed_bank_seeds(grid, row, col, k, seeds_k); } } - +/* +// no longer used static inline void germinate_seeds0(struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col, struct cats_thread_info *ts, const cats_dt_rates germination_rate) @@ -197,16 +199,16 @@ germinate_seeds0(struct cats_grid *grid, const cats_dt_coord row, const cats_dt_ grid->dispersed_seeds[row][col] = max_float(grid->dispersed_seeds[row][col] - (float) germinated, 0.0f); // fixme max_seeds } - +*/ inline static bool have_seeds_in_cell(const struct cats_grid *grid, const struct cats_configuration *conf, cats_dt_coord row, cats_dt_coord col, const struct cats_thread_info *ts) { - assert(grid->dispersed_seeds != NULL); - assert(grid->dispersed_seeds[row][col] >= 0); - return (grid->seed_bank[row][col] != NULL || grid->dispersed_seeds[row][col] > 0.5); + cats_dt_seeds d_seeds = get_dispersed_seeds(grid, row, col); + assert(d_seeds >= 0); + return (seed_bank_exists(grid, row, col) || d_seeds > 0.5); } @@ -242,21 +244,22 @@ cell_post_process_seeds(struct cats_grid *grid, struct cats_configuration *conf, struct cats_thread_info *ts) { assert(grid != NULL); - assert(grid->dispersed_seeds != NULL); - assert(grid->dispersed_seeds[row][col] >= 0); + assert(valid_dispersed_seeds_grid(grid, row)); + + cats_dt_seeds disp_seeds = get_dispersed_seeds(grid, row, col); + assert(disp_seeds >= 0); + if (disp_seeds == 0.0f) return; if (cell_excluded_by_overlay(conf, row, col)) { - grid->dispersed_seeds[row][col] = 0; + set_dispersed_seeds(grid, row, col, 0.0f); return; } - if (grid->dispersed_seeds[row][col] == 0.0) return; - const int32_t id = grid->id; ts->stats[id].stats[CS_SEEDS_BEFORE_POISSON] += 1; cats_dt_seeds seeds_after_poisson = poisson_seeds(ts->rng, - grid->dispersed_seeds[row][col]); /* IMPORTANT stochasticity required */ - grid->dispersed_seeds[row][col] = seeds_after_poisson; + disp_seeds); /* IMPORTANT stochasticity required */ + set_dispersed_seeds(grid, row, col, seeds_after_poisson); if (seeds_after_poisson > 0) ts->stats[id].stats[CS_SEEDS_AFTER_POISSON] += 1; } -- GitLab