Newer
Older

Peter Jentsch
committed
#remove Base.@propagate_inbounds during tests if you get segfaults or change anything,
# as that might mean there is an indexing bug that is not being caught,
#and therefore accessing the wrong memory is causing background errors

Peter Jentsch
committed
function contact_weight(p, contact_time)
return 1 - (1-p)^contact_time
end

Peter Jentsch
committed
function Φ(payoff,β)
return 1 / (exp(-1*β*payoff))
end

Peter Jentsch
committed
Base.@propagate_inbounds @views function update_alert_durations!(t,modelsol) # Base.@propagate_inbounds
@unpack notification_parameter,notification_threshold = modelsol.params
@unpack time_of_last_alert, app_user_index,inf_network,covid_alert_notifications,app_user = modelsol
for (i,node) in enumerate(modelsol.app_user_index)

Peter Jentsch
committed
for j in 2:14

Peter Jentsch
committed
covid_alert_notifications[j-1,i] = covid_alert_notifications[j,i] #shift them all back

Peter Jentsch
committed
end

Peter Jentsch
committed
total_weight_i = 0
for mixing_graph in inf_network.graph_list[t]
for j in neighbors(mixing_graph.g,node)
if app_user[j]
total_weight_i+= get_weight(mixing_graph,GraphEdge(node,j))
end

Peter Jentsch
committed
end
end

Peter Jentsch
committed
coin_flip = 1 - (1 - notification_parameter)^total_weight_i

Peter Jentsch
committed
r = rand(Random.default_rng(Threads.threadid()))

Peter Jentsch
committed
if r < coin_flip
covid_alert_notifications[end,i] = 1 #add the notifications for today
else
covid_alert_notifications[end,i] = 0
end
if sum(covid_alert_notifications[:,i])>=notification_threshold

Peter Jentsch
committed
time_of_last_alert[i] = t
end
end
end

Peter Jentsch
committed
Base.@propagate_inbounds @views function update_infection_state!(t,modelsol)
@unpack base_transmission_probability,recovery_rate,immunizing,immunization_begin_day = modelsol.params
@unpack u_inf,u_vac,u_next_inf,u_next_vac,demographics,inf_network,status_totals, immunization_countdown = modelsol

Peter Jentsch
committed
modelsol.daily_cases_by_age .= 0
modelsol.daily_immunized_by_age .= 0

Peter Jentsch
committed
function agent_transition!(node, from::AgentStatus,to::AgentStatus)
immunization_countdown[node] = -1

Peter Jentsch
committed
status_totals[Int(from)] -= 1
status_totals[Int(to)] += 1

Peter Jentsch
committed
u_next_inf[node] = to
end
u_next_inf .= u_inf

Peter Jentsch
committed
for i in 1:modelsol.nodes
agent_status = u_inf[i]
is_vaccinator = u_vac[i]
agent_demo = demographics[i]
if agent_status == Susceptible
if is_vaccinator && immunizing && immunization_countdown[i] == -1 && t> immunization_begin_day
immunization_countdown[i] = 14

Peter Jentsch
committed
else

Peter Jentsch
committed
for mixing_graph in inf_network.graph_list[t]

Peter Jentsch
committed
for j in neighbors(mixing_graph.g,i)

Peter Jentsch
committed
if u_inf[j] == Infected && u_next_inf[i] != Infected

Peter Jentsch
committed
if rand(Random.default_rng(Threads.threadid())) < contact_weight(base_transmission_probability,get_weight(mixing_graph,GraphEdge(i,j)))
modelsol.daily_cases_by_age[Int(agent_demo)]+=1

Peter Jentsch
committed
agent_transition!(i, Susceptible,Infected)
end

Peter Jentsch
committed
end
end
end
end
elseif agent_status == Infected

Peter Jentsch
committed
if rand(Random.default_rng(Threads.threadid())) < recovery_rate

Peter Jentsch
committed
agent_transition!(i, Infected,Recovered)

Peter Jentsch
committed
end
end
if immunization_countdown[i] == 0
modelsol.daily_immunized_by_age[Int(agent_demo)] += 1
agent_transition!(i, Susceptible,Immunized)
elseif immunization_countdown[i]>0
immunization_countdown[i] -= 1
end

Peter Jentsch
committed
end
end

Peter Jentsch
committed
Base.@propagate_inbounds @views function update_vaccination_opinion_state!(t,modelsol,total_infections)
@unpack π_base_y,π_base_m,π_base_o, η,γ, κ, ω, ω_en,γ,β = modelsol.params

Peter Jentsch
committed
@unpack demographics,time_of_last_alert, nodes, soc_network,u_vac,u_next_vac,app_user,app_user_list = modelsol
app_user_pointer = 0
for i in 1:nodes

Peter Jentsch
committed
vac_payoff = 0
num_soc_nbrs = 0
random_soc_network = sample(Random.default_rng(Threads.threadid()), soc_network.graph_list[t])

Peter Jentsch
committed
if !isempty(neighbors(random_soc_network.g,i))
random_neighbour = sample(Random.default_rng(Threads.threadid()), neighbors(random_soc_network.g,i))
if u_vac[random_neighbour] == u_vac[i]
vac_payoff += π_base[Int(demographics[i])] + total_infections*ω
if app_user[i] && time_of_last_alert[app_user_list[i]]>=0
vac_payoff += γ^(-1*(t - time_of_last_alert[app_user_list[i]])) * (η + total_infections*ω_en)

Peter Jentsch
committed
if u_vac[i]
if rand(Random.default_rng(Threads.threadid())) < 1 - Φ(vac_payoff,β)
u_next_vac[i] = false
end
else
if rand(Random.default_rng(Threads.threadid())) < Φ(vac_payoff,β)
u_next_vac[i] = true
end
end

Peter Jentsch
committed
end
end
end

Peter Jentsch
committed
modelsol.daily_vaccinators = count(==(true),u_vac) #could maybe make this more efficient

Peter Jentsch
committed

Peter Jentsch
committed
end
function weighted_degree(node,network::TimeDepMixingGraph)
weighted_degree = 0
for g_list in network.graph_list
for g in g_list
for j in neighbors(g.g,node)
weighted_degree += get_weight(g,GraphEdge(node,j))
end
end
end
return weighted_degree
end

Peter Jentsch
committed
function agents_step!(t,modelsol)

Peter Jentsch
committed
remake!(modelsol.inf_network,modelsol.index_vectors)
for network in modelsol.inf_network.graph_list[t] #this also resamples the soc network weights since they point to the same objects, but those are never used
sample_mixing_graph!(network) #get new contact weights

Peter Jentsch
committed
end
# @show modelsol.inf_network.graph_list[t]
# @show weighted_degree(1,modelsol.inf_network)
# @show weighted_degree(1,modelsol.soc_network)
if t == modelsol.params.infection_introduction_day

Peter Jentsch
committed
init_indices = rand(Random.default_rng(Threads.threadid()), 1:modelsol.nodes, round(Int,modelsol.nodes*modelsol.params.I_0_fraction))
modelsol.u_inf[init_indices] .= Infected
modelsol.status_totals[Int(Infected)] += length(init_indices)
end
if t>modelsol.params.infection_introduction_day
update_alert_durations!(t,modelsol)
end

Peter Jentsch
committed
update_vaccination_opinion_state!(t,modelsol,modelsol.status_totals[Int(Infected)])

Peter Jentsch
committed
update_infection_state!(t,modelsol)

Peter Jentsch
committed

Peter Jentsch
committed
modelsol.u_vac .= modelsol.u_next_vac
modelsol.u_inf .= modelsol.u_next_inf
end

Peter Jentsch
committed
function solve!(modelsol,recordings...)

Peter Jentsch
committed
for t in 1:modelsol.sim_length

Peter Jentsch
committed
#advance agent states based on the new network

Peter Jentsch
committed
for recording in recordings
record!(t,modelsol,recording)
end