From 7e7169268e78d0aa9fbd2302df8330ce21a6df6f Mon Sep 17 00:00:00 2001 From: "Troy Frever, NOAA Affiliate" Date: Mon, 16 Dec 2024 17:32:17 -0800 Subject: [PATCH] read 'habitatTypeExitConditionHours' for configurable consecutive Nearshore hours to exit (#13) * use number of consecutive nearshore hours for exit criteria * read 'habitatTypeExitConditionHours' from config file * defaults to 2 hours if not found in config file --- .idea/Skagit-IBM2.iml | 2 ++ .idea/modules.xml | 8 -------- run6_config/config_map_2013_data_2014.json | 3 ++- src/fish.cpp | 18 +++++++++++++----- src/fish.h | 5 +++++ src/model.cpp | 7 +++++++ src/model.h | 6 +++++- 7 files changed, 34 insertions(+), 15 deletions(-) create mode 100644 .idea/Skagit-IBM2.iml delete mode 100644 .idea/modules.xml diff --git a/.idea/Skagit-IBM2.iml b/.idea/Skagit-IBM2.iml new file mode 100644 index 0000000..771e54c --- /dev/null +++ b/.idea/Skagit-IBM2.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index f694079..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/run6_config/config_map_2013_data_2014.json b/run6_config/config_map_2013_data_2014.json index 5a386d7..ae074fc 100644 --- a/run6_config/config_map_2013_data_2014.json +++ b/run6_config/config_map_2013_data_2014.json @@ -15,5 +15,6 @@ "flowSpeedFile": "data/mod_flow_condensed.nc", "distribWseTempFile": "data/wse.temp.full.nc", "threadCount": 96, - "blindChannelSimplificationRadius": 15.0 + "blindChannelSimplificationRadius": 15.0, + "habitatTypeExitConditionHours": 6.0 } diff --git a/src/fish.cpp b/src/fish.cpp index 1167cfd..763055d 100644 --- a/src/fish.cpp +++ b/src/fish.cpp @@ -64,7 +64,8 @@ inline float forkLengthFromMass(float mass) { // This is a sustained swim speed const float SWIM_SPEED_BODY_LENGTHS_PER_SEC = 2.0f; -const float SECONDS_PER_TIMESTEP = 60.0f*60.0f; +constexpr float HOURS_PER_TIMESTEP = 1.0f; +constexpr float SECONDS_PER_TIMESTEP = HOURS_PER_TIMESTEP * 60.0f*60.0f; // Calculate a sustained-movement swim range (in m) from a fork length (in mm) inline float swimSpeedFromForkLength(float forkLength) { @@ -89,6 +90,7 @@ Fish::Fish( travel(0), status(FishStatus::Alive), exitStatus(FishStatus::Alive), + numExitHabitatHours(0), lastGrowth(0), lastPmax(0), lastMortality(0), @@ -351,6 +353,9 @@ float Fish::getFitness(Model &model, MapNode &loc, float cost) { return this->getGrowth(model, loc, cost) / this->getMortality(model, loc); } +void Fish::incrementExitHabitatHoursByOneTimestep() { + this->numExitHabitatHours += HOURS_PER_TIMESTEP; +} /* * Perform the movement simulation for this fish @@ -435,7 +440,6 @@ bool Fish::move(Model &model) { break; } } - MapNode *oldLocation = this->location; this->location = point; this->travel = cost; @@ -444,12 +448,16 @@ bool Fish::move(Model &model) { this->locationHistory->push_back(this->location->id); } - if (oldLocation->type == HabitatType::Nearshore && this->location->type == HabitatType::Nearshore) { - // Exit if at nearshore (TODO verify this behavior) + if (this->location->type == HabitatType::Nearshore) { + this->incrementExitHabitatHoursByOneTimestep(); + } else { + this->numExitHabitatHours = 0; + } + if (this->numExitHabitatHours >= model.habitatTypeExitConditionHours) { this->exit(model); return false; } - + /* // simplistic approach to exiting fish when they reach 75mm length or less than 30 if (this->forkLength >= 75 || this->forkLength < 30) { diff --git a/src/fish.h b/src/fish.h index 31c27f1..e8bc58d 100644 --- a/src/fish.h +++ b/src/fish.h @@ -47,6 +47,8 @@ class Fish { FishStatus status; // status on model exit; only used for keeping track of fish replays FishStatus exitStatus; + //number of hours currently spent in an exit habitat (Nearshore) + float numExitHabitatHours; // last timestep's growth (g) and Pmax float lastGrowth; float lastPmax; @@ -88,6 +90,9 @@ class Fish { * probability of arriving at the location */ void getDestinationProbs(Model &model, std::unordered_map &out); + // increment the number of hours in an exit habitat + void incrementExitHabitatHoursByOneTimestep(); + /* * Run this fish's movement update: * Get all reachable nodes and their costs, diff --git a/src/model.cpp b/src/model.cpp index 517336c..3829c36 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -18,6 +18,7 @@ // default mortality constants constexpr float MORT_CONST_C = 0.03096; constexpr float MORT_CONST_A = -0.42; +constexpr float DEFAULT_EXIT_CONDITION_HOURS = 2.0; /* * Constructs a model instance from parameters and data filenames. @@ -46,6 +47,7 @@ Model::Model( std::string recSizeDistsFilename, // List of map node IDs where new recruits enter the model std::vector recPointIds, + float habitatTypeExitConditionHours, // Path of the file containing map node descriptions (area, habitat type, elevation, among other columns) std::string mapLocationFilename, // Path of the file containing map edge descriptions (source and target nodes, path lengths, among other columns) @@ -74,6 +76,7 @@ Model::Model( exitedCount(0), mortConstA(MORT_CONST_A), mortConstC(MORT_CONST_C), + habitatTypeExitConditionHours(habitatTypeExitConditionHours), nextFishID(0UL), maxThreads(maxThreads), recruitTagRate(0.5f) @@ -127,6 +130,7 @@ Model::Model( exitedCount(0), mortConstA(MORT_CONST_A), mortConstC(MORT_CONST_C), + habitatTypeExitConditionHours(DEFAULT_EXIT_CONDITION_HOURS), nextFishID(0UL), maxThreads(maxThreads), recruitTagRate(0.5f) @@ -1083,6 +1087,9 @@ Model *modelFromConfig(std::string configPath) { std::string(d["recruitCountsFile"].GetString()), std::string(d["recruitSizesFile"].GetString()), recPoints, + d.HasMember("habitatTypeExitConditionHours") + ? d["habitatTypeExitConditionHours"].GetFloat() + : DEFAULT_EXIT_CONDITION_HOURS, std::string(d["mapNodesFile"].GetString()), std::string(d["mapEdgesFile"].GetString()), std::string(d["mapGeometryFile"].GetString()), diff --git a/src/model.h b/src/model.h index 0ea98c1..5e7294b 100644 --- a/src/model.h +++ b/src/model.h @@ -88,6 +88,10 @@ class Model { // Mortality constants overridden by ABC float mortConstA; float mortConstC; + + // number of consecutive Nearshore hours to satisfy exit condition + float habitatTypeExitConditionHours; + Model( int globalTimeIntercept, int hydroTimeIntercept, @@ -96,6 +100,7 @@ class Model { std::string recCountFilename, std::string recSizeDistsFilename, std::vector recPointIds, + float habitatTypeExitConditionHours, std::string mapLocationFilename, std::string mapEdgeFilename, std::string mapGeometryFilename, @@ -171,7 +176,6 @@ class Model { unsigned long nextFishID; size_t maxThreads; float recruitTagRate; - }; #define __FISH_MODEL_CLS