/** * Initializer for OLSR */ void olsr_init(node_state *s, tw_lp *lp) { hello *h; tw_event *e; olsr_msg_data *msg; tw_stime ts; //s->num_tuples = 0; s->num_neigh = 0; s->num_two_hop = 0; s->local_address = lp->gid; s->lng = tw_rand_unif(lp->rng) * GRID_MAX; s->lat = tw_rand_unif(lp->rng) * GRID_MAX; ts = tw_rand_unif(lp->rng) * STAGGER_MAX; e = tw_event_new(lp->gid, ts, lp); msg = tw_event_data(e); msg->type = HELLO_TX; msg->originator = s->local_address; msg->lng = s->lng; msg->lat = s->lat; h = &msg->mt.h; h->num_neighbors = 0; //h->neighbor_addrs[0] = s->local_address; tw_event_send(e); }
static void svr_init( svr_state * ns, tw_lp * lp) { tw_event *e; svr_msg *m; tw_stime kickoff_time; memset(ns, 0, sizeof(*ns)); /* each server sends a dummy event to itself that will kick off the real * simulation */ //printf("\n Initializing servers %d ", (int)lp->gid); /* skew each kickoff event slightly to help avoid event ties later on */ kickoff_time = g_tw_lookahead + tw_rand_unif(lp->rng); e = codes_event_new(lp->gid, kickoff_time, lp); m = tw_event_data(e); m->svr_event_type = KICKOFF; tw_event_send(e); return; }
void mem_event_handler(mem_state * s, tw_bf * bf, mem_message * m, tw_lp * lp) { tw_lpid dest; tw_event *e; tw_memory *b; int i; s->stats.s_recv++; // read membufs off inbound event, check it and free it for(i = 0; i < nbufs; i++) { b = tw_event_memory_get(lp); if(!b) tw_error(TW_LOC, "Missing memory buffers: %d of %d", i+1, nbufs); mem_verify(b); tw_memory_free(lp, b, my_fd); s->stats.s_mem_free++; s->stats.s_mem_get++; } if(tw_rand_unif(lp->rng) <= percent_remote) { bf->c1 = 1; dest = tw_rand_integer(lp->rng, 0, ttl_lps - 1); dest += offset_lpid; if(dest >= ttl_lps) dest -= ttl_lps; } else { bf->c1 = 0; dest = lp->gid; } e = tw_event_new(dest, tw_rand_exponential(lp->rng, mean), lp); // allocate membufs and attach them to the event for(i = 0; i < nbufs; i++) { b = mem_alloc(lp); if(!b) tw_error(TW_LOC, "no membuf allocated!"); mem_fill(b); tw_event_memory_set(e, b, my_fd); s->stats.s_mem_alloc++; } tw_event_send(e); }
void tmr_event_handler(tmr_state * s, tw_bf * bf, tmr_message * m, tw_lp * lp) { tw_lpid dest; * (int *) bf = 0; if(s->timer) { // if current event being processed is the timer if(tw_event_data(s->timer) == m) { bf->c1 = 1; m->old_timer = s->timer; s->timer = NULL; fprintf(f, "%lld: tmr fired at %lf\n", lp->gid, tw_now(lp)); return; } else { bf->c2 = 1; m->old_time = s->timer->recv_ts; tw_timer_reset(lp, &s->timer, tw_now(lp) + 100.0); if(s->timer == NULL) fprintf(f, "%lld: reset tmr failed %lf\n", lp->gid, tw_now(lp) + 100.0); else fprintf(f, "%lld: reset tmr to %lf\n", lp->gid, tw_now(lp) + 100.0); } } if(tw_rand_unif(lp->rng) <= percent_remote) { bf->c3 = 1; dest = tw_rand_integer(lp->rng, 0, ttl_lps - 1); dest += offset_lpid; if(dest >= ttl_lps) dest -= ttl_lps; } else { bf->c3 = 0; dest = lp->gid; } if(!lp->gid) dest = 0; tw_event_send(tw_event_new(dest, tw_rand_exponential(lp->rng, mean), lp)); }
//Forward event handler void model_event (state *s, tw_bf *bf, message *in_msg, tw_lp *lp) { int self = lp->gid; // initialize the bit field *(int *) bf = (int) 0; // update the current state // however, save the old value in the 'reverse' message SWAP(&(s->value), &(in_msg->contents)); // handle the message switch (in_msg->type) { case HELLO : { s->rcvd_count_H++; break; } case GOODBYE : { s->rcvd_count_G++; break; } default : printf("Unhandeled forward message type %d\n", in_msg->type); } tw_event *e = tw_event_new(self, 1, lp); message *msg = tw_event_data(e); //# randomly choose message type double random = tw_rand_unif(lp->rng); if (random < 0.5) { msg->type = HELLO; } else { msg->type = GOODBYE; } msg->contents = tw_rand_unif(lp->rng); msg->sender = self; tw_event_send(e); }
//Init function // - called once for each LP // ! LP can only send messages to itself during init ! void model_init (state *s, tw_lp *lp) { int self = lp->gid; // init state data s->rcvd_count_H = 0; s->rcvd_count_G = 0; s->value = -1; // Init message to myself tw_event *e = tw_event_new(self, 1, lp); message *msg = tw_event_data(e); msg->type = HELLO; msg->contents = tw_rand_unif(lp->rng); msg->sender = self; tw_event_send(e); }
static void node_init(node_state *ns, tw_lp *lp) { tw_event *e; node_msg *m; tw_stime init_time; memset(ns, 0, sizeof(*ns)); init_time = g_tw_lookahead + tw_rand_unif(lp->rng); e = codes_event_new(lp->gid, init_time, lp); m = tw_event_data(e); m->node_event_type = INIT; tw_event_send(e); return; }
void phold_pre_run(phold_state * s, tw_lp * lp) { tw_lpid dest; if(tw_rand_unif(lp->rng) <= percent_remote) { dest = tw_rand_integer(lp->rng, 0, ttl_lps - 1); } else { dest = lp->gid; } if(dest >= (g_tw_nlp * tw_nnodes())) tw_error(TW_LOC, "bad dest"); tw_event_send(tw_event_new(dest, tw_rand_exponential(lp->rng, mean) + lookahead, lp)); }
static void svr_init( svr_state * ns, tw_lp * lp) { tw_event *e; svr_msg *m; tw_stime kickoff_time; memset(ns, 0, sizeof(*ns)); /* each server sends a dummy event to itself */ /* skew each kickoff event slightly to help avoid event ties later on */ kickoff_time = g_tw_lookahead + tw_rand_unif(lp->rng); e = codes_event_new(lp->gid, kickoff_time, lp); m = tw_event_data(e); m->event_type = KICKOFF; tw_event_send(e); return; }
static void svr_init( svr_state * ns, tw_lp * lp) { tw_event *e; svr_msg *m; tw_stime kickoff_time; memset(ns, 0, sizeof(*ns)); /* each server sends a dummy event to itself that will kick off the real * simulation */ /* skew each kickoff event slightly to help avoid event ties later on */ kickoff_time = g_tw_lookahead + tw_rand_unif(lp->rng); e = tw_event_new(lp->gid, kickoff_time, lp); m = tw_event_data(e); msg_set_header(magic, KICKOFF, lp->gid, &m->h); tw_event_send(e); return; }
void phold_event_handler(phold_state * s, tw_bf * bf, phold_message * m, tw_lp * lp) { tw_lpid dest; if(tw_rand_unif(lp->rng) <= percent_remote) { bf->c1 = 1; dest = tw_rand_integer(lp->rng, 0, ttl_lps - 1); // Makes PHOLD non-deterministic across processors! Don't uncomment /* dest += offset_lpid; */ /* if(dest >= ttl_lps) */ /* dest -= ttl_lps; */ } else { bf->c1 = 0; dest = lp->gid; } if(dest >= (g_tw_nlp * tw_nnodes())) tw_error(TW_LOC, "bad dest"); tw_event_send(tw_event_new(dest, tw_rand_exponential(lp->rng, mean) + lookahead, lp)); }
void phold_event_handler(phold_state * s, tw_bf * bf, phold_message * m, tw_lp * lp) { tw_lpid dest; if(tw_rand_unif(lp->rng) <= percent_remote) { bf->c1 = 1; dest = tw_rand_integer(lp->rng, 0, ttl_lps - 1); dest += offset_lpid; if(dest >= ttl_lps) dest -= ttl_lps; } else { bf->c1 = 0; dest = lp->gid; } rn_event_send( rn_event_new(dest, tw_rand_exponential(lp->rng, mean), lp, DOWNSTREAM, 0)); }
void epi_xml(epi_state * state, tw_lp * lp) { xmlNodePtr agent; xmlNodePtr move; rn_machine *m = rn_getmachine(lp->id); epi_agent *a; epi_ic_stage *s; double x; int ct; int i; char *sick; // create census tract table if it does not exist // need 1 more than number of stages to save dead agents // dead is not a stage. if (!g_epi_ct) { g_epi_nct = 2200; //rn_getarea(m)->nsubnets; g_epi_ct = tw_vector_create(sizeof(unsigned int *), g_epi_nct); for (i = 0; i < g_epi_nct; i++) g_epi_ct[i] = tw_vector_create(sizeof(unsigned int), g_epi_nstages); } state->stats = tw_vector_create(sizeof(epi_statistics), 1); state->pq = pq_create(); ct = rn_getsubnet(m)->id - rn_getarea(m)->subnets[0].id; // spin through agents 'homed' at this location and allocate + init them // // NOTE: May not have *any* agents homed at a given location for(agent = node->children; agent; agent = agent->next) { if(0 != strcmp((char *) agent->name, "agent")) continue; a = tw_vector_create(sizeof(epi_agent), 1); a->ct = m->uid; //ct; a->num = tw_getlp(atoi(xml_getprop(agent, "num"))); //a->a_type = atoi(xml_getprop(agent,"type")); sick = xml_getprop(agent, "sick"); if(g_epi_psick > EPSILON) { if ( tw_rand_unif(lp->rng) < g_epi_psick ) sick = "1"; } if(0 != strcmp(sick, "0")) { //a->ts_infected = atof(sick); a->stage = EPI_INCUBATING; s = &g_epi_stages[a->stage]; x = ((double) tw_rand_integer(lp->rng, 0, INT_MAX) / (double) INT_MAX); a->ts_stage_tran = (s->min_duration + (x * (s->max_duration - s->min_duration))); #if EPI_XML_VERIFY printf("\tstage: %d, time %5f \n", s->stage_index, a->ts_stage_tran); #endif g_epi_nsick++; } else { a->stage = EPI_SUSCEPTIBLE; a->ts_stage_tran = DBL_MAX; //a->ts_infected = DBL_MAX; } g_epi_ct[a->ct][a->stage]++; //a->id = g_epi_nagents++; g_epi_nagents++; a->curr = 0; //a->ts_last_tran = 0.0; a->ts_next = a->ts_remove = (double) 86400.0; //a->n_infected = 0; for(move = agent->children; move; move = move->next) { if(0 != strcmp((char *) move->name, "move")) continue; a->nloc++; } if(!a->nloc) tw_error(TW_LOC, "Agent has no locations!"); a->nloc++; // add a location to return home at end of day a->loc = tw_vector_create(sizeof(int) * a->nloc, 1); a->dur = tw_vector_create(sizeof(tw_stime) * a->nloc, 1); int seconds_used = 0; // totals duration to check for 24 hours for(i = 0, move = agent->children; move; move = move->next) { if(0 != strcmp((char *) move->name, "move")) continue; a->loc[i] = atoi(xml_getprop(move, "loc")); a->dur[i] = atoi(xml_getprop(move, "dur")) * 3600; seconds_used += a->dur[i]; i++; } if (seconds_used > 86400) tw_error(TW_LOC, "Agent has duration more than 24 hours\n"); else if (seconds_used == 86400) a->nloc--; // do not need last location else { a->loc[a->nloc-1] = a->loc[0]; // return home a->dur[a->nloc-1] = 86400 - seconds_used; } a->behavior_flags = 0; if (g_epi_worried_well_rate > 0) { if (tw_rand_unif(lp->rng) < g_epi_worried_well_rate) a->behavior_flags = 1; } else if (g_epi_work_while_sick_p > EPSILON) if (tw_rand_unif(lp->rng) < g_epi_work_while_sick_p) a->behavior_flags = 2; // Set ts_next and enqueue a->ts_remove = a->dur[a->curr]; if(a->ts_remove < a->ts_stage_tran) a->ts_next = a->ts_remove; else a->ts_next = a->ts_stage_tran; pq_enqueue(state->pq, a); } }
/** * Initializer function for SRW. Here we set all the necessary * initial values we assume for the beginning of the simulation. * We also bootstrap the event queue with some random data. */ void srw_init(srw_state *s, tw_lp *lp) { int i; int num_radios; tw_event *e; /* global_id is required to make sure all nodes get unique IDs */ static long global_id = 0; /* current_id is just the starting ID for this particular iteration */ long current_id = global_id; /* Initialize the state of this LP (or master) */ num_radios = tw_rand_integer(lp->rng, 1, SRW_MAX_GROUP_SIZE); s->num_radios = num_radios; s->movements = 0; s->comm_fail = 0; s->comm_try = 0; /* Initialize nodes */ for (i = 0; i < num_radios; i++) { (s->nodes[i]).node_id = global_id++; (s->nodes[i]).lng = 0.0; (s->nodes[i]).lat = 0.0; (s->nodes[i]).movements = 0; (s->nodes[i]).comm_fail = 0; (s->nodes[i]).comm_try = 0; } /* Priming events */ for (i = 0; i < num_radios; i++) { tw_stime ts; srw_msg_data *msg; // GPS event first, as it's the simplest ts = tw_rand_unif(lp->rng); ts = ts * SRW_GPS_RATE; e = tw_event_new(lp->gid, ts, lp); msg = tw_event_data(e); msg->node_id = current_id + i; msg->type = GPS; tw_event_send(e); // Now schedule some movements ts = tw_rand_exponential(lp->rng, SRW_MOVE_MEAN); e = tw_event_new(lp->gid, ts, lp); msg = tw_event_data(e); msg->node_id = current_id + i; msg->type = MOVEMENT; // We have to figure out a good way to set the initial lat/long tw_event_send(e); // Now some communications ts = tw_rand_exponential(lp->rng, SRW_COMM_MEAN); e = tw_event_new(lp->gid, ts, lp); msg = tw_event_data(e); msg->node_id = current_id + i; msg->type = COMMUNICATION; // Something should probably go here as well... tw_event_send(e); } }
/* * Stage transition causes the agent to be removed from the * queue (it is at the head), increment the stage, collect * statistics, and place back in the queue with the minimum * of the next stage transition time and the remove time. */ void agent_stage_tran(epi_state * state, tw_bf * bf, tw_memory * buf, epi_pathogen * p, tw_lp * lp) { epi_ic_stage *s; epi_agent *a; a = tw_memory_data(buf); s = &g_epi_diseases[p->index].stages[p->stage]; if(5 == a->id || 1) printf("%lld: transition %d at %lf \n", lp->gid, a->id && 0, tw_now(lp)); // if this agent is contagious in the old stage, then reduce the location number of // contagious agents by one. if(s->ln_multiplier != 0.0) { state->ncontagious[p->index]--; state->ncontagious_tot--; if(a->behavior_flags == EPI_AGENT_WORRIED_WELL) a->behavior_flags = 0; } if(state->ncontagious[p->index] < 0) tw_error(TW_LOC, "Less than zero ncontagious!"); g_epi_regions[a->region][p->index][p->stage]--; p->stage++; g_epi_regions[a->region][p->index][p->stage]++; if(p->stage >= g_epi_diseases[p->index].nstages) tw_error(TW_LOC, "Invalid stage: %d", p->stage); s = &g_epi_diseases[p->index].stages[p->stage]; p->ts_stage_tran = tw_now(lp); if(fabs(s->max_duration - s->min_duration) < EPSILON) p->ts_stage_tran += s->min_duration; else p->ts_stage_tran += s->min_duration + tw_rand_unif(lp->rng) * (s->max_duration - s->min_duration); if(p->ts_stage_tran > tw_now(lp) + s->max_duration) tw_error(TW_LOC, "Too long!"); if(p->ts_stage_tran < tw_now(lp)) tw_error(TW_LOC, "Backwards stage tran!"); if(p->ts_stage_tran < s->min_duration) tw_error(TW_LOC, "Too short!"); // Perform mortality check if (s->mortality_rate > 0 && tw_rand_unif(lp->rng) < s->mortality_rate ) { a->behavior_flags = EPI_AGENT_DEAD; a->days_remaining = 0; g_epi_regions[a->region][p->index][p->stage]--; p->stage = g_epi_diseases[p->index].nstages; g_epi_regions[a->region][p->index][p->stage]++; // collect statistics state->stats->s_ndead++; } else { // if new stage has infectivity, // then increment number of contagious agents in location. if(s->ln_multiplier != 0.0) { state->ncontagious[p->index]++; state->ncontagious_tot++; state->stats->s_ninfected++; // then must set number of days to stay home if(!(a->behavior_flags & EPI_AGENT_WORK_WHILE_SICK)) { a->days_remaining = ((int) (p->ts_stage_tran - tw_now(lp)) / TWENTY_FOUR_HOURS); if (a->days_remaining < 1) a->days_remaining = 1; g_epi_hospital[state->hospital][0]++; } } epi_agent_update_ts(state, bf, a, lp); // re-enqueue with new ts_next pq_enqueue(g_epi_pq[lp->id], buf); } }
/* * epi_seir_compute: compute SEIR model for all agents in location LPn * * Assume that the probability of catching the disease is constant over time. * If the probability of catching the disease in one hour is P, then the * geometric distribution gives the number of hours before the disease is * caught. We do a draw on the random number generator from the geometric * distribution and if the result is less than the time interval, then the * agent gets sick at that time. */ void epi_seir_compute(epi_state * state, tw_bf * bf, epi_agent * in_a, tw_lp * lp) { /* * For each susceptible agent, for each contagious agent, determine * the susceptible agent caught the disease. */ double draw, delta_t; epi_agent *a, *ai; epi_ic_stage *s, *sn; unsigned int queue_size; unsigned int i, j; void *pq; queue_size = pq_get_size(state->pq); if (queue_size <= 1) return; delta_t = tw_now(lp) - state->last_event; //printf(" lp %2d SEIR delta_t %f at %f\n", (int) lp->id, delta_t, tw_now(lp)); if (delta_t < EPSILON) // already done an seir check at this time. return; //printf("SEIR Check %f\n", tw_now(lp)); pq = state->pq; //printf( "Queue size: %d ", queue_size); for ( i = 0; i < queue_size; i++) { a = (epi_agent *) pq_next( pq, i); //printf("\ta: %d, stage: %d\n ", a->id, a->stage); if (a->stage == EPI_SUSCEPTIBLE) { for (j = 0; j < queue_size; j++) { if ( j == i ) continue; ai = (epi_agent *) pq_next(pq, j); s = &g_epi_stages[ai->stage]; //printf("a: %d, ai: %d, ln_multiplier: %f\n", a->id, ai->id, s->ln_multiplier); if (abs(s->ln_multiplier) > EPSILON) { // tw_geometric draws from uniform until the draw is greater than P. // tw_geometric then returns the number of draws. // For large P (which is 1.0 - multiplier) this could be very large. // Also note that tw_geometric always returns an integer of 1 or // greater. draw = tw_rand_unif(lp->id); draw = log(draw); draw /= g_epi_stages[a->stage].ln_multiplier; //draw = tw_rand_geometric(lp->id, (s->start_multiplier + s->stop_multiplier)/2); //state->stats->s_ndraws += draw; state->stats->s_nchecked++; //printf("SEIR agent %d, stage %d, agent %d, stage %d, draw: %g\n", // a->id, a->stage, ai->id, ai->stage, draw); if (draw <= delta_t) //Make agent sick { #if EPI_DEBUG printf("%7.3f, lp, %7d, agent_infect, , , , %7d, %5.3f, %5.2f\n", tw_now(lp), (int) lp->id, a->id, delta_t, draw); #endif a->stage = EPI_INCUBATING; g_epi_ct[a->ct][0]--; g_epi_ct[a->ct][1]++; if (g_epi_position_f) fprintf(g_epi_position_f, "%.3f,%d,%d,%d\n", tw_now(lp), a->id, (int) lp->id, a->stage); sn = &g_epi_stages[a->stage]; a->ts_infected = tw_now(lp); a->ts_stage_tran = tw_rand_unif(lp->id)*(sn->max_duration - sn->min_duration) + sn->min_duration + tw_now(lp); a->ts_last_tran = tw_now(lp); // collect statistics state->stats->s_ninfected++; break; } #if EPI_DEBUG else { printf("%7.3f, lp, %7d, agent_not_infect, , , , %7d, %5.3f, %5.2f\n", tw_now(lp), (int) lp->id, a->id, delta_t, draw); } #endif } } } } //printf("SEIR compputed at %f ", state->last_event); }
/* * epi_init - initialize node LPs state variables * * state - our node LP state space * lp - our node LP */ void epi_init(epi_state * state, tw_lp * lp) { tw_memory *b; tw_memory *agent = NULL; tw_stime ts_min_tran = DBL_MAX; epi_agent *a; epi_pathogen *p; epi_ic_stage *s; double x; int i; int j; int sz; // hard-coded, single hospital LP if(lp->id == g_tw_nlp-1) { fprintf(g_epi_hospital_f, "0 0 %u %u %u\n", g_epi_hospital[0][0], g_epi_hospital_ww[0][0], g_epi_hospital_wws[0][0]); g_epi_hospital[0][0] = 0; g_epi_hospital_ww[0][0] = 0; g_epi_hospital_wws[0][0] = 0; return; } // ID of the hospital I go to (or nearest if office/school) state->hospital = 0; state->stats = tw_calloc(TW_LOC, "", sizeof(epi_statistics), 1); state->ncontagious = tw_calloc(TW_LOC, "", sizeof(unsigned int), g_epi_ndiseases); state->ts_seir = tw_calloc(TW_LOC, "", sizeof(tw_stime), g_epi_ndiseases); for(i = 0; i < g_epi_ndiseases; i++) state->ts_seir[i] = DBL_MAX; // if no agents initially at this location, then we are done! if(0 == (sz = pq_get_size(g_epi_pq[lp->id]))) return; // determine agents initial parameters / configuration for(i = 0; i < sz; i++) { agent = pq_next(g_epi_pq[lp->id], i); a = tw_memory_data(agent); for(j = 0; j < g_epi_ndiseases; j++) { if(!a->id && !j) { // ALLOCATE PATHOGEN AND FILL IT IN b = tw_memory_alloc(lp, g_epi_pathogen_fd); p = tw_memory_data(b); b->next = a->pathogens; a->pathogens = b; p->index = j; p->stage = EPI_SUSCEPTIBLE; p->ts_stage_tran = DBL_MAX; g_epi_regions[a->region][p->index][p->stage]--; p->stage = EPI_EXPOSED; g_epi_regions[a->region][p->index][p->stage]++; g_epi_exposed_today[j]++; // determine if agents start out sick. if(tw_rand_unif(lp->rng) < g_epi_sick_rate) { s = &g_epi_diseases[p->index].stages[p->stage]; x = ((double) tw_rand_integer(lp->rng, 0, INT_MAX) / (double) INT_MAX); p->ts_stage_tran = (s->min_duration + (x * (s->max_duration - s->min_duration))); if(0.0 >= p->ts_stage_tran) tw_error(TW_LOC, "Immediate stage transition?!"); //state->stats->s_ninfected++; state->ncontagious[p->index]++; state->ncontagious_tot++; //g_epi_hospital[0][0]++; g_epi_sick_init_pop[j]++; ts_min_tran = min(ts_min_tran, p->ts_stage_tran); if(!a->id) printf("%ld: agent exposed %d: %s, transition at %lf\n", lp->id, a->id, g_epi_diseases[j].name, p->ts_stage_tran); } } } // reflect ts_next change in PQ ordering if(ts_min_tran < a->ts_next) { a->ts_next = ts_min_tran; pq_delete_any(g_epi_pq[lp->id], &agent); pq_enqueue(g_epi_pq[lp->id], agent); } // determine if agents are a part of worried well population. if(g_epi_ww_rate) { if(tw_rand_unif(lp->rng) < g_epi_ww_rate) { a->behavior_flags = 1; g_epi_hospital_ww[0][0]++; g_epi_ww_init_pop++; } } else if(g_epi_wws_rate) { if(tw_rand_unif(lp->rng) < g_epi_wws_rate) { a->behavior_flags = 2; g_epi_hospital_wws[0][0]++; g_epi_wws_init_pop++; } } // define agent's at work contact population //g_epi_regions[a->region][a->stage]++; } epi_location_timer(state, lp); }