EN Time dynamics

This is an English translation of the Dutch page Tijdsdynamiek, which is leading. Translated on 8 November 2026 from wiki commit 428045e.

The RuimteScanner 2.0 model does not work with a single time step, but simulates spatial developments over a series of projection years. This page describes how the temporal structure is built, which choices were made in it and which dependencies exist between parameters.

Base year and final year

The model has three anchor years, with the value in the NL2120 application in brackets:

  • Model_StartYear (2023): the base year from which the simulation starts. The state in this year (dwellings, jobs, building footprints, land use) forms the starting situation.
  • Model_FirstZichtjaar (2040): the first projection year, and therefore the second model year after the base year.
  • Model_FinalYear (2120): the last year for which the allocation is computed.

The base year has a double function. It is both the starting point of the allocation and the calibration year for densities: the ratio of dwellings per hectare and of jobs per m² of building footprint in this year is the reference for all density calculations in later projection years.

Relation with input data

The base year must match the reference year of the main input registers. The most critical link is the one with LISA (the national register of jobs, Landelijk Informatiesysteem Arbeidsplaatsen), because job data play a central role in the density calculation for employment. When employment is allocated as well, Model_StartYear must therefore be equal to LISA_StartYear. This requirement is enforced by an IntegrityCheck.

The background is that the job density (m² of building footprint per hectare) is computed as a ratio whose numerator (building footprint per subsector) is taken from the LISA year and whose denominator (hectares per land-use class) from the Model_StartYear. With unequal years this ratio is inconsistent. In addition, jobs from LISA are linked to buildings from the BAG of the corresponding year; with a mismatch, buildings constructed after the LISA reference year contain no jobs, which locally distorts the density ratio.

Other input registers (BAG, BBG, BGT, NVM) have their own reference years, which are set through parameters in ModelParameters.dms. The BAG is also used for a more recent reference year than the base year (through BAG_RecentYear), to include recent building developments. See BAG new construction in detail (in Dutch) for this procedure.

What happens in each projection year

Projection years

Between the base year and the final year lie the projection years: the points in time for which the model computes an allocation. The set is built in Classifications/Time.dms:

  1. The base year itself (Model_StartYear). This is not a projection year in the allocation but the starting point.
  2. The first projection year (Model_FirstZichtjaar).
  3. From there, a projection year every Model_ZichtjaarInterval years, up to and including the final year (Model_FinalYear). An IntegrityCheck requires the final year to fall exactly on that grid; otherwise it would drop out.

In the NL2120 application, with an interval of ten years, these are nine projection years, Y2040 up to and including Y2120. Each projection year has a predecessor (PrevYear); for the first one this is the base year. The allocation for a projection year builds on the results of its predecessor.

The first projection year can be set; in the NL2120 application it is 2040 (#658). The TIGRIS claim for 2030 lies below the base-year state in many regions, and for jobs in almost all regions. The model cannot demolish dwellings or jobs to meet a claim, so only overrealisation could result there; see Claim realisation (in Dutch). With 2040 as the first projection year that constraint disappears for most regions. The first allocation step then covers seventeen years instead of seven. The growth factors use the actual length of the period from Zichtjaar/PrevYearRange_rel, so that works out by itself, but the intermediate step 2030 is missing from the path dependence.

The claims do not run as far as the projection years. TIGRIS delivers up to and including 2060, and ModelParameters/Advanced/FromWhichDoWeKeepTIGRISconstant (2060) makes every later projection year read the claim map of 2060. From 2070 onwards the requirement for housing and employment therefore no longer grows, and differences between variants in those years come from the spatial steering and not from extra demand.

AlleenEindjaar

The parameter AlleenEindjaar (default: FALSE) determines whether all projection years are run or only the final year.

With TRUE the model jumps directly from the base year to the final year. The intermediate projection years are not computed and do not appear in the GeoDMS tree. This saves computing time, but the path dependence is lost: densification and displacement mechanisms that normally work through over decades are skipped.

With FALSE all projection years are run in sequence. The results of each projection year (the state after allocation) are the input for the next. This is the fully path-dependent mode.

The choice affects the model results. With AlleenEindjaar=TRUE all claims for the whole period are allocated at once, so the model fills more space in one go without intermediate feedback. In batch mode this parameter is controlled through the environment variable AlleenEindjaar; RunAll.cmd sets it to FALSE by default and asks whether you want only the final year after all, Run2120.ps1 does not set it and shows the setting from the configuration at the start.

Running the projection years in sequence is not only a matter of accuracy (#637). The suitability for housing takes into account the nature and the water present at the start of a projection year, and that mechanism does nothing when there is only one projection year. See Suitability.

Sequences and iterations

Within each projection year the model runs two nested loops: sequences (outer loop) and iterations (inner loop).

Iterations

Iterations are needed to simulate competition between subsectors. In each iteration part of the regional claim of each subsector is assigned to the most suitable available locations. After each iteration residual locations (where nothing has been allocated yet) and residual claims (regional demand not yet met) remain. In the next iteration the residual claims are assigned to the residual locations.

The number of iterations is set through Default_NrOfIters in ModelParameters.dms, and it is 15. A higher number of iterations leads to a finer distribution but a longer computing time. The allocation table can deviate from it per row: housing and employment at NVM level run 5 iterations in later sequences instead of the default.

Sequences

Sequences are needed to deal with displacement between sectors. When a sector claims locations where actors or objects of an earlier sector were already present, those existing actors and objects are displaced. The displaced units generate residual claims that are allocated again in a next sequence.

The minimum number of sequences is 2 (Default_NrOfSequences, enforced through an IntegrityCheck). In the first sequence all sectors are allocated in order. In the second sequence only the sectors that suffered displacement in the first sequence are run again (controlled through UseInLaterSequences per combination of sector and allocation region).

Order of the sectors

The order in which sectors are allocated is set in the table SectorAllocRegio in ModelParameters.dms, not with the variant parameters. Each row names a sector, the regional level, whether the sector is run again in later sequences, and the number of iterations in the first and in the later sequences. Sectors that do not take part are commented-out rows in the same table, so switching one on is a matter of restoring the row and raising the row count. In the NL2120 application eight rows are active:

  1. Housing at NVM level, then COROP, then province
  2. Employment at NVM level, then COROP, then province
  3. Water storage at the level of the water storage region
  4. Agriculture at province level

Holiday accommodation, solar and wind are commented out there. That is a choice of that application and not a property of the model.

Per sector the allocation is carried out at several regional levels, from fine to coarse. Each coarser level sets the claim of its own region against the state again, so that a shortage in a fine region finds room at the coarser level as long as the larger region as a whole still has a residual claim; see Overflow (in Dutch). The parameter UseInLaterSequences determines per combination of sector and region whether the sector is run again in later sequences when displacement occurs.

Decoupling

The model can be run in steps by storing intermediate results (“decoupling”) and reusing them in later calculations. That determines the computing time during development and debugging, and it makes a batch run with one process per projection year possible.

The allocation chain has three steps, each with its own switch:

Parameter Step What is decoupled
BaseDataOntkoppeld 1 Generic data, independent of scenario and variant
VariantDataOntkoppeld 2 Variant-specific data from before the allocation
StandAllocatieOntkoppeld 3 The state after the allocation per projection year; a projection year then reads the state of its predecessor from the tifs

The indicators have two: IndicatorenOntkoppeld, with which a projection year reads what it needs from its predecessor from the chain tifs, and TabellenUitExport, with which the tables read back the written maps. The switches for individual files, such as BAG_WP5_rel_Ontkoppeld and OpbrengstdervingOntkoppeld, and the mechanism that decides whether a file may be reused, are on Decoupled files (in Dutch).

Setting a parameter to TRUE means: read this part from disk instead of computing it again. The condition is that the decoupled files are up to date for the current configuration. In a production run, separate steps first write the base data and the variant data, and the allocation then runs with all three switches on TRUE; see Running a batch run (in Dutch).

Not all combinations make sense. VariantDataOntkoppeld=FALSE together with BaseDataOntkoppeld=FALSE only makes sense if the base data really has to be made again as well. There is no IntegrityCheck on the combinations.

OntkoppelStedelijkeKlasses does not belong to this series. It is a debug switch with which only agriculture allocates and the urban sectors take over their incoming state; in a full series it is FALSE.