#include #include #include #include "delta.h" #include "kirkrand.h" #include "r250norm.h" /*************************************************************************** InitAdults() This function initializes the adult distribution based on a weighted lottery choice of one species to attempt colonization. The species weights are based on the normal curves defined by the species parameters. If a species is selected, then it can attempt colonization. Colonization occurs if a species is in water shallower than its mean or if its probability of occurence is greater than a randomly generated number between 0 & 1. Arguments: struct Plant ***plant pointer to plant structure struct Basin *basin pointer to basin parameters struct Lifehist *lifehist pointer to lifehist parameters struct Run *run pointer to run parameters Return Value: void ****************************************************************************/ void InitAdults(struct Basin *basin, struct Lifehist *lifehist, struct Plant ***plant, struct Run *run, double **topo, double *water) { int x, y, i, select; double prob[MAXSP],probcum[MAXSP], probsum, d; double z, zsqr, mean, width, depth; for(y=0; y < basin->ymax[0]; y++) { for(x=0; x < basin->xmax[0]; x++) { GetDepth(basin, run, topo, water, &depth, x, y); if(depth == -9999) { plant[x][y][0].adult[0] = -9999; continue; } for(probsum = 0, i = 0; i < MAXSP; i++) { /*set invasion probs.*/ probcum[i] = 0; GetProb(&(prob[i]), &i, &depth); probsum += prob[i]; } if(probsum) { for(i = 1; i < MAXSP; i++) { probcum[i] = (prob[i]/probsum) + probcum[i-1]; } } d = dr250(); /*changed from being included in next if statement 1/23/97*/ for(i=1, select=0; i< MAXSP; i++) { /*select adult to colonize*/ if(probcum[i]>=d) { select = i; break; } } if(prob[select]>(d=dr250())|| lifehist->depthmean[i]>depth) { /*check if plant can colonize*/ plant[x][y][0].adult[0] = select; if(prob[select]>(d=dr250())|| lifehist->depthmean[i]>depth) { /*check if plant can reproduce*/ plant[x][y][0].reproduce[0] = 1; } plant[x][y][0].origx[0] = x; plant[x][y][0].origy[0] = y; } } } } /**************************************************************************** InitSeeds() This function creates a random seed dipersal. The lifehist parameter "initbank" gives the mean number of seeds to be found in the initial seedbank. (initbank*total cells within rseedbank elevation range) = total number of seeds dispersed randomly throughout the basin using a normal approximation of the binamila distribution . Arguments: struct Plant ***plant pointer to plant structure struct Basin *basin pointer to basin parameters struct Lifehist *lifehist pointer to lifehistory parameters Return Value: void ****************************************************************************/ void InitSeeds(struct Basin *basin, struct Lifehist *lifehist, struct Plant ***plant, struct Run *run, double **topo) { int x, y, i; double b0, b1, b2, elev, sdev, norm, lgseeds; long seeds; for(y=0; y < basin->ymax[0]; y++) { for(x=0; x < basin->xmax[0]; x++) { GetElev(basin, run, topo, &elev, x, y); /*Add one m to elevation as the seed regressions are based on a zero elevation of 247.5 and GetElev() returns an elevation relative to the max flooding level of 248.5. */ if(elev != -9999) { elev += 1; } for(i=1; i < MAXSP; i++) { /*Blank out cells that are off the grid*/ if(elev == -9999) { plant[x][y][0].seed[i]=-9999; plant[x][y][1].seed[i]=-9999; continue; } /****************************************************/ /*Calculate the number of seeds present of species i*/ /****************************************************/ /*Collect regression parameters*/ b0 = lifehist->seedb0[i]; b1 = lifehist->seedb1[i]; b2 = lifehist->seedb2[i]; /*Calculate untransformed seed values*/ lgseeds = b0 + b1*elev + b2*elev*elev; /*Add on error in seed distributions*/ sdev = sqrt(lifehist->seedvar[i]); norm=r250norm(); lgseeds += norm*sdev; seeds = (long)(pow(10, lgseeds) - 1); if(seeds < 0) { seeds = 0; } plant[x][y][0].seed[i]= seeds; plant[x][y][1].seed[i]= seeds; } } } } /*************************************************************************** DisperseVege() This function randomly disperses rhizomes to neighboring empty cell. It also passes along the origin of the original genet. Preference for dispersal between neighbors is random. Cell must be empty to be colonized and species colonizer must be rhizomatous. The dispersal algorithm is repeated "cell" times which is the max number of cells that a rhizome can colonize in a step (maxrhiz m/cellsize m). ***Warning*** adults for t = 0 and 1 are iteratively updated within a step "cell" times to account for the repeated exppansion of rhizomes in a time step. Arguments: struct Plant ***plant pointer to plant structure struct Basin *basin pointer to basin parameters struct Lifehist *lifehist pointer to lifehist parameters struct Run *run pointer to run parameters Return Value: void ****************************************************************************/ void DisperseVege(struct Basin *basin, struct Lifehist *lifehist, struct Plant ***plant, struct Run *run, double **topo, double *water) { int x, y, i, j, k, c, select, total, cells, adult; double prob[NEIGHBORS],probcum[NEIGHBORS], probsum; double depth, z, zsqr, mean, width, d; struct Local adults[NEIGHBORS]; struct Local local[NEIGHBORS]; cells = (int)(run->maxrhiz[0]/basin->cellsize[0]); for(c = 0; c < cells; c++) { for(y=0; y < basin->ymax[0]; y++) { for(x=0; x < basin->xmax[0]; x++) { if(plant[x][y][0].adult[0]==0) { /*ck if cell is empty and not a blank*/ for(total = 0, k = 0; k < NEIGHBORS; k++) { local[k].x[0]=-9; /*initialize arrays*/ local[k].y[0]=-9; adults[k].sp[0]=0; adults[k].x[0]=-9; adults[k].y[0]=-9; probcum[k]=0; prob[k]=0; } GetNeighbors(basin, local, x,y);/*get cell addresses of neighbors*/ for(total = 0, k = 0; k < NEIGHBORS; k++) { i = local[k].y[0]; j = local[k].x[0]; if(local[k].x[0] < 0 || local[k].y[0] < 0) { /*ck for cells off grid (-9's)*/ continue; } if(plant[j][i][1].adult[0]<=0) { /*ck for empty or blanked cells*/ continue; } if(plant[j][i][1].reproduce[0]==0) { /*ck for nonreproductive plants*/ continue; } if(lifehist->rhizome[plant[j][i][1].adult[0]]==0) { /*ck for nonrerhizomatous plants*/ continue; } adults[total].sp[0] = plant[j][i][1].adult[0]; /*pass along sp and origin of genet*/ adults[total].x[0] = plant[j][i][1].origx[0]; adults[total].y[0] = plant[j][i][1].origy[0]; total++; } GetDepth(basin, run, topo, water, &depth, x, y); for(probsum = 0, k = 0; k < NEIGHBORS; k++) { /*set invasion probs.*/ adult = adults[k].sp[0]; if(adult) { GetProb(&(prob[k]), &adult, &depth); probsum += prob[k]; } } if(probsum) { probcum[0] = (prob[0]/probsum); for(k = 1; k < NEIGHBORS; k++) { probcum[k] = (prob[k]/probsum) + probcum[k-1]; if(prob[k]==0) { break; } } } if(total) { for(k=0, select=0; k< NEIGHBORS; k++) { /*select adult to colonize*/ if(probcum[k]>=(d=dr250())) { select = k; break; } } /*Test if selected adult species colonizes*/ if(adults[select].sp[0]!= 0 && prob[select]>(d=dr250())) { plant[x][y][0].adult[0] = adults[select].sp[0]; plant[x][y][0].origx[0] = adults[select].x[0]; plant[x][y][0].origy[0] = adults[select].y[0]; plant[x][y][0].reproduce[0] = 1; } } } } } if(c) { /*update cells only if maxrhiz > cellsize*/ for(y=0; y < basin->ymax[0]; y++) { /*within step update*/ for(x=0; x < basin->xmax[0]; x++) { plant[x][y][1].adult[0] = plant[x][y][0].adult[0]; plant[x][y][1].origx[0] = plant[x][y][0].origx[0]; plant[x][y][1].origy[0] = plant[x][y][0].origy[0]; plant[x][y][1].reproduce[0] = plant[x][y][0].reproduce[0]; } } } } }