-
Notifications
You must be signed in to change notification settings - Fork 0
/
coral_subs.F90
280 lines (204 loc) · 6.99 KB
/
coral_subs.F90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
subroutine corpop
! Sets initial coral distribution
use globalvars, only: percentcover, grid, coral
use functions, only: percentcor
implicit none
real :: perc ! Current percentage of coral
integer :: i, j, sizint, x, y ! Looping integers, size of shape, coords
real :: coordinate(2) ! Holds x,y coordinates of center of cluster
real :: choice, size ! shape choice, size of shape
real :: healtharr ! health of coral being placed. one to five
! Initialize
perc = percentcor(grid)
! Working loop
do while (perc .lt. percentcover)
! Get random numbers for placement
call random_number(coordinate)
call random_number(choice)
call random_number(size)
! Size of shape
size = 3.0*size + 1.0
! Make integer
sizint = nint(size)
! Determine where the shape goes
coordinate = float(grid)*coordinate
! Get number for health
call random_number(healtharr)
! Fit between 1 and five
healtharr = 1.0 + healtharr*9.0
! Set coordinates to integers that fit in the grid
x = floor(coordinate(1)) + 1
y = floor(coordinate(2)) + 1
! Loop through shape and place
do j = y, y+sizint, 1
do i = x, x+sizint, 1
! Ensure that we aren't going out of bounds.
if ((j .ge. 1) .and. (j .le. grid) .and. (i .ge. 1) .and. (i .le. grid)) then
coral(i,j) = coral(i,j) + healtharr
end if
end do
end do
! Trim outliers
where (coral .lt. 0.05) coral = 0.0
where (coral .gt. 10.0) coral = 10.0
! Update percentage
perc = percentcor(grid)
end do
end subroutine
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine corexp(new)
! Subroutine grows the coral into new spots
use globalvars, only: coral, bacteria, lys, grid, check, numnew
use functions, only: bactouch
implicit none
integer,intent(in) :: new
integer :: spawned(2,new)
real :: temp ! Holds a random number which checks to see if a new coral is generated
real :: coord ! Holds the coordinates of the new coral
integer :: x, y, i, j, l, c ! Integers for coordinates, looping, and algae locations
integer,allocatable :: algaeloc(:,:) ! Holds the locations where there is algae and not coral
real :: bactfact, neighbors ! Bacterial influence factor, holds number of coral neighbors
real :: bact_imp, totbact
integer :: tstep_new
! Initialize the 'counting' integer to update algaeloc locations
c = 0
tstep_new = 0
! Determines how many locations are not coral
check = (coral .eq. 0.0)
! Sends the count to an integer and allocates algaeloc
l = count(check)
allocate(algaeloc(2,l))
algaeloc = 0
! Checks coral average against threshold, checks against probability of
! generation, if passes calls random locations in algaeloc and places coral.
! Do loops to find exact coordinates of coral
do i = 1, grid, 1
do j = 1, grid, 1
neighbors = 0
! Checks for coral around the input gridpoint and out-of-bounds
if ((i .gt. 1) .and. (coral(i-1,j) .ne. 0.0)) then
neighbors = 1.0
end if
if ((i .lt. grid) .and. (coral(i+1,j) .ne. 0.0)) then
neighbors = neighbors + 1.0
end if
if ((j .lt. grid) .and. (coral(i,j+1) .ne. 0.0)) then
neighbors = neighbors + 1.0
end if
if ((i .gt. 1) .and. (coral(i,j-1) .ne. 0.0)) then
neighbors = neighbors + 1.0
end if
if ((i .lt. grid) .and. (j .lt. grid) .and. (coral(i+1,j+1) .ne. 0.0)) then
neighbors = neighbors + 1.0
end if
if ((i .gt. 1) .and. (j .gt. 1) .and. (coral(i-1,j-1) .ne. 0.0)) then
neighbors = neighbors + 1.0
end if
if ((i .lt. grid) .and. (j .gt. 1) .and.(coral(i+1,j-1) .ne. 0.0)) then
neighbors = neighbors + 1.0
end if
if ((i .gt. 1) .and. (j .lt. grid) .and. (coral(i-1,j+1) .ne. 0.0)) then
neighbors = neighbors + 1.0
end if
! Must be adjacent to coral
if ((coral(i,j) .eq. 0.0) .and. (neighbors .ne. 0.0)) then
! Saves the locations of algae into algaeloc
c = c + 1
algaeloc(1,c) = i
algaeloc(2,c) = j
end if
end do
end do
spawned = 0
! Logic statements for coordinates
do i = 1, new, 1
102 call random_number(coord)
x = algaeloc(1,floor(c*coord))
y = algaeloc(2,floor(c*coord))
do j = 1, new, 1
if ((x .eq. spawned(1,i)).or.(y .eq. spawned(2,i))) then
goto 102
end if
end do
spawned(1,i) = x
spawned(2,i) = y
! Check for bounds
if (x .lt. 1) x = 1
if (y .lt. 1) y = 1
if (x .gt. grid) x = grid
if (y .gt. grid) y = grid
call random_number(temp)
bactfact = real((bacteria(2*x,2*y)%totalpop+bacteria(2*x-1,2*y)%totalpop &
+bacteria(2*x-1,2*y-1)%totalpop+bacteria(2*x,2*y-1)%totalpop))
totbact = bactfact + real((lys(2*x,2*y)%totalpop+lys(2*x-1,2*y)%totalpop &
+lys(2*x-1,2*y-1)%totalpop+lys(2*x,2*y-1)%totalpop))
bact_imp = bactouch(totbact)
! Set new coral if bacteria is not enough to prevent
if (temp .ge. bact_imp) then
numnew = numnew + 1
tstep_new = tstep_new + 1
coral(x,y) = 2.5
end if
end do
write(*,*) "Number of new coral growths:", tstep_new
deallocate(algaeloc)
end subroutine
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine growth(arrin,arrout,deconst)
use functions
! Grows the input grid location based on value and neighbors.
use globalvars, only: grid, bacteria, lys, growavg
use functions, only: bactouch, percentcor
implicit none
real,dimension(grid,grid), intent(in) :: arrin ! Input array
real,intent(in) :: deconst ! growth modifier for disease
real,dimension(grid,grid), intent(out) :: arrout ! Output array
real :: bactcoral, lyscoral, tot_bac
real :: grow, bacteff ! Bacterial influences
integer :: x, y ! Looping integers
real :: cur_perc, growpercent, ran
! Initialize
growavg = 0.0
! Loops
do x = 1, grid, 1
yloop: do y = 1, grid, 1
! Reset
bactcoral = 0.0
lyscoral = 0.0
! bact. pop on coral directly
bactcoral = real((bacteria(2*x,2*y)%totalpop+bacteria(2*x-1,2*y)%totalpop &
+bacteria(2*x-1,2*y-1)%totalpop+bacteria(2*x,2*y-1)%totalpop))
lyscoral = real((lys(2*x,2*y)%totalpop+lys(2*x-1,2*y)%totalpop &
+lys(2*x-1,2*y-1)%totalpop+lys(2*x,2*y-1)%totalpop))
! normalize to area of region covered
tot_bac = bactcoral + lyscoral
! Edge cases
if (bactcoral .lt. 0.0) then
bactcoral = 0.0
end if
! Check amount of influence from bacteria
bacteff = bactouch(tot_bac)
call random_number(growpercent)
call random_number(ran)
! Determine growth
if (ran .lt. 0.5) then
growpercent = 0.1 + 0.05*growpercent
else
growpercent = 0.1 - 0.05*growpercent
end if
! growth avg = 0.1, at full capacity bacteria should win
grow = 1.0 + (deconst*growpercent - 0.15*bacteff)
! Sum to average
growavg = growavg + grow
! Grow location
arrout(x,y) = arrin(x,y)*grow
end do yloop
end do
! Normalize the average growth
cur_perc = percentcor(grid)
growavg = growavg/(float(grid*grid))
! Set to maximum
where (arrout .gt. 5.0) arrout = 5.0
where (arrout .lt. 0.05) arrout = 0.0
end subroutine
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!