collembola.cl
3.35 KB
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
/**
* pre-OpenCL 1.1 compatibility macros
*/
#if __OPENCL_VERSION__ <= CL_VERSION_1_0
#define atomic_add(p, v) atom_add(p, v)
#define atomic_inc(p) atom_inc(p)
#endif
typedef struct {
int width;
int height;
float growthRate;
float diffusionRate;
float diffusionThreshold;
float mortalityRate;
int speciality;
} CollemWorld;
#define PREF_FOREST 1
#define PREF_CULTURAL 2
#define PREF_CITY 3
#define MATCH_PREFERENCE(pref, type) \
((pref == PREF_FOREST && (type == 6 || type == 7 || type == 8 || type == 10)) \
|| ((pref == PREF_CULTURE && (type == 3 || type == 4 || type == 5)) \
|| ((pref == PREF_CITY && (type == 1)
/*
kernel void collembola(global int * patches, int width)
{
const int i = get_global_id(0);
const int j = get_global_id(1);
//patches[i * width + j] = -patches[i * width + j];
// Diffusion
}*/
#define CELL(world, values, x, y) (values[x * world->width + y])
#define OVERFLOW(world, values, x, y)(values[(x + 1) * (world->width + 2) + 1 + y])
kernel void newArrivals(
global CollemWorld *world,
global int *populations,
global int *patchesOwners,
global int *plotsPopulations,
global int *plotsSurfaces)
{
const int i = get_global_id(0);
const int j = get_global_id(1);
const int plotId = CELL(world, patchesOwners, i, j);
if (plotId == -1) return;
CELL(world, populations, i, j) =
CELL(world, populations, i, j) + (world->growthRate * plotsPopulations[plotId]) / plotsSurfaces[plotId];
}
kernel void reproduction(
global CollemWorld *world,
global int *populations,
global int *patchesOwners,
global int *plotsPopulations)
{
const int i = get_global_id(0);
const int j = get_global_id(1);
const int plotId = CELL(world, patchesOwners, i, j);
if (plotId == -1) return;
atomic_add(plotsPopulations + plotId, CELL(world, populations, i, j));
}
kernel void diffusion(
global CollemWorld *world,
global int *populations,
global int *overflows,
global int *newPopulations)
{
const int i = get_global_id(0);
const int j = get_global_id(1);
// Determine if we have something to diffuse
/*if (CELL(world, populations, i, j) > world->diffusionThreshold) {
OVERFLOW(world, overflows, i, j) = CELL(world, populations, i, j) * world->diffusionRate;
//OVERFLOW(world, overflows, i, j) = 0;
}*/
OVERFLOW(world, overflows, i, j) = CELL(world, populations, i, j) * world->diffusionRate;
barrier(CLK_GLOBAL_MEM_FENCE);
int surplus = OVERFLOW(world, overflows, i + 1, j) + OVERFLOW(world, overflows, i - 1, j) + OVERFLOW(world, overflows, i, j - 1) + OVERFLOW(world, overflows, i, j + 1);
//int surplus = 0;
CELL(world, newPopulations, i, j) = CELL(world, populations, i, j) + surplus / 8.0 - OVERFLOW(world, overflows, i, j);
barrier(CLK_GLOBAL_MEM_FENCE);
//CELL(world, newPopulations, i, j) = world->width * 1000 + world->height;
//CELL(world, newPopulations, i, j) = surplus;
}
kernel void death(
global CollemWorld *world,
global int *populations,
global int *patchesType)
{
/*const int i = get_global_id(0);
const int j = get_global_id(1);
int patchType = CELL(world, patchesType, i, j);
if (patchType == TYPE_ARTIFICIAL) {
CELL(world, populations, i, j) = 0;
} else if (patchType != world->speciality) {
CELL(world, populations, i, j) -= CELL(world, populations, i, j) * world->mortalityRate;
}*/
}