Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nutrient intake #113

Closed
wants to merge 21 commits into from
Closed

Nutrient intake #113

wants to merge 21 commits into from

Conversation

evadelmas
Copy link
Collaborator

✨ New feature: Nutrient intake model

This PR includes some changes in the code architecture:

  • new producer_growth field in ModelParameters: this field contains the model for producer growth and the corresponding parameters. For now it can be one of either LogisticGrowth (with parameters K and α) or NutrientIntake (with all corresponding parameters)
  • argument K (carrying capacity) moved from environment to producer_growth
  • field producer_competition removed, α moved to producer_growth

@evadelmas
Copy link
Collaborator Author

evadelmas commented Feb 20, 2023

To do:

  • Remove K from environment
  • Fix the extinction callback
  • Resolve conflicts
  • Fix the existing tests
  • Add new tests
  • Document
  • Use case
  • House cleaning

.gitignore Outdated Show resolved Hide resolved
src/model/dbdt.jl Outdated Show resolved Hide resolved
src/model/simulate.jl Outdated Show resolved Hide resolved
@evadelmas
Copy link
Collaborator Author

evadelmas commented Feb 20, 2023

I just realized that the extinction callback needs to be adjusted to avoid monitoring nutrients (added to the todo list above).

Copy link
Collaborator

@iago-lito iago-lito left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @evadelmas and thank you for the PR :)

First off, there has been a small merge/rebasing glitch, but I think it's fixed now that your branch has been relocated to f14606c. One file seemed not to have benefited from the update: model_parameters.jl. The consequence is that producer_competition and temperature_dependence members of ModelParameters have been lost. But it's rather easy just to restore them. I have pointed the lines to restore in my comments below :)

The comments below are numerous, but don't trust the number: most of them are only small style edit suggestions. Also, some are repeated on every occurence of the same problem just to make sure we don't forget one. Also again, I have written them on-the-fly as I read, so a few early ones may be invalidated by later ones.

Some raise deeper topics, which I stress now in this summary:

  • The feature you are implementing here constitutes a strong extension to the semantics of the variables passed to solve(..), because B does not contain only biomasses now, but both biomasses and nutrients. As consequences, I think that:

    • B needs to be renamed to something more generic. But we can delay that until the upcoming big renaming pass (Refresh identifiers names. #114).

    • B[5:8] or solution[:, 5:8] becomes rather unsafe to do for users because we are not featuring some direct index ↦ species mapping anymore. I suggest that helper functions be written then like get_species(solution, 5:8) and get_nutrients(solution, 2:3), to dissociate species/nutrients indexes from simulation variables indexes. (see former discussion on this topic there with @alaindanet)

  • If I understand correctly. "Nutrient dynamics", as a feature, encompasses both "producers competition" and former "logistic growth".

    • Regarding "producers competition", we need to decide what to do with @alaindanet's former files, especially producers_competition.jl. FWIU this PR copies some of his code into producer_growth.jl, but the original copy remains there and I think it's unused now. Also the parameter α is now duplicated within ModelParameters. I am not confident that its eventual location should be either ModelParameters.producers_competition.α or ModelParameters.producer_growth.α, because I think α will soon have "friends" and that they should all live in MultiplexNetwork. See Edges between species actually carry *data*. #82 about that. As a consequence, I think it's not a big deal where exactly α lives in the context of this PR, but it should be only one place, and we should not rely on it being there for long.

    • Regarding "logistic growth", we need to decide what to do with the file productivity.jl, because I think it's now unused in the context of this PR. I see no problem with it being removed entirely, but we can't exactly do this yet because it still contains some boost code. I was not happy with the boost code being scattered throughout the project anyway, and I was planning on gathering it all into only a few files in the future. So maybe you can only delete non-boost-related functions within productivity.jl in the meantime.

And this is all about the deep issues to address :) I otherwise think the overall design of this PR is good, with a clear specification what the new producer_growth field does and a straightforward implementation of the nutrient dynamics. As you wrote, a few docstrings are missing yet. And the tests also do not pass. I believe it's a big step to get into updating them to feature nutrient dynamics, so keep up with the good work then :)

.vscode/settings.json Show resolved Hide resolved
src/model/dbdt.jl Outdated Show resolved Hide resolved
src/model/dbdt.jl Outdated Show resolved Hide resolved
src/model/dbdt.jl Outdated Show resolved Hide resolved
src/model/dbdt.jl Outdated Show resolved Hide resolved
"""
LogisticGrowth(B, i, j)
"""
function (F::LogisticGrowth)(i, B, r, network::MultiplexNetwork, N = nothing)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

N = 0 ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, unless we need to disambiguate two corner cases that I have been (perhaps erroneously) identifiying so far: if a model uses logistic growth, then there are no nutrients variables. Okay. But would it make sense that a model uses nutrients intake with no nutrient variables? In other terms, would there be any use in doing:

NutrientIntake(foodweb; n=0)

, which would still be different from LogisticGrowth(foodweb), or would it make no sense?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used nothing because there are no nutrients in the logistic model, it's just here because I needed the two functions (LogisticGrowth and NutrientIntake) to have the same arguments.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, interesting.. is it because you are using them later with some sort of macro or meta-programming approach?

function logisticgrowth(B, r, K, s)
!isnothing(K) || return 0
r * B * (1 - s / K)
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so IIUC these functions predate the content of file src/model/productivity.jl, righ? It would make sense that this file be deleted in the context of this PR then.. but now productivity.jl also contains boost-related code. I was intending to move that code elsewhere though. So I guess I can handle that when refactoring the boost later?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's safe to remove productivity.jl - will do it in the next session

src/inputs/producer_growth.jl Outdated Show resolved Hide resolved
nutrientintake(B[i], r[i], F.Kₗᵢ[i,:], N)
end
function nutrientintake(B, r, K, N)
!all(isnothing.(K)) || return 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all(isnothing.(K)) && return 0

function nutrientintake(B, r, K, N)
!all(isnothing.(K)) || return 0
G_li = N ./ (K .+ N)
minG = minimum(G_li)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that's an interesting logic :) I guess you'll cite the paper in the docstring once you write it?

@iago-lito
Copy link
Collaborator

Wops, sorry @evadelmas I did not realize that you issued comments here before I finished my review. I'm addressing them rn :)

D::Real = 0.25,
Sₗ::Union{Vector{<:Float64},<:Real} = repeat([10.0], n),
Cₗᵢ::Union{SparseMatrixCSC{<:Float64}, Vector{<:Float64}, Matrix{<:Float64}} = [range(1, 0.5, length = n);],
Kₗᵢ::Union{Matrix{Union{Nothing,<:Real}}, <:Real} = 1.0)
Copy link
Contributor

@alaindanet alaindanet Feb 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be we should find a less ambiguous name for half saturation rates $K_{ii}$, which is very similar to carrying capacity $K_i$ ?

I saw alternative notation like $Km_{ii}$ ($m$ for Michaelis-Menten) or $Ks_{ii}$ ($s$ for saturation). Another alternative could to have smallcase K, $k_{ii}$ as now we have $C_{ii}$ for nutrient and $c$ for consumer interference (may be still too ambiguous).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch here @alaindanet! Maybe it's a discussion worth moving to #114? I think an effort to harmonize all names at once, and in particular single-letter names, will be very helpful to not eventually get drowned under short notations ^ ^"

Kickoff starter discussion #98.

Regarding this particular $K$ here, I suggest we don't have this discussion yet within the context of this PR, and leave the name as-is for now so as to not make the PR harder to land. Would you both be okay to delay the renaming until #114 is properly addressed?

@iago-lito
Copy link
Collaborator

This feature continues in #124.

@iago-lito
Copy link
Collaborator

Closed by #124.

@iago-lito iago-lito closed this Jun 27, 2023
@iago-lito iago-lito deleted the nutrient_intake branch March 12, 2024 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants