void Critter::MaybeReproduce(std::list<Critter *> &group) { if (!attacker() && food >= 0.5 && ofRandomuf() < reproductivity() && group.size() < kMaxPopulation) { area *= kChildScaleFactor; food -= 0.5; age = 0; const ofVec2f epsilon = ofVec2f(0.1, 0.1); Critter *critter = new Critter(player, 0, mass, area, position + epsilon, velocity); group.push_back(critter); } const float cell_mortality = radius() <= kBreederSize ? mortality() : kWallMortality; if (ofRandomuf() < cell_mortality * age * age * age) { area = 0; } }
// Calculates rates of growth, mortality and fecundity for individual with size m. Memory for GMR[5] must be allocated elsewhere // Env[] contains estimates of light environment at different depths in the canopy used in calculating production. void Strategy::Grow_Mort_Repro(vector<double>& GMR, double m, const double Env[], double t) { GMR[3] = Production(Env, m); // GPP GMR[6] = Respiration(m); // Maintenance respiration GMR[4] = (*p).Y * (GMR[3] - GMR[6]); // NPP GMR[5] = Turnover(m); // Tissue turnover double dmdt = GMR[4] - GMR[5]; // NET PRODUCTION GMR[0] = (1 - r_alloc(m)) / dTotalMass_dm(m) * max(0.0, dmdt); // GROWTH - only positive growth allowed GMR[1] = mortality(dmdt, m); // MORTALITY GMR[2] = (*p).Pi_0 * (max(0.0, dmdt) * r_alloc(m)) / ((*p).c_acc * total_mass_at_birth); // REPRODUCTION // Check for NaN in mortality if ((!(GMR[1] >= 0) && !(GMR[1] < 0))) cout << "Mort " << lma << "\t" << GMR[1] << "\t" << dmdt << "\t" << m << "\t" << LfAr(m) << "\t" << dmdt / LfAr(m) << "\t" << exp((*p).c_d1 * rho + (*p).c_d2 * dmdt / LfAr(m)) << endl; }
//---------------------------------------------------------------------------------- //std::vector<EnumConclusion> Simulation::execute() void Simulation::execute(MeasurementsTable& table, std::vector<EnumConclusion>& conclusions) { checkPopSize("void Simulation::execute() - #1"); std::cout << "Start of simulation, running time (timesteps): " << mMaxTime << std::endl; std::cout << "Starting population size: " << SoilMiteBase::getPopSize() << std::endl; mErrorCode = EcNoError; for(unsigned int time=0; time<mMaxTime && mErrorCode==EcNoError; ++time) { changeEnvironment(time,table); intake(table); reproduction(table); mortality(); measurePopulation(table); if (mOptionsFileParameters.showYearSummary==true) table.showYearHorizontal(time); } checkPopSize("void Simulation::execute() - #2"); mpFunctions->coutAll(); std::cout << "Body size adult: " << SoilMiteBase::getBodySizeAdult() << std::endl; //Some conclusions if (mOffspringProduced==false) conclusions.push_back(CcNoOffspringProduced); switch(mErrorCode) { case EcNoError: conclusions.push_back(CcNoError); break; case EcPopExtinct: conclusions.push_back(CcPopExtinct); break; case EcPopSizeTooBig: conclusions.push_back(CcPopSizeTooBig); break; case EcNoffspringTooBigSingleParent: conclusions.push_back(CcNoffspringTooBigSingleParent); break; case EcNoffspringTooBigAllParents: conclusions.push_back(CcNoffspringTooBigAllParents); break; } }
void daily_bgc (bgc_struct BGCM, bgc_grid * grid, const double t, const double naddfrac, int first_balance) { siteconst_struct *sitec; metvar_struct *metv; co2control_struct *co2; ndepcontrol_struct *ndepctrl; control_struct *ctrl; epconst_struct *epc; epvar_struct *epv; psn_struct *psn_sun, *psn_shade; wstate_struct *ws; wflux_struct *wf; cstate_struct *cs; cflux_struct *cf; nstate_struct *ns; nflux_struct *nf; ntemp_struct *nt; phenology_struct *phen; summary_struct *summary; struct tm *timestamp; time_t *rawtime; /* miscelaneous variables for program control in main */ int simyr, yday, metyr, metday; int annual_alloc; int outv; int i, nmetdays; double tair_avg, tdiff; int dayout; double daily_ndep, daily_nfix, ndep_scalar, ndep_diff, ndep; int ind_simyr; sitec = &grid->sitec; metv = &grid->metv; co2 = &BGCM->co2; ndepctrl = &BGCM->ndepctrl; ctrl = &BGCM->ctrl; epc = &grid->epc; epv = &grid->epv; ws = &grid->ws; wf = &grid->wf; cs = &grid->cs; cf = &grid->cf; ns = &grid->ns; nf = &grid->nf; nt = &grid->nt; phen = &grid->phen; psn_sun = &grid->psn_sun; psn_shade = &grid->psn_shade; summary = &grid->summary; rawtime = (time_t *) malloc (sizeof (time_t)); *rawtime = (int)t; timestamp = gmtime (rawtime); /* Get co2 and ndep */ if (ctrl->spinup == 1) /* Spinup mode */ { metv->co2 = co2->co2ppm; daily_ndep = ndepctrl->ndep / 365.0; daily_nfix = ndepctrl->nfix / 365.0; } else /* Model mode */ { /* atmospheric CO2 and Ndep handling */ if (!(co2->varco2)) { /* constant CO2, constant Ndep */ metv->co2 = co2->co2ppm; daily_ndep = ndepctrl->ndep / 365.0; daily_nfix = ndepctrl->nfix / 365.0; } else { /* When varco2 = 1, use file for co2 */ if (co2->varco2 == 1) metv->co2 = get_co2 (BGCM->Forcing[CO2_TS][0], t); if (metv->co2 < -999) { printf ("Error finding CO2 value on %4.4d-%2.2d-%2.2d\n", timestamp->tm_year + 1900, timestamp->tm_mon + 1, timestamp->tm_mday); exit (1); } /* When varco2 = 2, use the constant CO2 value, but can vary * Ndep */ if (co2->varco2 == 2) metv->co2 = co2->co2ppm; if (ndepctrl->varndep == 0) { /* Increasing CO2, constant Ndep */ daily_ndep = ndepctrl->ndep / 365.0; daily_nfix = ndepctrl->nfix / 365.0; } else { daily_ndep = get_ndep (BGCM->Forcing[NDEP_TS][0], t); daily_nfix = ndepctrl->nfix / 365.0; if (daily_ndep < -999) { printf ("Error finding NDEP %4.4d-%2.2d-%2.2d\n", timestamp->tm_year + 1900, timestamp->tm_mon + 1, timestamp->tm_mday); exit (1); } else { daily_ndep = daily_ndep / 365.0; } } } } precision_control (ws, cs, ns); /* zero all the daily flux variables */ make_zero_flux_struct (wf, cf, nf); /* phenology fluxes */ phenology (epc, metv, phen, epv, cs, cf, ns, nf); /* test for the annual allocation day */ if (phen->remdays_litfall == 1) annual_alloc = 1; else annual_alloc = 0; /* Calculate leaf area index, sun and shade fractions, and specific * leaf area for sun and shade canopy fractions, then calculate * canopy radiation interception and transmission */ radtrans (cs, epc, metv, epv, sitec->sw_alb); /* update the ann max LAI for annual diagnostic output */ if (epv->proj_lai > epv->ytd_maxplai) epv->ytd_maxplai = epv->proj_lai; /* soil water potential */ epv->vwc = metv->swc; soilpsi (sitec, epv->vwc, &epv->psi); /* daily maintenance respiration */ maint_resp (cs, ns, epc, metv, cf, epv); /* begin canopy bio-physical process simulation */ if (cs->leafc && metv->dayl) { /* conductance */ canopy_et (metv, epc, epv, wf); } /* Do photosynthesis only when it is part of the current growth season, as * defined by the remdays_curgrowth flag. This keeps the occurrence of * new growth consistent with the treatment of litterfall and * allocation */ //printf ("leafc %lf dormant %lf, dayl %lf, soilc = %lf\n", cs->leafc, epv->dormant_flag, metv->dayl, summary->soilc); if (cs->leafc && !epv->dormant_flag && metv->dayl) total_photosynthesis (metv, epc, epv, cf, psn_sun, psn_shade); else epv->assim_sun = epv->assim_shade = 0.0; nf->ndep_to_sminn = daily_ndep; nf->nfix_to_sminn = daily_nfix; /* daily litter and soil decomp and nitrogen fluxes */ decomp (metv->tsoil, epc, epv, cs, cf, ns, nf, nt); /* Daily allocation gets called whether or not this is a current growth * day, because the competition between decomp immobilization fluxes and * plant growth N demand is resolved here. On days with no growth, no * allocation occurs, but immobilization fluxes are updated normally */ daily_allocation (cf, cs, nf, ns, epc, epv, nt, naddfrac, ctrl->spinup); /* reassess the annual turnover rates for livewood --> deadwood, and for * evergreen leaf and fine root litterfall. This happens once each year, * on the annual_alloc day (the last litterfall day) */ if (annual_alloc) annual_rates (epc, epv); /* daily growth respiration */ growth_resp (epc, cf); /* daily update of carbon state variables */ daily_carbon_state_update (cf, cs, annual_alloc, epc->woody, epc->evergreen); /* daily update of nitrogen state variables */ daily_nitrogen_state_update (nf, ns, annual_alloc, epc->woody, epc->evergreen); /* Calculate N leaching loss. This is a special state variable update * routine, done after the other fluxes and states are reconciled in order * to avoid negative sminn under heavy leaching potential */ //nleaching(ns, nf, ws, wf); /* Calculate daily mortality fluxes and update state variables */ /* This is done last, with a special state update procedure, to insure * that pools don't go negative due to mortality fluxes conflicting with * other proportional fluxes */ mortality (epc, cs, cf, ns, nf); /* Test for carbon balance */ check_carbon_balance (cs, &epv->old_c_balance, first_balance); /* Test for nitrogen balance */ check_nitrogen_balance (ns, &epv->old_n_balance, first_balance); /* Calculate carbon summary variables */ csummary (cf, cs, summary); }
int main (int argc, char* argv[]) { srand(atoi(argv[1])); //Take argument to write special extension to file double Btotalple, Bnurseple, Bspawnple, Btotalsol, Bnursesol, Bspawnsol ; /* biomass on nursery, total biomass */ //Read in the data readgrid(&GridFood , X_MAX, Y_MAX, 52, theFood); cout << "Read Food completed" << endl; readgrid(&GridTemp , X_MAX, Y_MAX, 52, theTemp); cout << "Read Temp completed" << endl; readgrid(&GridLMort , X_MAX, Y_MAX, 52, theLMort); cout << "Read Larval Mortality completed" << endl; readgrowthgam(&WeekPropFood,52,theGrowthGam); cout << "Read growth gam completed" << endl; /* INITIALISE INDIVIDUALS AT START, FIRST PLAICE, THEN SOLE */ for(int i=0; i < POPMAX; i++) { ple[i].sex = (i%2)+1; ple[i].weight = BORNWGHT; ple[i].id = id ; ple[i].stage = 1 ; /* everybody should be mature */ ple[i].age = 52 ; ple[i].u_m = U_M ; ple[i].u_f = U_F; if(SPAREA == 1){ ple[i].X = 75 ; ple[i].Y = 53 ; } else if(SPAREA == 2){ ple[i].X = 91 ; ple[i].Y = 67 ; } int X = ple[i].X; int Y = ple[i].Y; int resX, resY; for(int dd=0; dd < L_CHR1; dd++){ //check juvenile strategy do{ple[i].juvXdir[dd] = (char)( (rand()% 11) -5); // Movement of maximum 5 left or right // ple[i].juvYdir[dd] = (char)( (rand()% 11) -5); // Movement of maximum 5 up or down // resX = (int) (ple[i].juvXdir[dd] * ple[i].swim()) ; resY = (int) (ple[i].juvYdir[dd] * ple[i].swim()) ; } while ((theTemp[1][X + resX][Y + resY ] < -15) ||(( X + resX) <0) || (( X + resX) > X_MAX) ||(( Y + resY) < 0) || ((Y + resY) > Y_MAX)); X += resX; Y += resY; ple[i].weight = ple[i].weight + ple[i].growth(theFood[(dd+6)%52][X][Y], theTemp[(dd+6)%52][X][Y],theGrowthGam[(dd+6)%52]); } for(int dd=0; dd <L_CHR2; dd++){ //check juvenile strategy ple[i].adultXdir[dd] = (char)( (rand()% 11) -5); // Movement of maximum 5 left or right // ple[i].adultYdir[dd] = (char)( (rand()% 11) -5); // Movement of maximum 5 up or down // } ple[i].weight = BORNWGHT; id++; } // for(int i=0; i < POPMAX; i++){ // sol[i].sex = (i%2)+1; // sol[i].weight = BORNWGHT ; // sol[i].id = id ; // sol[i].stage = 1 ; // sol[i].age = 52 ; // sol[i].u_m = U_M ; // sol[i].u_f = U_F; // if(SPAREA == 1){ // sol[i].X = 75 ; // sol[i].Y = 53 ; // } else if(SPAREA == 2){ // sol[i].X = 91 ; // sol[i].Y = 67 ; // } // int X = sol[i].X; // int Y = sol[i].Y; // int resX, resY; // for(int dd=0; dd < L_CHR1; dd++){ //check juvenile strategy // do{sol[i].juvXdir[dd] = (char)( (rand()% 11) -5); // Movement of maximum 5 left or right // // sol[i].juvYdir[dd] = (char)( (rand()% 11) -5); // Movement of maximum 5 up or down // // resX = (int) (sol[i].juvXdir[dd] * sol[i].swim()) ; // resY = (int) (sol[i].juvYdir[dd] * sol[i].swim()) ; // } while ((theTemp[1][X + resX][Y + resY ] < -15) ||(( X + resX) <0) ||((X + resX) > X_MAX) ||((Y + resY )< 0) ||((Y + resY) > Y_MAX)); // X += resX; // Y += resY; // sol[i].weight = sol[i].weight + sol[i].growth(theFood[(dd+6)%52][X][Y], theTemp[(dd+6)%52][X][Y],theGrowthGam[(dd+6)%52]); // } // for(int dd=0; dd < L_CHR2 ; dd++){ //check juvenile strategy // sol[i].adultXdir[dd] = (char)((rand()% 11) -5); // Movement of maximum 5 left or right // // sol[i].adultYdir[dd] = (char)((rand()% 11) -5); // Movement of maximum 5 up or down // // } // sol[i].weight = BORNWGHT; // id++; // } // end for loop over individuals / cout << "Initialisation of Plaice and Sole done" << endl; int aliveple = POPMAX, alivesol = POPMAX; string ext(".csv"); //Open file to write output to disk string SPname("_SPAREA"); char buffer [4]; string SP(itoa(SPAREA,buffer,10)); filename += ( argv[1] + SPname + SP + ext); cout << filename << endl; popname += (argv[1] + SPname + SP + ext); myfile.open (filename.c_str() ); mypopulation.open(popname.c_str()); /* START SIM */ for(int t = 6; t < T_MAX; t++){ /* CALCULATE TOTAL BIOMASS AND BIOMASS ON NURSERY FOR TWO SPECIES */ Bnurseple = Btotalple = Bspawnple = Bnursesol = Btotalsol = Bspawnsol = 0; for(int n = 0 ; n < aliveple ; n++) { if (ple[n].stage < 3 ) { Btotalple += ple[n].weight ; if (ple[n].stage < 2 ) Bnurseple += ple[n].weight; } } // for(int n = 0 ; n < alivesol ; n++) { // if (sol[n].stage < 3 ) { // Btotalsol += sol[n].weight ; // if (sol[n].stage < 2 ) Bnursesol += sol[n].weight; // } // } Bspawnple = Btotalple - Bnurseple; // Bspawnsol = Btotalsol - Bnursesol; move(ple, aliveple, t%52, theTemp); // Move individuals every tenth timestep // // move(sol, alivesol, t%52, theTemp); // Move individuals every tenth timestep // age (ple, aliveple) ; // Function of ageing // // age (sol, alivesol) ; // Function of ageing // mortality(ple, LAMBDAple, aliveple ,Bnurseple ) ; // Function mortality // // mortality(sol, LAMBDAsol, alivesol ,Bnursesol ) ; // Function mortality */ growth (ple, aliveple, Bnurseple, t % 52, theFood, theTemp, theGrowthGam) ; // Function of growth // // growth (sol, alivesol, Bnursesol, t % 52, theFood, theTemp, theGrowthGam) ; // Function of growth // if(t%52 == 10 ) maturation (ple, aliveple) ; //Checked with Cindy, gonads start to develop in March // Function of maturation // // if(t%52 == 10 ) maturation (sol, alivesol) ; // Function of maturation // if(t%52 == 5) cout<<"i " << argv[1] <<" t " << t << " ssb ple " << Bspawnple<<" num ple "<<aliveple<< endl; //output(ple,t, 3); // Write biomass and number to screen, followed by data for 10$ // if(t%52 == 5) cout<<"i " << argv[1] << " t " << t << " ssb sol " << Bspawnsol<<" num sol "<<alivesol<< endl; //output(sol,t, 3); // Write biomass and number to screen, followed by data fo$ aliveple = alive2front (ple) ; // shuffle so that alives are in front*/ // alivesol = alive2front (sol) ; // shuffle so that alives are in front*/ if(t%52 == 5) aliveple = reproduction(ple, R1ple, R2ple, aliveple, Bspawnple, theTemp); // Function of reproduction in week 5*/ // if(t%52 == 5) alivesol = reproduction(sol, R1sol, R2sol, alivesol, Bspawnsol, theTemp); // Function of reproduction in week 5*/ if(t%52 == 5){ larvalmortality (ple, aliveple, theLMort); aliveple = alive2front (ple);} // larvalmortality depends on field, now uniform field where everybody survives // // if(t%52 == 5){ larvalmortality (sol, alivesol, theLMort); alivesol = alive2front (sol);} // larvalmortality depends on field, now uniform field where everybody survives // //Write output if ((t==6) ||( (t+A_MAX) % (int)(T_MAX/(T_STEP-1)) < 52 && t % 52 == 6)){ int nn = aliveple; int age = ple[nn].age; do{ age = ple[nn].age; nn--; } while ((nn > (aliveple - P_WRITE)) && (age <= 53)); minid = ple[nn + 1].id; maxid = ple[aliveple - 1].id; } else if ((t < 6 + A_MAX) ||( (t + A_MAX)% (int)(T_MAX/(T_STEP-1)) < A_MAX +52)){ for(int nn = 0; nn < aliveple; nn++){ if(ple[nn].stage < 3 && (ple[nn].id > minid & ple[nn].id < maxid)){ myfile <<t << "," << ple[nn].id << "," << (int) ple[nn].sex << "," << ple[nn].age << "," << (int) ple[nn].stage << "," << ple[nn].X << "," << ple[nn].Y << "," << ple[nn].weight << "," << (int) ple[nn].juvXdir[(int) (ple[nn].age)] << "," << (int) ple[nn].juvYdir[(int) (ple[nn].age)] << "," << (int) ple[nn].adultXdir[(t+1)%52] << "," << (int) ple[nn].adultYdir[(t+1)%52] << endl; } } } //Write output every 15 years (cycle of complete new population) if(t % (A_MAX) == 5){ writePopStruct(mypopulation, ple,aliveple,t);} } //end of timeloop myfile.close() ; mypopulation.close(); return 0 ; }