5.17. Step 17: Secondary Education¶
5.17.1. Model Description¶
At this step we add an optional module for a secondary school which can be attended after graduating from primary school. The model is a period model parameterized by intake, progression and repetition rates.
5.17.2. The new Educ2BasePeriodModel.mpp Module¶
This is an optional module for modeling a “School Two” which can be attended after graduating from the”School One” - in the current implementation this school refers tw a secondary school. The number of grades can be set in the range EDUC_TWO_GRADE and thus is adaptable for the application context. The model follows a period approach. Each year at the end and beginning of school season it is decided if a person enters school, succeeds a grade, progresses to the next or repeats a grade, interrups studies or permanently drops out. A parameter controls the maximum number of years which can be delayed due to repetition or temporary dropout. A student interrupting education can resume studies after a year or stay out permanently. The model is driven by parameters for each calendar year and grade:
- The probability to pass a grade
- The probability to move on directly after passing a grade
- The probability to repeat a grade immediately after failing it
- The probability to resume studies after being out for a year after passing a grade
- The pribability to repeat a grade after being out for a year after failing a grade
- The maximum number of years studies can be delayed by repetition or inactive spells
Besides grade and period, the school progression parameters have two additional dimensions, one for geographical region, the other for personal characteristics. The levels of these two characteristics are model specific, they are declared in the classifications EDUC_TWO_GEO and EDUC_TWO_GROUP, with the corresponding states educ_two_geo and educ_two_group. Currently only totals are implemented.
As an optional module the module can be added or removed from the model. The only required code change in other modules is the creation of the actor SchoolTwoActor in the Simulation() function.
////////////////////////////////////////////////////////////////////////////////////////////////////
// Actor Sets
////////////////////////////////////////////////////////////////////////////////////////////////////
//EN The School Two
actor_set SchoolTwoActor asSchoolTwoActor;
//EN Potential Students of School Two
actor_set Person asPotentialSchoolTwoStudent
filter educ_one_grade_passed == MAX(EDUC_ONE_GRADE)
&& educ_two_status != ETS_OUT && educ_two_delay <= Educ2AllowedDelays;
//EN Students of School Two To Be Processed
actor_set Person asPotentialSchoolTwoStudentToProcess
filter is_alive && educ_two_to_process;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Types
////////////////////////////////////////////////////////////////////////////////////////////////////
range EDUC_TWO_GRADE { 1, 6 }; //EN Grades School Two
range EDUC_TWO_GRADE0 { 0 , 6 }; //EN Grades School Two (incl. 0)
range EDUC_TWO_ENTRY_DUR { 0, 2 }; //EN Possible entry points years since primary
classification EDUC_TWO_STATUS //EN Current attendance status in School Two
{
ETS_NEVER, //EN Never entered
ETS_WAIT, //EN Wait for entry (e.g. school break)
ETS_ATTEND, //EN Currently attending
ETS_PAUSE, //EN Pause
ETS_OUT //EN Left school
};
classification EDUC_TWO_GEO //EN Regional Unit
{
ETG_OO //EN All
};
classification EDUC_TWO_GROUP //EN Population Group
{
E2G_OO //EN All
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Prameters
////////////////////////////////////////////////////////////////////////////////////////////////////
parameters
{
//EN Lower Secondary Period Direct Progression Intake
double Educ2DirectProgressionIntake[EDUC_TWO_GEO][EDUC_TWO_GROUP][EDUC_TWO_GRADE][SIM_YEAR_RANGE];
//EN Lower Secondary Period Delayed Progression Intake
double Educ2DelayedProgressionIntake[EDUC_TWO_GEO][EDUC_TWO_GROUP][EDUC_TWO_GRADE][SIM_YEAR_RANGE];
//EN Lower Secondary Period Success
double Educ2PeriodSuccess[EDUC_TWO_GEO][EDUC_TWO_GROUP][EDUC_TWO_GRADE][SIM_YEAR_RANGE];
//EN Lower Secondary Period Direct Repetition Intake
double Educ2DirectRepetitionIntake[EDUC_TWO_GEO][EDUC_TWO_GROUP][EDUC_TWO_GRADE][SIM_YEAR_RANGE];
//EN Lower Secondary Period Delayed Repetition Intake
double Educ2DelayedRepetitionIntake[EDUC_TWO_GEO][EDUC_TWO_GROUP][EDUC_TWO_GRADE][SIM_YEAR_RANGE];
//EN Maximum years of delays allowed (interruption, repetition of grades)
int Educ2AllowedDelays;
model_generated double StartSchoolTwoYear; //EN Start of school year
model_generated double EndSchoolTwoYear; //EN End of school year
};
parameter_group EducTwo //EN Secondary School
{
Educ2DirectProgressionIntake, Educ2DelayedProgressionIntake, Educ2PeriodSuccess,
Educ2DirectRepetitionIntake, Educ2DelayedRepetitionIntake, Educ2AllowedDelays
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Actors
////////////////////////////////////////////////////////////////////////////////////////////////////
actor Person
{
int educ_two_delay = { 0 };
logical educ_two_to_process = { FALSE };
EDUC_TWO_STATUS educ_two_status = { ETS_NEVER };
EDUC_TWO_GRADE0 educ_two_grade_attended = { 0 }; //EN Highest grade attended
EDUC_TWO_GRADE0 educ_two_grade_passed = { 0 }; //EN Highest grade passed
EDUC_TWO_GEO educ_two_geo = {ETG_OO}; //EN Geographical location
EDUC_TWO_GROUP educ_two_group = {E2G_OO}; //EN Person group
};
actor SchoolTwoActor
{
TIME time_start_school_two_year = { TIME_INFINITE}; //EN Next start of school year
TIME time_end_school_two_year = { TIME_INFINITE}; //EN Next end of school year
event timeStartSchoolTwoYearEvent, StartSchoolTwoYearEvent; //EN Start school year event
event timeEndSchoolTwoYearEvent, EndSchoolTwoYearEvent; //EN End school year event
};
actor Clock
{
void SetSchoolYearTwoClock(); //EN Clock for scheduling school year
hook SetSchoolYearTwoClock, StartYearClock; //EN Hooked to Start Year
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Implementation School Two Functions
////////////////////////////////////////////////////////////////////////////////////////////////////
TIME SchoolTwoActor::timeStartSchoolTwoYearEvent(){return time_start_school_two_year;}
void SchoolTwoActor::StartSchoolTwoYearEvent()
{
for (long nJ = 0; nJ < asPotentialSchoolTwoStudent->Count(); nJ++)
{
auto prPerson = asPotentialSchoolTwoStudent->Item(nJ);
if (prPerson->educ_two_status == ETS_WAIT )
{
prPerson->educ_two_status = ETS_ATTEND ;
prPerson->educ_two_grade_attended = prPerson->educ_two_grade_passed + 1;
}
}
time_start_school_two_year = TIME_INFINITE;
}
TIME SchoolTwoActor::timeEndSchoolTwoYearEvent(){return time_end_school_two_year;}
void SchoolTwoActor::EndSchoolTwoYearEvent()
{
// Flag the persons to be processed
for (long nJ = 0; nJ < asPotentialSchoolTwoStudent->Count(); nJ++)
{
auto prPerson = asPotentialSchoolTwoStudent->Item(nJ);
prPerson->educ_two_to_process = TRUE;
}
// Process all potential students
for (long nJ = 0; nJ < asPotentialSchoolTwoStudentToProcess->Count(); nJ++)
{
auto prPerson = asPotentialSchoolTwoStudentToProcess->Item(nJ);
int nGeo = prPerson->educ_two_geo;
int nGroup = prPerson->educ_two_group;
int nGradeAttend = RANGE_POS(EDUC_TWO_GRADE, prPerson->educ_two_grade_attended);
int nYear = RANGE_POS(SIM_YEAR_RANGE, prPerson->calendar_year);
// Potential Student has not entered school yet
if (prPerson->educ_two_status == ETS_NEVER && (
( prPerson->educ_two_delay == 0 && RandUniform(39) < Educ2DirectProgressionIntake[nGeo][nGroup][0][nYear] ) ||
( prPerson->educ_two_delay == 1 && RandUniform(40) < Educ2DelayedProgressionIntake[nGeo][nGroup][0][nYear] )))
{
prPerson->educ_two_status = ETS_WAIT;
prPerson->educ_two_delay = 0; //reset at school entry
}
else if (prPerson->educ_two_status == ETS_NEVER) prPerson->educ_two_delay++;
// Active student in last year
else if (prPerson->educ_two_grade_attended == MAX(EDUC_TWO_GRADE) && prPerson->educ_two_status == ETS_ATTEND)
{
// Graduate
if ( RandUniform(41) < Educ2PeriodSuccess[nGeo][nGroup][nGradeAttend][nYear] )
{
prPerson->educ_two_grade_passed = prPerson->educ_two_grade_attended;
prPerson->educ_two_status = ETS_OUT;
}
// Fail and repeat if still time
else if (RandUniform(42) < Educ2DirectRepetitionIntake[nGeo][nGroup][nGradeAttend][nYear] && prPerson->educ_two_delay < Educ2AllowedDelays)
{
prPerson->educ_two_delay++;
prPerson->educ_two_status = ETS_WAIT;
}
// Fail and wait
else if ( prPerson->educ_two_delay + 1 < Educ2AllowedDelays )
{
prPerson->educ_two_delay++;
prPerson->educ_two_status = ETS_PAUSE;
}
// Fail and finally out
else
{
prPerson->educ_two_status = ETS_OUT;
}
}
// Active student before last year
else if (prPerson->educ_two_grade_attended < MAX(EDUC_TWO_GRADE) && prPerson->educ_two_status == ETS_ATTEND)
{
// Decide grade success
if ( RandUniform(43) < Educ2PeriodSuccess[nGeo][nGroup][nGradeAttend][nYear] )
{
prPerson->educ_two_grade_passed = prPerson->educ_two_grade_attended;
}
// Success
if ( prPerson->educ_two_grade_passed == prPerson->educ_two_grade_attended )
{
if (RandUniform(44) < Educ2DirectProgressionIntake[nGeo][nGroup][nGradeAttend+1][nYear])
{
prPerson->educ_two_status = ETS_WAIT;
}
else if (prPerson->educ_two_delay < Educ2AllowedDelays)
{
prPerson->educ_two_delay++;
prPerson->educ_two_status = ETS_PAUSE;
}
else prPerson->educ_two_status = ETS_OUT;
}
// no success
else
if (RandUniform(45) < Educ2DirectRepetitionIntake[nGeo][nGroup][nGradeAttend][nYear]
&& prPerson->educ_two_delay < Educ2AllowedDelays)
{
prPerson->educ_two_delay++;
prPerson->educ_two_status = ETS_WAIT;
}
else if (prPerson->educ_two_delay + 1 < Educ2AllowedDelays)
{
prPerson->educ_two_delay = prPerson->educ_two_delay + 2;
prPerson->educ_two_status = ETS_PAUSE;
}
else prPerson->educ_two_status = ETS_OUT;
}
// Previousely inactive
else
{
// Progression
if ( prPerson->educ_two_grade_attended == prPerson->educ_two_grade_passed
&& RandUniform(46) < Educ2DelayedProgressionIntake[nGeo][nGroup][nGradeAttend+1][nYear] )
{
prPerson->educ_two_status = ETS_WAIT;
}
// Repetition
else if (RandUniform(47) < Educ2DelayedRepetitionIntake[nGeo][nGroup][nGradeAttend][nYear] )
{
prPerson->educ_two_status = ETS_WAIT;
}
else prPerson->educ_two_status = ETS_OUT;
}
}
// Unflag all persons
while (asPotentialSchoolTwoStudentToProcess->Count() > 0)
{
asPotentialSchoolTwoStudentToProcess->Item(0)->educ_two_to_process = FALSE;
}
time_end_school_two_year = TIME_INFINITE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Implementatation Clock Functions
////////////////////////////////////////////////////////////////////////////////////////////////////
void Clock::SetSchoolYearTwoClock()
{
asSchoolTwoActor->Item(0)->time_start_school_two_year = WAIT(StartSchoolTwoYear);
asSchoolTwoActor->Item(0)->time_end_school_two_year = WAIT(EndSchoolTwoYear);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Pre-Simulation
////////////////////////////////////////////////////////////////////////////////////////////////////
void PreSimulation()
{
StartSchoolTwoYear = StartSchoolOneYear + 0.000114155; // one hour later than school one
EndSchoolTwoYear = EndSchoolOneYear + 0.000114155; // one hour later than school one
};
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
table Person School2TrackTab //EN School TWO Enrolment
[trigger_changes(calendar_year) && in_projected_time && is_resident && educ_two_status == ETS_ATTEND]
{
{
unit //EN Students
}
* sim_year
* educ_two_grade_attended+
};
5.17.3. Initializations in the Simulation() Function¶
The new actor is created in the Simulation() function.
// Create the School Two
auto prSchoolTwoActor = new SchoolTwoActor();
prSchoolTwoActor->Start();