Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • development
  • main
  • refactor-libraries
  • 1.0.0
  • 1.0.1
  • 1.0.2
  • 1.0.3
  • 1.1.0
8 results

Target

Select target project
  • bdc/cats
1 result
Select Git revision
  • development
  • main
  • refactor-libraries
  • 1.0.0
  • 1.0.1
  • 1.0.2
  • 1.0.3
  • 1.1.0
8 results
Show changes
Showing
with 376 additions and 169 deletions
......@@ -33,6 +33,7 @@
#include "populations/population.h"
#include "inline_population.h"
#include "dispersal/dispersal.h"
#include "misc/cats_maths_inline.h"
cats_dt_environment **convert_double_to_environment(const struct cats_2d_array_double *in_grid)
......@@ -43,7 +44,7 @@ cats_dt_environment **convert_double_to_environment(const struct cats_2d_array_d
const cats_dt_coord cols = in_grid->dimension.cols;
for (int32_t r = 0; r < rows; r++) {
for (int32_t c = 0; c < cols; c++) {
array[r][c] = (float) in_grid->data[r][c];
array[r][c] = (float) in_grid->data[r][c]; // converter [convert_double_to_environment]
}
}
......
......@@ -53,10 +53,10 @@ 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;
grid->seed_bank[row][col] = NULL; // initialisation [setup_grid_seed_structure]
}
}
}
......@@ -98,10 +98,10 @@ void setup_grid_juvenile_structures_opt(struct cats_configuration *conf, struct
grid->juveniles = calloc_or_die(grid->dimension.rows, sizeof(cats_dt_population **));
for (cats_dt_coord row = 0; row < grid->dimension.rows; row++) {
grid->juveniles[row] = calloc_or_die(grid->dimension.cols, sizeof(cats_dt_population *));
grid->juveniles[row] = calloc_or_die(grid->dimension.cols, sizeof(cats_dt_population *)); // initialisation [setup_grid_juvenile_structures_opt]
for (cats_dt_coord col = 0; col < grid->dimension.cols; col++) {
grid->juveniles[row][col] = NULL;
grid->juveniles[row][col] = NULL; // initialisation [setup_grid_juvenile_structures_opt]
}
}
}
......
......@@ -42,6 +42,25 @@
#include "inline_carrying_capacity.h"
#include "inline_population.h"
#include "inline_vital_ages.h"
#include "grids/dimensions.h"
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_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;
if (grid->seeds_produced == NULL) return false;
if (grid->seeds_produced[row] == NULL) return false; // validator [valid_produced_seed_grid]
return true;
}
static inline cats_dt_environment
......@@ -49,11 +68,124 @@ get_suitability_from_env(const struct cats_environment *set, cats_dt_coord row,
{
assert(set->type == ENVIRONMENT_TYPE_SUITABILITY);
assert(set->count == 1);
assert(row >= 0);
assert(col >= 0);
assert(row < set->environments[0]->current.dimension.rows);
assert(col < set->environments[0]->current.dimension.cols);
return set->environments[0]->current.values[row][col];
assert(valid_coordinates(&set->environments[0]->current.dimension, row, col));
return load_input_environment_raster(&set->environments[0]->current, row, col);
}
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_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]; // 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)
{
assert(value >= 0.0f);
assert(value <= 1.0f);
set_input_environment_raster(&grid->suitability->environments[0]->current, row, col, value);
}
......@@ -171,13 +303,13 @@ static inline cats_dt_environment get_suitability(const struct cats_grid *grid,
static inline double get_seed_sum(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
{
assert(grid != NULL && grid->juveniles != NULL);
assert(row >= 0 && row < grid->dimension.rows);
assert(col >= 0 && col < grid->dimension.cols);
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;
}
......@@ -187,20 +319,16 @@ static inline cats_dt_population_sum
get_juvenile_sum(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
{
assert(grid != NULL && grid->juveniles != NULL);
assert(row >= 0 && row < grid->dimension.rows);
assert(col >= 0 && col < grid->dimension.cols);
assert(grid->juveniles[row] != NULL);
if (!juveniles_exist(grid, row, col)) return 0;
const cats_dt_population *juveniles = grid->juveniles[row][col];
if (juveniles == NULL) return 0;
const cats_dt_population *juveniles = grid->juveniles[row][col]; // getter [get_juvenile_sum]
cats_dt_population_sum juvenile_sum = 0;
const int32_t max_stage =
get_vital_age(grid, VA_AGE_OF_MATURITY_MAX) + 1; //grid->param.max_age_of_maturity + 1;
const int32_t max_stage = get_vital_age(grid, VA_AGE_OF_MATURITY_MAX) + 1;
for (int32_t i = 0; i < max_stage; i++) {
juvenile_sum += juveniles[i];
juvenile_sum += juveniles[i]; // getter [get_juvenile_sum]
}
return juvenile_sum;
}
......
......@@ -36,6 +36,7 @@
#include "configuration/configuration.h"
#include "plants/juveniles.h"
#include "inline_vital_ages.h"
#include "inline_carrying_capacity.h"
static inline cats_dt_rates juvenile_cc_multiplier(const struct cats_species_param *param, int32_t stage)
......
......@@ -28,6 +28,7 @@
#include "assert.h"
#include "overlays/overlays.h"
#include "configuration/configuration.h"
#include "grids/direct_access.h"
static inline bool
......@@ -35,21 +36,20 @@ cell_excluded_by_habitat(const struct cats_configuration *config, cats_dt_coord
{
if (!config->overlays.have_overlays) return false;
if (!config->overlays.overlay[OL_HABITAT_TYPE_CC].enabled) return false;
return (config->overlays.habitat_cc->data[row][col] == 0.0);
return (load_input_2d_array_double(config->overlays.habitat_cc, row, col) == 0.0);
}
static inline bool
cell_excluded_by_overlay(const struct cats_configuration *config, cats_dt_coord row, cats_dt_coord col)
{
assert(config != NULL);
if (config->overlays.have_overlays == false || config->overlays.overlay[OL_EXCLUSION].enabled == false) return false;
if (config->overlays.have_overlays == false || config->overlays.overlay[OL_EXCLUSION].enabled == false)
return false;
assert(config->overlays.exclusion->data != NULL);
const char value = config->overlays.exclusion->data[row][col];
const char value = load_input_2d_array_char(config->overlays.exclusion, row, col);
switch (value) { // NOLINT(hicpp-multiway-paths-covered)
case OL_EXCLUSION_NOT_EXCLUDED:
......@@ -63,5 +63,17 @@ cell_excluded_by_overlay(const struct cats_configuration *config, cats_dt_coord
exit_cats(EXIT_FAILURE);
}
static inline double get_overlay_habitat_cc_value(const struct cats_configuration *conf, cats_dt_coord row, cats_dt_coord col)
{
assert(conf->overlays.overlay[OL_HABITAT_TYPE_CC].enabled);
return conf->overlays.habitat_cc->data[row][col]; // getter [get_overlay_habitat_cc_value]
}
static inline double get_overlay_resource_value(const struct cats_configuration *conf, cats_dt_coord row, cats_dt_coord col)
{
assert(conf->overlays.overlay[OL_RESOURCE].enabled);
return conf->overlays.resources->data[row][col]; // getter [get_overlay_resource_value]
}
#endif //CATS_INLINE_OVERLAYS_H
......@@ -34,17 +34,56 @@
#include "inline_overlays.h"
#include "populations/carrying_capacity.h"
#include "populations/plant_juveniles.h"
#include "grids/dimensions.h"
#include "inline_vital_ages.h"
static inline bool valid_population_grid(const struct cats_grid *grid, cats_dt_coord row)
{
if (grid && grid->population && grid->population[row]) return true; // validator [valid_population_grid]
return false;
}
static inline bool valid_juvenile_grid(const struct cats_grid *grid, cats_dt_coord row)
{
if (grid == NULL) return false;
if (grid->juveniles == NULL) return false;
if (grid->juveniles[row] == NULL) return false; // validator [valid_juvenile_grid]
return true;
}
static inline bool juveniles_exist(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
{
assert(valid_coordinates(&grid->dimension, row, col));
assert(valid_juvenile_grid(grid, row));
return grid->juveniles[row][col] != NULL; // validator [juveniles_exist]
}
static inline cats_dt_population get_juveniles(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, int year)
{
if (juveniles_exist(grid, row, col) == false) return 0;
assert(year < get_vital_age(grid, VA_AGE_OF_MATURITY_MAX) + 1);
// FIXME check year
return grid->juveniles[row][col][year]; // getter [get_juveniles]
}
static inline void set_juveniles(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, int year, cats_dt_population juv)
{
assert(juveniles_exist(grid, row, col));
assert(year < get_vital_age(grid, VA_AGE_OF_MATURITY_MAX) + 1);
assert(juv >= 0);
grid->juveniles[row][col][year] = juv; // setter [set_juveniles]
}
static inline cats_dt_population
get_adult_population(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
{
assert(grid != NULL && grid->population != NULL);
assert(row >= 0 && row < grid->dimension.rows);
assert(col >= 0 && col < grid->dimension.cols);
assert(grid->population[row] != NULL);
assert(grid->population[row][col] >= 0);
return grid->population[row][col]; // getter
assert(valid_population_grid(grid, row));
assert(valid_coordinates(&grid->dimension, row, col));
assert(grid->population[row][col] >= 0); // getter [get_adult_population]
return grid->population[row][col]; // getter [get_adult_population]
}
......@@ -81,20 +120,12 @@ static inline cats_dt_population
reduce_population_by(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_population to_reduce)
{
assert(to_reduce >= 0);
assert(grid != NULL);
assert(grid->population != NULL);
assert(row < grid->dimension.rows);
assert(col < grid->dimension.cols);
assert(row >= 0);
assert(col >= 0);
assert(grid->population[row] != NULL);
//cats_dt_population cc = get_carrying_capacity(grid, row, col);
assert(valid_population_grid(grid, row));
assert(valid_coordinates(&grid->dimension, row, col));
cats_dt_population pop = get_adult_population(grid, row, col);
if (to_reduce > pop) { to_reduce = pop; }
grid->population[row][col] = pop - to_reduce;// setter;
grid->population[row][col] = pop - to_reduce; // setter [reduce_population_by]
return to_reduce;
}
......@@ -104,9 +135,8 @@ static inline void
set_population_ignore_cc(const struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col,
const cats_dt_population pop)
{
assert(grid != NULL && grid->population != NULL);
assert(row >= 0 && row < grid->dimension.rows && col >= 0 && col < grid->dimension.cols);
assert(grid->population[row] != NULL);
assert(valid_population_grid(grid, row));
assert(valid_coordinates(&grid->dimension, row, col));
if (pop > CATS_MAX_POPULATION || pop < 0.0) {
log_message(LOG_ERROR, "%s: population %d out of allowed population range [0, %d].",
......@@ -114,7 +144,7 @@ set_population_ignore_cc(const struct cats_grid *grid, const cats_dt_coord row,
exit(EXIT_FAILURE);
}
if (pop >= 0) grid->population[row][col] = pop; // setter ignore cc;
if (pop >= 0) grid->population[row][col] = pop; // setter [set_population_ignore_cc]
}
......@@ -169,19 +199,14 @@ static inline cats_dt_population
get_population_ts(const struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col, const int threshold,
int64_t *unfiltered)
{
assert(grid != NULL);
assert(grid->population != NULL);
assert(row < grid->dimension.rows);
assert(col < grid->dimension.cols);
assert(row >= 0);
assert(col >= 0);
assert(grid->population[row] != NULL);
assert(valid_population_grid(grid, row));
assert(valid_coordinates(&grid->dimension, row, col));
cats_dt_population tmp = grid->population[row][col]; // getter
cats_dt_population tmp = grid->population[row][col]; // getter [get_population_ts]
if (unfiltered) *unfiltered = tmp;
if (grid->population[row][col] >= threshold) {
if (grid->population[row][col] >= threshold) { // getter [get_population_ts]
return tmp;
} else {
return 0;
......
......@@ -29,6 +29,7 @@
#include "data/cats_grid.h"
#include "vital_rates/glm_functions.h"
#include "vital_rates/direct_functions.h"
#include "inline.h"
static inline cats_dt_rates get_vital_rate_maximum(const struct cats_vital_rate *vr)
......
......@@ -28,6 +28,12 @@
#include <memory/cats_memory.h>
static inline cats_dt_population debug_get_juveniles(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, int year)
{
if (grid->juveniles[row][col] == NULL) return 0; // debug [debug_get_juveniles]
return grid->juveniles[row][col][year]; // debug [debug_get_juveniles]
}
void
debug_juveniles(const struct cats_grid *grid, const struct cats_configuration *conf, cats_dt_coord row,
cats_dt_coord col, const char *action)
......@@ -38,11 +44,7 @@ debug_juveniles(const struct cats_grid *grid, const struct cats_configuration *c
const int32_t max_age_of_maturity = get_vital_age(grid, VA_AGE_OF_MATURITY_MAX);
for (int32_t i = 0; i < max_age_of_maturity + 1; i++) {
if (grid->juveniles[row][col]) {
fprintf(cats_debug.misc_debug_file, ",%d", grid->juveniles[row][col][i]);
} else {
fprintf(cats_debug.misc_debug_file, ",%d", 0);
}
fprintf(cats_debug.misc_debug_file, ",%d", debug_get_juveniles(grid, row, col, i));
}
fprintf(cats_debug.misc_debug_file, "\n");
......@@ -55,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]);
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]) {
fprintf(cats_debug.misc_debug_file, ",%f", grid->seed_bank[row][col][i]);
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);
}
......
......@@ -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);
}
}
......
......@@ -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
......@@ -110,17 +110,19 @@ struct cats_2d_array_char *translate_exclusion(const struct cats_2d_array_double
for (cats_dt_coord row = 0; row < rows; row++) {
for (cats_dt_coord col = 0; col < cols; col++) {
const int32_t val = (int32_t) round(data->data[row][col]);
const int32_t in_val = (int32_t) round(data->data[row][col]); // converter [translate_exclusion]
char out_val;
if (val == 0) {
result->data[row][col] = OL_EXCLUSION_NOT_EXCLUDED;
if (in_val == 0) {
out_val = OL_EXCLUSION_NOT_EXCLUDED;
} else if (isnan(data->data[row][col])) {
result->data[row][col] = OL_EXCLUSION_NAN;
out_val = OL_EXCLUSION_NAN;
count += 1;
} else {
result->data[row][col] = OL_EXCLUSION_EXCLUDED;
out_val = OL_EXCLUSION_EXCLUDED;
count += 1;
}
result->data[row][col] = out_val; // converter [translate_exclusion]
}
}
......
......@@ -30,6 +30,7 @@
#include "cats_csv/cats_csv.h"
#include "logging.h"
#include "memory/cats_memory.h"
#include "grids/direct_access.h"
void cleanup_habitat_layer_cc_aux(void **data)
......@@ -128,14 +129,31 @@ struct cats_2d_array_double *translate_habitat(const struct cats_2d_array_double
double value = data->data[row][col];
if (isnan(value)) {
result->data[row][col] = 0.0;
result->data[row][col] = 0.0; // converter [translate_habitat]
} else {
int32_t val = (int32_t) round(value);
double multi = get_habitat_cc_multiplier(habitat_info, val);
result->data[row][col] = multi;
result->data[row][col] = multi; // converter [translate_habitat]
}
}
}
return result;
}
double get_overlay_cc_multiplier(const struct cats_configuration *conf, cats_dt_coord row, cats_dt_coord col)
{
if (!conf->overlays.overlay[OL_HABITAT_TYPE_CC].enabled) {
return 1.0;
}
double multiplier = load_input_2d_array_double(conf->overlays.habitat_cc, row, col);
if (multiplier <= 0.0) {
return 0.0;
}
return multiplier;
}
\ No newline at end of file
......@@ -26,6 +26,7 @@
#include <stdint.h>
#include "../../memory/arrays.h"
#include "configuration/configuration.h"
#define MAX_HABITAT_TYPE_CODES 1024
......@@ -43,4 +44,6 @@ struct cats_2d_array_double *translate_habitat(const struct cats_2d_array_double
struct habitat_layer_cc_aux *load_habitat_layer_cc_aux(const char *csv_file, double default_value);
double get_overlay_cc_multiplier(const struct cats_configuration *conf, cats_dt_coord row, cats_dt_coord col);
#endif //CATS_OVERLAY_HABITAT_TYPE_CC_H
#include <assert.h>
#include <math.h>
#include "overlay_resources.h"
#include "memory/arrays.h"
......@@ -14,15 +13,15 @@ struct cats_2d_array_double *translate_resources(const struct cats_2d_array_doub
for (cats_dt_coord row = 0; row < rows; row++) {
for (cats_dt_coord col = 0; col < cols; col++) {
double value = data->data[row][col];
double in_value = data->data[row][col]; // converter [translate_resources]
double out_value;
if (isnan(value)) {
result->data[row][col] = 0.0;
if (isnan(in_value)) {
out_value = 0.0;
} else {
if (value <0 ) value = 0;
result->data[row][col] = value;
}
if (in_value < 0 ) in_value = 0;
out_value = in_value;
} result->data[row][col] = out_value; // converter [translate_resources]
}
}
......
......@@ -35,53 +35,63 @@ 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);
}
void inter_period_survival_juveniles(struct cats_grid *grid, struct cats_configuration *conf, cats_dt_coord row,
cats_dt_coord col, struct cats_thread_info *ts)
{
if (grid->juveniles[row][col] == NULL) return;
if (juveniles_exist(grid, row, col) == false) return;
const int32_t mat_max = get_vital_age(grid, VA_AGE_OF_MATURITY_MAX);
const int32_t mat_min = get_vital_age(grid, VA_AGE_OF_MATURITY_MIN);
......@@ -94,30 +104,34 @@ void inter_period_survival_juveniles(struct cats_grid *grid, struct cats_configu
germination_to_adult_survival, &grid->param);
for (int32_t i = 0; i <= mat_max; i++) {
cats_dt_rates modified_juvenile_transition_rate = age_modified_juvenile_survival_rate(
juvenile_transition_rate, i, mat_min, mat_max);
cats_dt_rates juvenile_mortality = (1.0 - modified_juvenile_transition_rate);
assert(juvenile_mortality >= 0 && juvenile_mortality <= 1.0);
assert(grid->juveniles[row][col][i] >= 0);
cats_dt_population juveniles_i = get_juveniles(grid, row, col, i);
assert(juveniles_i >= 0);
cats_dt_population dying = poisson_population_capped(ts->rng,
(cats_dt_rates) grid->juveniles[row][col][i] *
(cats_dt_rates) juveniles_i *
juvenile_mortality,
grid->juveniles[row][col][i]);
juveniles_i);
set_juveniles(grid, row, col, i, juveniles_i - dying);
grid->juveniles[row][col][i] = grid->juveniles[row][col][i] - dying;
assert(grid->juveniles[row][col][i] >= 0);
assert(get_juveniles(grid, row, col, i) >= 0);
}
// advance juvenile stage (after transition rates have been applied)
for (int32_t stage = mat_max; stage > 0; stage--) {
grid->juveniles[row][col][stage] = grid->juveniles[row][col][stage - 1];
cats_dt_population juveniles_younger = get_juveniles(grid, row, col, stage - 1);
set_juveniles(grid, row, col, stage, juveniles_younger);
}
// youngest stage now empty
grid->juveniles[row][col][0] = 0;
set_juveniles(grid, row, col, 0, 0);
}
......
......@@ -54,21 +54,23 @@ juvenile_adult_transition(struct cats_grid *g, cats_dt_coord row, cats_dt_coord
// once the cell is full, we stop and juveniles have to wait at least until
// the next year to have a chance to mature
// FIXME check max age!
for (int32_t age = mat_max; age >= mat_min; age--) {
cats_dt_population juveniles = g->juveniles[row][col][age];
cats_dt_population juveniles = get_juveniles(g, row, col, age);
if (juveniles == 0) continue;
// the cell_maturation rate depends on the age -- the older the juvenile, the higher the probability to mature
cats_dt_rates maturation_rate = age_specific_maturation_rate(age, juvenile_survival_rate, mat_min,
mat_max);
cats_dt_population newly_matured = poisson_population_capped(ts->rng, (cats_dt_rates) juveniles *
maturation_rate,
juveniles);
newly_matured = min_population_t(newly_matured, space_left);
set_juveniles(g, row, col, age, juveniles - newly_matured);
g->juveniles[row][col][age] = juveniles - newly_matured;
assert(g->juveniles[row][col][age] >= 0);
assert(get_juveniles(g, row, col, age) >= 0);
newly_matured_sum += newly_matured;
space_left -= newly_matured;
......@@ -100,8 +102,7 @@ cell_maturation(struct cats_grid *grid, struct cats_thread_info *ts, cats_dt_coo
#else
if (__builtin_expect(cell_excluded_by_overlay(conf, row, col), false)) { return 0; }
#endif
if (grid->juveniles[row][col] == NULL) return 0;
if (juveniles_exist(grid, row, col) == false) return 0;
const int32_t mat_max = get_vital_age(grid, VA_AGE_OF_MATURITY_MAX);
const int32_t mat_min = get_vital_age(grid, VA_AGE_OF_MATURITY_MIN);
......
......@@ -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
......
......@@ -29,6 +29,7 @@
#include "data/cats_grid.h"
#include "inline_population.h"
#include "populations/population.h"
#include "misc/cats_maths_inline.h"
cats_dt_rates get_pollination_probability(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col,
......
......@@ -29,6 +29,7 @@
#include "seeds.h"
#include "inline_population.h"
#include "populations/population.h"
#include "inline_vital_ages.h"
#include <memory/cats_memory.h>
......@@ -39,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]
}
......@@ -92,19 +85,18 @@ inline
void
create_juvenile_structure_if_needed(struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col)
{
if (grid->juveniles[row][col]) return;
if (juveniles_exist(grid, row, col)) return;
const int32_t max_age_of_maturity = get_vital_age(grid, VA_AGE_OF_MATURITY_MAX);
grid->juveniles[row][col] = create_juvenile_structure(max_age_of_maturity);
grid->juveniles[row][col] = create_juvenile_structure(max_age_of_maturity); // initialisation [create_juvenile_structure_if_needed]
}
void destroy_juveniles(const struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col)
{
assert(grid != NULL);
assert(row >= 0 && row < grid->dimension.rows);
assert(col >= 0 && col < grid->dimension.cols);
assert(grid != NULL); // clean-up [destroy_juveniles]
assert(row >= 0 && row < grid->dimension.rows); // clean-up [destroy_juveniles]
assert(col >= 0 && col < grid->dimension.cols); // clean-up [destroy_juveniles]
assert(grid->juveniles != NULL);
......@@ -113,10 +105,10 @@ void destroy_juveniles(const struct cats_grid *grid, const cats_dt_coord row, co
const int32_t stages = max_age_of_maturity + 1;
assert(stages >= 0);
if (grid->juveniles[row] && grid->juveniles[row][col]) {
memset(grid->juveniles[row][col], 0, stages * sizeof(cats_dt_population));
free(grid->juveniles[row][col]);
grid->juveniles[row][col] = NULL;
if (grid->juveniles[row] && grid->juveniles[row][col]) { // clean-up [destroy_juveniles]
memset(grid->juveniles[row][col], 0, stages * sizeof(cats_dt_population)); // clean-up [destroy_juveniles]
free(grid->juveniles[row][col]); // clean-up [destroy_juveniles]
grid->juveniles[row][col] = NULL; // clean-up [destroy_juveniles]
}
}
......
......@@ -33,6 +33,8 @@
#include "inline_overlays.h"
#include "inline_population.h"
#include "populations/population.h"
#include "misc/cats_maths_inline.h"
#include "inline_vital_ages.h"
#ifdef USEMPI
#include "mpi/mpi_cats.h"
......@@ -85,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);
......@@ -122,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;
......@@ -165,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)
......@@ -195,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);
}
......@@ -240,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;
}