Step 21: Net Migration

Overview

At this step we add the optional module NetMigration.mpp which gives the user an additional option of modeling international migration - net migration - based on a parameter of total net migration by ag, sex, and period. This option is useful if only data on net migration are available, as is the case for Eurostat population projections.

The new NetMigration.mpp Module

This module gives the user an additional option of modeling international migration - net migration - based on a parameter of total net migration by age, sex, and period. This option is useful if only data on net migration are available, as is the case for Eurostat population projections. The module introduces a new selection switch for modeling international migration:

  • Do not model migration
  • Immigration only
  • Emigration only
  • Immigration & Emigration
  • Net Migration

This selection parameter is used to set the previousely used checkboxes for modeling immigration and emigration which were changed to model-generated parameters set in the pre-simulation phase. If net migration is chosen, the immigration parameters are overwritten by values based on the new net migration parameter. For emigration, a new Clock function DoNetEmigration() was added which - when selected - replaces the DoEmigration() function.

The addition of this module required only minor changes to other modules:

  • Emigration.mpp: the parameter ModelEmigration is made model-generated
  • Immigration.mpp the parameter ModelImmigration is made model-generated, ImmigrationAgeSexAll is changed from cumrate to double
  • model_core.mpp: the condition to generate immigrants is changed to also include net immigration
  • PersonCore: age and sex of immigrants are now sampled from the model-generated parameter MgImmigrationAgeSexAll


////////////////////////////////////////////////////////////////////////////////////////////////////
// Types
////////////////////////////////////////////////////////////////////////////////////////////////////


classification MIGRATION_SETTINGS //EN Migration Settings
{
    MSE_NON,            //EN Do not model migration
    MSE_IMMI,           //EN Immigration only
    MSE_EMI,            //EN Emigration only
    MSE_ALL,            //EN Immigration & Emigration
    MSE_NET             //EN Net Migration
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Parameters
////////////////////////////////////////////////////////////////////////////////////////////////////

parameters
{
    //EN Migration Settings
    MIGRATION_SETTINGS MigrationSettings;

    //EN Model net migration
    model_generated logical ModelNetMigration;

    //EN Net migration by age and sex
    double NetMigrationSexPeriodAge[SEX][SIM_YEAR_RANGE][AGE_RANGE];

    //EN Total number of immigrants
    model_generated long MgImmigrationTotal[SIM_YEAR_RANGE];

    //EN Age-Sex distribution of immigrants
    model_generated cumrate [2] MgImmigrationAgeSexAll[SIM_YEAR_RANGE][SEX][AGE_RANGE];
};

parameter_group PG_NetMigration                          //EN Net Migration
{
    NetMigrationSexPeriodAge
};

parameter_group PG_Migration                            //EN International Migration
{
    MigrationSettings,
    PG_Immigration,
    PG_Emigration,
    PG_NetMigration
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// States & Functions
////////////////////////////////////////////////////////////////////////////////////////////////////

actor Clock
{
    void DoNetEmigration();                                     //EN Net Emigration
    hook DoNetEmigration, MidYearClockEvent, 6;                 //EN hook to mid year
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Implementation
////////////////////////////////////////////////////////////////////////////////////////////////////

void Clock::DoNetEmigration()
{
    if (clock_year >= MIN(SIM_YEAR_RANGE) && ModelNetMigration == TRUE)
    {
        // for each age by sex
        for (int nSex = 0; nSex < SIZE(SEX); nSex++)
        {
            for (int nAge = 0; nAge < SIZE(AGE_RANGE); nAge++)
            {
                double dExpectedEmigrants = 0.0;
                long nExpectedEmigrants = 0;

                if (NetMigrationSexPeriodAge[nSex][RANGE_POS(SIM_YEAR_RANGE, clock_year)][nAge] < 0) // there is net emigration
                {
                    // determine number of emigrants
                    dExpectedEmigrants = -NetMigrationSexPeriodAge[nSex][RANGE_POS(SIM_YEAR_RANGE, clock_year)][nAge]
                        / asGlobals->Item(0)->person_weight;
                    nExpectedEmigrants = int(dExpectedEmigrants);
                    if (RandUniform(46) < dExpectedEmigrants - (double)nExpectedEmigrants) nExpectedEmigrants++;

                    // Make somebody emigrate
                    for (int nIndex = 0; nIndex < nExpectedEmigrants; nIndex++)
                    {
                        if (asAllPersonsSexAge[nSex][nAge]->Count() > 0)
                        {
                            auto prPerson = asAllPersonsSexAge[nSex][nAge]->GetRandom(RandUniform(47));
                            prPerson->DoEmigrate();
                        }
                    }
                }
            }
        }
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Pre-Simulation
////////////////////////////////////////////////////////////////////////////////////////////////////

void PreSimulation()
{
    // Settings

    if (MigrationSettings == MSE_NON)                   // Do not model migration
    {
        ModelNetMigration = FALSE;
        ModelImmigration = FALSE;
        ModelEmigration = FALSE;
    }
    else if (MigrationSettings == MSE_IMMI)             //EN Immigration only
    {
        ModelNetMigration = FALSE;
        ModelImmigration = TRUE;
        ModelEmigration = FALSE;
    }
    else if (MigrationSettings == MSE_EMI)              //EN Emigration only
    {
        ModelNetMigration = FALSE;
        ModelImmigration = FALSE;
        ModelEmigration = TRUE;
    }
    else if (MigrationSettings == MSE_ALL)              //EN Immigration & Emigration
    {
        ModelNetMigration = FALSE;
        ModelImmigration = TRUE;
        ModelEmigration = TRUE;
    }
    else                                                //EN Net Migration
    {
        ModelNetMigration = TRUE;
        ModelImmigration = FALSE;
        ModelEmigration = FALSE;
    }

    // Parameters

    for (int nYear = 0; nYear < SIZE(SIM_YEAR_RANGE); nYear++)
    {
        MgImmigrationTotal[nYear] = 0.0;
    }

    if (ModelNetMigration)
    {
        for (int nYear = 0; nYear < SIZE(SIM_YEAR_RANGE); nYear++)
        {
            double dSumImmigrants = 0;
            for (int nSex = 0; nSex < SIZE(SEX); nSex++)
            {
                for (int nAge = 0; nAge < SIZE(AGE_RANGE); nAge++)
                {
                    if (NetMigrationSexPeriodAge[nSex][nYear][nAge] > 0)
                    {
                        MgImmigrationAgeSexAll[nYear][nSex][nAge] = NetMigrationSexPeriodAge[nSex][nYear][nAge];
                        dSumImmigrants = dSumImmigrants + NetMigrationSexPeriodAge[nSex][nYear][nAge];
                    }
                    else
                    {
                        MgImmigrationAgeSexAll[nYear][nSex][nAge] = 0.0;
                    }
                }
            }
            MgImmigrationTotal[nYear] = dSumImmigrants;
        }
    }
    else
    {
        for (int nYear = 0; nYear < SIZE(SIM_YEAR_RANGE); nYear++)
        {
            MgImmigrationTotal[nYear] = ImmigrationTotal[nYear];
        }

        for (int nYear = 0; nYear < SIZE(SIM_YEAR_RANGE); nYear++)
        {
            for (int nSex = 0; nSex < SIZE(SEX); nSex++)
            {
                for (int nAge = 0; nAge < SIZE(AGE_RANGE); nAge++)
                {
                    MgImmigrationAgeSexAll[nYear][nSex][nAge] = ImmigrationAgeSexAll[nSex][nAge];
                }
            }
        }
    }
}