Skip to contents

marlin has a lot of features built into it to simulate dynamics over time. However, we cannot possibly build in every possible use case a researcher might have.

To that end, and important feature of marlin is that the outputs of a marlin simulation can be passed as the input to a marlin simulation. This means you can run the model for one time step, insert whatever whacky stuff you want to do, then run a new step.

As an example, we’ll do a very cartoonish version of a “management strategy evaluation”, where we

  1. Simulate a fishery for a time step

  2. Simulate a perfect stock assessment that tells us depletion (biomass / unfished biomass)

  3. Applies a harvest control rule that sets a catch quota based on the results of our assessment

  4. Run another time step with the supplied quota.

  5. Repeat process

library(marlin)

library(tidyverse)
#> ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
#>  dplyr     1.1.4      readr     2.1.5
#>  forcats   1.0.0      stringr   1.5.1
#>  ggplot2   3.5.1      tibble    3.2.1
#>  lubridate 1.9.3      tidyr     1.3.1
#>  purrr     1.0.2     
#> ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
#>  dplyr::filter() masks stats::filter()
#>  dplyr::lag()    masks stats::lag()
#>  Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

theme_set(theme_marlin(base_size = 14))

resolution <- 10 # resolution is in squared patches, so 20 implies a 20X20 system, i.e. 400 patches 

burn_years <- 20

seasons <- 4

sim_steps <- 20 * seasons


time_step <- 1 / seasons

fauna <- 
  list(
    "striped marlin" = create_critter(
      scientific_name = "Kajikia audax",
      adult_diffusion = 10,
      seasons = seasons,
      fished_depletion = 0.2,
      resolution = resolution,
      steepness = 0.6,
      ssb0 = 1000
    )
  )


fleets <- list(
  "longline" = create_fleet(
    list("striped marlin" = Metier$new(
        critter = fauna$`striped marlin`,
        price = 10,
        sel_form = "logistic",
        sel_start = 1,
        sel_delta = .01,
        catchability = 0,
        p_explt = 2
      )
    ),
    base_effort = resolution ^ 2,
    resolution = resolution,
    responsiveness = .5,
    cost_per_unit_effort = 1,
    fleet_model = "open access")
,
"handline" = create_fleet(
  list("striped marlin" = Metier$new(
    critter = fauna$`striped marlin`,
    price = 10,
    sel_form = "logistic",
    sel_start = 1,
    sel_delta = .01,
    catchability = 0,
    p_explt = 1
  )
  ),
  base_effort = resolution ^ 2,
  resolution = resolution,
  fleet_model = "constant effort"
))

fleets <- tune_fleets(fauna, fleets, tune_type = "depletion") 


hcr_cutoff <- 0.2

hcr_target <- 0.5

max_u <- 0.2

depletion <- seq(0,1, by= 0.1)

hcr_slope <- max_u / (hcr_target - hcr_cutoff)

hcr_intercept <- -hcr_slope * hcr_cutoff

hcr <- pmin(max_u,pmax(.01,hcr_slope * depletion + hcr_intercept))

hcr_frame <- data.frame(depletion = depletion, hcr = hcr)

hcr_frame %>% 
  ggplot(aes(depletion, hcr)) + 
  geom_line() + 
  scale_x_continuous(name = "B/B0") + 
  scale_y_continuous(name = "Fishing Mortality Rate")

mse_sim <- simmar(fauna = fauna,
                  fleets = fleets,
                  years = burn_years)

test <- process_marlin(mse_sim, keep_age = FALSE)

initial_conditions <- mse_sim[[length(mse_sim)]]

starting_step = marlin::clean_steps(last(names(mse_sim)))
  
for (y in 2:sim_steps){
  
  depletion <- purrr::map(mse_sim[[length(mse_sim)]], ~ sum(.x$ssb_p_a) / .x$ssb0)
  
  u <- map(depletion, ~  pmin(max_u,pmax(0.01,hcr_slope * .x + hcr_intercept)))
  
  quotas <- purrr::map2(mse_sim[[length(mse_sim)]], u, ~ sum(.x$ssb_p_a) * .y)
  
  next_step <- simmar(
  fauna = fauna,
  fleets = fleets,
  steps = 1,
  initial_conditions = initial_conditions,
  manager = list(quotas = quotas),
  starting_step = starting_step,
  keep_starting_step = FALSE
)

  initial_conditions <- next_step[[length(next_step)]]
  
  starting_step = marlin::clean_steps(last(names(next_step)))

  mse_sim <- append(mse_sim, next_step)
  
}


processed_mse_sim <- process_marlin(mse_sim)

a = processed_mse_sim$fauna |> 
  group_by(step, critter) |> 
  summarise(ssb = sum(ssb))
#> `summarise()` has grouped output by 'step'. You can override using the
#> `.groups` argument.

b = processed_mse_sim$fauna |> 
  group_by(step, critter) |> 
  summarise(c = sum(c))
#> `summarise()` has grouped output by 'step'. You can override using the
#> `.groups` argument.


plot_marlin(processed_mse_sim, plot_var = "c", max_scale = FALSE)


plot_marlin(processed_mse_sim, plot_var = "b", max_scale = FALSE)