Commit 628eee5d authored by Sævik Pål Næverlid's avatar Sævik Pål Næverlid
Browse files

Merge branch 'feature/lakselus'

parents ac7199b4 0d101236
......@@ -41,10 +41,12 @@ subpackage folders.
1. Copy `ladim.yaml` and `particle.rls` from the IBM subpackage of interest
into the working directory.
2. If the `pip` installation step was skipped, the `ibm.py` module must be
2. Make desired changes to the `yaml` and `rls` files. More detailed
instructions are found in the `README.md` file within the subpackage.
3. If the `pip` installation step was skipped, the `ibm.py` module must be
copied as well, and the `ibm.module` entry in `ladim.yaml` must be changed
to `"ibm"`.
3. Run `ladim` and the output is written to `out.nc`.
4. Run `ladim` and the output is written to `out.nc`.
## Add new IBMs
......
# Salmon lice
The module represents salmon lice having a vertical swimming behaviour due to
ambient light and salt conditions.
The model is based on a number of scientific works on salmon lice behaviour, including
- [Author et al. (2011)](http://dx.doi.org/doicode_here)
- New salinity model: [Author et al. (2011)](http://dx.doi.org/doicode_here)
## Usage
Modify `ladim.yaml` and `particles.rls` to suit your needs.
Common changes applied to `ladim.yaml`:
- Start date of simulation (`time_control.start_time`)
- Stop date of simulation (`time_control.stop_time`)
- Forcing input file (`gridforce.input_file`)
- Vertical diffusion parameter (`ibm.vertical_mixing`)
- Horizontal diffusion parameter (`numerics.diffusion`)
- Time step length (`numerics.dt`)
- Output frequency (`output_variables.outper`)
- Salinity model (`ibm.salinity_model`)
The file `particles.rls` is a tab-delimited text file containing particle
release time and location, as well as particle attributes at the release time.
The order of the columns is given by the entry `particle_release.variables`
within `ladim.yaml`.
Finally, copy `ladim.yaml` and `particles.rls` to a separate directory and
run `ladim` here.
## Output
The simulation result is stored in a file specified by the `files.output_file`
entry in `ladim.yaml`. The output variables are specified by the
`output_variables` entries.
## Real-world example
An example of configuration file and release file used in a real scenario is
provided by `anne2019_ladim.yaml` and `anne2019_particles.rls`.
This diff is collapsed.
# Configuration file salmon lice model using ROMS output
#
time_control:
# Start and stop of simulation
start_time: 2019-03-02 00:00:00
stop_time: 2019-07-16 00:00:00
# Reference time for netcdf output
# by default set to start_time
# can be overridden explicitly
reference_time: 2000-01-01
files:
grid_file : /gpfs/gpfs0/osea/jonal/NorKyst-800m_Lus/his/2019/norkyst_800m_his.nc4_2019052301-2019052400
input_file : /gpfs/gpfs0/osea/jonal/NorKyst-800m_Lus/his/2019/norkyst_800m_his.nc4_*
particle_release_file : ./lice_2019.rls
output_file : /gpfs/gpfs0/osea/Arkiv_V2/Raw2019/raw_0000.nc
gridforce:
# Format = [i0, i1, j0, j1]
# subgrid: [0, -1, 0, -1]
# mapping: model name -> name in input file
# velocity: {U: u, V: v}
module: ladim.gridforce.ROMS
ibm_forcing: {temp: temp, salt: salt}
# grid arguments
#grid:
# subgrid: [1, 600, 1, 775]
# Samle IBM-variablene her
ibm:
# IBM-module, omit or '' for no IBM
ibm_module: ibm_lice_annesalt
state:
# pid, X, Y, Z are mandatory and should not be given
# Ingen, kan bruke [] eller kutte linjen
ibm_variables: [super, age, days, temp, salt]
#warm_start_variables: [X, Y, Z, super, age]
particle_release:
release_type: continuous
release_frequency: [1, h]
variables: [mult, release_time, X, Y, Z, farmid, super]
# Converters (if not float)
mult: int
release_time: time
farmid: int
particle_variables: [release_time, farmid]
output_variables:
# Output period, format [value, unit], unit = s, m, h, or d
outper: [1, h]
# Split fil, daglig
numrec: 24
# Variable names
particle: [release_time, farmid]
instance: [pid, X, Y, Z, super, age, days, temp, salt]
# NetCDF arguments
release_time:
ncformat: f8
long_name: particle release time
units: seconds since reference_time
# Faa til template over
farmid: {ncformat: i4, long_name: fish farm location number}
pid: {ncformat: i4, long_name: particle identifier}
X: {ncformat: f4, long_name: particle X-coordinate}
Y: {ncformat: f4, long_name: particle Y-coordinate}
Z:
ncformat: f4
long_name: particle depth
standard_name: depth_below_surface
units: m
positive: down
age:
ncformat: f4
long_name: particle age in degree-days
units: Celcius days
standard_name: integral_of_sea_water_temperature_wrt_time
super: {ncformat: f4, long_name: number of individuals in instance}
temp:
ncformat: f4,
long_name: temperature,
standard_name: sea_water_temperature,
units: Celcius
salt:
ncformat: f4,
long_name: salinity,
standard_name: sea_water_salinity,
days: {ncformat: f4, long_name: Days after haching}
numerics:
# Model time step, [value, unit]
dt: [600, s]
# Advection method: options =
# EF = Euler-Forward,
# RK2, RK4 = Runge-Kutta 2nd or 4th order
advection: RK4
# Horizontal diffusion coefficient [m2.s-1]
# zero = no diffusion
diffusion: 1.0
import numpy as np
from ladim.ibms import light
class IBM:
def __init__(self, config):
# Constants
mortality = 0.17 # [days-1]
# mm2m = 0.001
# g = 9.81
# tempB = 7.0 # set default temperature
self.k = 0.2 # Light extinction coefficient
self.swim_vel = 5e-4 # m/s
self.D = config["ibm"].get('vertical_mixing', 1e-3) # Vertical mixing [m*2/s]
self.vertical_diffusion = self.D > 0
self.dt = config["dt"]
self.mortality_factor = np.exp(-mortality * self.dt / 86400)
salinity_model = config["ibm"].get('salinity_model', 'new')
self.new_salinity_model = (salinity_model == 'new')
def update_ibm(self, grid, state, forcing):
# Mortality
state.super *= self.mortality_factor
# Update forcing
state.temp = forcing.field(state.X, state.Y, state.Z, "temp")
state.salt = forcing.field(state.X, state.Y, state.Z, "salt")
# Age in degree-days
state.age += state.temp * state.dt / 86400
state.days += 1.0*(state.dt/86400)
# Light at depth
lon, lat = grid.lonlat(state.X, state.Y)
light0 = light.surface_light(state.timestamp, lon, lat)
Eb = light0 * np.exp(-self.k * state.Z)
# Swimming velocity
W = np.zeros_like(state.X)
# Upwards if light enough (decreasing depth)
W[Eb >= 0.01] = -self.swim_vel
if self.new_salinity_model:
# Mixture of down/up if salinity between 23 and 31
# Downwards if salinity < 31
salt_limit = np.random.uniform(23, 31, W.shape)
else:
# Downwards if salinity < 20
salt_limit = 20
W[state.salt < salt_limit] = self.swim_vel
# Random diffusion velocity
if self.vertical_diffusion:
rand = np.random.normal(size=len(W))
W += rand * (2 * self.D / self.dt) ** 0.5
# Update vertical position, using reflexive boundary condition at the top
state.Z += W * self.dt
state.Z[state.Z < 0] *= -1
# For z-version, do not go below 20 m
state.Z[state.Z >= 20.0] = 19.0
# Mark particles older than 200 degree days as dead
state.alive = state.alive & (state.age < 200)
time_control:
# Start and stop of simulation
start_time : 2015-09-07 04:00:00
stop_time : 2015-09-07 04:05:00
reference_time : 2000-01-01 04:00:00
files:
particle_release_file : particles.rls
output_file : out.nc
gridforce:
module: ladim.gridforce.ROMS
input_file: forcing.nc # Use wildcards (*) to select a range of files
ibm_forcing:
temp: temp
salt: salt
ibm:
module: ladim_ibm.salmon_lice
variables:
- super # Number of actual salmon lice per simulation particle
- age # Age of particle [degree*days]
- days # Age of particle [days]
- temp # Particle ambient temperature [Celcius]
- salt # Particle ambient salinity [1]
salinity_model: new # 'old' or 'new'
vertical_mixing: 0.001 # [m^2/s]
particle_release:
release_type: continuous
release_frequency: [60, s] # Normally: [1, h]
variables:
- mult # Number of particles released
- release_time # Time of release, formatted as yyyy-mm-ddThh:mm:ss
- X # X coordinate of release location
- Y # Y coordinate of release location
- Z # Depth of release location
- farmid # Custom id used to group particles in post processing
- super # Number of actual salmon lice per simulation particle
# Converters (if not float)
mult: int
release_time: time
farmid: int
particle_variables: [release_time, farmid]
output_variables:
# Output period, format [value, unit], unit = s, m, h, or d
outper: [60, s] # Normally: [1, h]
# Uncomment the entry below to split output file into daily files
# numrec: 24
# Variable names
particle: [release_time, farmid]
instance: [pid, X, Y, Z, super, age, days, temp, salt]
# --- Output format for standard variables ---
release_time:
ncformat: f8
long_name: particle release time
units: seconds since reference_time
pid:
ncformat: i4
long_name: particle identifier
X:
ncformat: f4
long_name: particle X-coordinate
Y:
ncformat: f4
long_name: particle Y-coordinate
Z:
ncformat: f4
long_name: particle depth
standard_name: depth_below_surface
units: m
positive: down
# --- Output format for IBM-specific variables ---
temp:
ncformat: f4
long_name: temperature
standard_name: sea_water_temperature
units: Celcius
farmid:
ncformat: i4
long_name: fish farm location number
age:
ncformat: f4
long_name: particle age in degree-days
units: Celcius days
standard_name: integral_of_sea_water_temperature_wrt_time
super:
ncformat: f4
long_name: number of individuals in instance
salt:
ncformat: f4
long_name: salinity
standard_name: sea_water_salinity
days:
ncformat: f4
long_name: Days after haching
units: days
numerics:
# Model time step, [value, unit]
dt: [60, s] # usually 120 on 160m NorFjords, 600 NorKyst, 1800 SVIM
advection: RK4 # either EF, RK2 or RK4 (recommended)
diffusion: 1.0 # [m*2/s]
1 2015-09-07T04:00:00 3 4 0 11111 4000
2 2015-09-07T04:00:00 4 5 10 22222 2000
1 2015-09-07T04:00:00 5 6 20 33333 1000
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment