Commit 86efa21a authored by Poulet Camille's avatar Poulet Camille
Browse files

Merge branch 'develop' of gitlab-ssh.irstea.fr:SimAquaLife/GR3D into exploration_GR3D_process

parents 184dd5b8 c697a18b
......@@ -289,6 +289,7 @@
<tempMinRep>10</tempMinRep>
<tempOptRep>17</tempOptRep>
<tempMaxRep>30</tempMaxRep>
<Soffset>-1.0</Soffset>
<eta>2.4</eta>
<ratioS95__S50>1.9</ratioS95__S50>
<a>270000</a>
......
......@@ -296,12 +296,13 @@
<minimumRecruitsForPopulatedBasin>50</minimumRecruitsForPopulatedBasin>
</analysis.AnalyseFishDistribution>
<species.ReproduceAndSurviveAfterReproductionWithDiagnose>
<species.ReproduceWithDiagnose>
<synchronisationMode>ASYNCHRONOUS</synchronisationMode>
<reproductionSeason>SPRING</reproductionSeason>
<tempMinRep>10</tempMinRep>
<tempOptRep>17</tempOptRep>
<tempMaxRep>30</tempMaxRep>
<Soffset>-1.0</Soffset>
<eta>2.4</eta>
<ratioS95__S50>1.9</ratioS95__S50>
<a>270000</a>
......@@ -311,13 +312,17 @@
<proportionOfFemaleAtBirth>0.5</proportionOfFemaleAtBirth>
<initialLength>2.8</initialLength>
<sigmaRecruitment>0.2</sigmaRecruitment>
<survivalRateAfterReproduction>0.1</survivalRateAfterReproduction>
<maxNumberOfSuperIndividualPerReproduction>100.0
</maxNumberOfSuperIndividualPerReproduction>
<withDiagnose>false</withDiagnose>
<displayFluxesOnConsole>false</displayFluxesOnConsole>
</species.ReproduceAndSurviveAfterReproductionWithDiagnose>
</species.ReproduceWithDiagnose>
<species.SurviveAfterReproduction>
<synchronisationMode>ASYNCHRONOUS</synchronisationMode>
<afterReproductionSeason>SPRING</afterReproductionSeason>
<survivalRateAfterReproduction>0.1</survivalRateAfterReproduction>
</species.SurviveAfterReproduction>
<species.MigrateFromRiverToInshore>
<synchronisationMode>ASYNCHRONOUS</synchronisationMode>
......
......@@ -185,6 +185,13 @@ modifiedMasterReaction = function(temperature, par){
return(rate)
}
# DeucthEtal
# Deutsch, Curtis A., Joshua J. Tewksbury, Raymond B. Huey, Kimberly S. Sheldon, Cameron K. Ghalambor, David C. Haak, et Paul R. Martin. « Impacts of Climate Warming on Terrestrial Ectotherms across Latitude ». Proceedings of the National Academy of Sciences 105, nᵒ 18 (5 juin 2008): 6668‑72. https://doi.org/10.1073/pnas.0709472105.
# Huey, Raymond B., et R. D. Stevenson. « Integrating Thermal Physiology and Ecology of Ectotherms: A Discussion of Approaches ». American Zoologist 19, nᵒ 1 (1 février 1979): 357‑66. https://doi.org/10.1093/icb/19.1.357.
# Payne, Nicholas L., James A. Smith, Dylan E. van der Meulen, Matthew D. Taylor, Yuuki Y. Watanabe, Akinori Takahashi, Teagan A. Marzullo, Charles A. Gray, Gwenael Cadiou, et Iain M. Suthers. « Temperature Dependence of Fish Performance in the Wild: Links with Species Biogeography and Physiological Thermal Tolerance ». Functional Ecology 30, nᵒ 6 (2016): 903‑12. https://doi.org/10.1111/1365-2435.12618.
temperature = seq(0,100,.1)
plot(temperature, modifiedMasterReaction(temperature, par = c(48.6, 49.7, 388, 1)), type = 'l', ylab = 'rate', main = "modifiedMasterReaction",
......@@ -250,3 +257,17 @@ plot(temperature, modifiedThorntonLessem(temperature, par = c(Tmin, 14, 27, Tmax
temperature[which.max(modifiedThorntonLessem(temperature, par = c(Tmin, 14, 27, Tmax)))]
lines(temperature, modifiedLehman(temperature, par = c(Tmin, 21.3, Tmax)), col = 'red')
StrabakaGnauck = function(temperature, par){
# in Lefrançois, C., et G. Claireaux (2003). Influence of Ambient Oxygenation and Temperature on Metabolic Scope and
# Scope for Heart Rate in the Common Sole Solea Solea. Marine Ecology Progress Series 259 : 273‑84.
Topt = par[1]
Tmax = par[2]
omega = par[3]
rate = ((Tmax - temperature) / (Tmax - Topt))^omega * exp(-omega * (Tmax - temperature) / (Tmax - Topt) )
return(rate)
}
plot(temperature, StrabakaGnauck(temperature, par = c(19.74, 30.48, 1.87)))
\ No newline at end of file
......@@ -47,10 +47,11 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG
private double tempOptRep = 20.;
private double eta = 2.4; // parameter linking surface of a basin and S_etoile
private double ratioS95_S50 = 2.;
private double Soffset = -1.;
private double a = 270000.; // Parameter of fecndity (number of eggs per individual) Modifié depuis la valeur
// initial de tHibault, qui était 135000
// initial de tHibault, qui était 135000
private double delta_t = 0.33; // duration of the mortality considered in the reproduction process (ex.: from eggs
// to juvenile in estuary for alosa alosa = 0.33)
// to juvenile in estuary for alosa alosa = 0.33)
private double survOptRep = 0.0017;
private double lambda = 0.00041;
private double initialLength = 2.;
......@@ -95,6 +96,9 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG
mortalityFunction = new MortalityFunction();
stockRecruitmentRelationship = new StockRecruitmentRelationship();
if (Double.isNaN(Soffset))
Soffset = -1.;
}
......@@ -195,10 +199,13 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG
amountPerSuperIndividual = alpha / maxNumberOfSuperIndividualPerReproduction;
// Compute the Allee effect parameters S95 and S50
S95 = eta * riverBasin.getAccessibleSurface(); // corresponds to S* in the rougier publication
S50 = S95 / ratioS95_S50;
if (Soffset >= 0.) {
S95 = Soffset;
S50 = Soffset;
} else {
S95 = eta * riverBasin.getAccessibleSurface(); // corresponds to S* in the rougier publication
S50 = S95 / ratioS95_S50;
}
// initilisation of the stock recruitment relationship
stockRecruitmentRelationship.init(alpha, beta, S50, S95);
......@@ -223,7 +230,7 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG
// System.out.println(fish.getAge() + " -> "+ fish.getLength() + "
// ("+fish.getStage()+")");
numberOfFemaleSpawners += fish.getAmount(); // on ajoute a chaque fois le fish.getAmount
// (CcumSum)
// (CcumSum)
if (fish.getNumberOfReproduction() < 1) {
numberOfFemaleSpawnerForFirstTime += fish.getAmount();
femaleSpawnersForFirstTimeAgesSum += fish.getAge() * fish.getAmount();
......@@ -231,7 +238,7 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG
}
} else if (fish.getGender() == Gender.MALE) {
numberOfMaleSpawners += fish.getAmount(); // on ajoute a chaque fois le fish.getAmount
// (CcumSum)
// (CcumSum)
if (fish.getNumberOfReproduction() < 1) {
numberOfMaleSpawnerForFirstTime += fish.getAmount();
maleSpawnersForFirstTimeAgesSum += fish.getAge() * fish.getAmount();
......@@ -657,7 +664,11 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG
public double getEffectiveStock(double stock) {
return stock / (1 + Math.exp(-log19 * (stock - S50) / (S95 - S50)));
if (S50 == S95) // catchment size independant Allee effect (including no Allee effect when S95 = 0)
return (stock < S95 ? 0. : stock);
else // catchment size dependant Allee effect
return stock / (1 + Math.exp(-log19 * (stock - S50) / (S95 - S50)));
}
......
This diff is collapsed.
package species;
import java.util.Hashtable;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import org.openide.util.lookup.ServiceProvider;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import environment.RiverBasin;
import environment.Time;
import environment.Time.Season;
import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess;
import fr.cemagref.simaqualife.kernel.util.TransientParameters.InitTransientParameters;
import fr.cemagref.simaqualife.pilot.Pilot;
import miscellaneous.BinomialForSuperIndividualGen;
import species.DiadromousFish.SpawnerOrigin;
import umontreal.iro.lecuyer.probdist.NormalDist;
import umontreal.iro.lecuyer.randvar.NormalGen;
@ServiceProvider(service = AquaNismsGroupProcess.class)
public class SurviveAfterReproduction extends AquaNismsGroupProcess<DiadromousFish, DiadromousFishGroup> {
private Season afterReproductionSeason = Season.SUMMER;
private double survivalRateAfterReproduction = 0.1;
private transient NormalGen genNormal;
/**
* the random numbers generator for binomial draws
*
* @unit --
*/
private transient BinomialForSuperIndividualGen aleaGen;
public static void main(String[] args) {
System.out.println((new XStream(new DomDriver())).toXML(new SurviveAfterReproduction()));
}
@Override
@InitTransientParameters
public void initTransientParameters(Pilot pilot) {
super.initTransientParameters(pilot);
genNormal = new NormalGen(pilot.getRandomStream(), new NormalDist(0., 1.));
aleaGen = new BinomialForSuperIndividualGen(pilot.getRandomStream());
}
@Override
public void doProcess(DiadromousFishGroup group) {
Time time = group.getEnvironment().getTime();
if (time.getSeason(group.getPilot()) == afterReproductionSeason) {
for (RiverBasin riverBasin : group.getEnvironment().getRiverBasins()) {
long survivalAmount;
List<DiadromousFish> fishInBasin = riverBasin.getFishs(group);
if (fishInBasin != null) {
// Initiate the total fluxes for this basin
Map<SpawnerOrigin, Map<String, Double>> totalInputFluxes = new Hashtable<SpawnerOrigin, Map<String, Double>>(); // On
totalInputFluxes.put(SpawnerOrigin.AUTOCHTONOUS, new Hashtable<String, Double>());
totalInputFluxes.put(SpawnerOrigin.ALLOCHTONOUS, new Hashtable<String, Double>());
for (SpawnerOrigin origin : totalInputFluxes.keySet()) {
for (String nutrient : group.getNutrientRoutine().getNutrientsOfInterest()) {
totalInputFluxes.get(origin).put(nutrient, 0.); // ON MET A JOUR NOTRE map
}
totalInputFluxes.get(origin).put("biomass", 0.);
}
// iterate on the fish
ListIterator<DiadromousFish> fishIterator = fishInBasin.listIterator();
while (fishIterator.hasNext()) {
DiadromousFish fish = fishIterator.next();
if (fish.isMature()) {
// origin of the spwaner
SpawnerOrigin spawnerOrigin = (fish.getBirthBasin() == riverBasin ? SpawnerOrigin.AUTOCHTONOUS
: SpawnerOrigin.ALLOCHTONOUS);
// survival amount of fish
double biomass = 0.;
survivalAmount = aleaGen.getSuccessNumber(fish.getAmount(), survivalRateAfterReproduction);
// at least one fish in the SI survive, the other die
if (survivalAmount > 0) {
// ---------------------------------------------------------- start of nutrient routine
// nutrient fluxes for one fish surviving after spawning (fish.getAmount):
// excretion + gametes
Map<String, Double> aFluxAfterSurvival = group.getNutrientRoutine()
.computeNutrientsInputForSurvivalAfterSpawning(fish);
// nutrient fluxes for one fish dying after spawning (fish.getAmount):
// carcasses + excretion + gametes
Map<String, Double> aFluxForDeadFish = group.getNutrientRoutine()
.computeNutrientsInputForDeathAfterSpawning(fish);
for (String nutrient : aFluxAfterSurvival.keySet()) {
// For all survival fish in the SI
group.getNutrientRoutine().getNutrientImportFluxesCollection().put(
time.getYear(group.getPilot()), nutrient, fish.getBirthBasin().getName(),
riverBasin.getName(), aFluxAfterSurvival.get(nutrient) * survivalAmount);
// For all dead fish in the SI
group.getNutrientRoutine().getNutrientImportFluxesCollection().put(
time.getYear(group.getPilot()), nutrient, fish.getBirthBasin().getName(),
riverBasin.getName(),
aFluxForDeadFish.get(nutrient) * (fish.getAmount() - survivalAmount));
}
// take into account the fish origine
for (String nutrient : aFluxAfterSurvival.keySet()) {
// For all survival fish
totalInputFluxes.get(spawnerOrigin).put(nutrient,
totalInputFluxes.get(spawnerOrigin).get(nutrient)
+ aFluxAfterSurvival.get(nutrient) * survivalAmount);
// For all dead fish
totalInputFluxes.get(spawnerOrigin).put(nutrient,
totalInputFluxes.get(spawnerOrigin).get(nutrient)
+ aFluxForDeadFish.get(nutrient) * (fish.getAmount() - survivalAmount));
}
// compute biomass for dead fish
biomass = group.getNutrientRoutine().getWeight(fish) * (fish.getAmount() - survivalAmount);
totalInputFluxes.get(spawnerOrigin).put("biomass",
totalInputFluxes.get(spawnerOrigin).get("biomass") + biomass);
// ------------------------------------------------------ end of nutrient routine
// update the amount of individual in the super-individual
fish.setAmount(survivalAmount);
} else { // the superindividual dies !!!
// ------------------------------------------------------ start of nutrient routine
// nutrient fluxes for one fish dying after spawning (fish.getAmount):
// carcasses + excretion + gametes
Map<String, Double> aFluxForDeadFish = group.getNutrientRoutine()
.computeNutrientsInputForDeathAfterSpawning(fish); //
for (String nutrient : aFluxForDeadFish.keySet()) {
group.getNutrientRoutine().getNutrientImportFluxesCollection().put(
time.getYear(group.getPilot()), nutrient, fish.getBirthBasin().getName(),
riverBasin.getName(),
aFluxForDeadFish.get(nutrient) * (fish.getAmount() - survivalAmount));
}
biomass = group.getNutrientRoutine().getWeight(fish) * (fish.getAmount());
totalInputFluxes.get(spawnerOrigin).put("biomass",
totalInputFluxes.get(spawnerOrigin).get("biomass") + biomass);
// ------------------------------------------------------ end of nutrient routine
// remove fish because fish is dead
fishIterator.remove();
}
}
}
}
}
}
}
}
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