17  Calculating water flow accumulation

17.1 Water flow algorithm

Towards our calculation of land productivity, we advance using our GIS data in combination with parts of the Land submodel in the Indus Village model (Angourakis 2021). Our objective in this step is to reach a flow accumulation value for each patch according to their relative elevation within the terrain. This will serve as a proxy of the region hydrology beyond the data we have on rivers.

The submodel is based on the algorithm described in Jenson & Domingue (1988) through the implementation used by Huang & Lee (2015).

Jenson, S. K., and J. O. Domingue. 1988. ‘Extracting Topographic Structure from Digital Elevation Data for Geographic Information System Analysis’. Photogrammetric Engineering and Remote Sensing 54 (11): 1593–1600.

Huang, Pin Chun, and Kwan Tun Lee. 2015. ‘A Simple Depression-Filling Method for Raster and Irregular Elevation Datasets’. Journal of Earth System Science 124 (8): 1653–65. https://doi.org/10.1007/s12040-015-0641-2.

17.2 Adding the main procedures

The algorithm uses a numeric codification of the eight neighbour directions and a tag that classifies patches as “start”, “pending”, “done”, progressively converting the formers into the latter. Patches on the edge of the map are directed automatically towards the outside. Because this is an significant piece of code based on a specific reference, we will enclose all related procedures within a especial commentary note:

Outside this enclosed section, we add the two main procedures set-flow-directions and set-flow-accumulations inside a higher level setup-flows:

We add a last step to get maxFlowAccumulation, which we will need for scaling purposes.

17.3 Visualisation

As usual, we need to implement some extra code to be able to visualise the outcome. In this case, however, we would like to observe simultaneously flow direction, flow accumulation and elevation. For this, we will use an accessory agent type whose only function is representing the flow of patches on top of its colour.

Now, press “setup”. The calculation of variables is made relatively fast, but displaying all flowHolders will take some time.

View of flow direction and accumulation, calculated with ‘flows’ module
View of flow direction and accumulation, calculated with ‘flows’ module

17.4 Assessing fit

To better visualise how much flow_accumulation actually gets accumulated, let us run the following “highlight” command directly in the console:

Highlight of patches with flow accumulation greater than 10
Highlight of patches with flow accumulation greater than 10

Focus view on a sample of patches:
| | | | — | — | | patch 70 145 | | | patch 179 69 | | | patch 70 145 | | | patch 201 108 | | | patch 125 99 | | | patch 54 76 | |

Our approximation of the region’s hydrological system is definitely not perfect. As a minimum, we want the main river, Lithaíos, to emerge, even if following an approximated path. The problem is most likely generated by our previous step: reducing the resolution of the original DEM. The height map we are using has many “sinks” in it (i.e., patches not at the edge with the lowest elevation among its neighbours).

Worse, it might be that the roughness of the terrain escapes even the lowest of the resolutions treatable at this scale, to a point where the pathways of rivers cannot be retraced using height maps. Let us work with the first hypothesis and address the sinks in our processed height map.

17.5 Improving fit with fill-sink

Our result could be improved by using the fill-sink procedure in the original Land model implementation (see code in the Indus Village repository), which is based on Huang & Lee (2015).

This procedure fills up the elevation of “sink” patches so flow can continue moving, until it reaches the edge of the map.

First, we can identify sink patches with the following procedure:

We then used it together with our previous “highlight” command in the console:

Highlight of sink patches
Highlight of sink patches

We then implement the fill-sinks algorithm:

After running setup again, we obtain a much better result. We can now clearly identify what should be the Lithaíos river and its path is not too far from our original river data.

View of flow direction and accumulation, calculated with ‘flows’ module with the fill-sinks procedure
View of flow direction and accumulation, calculated with ‘flows’ module with the fill-sinks procedure

Highlight of patches with flow accumulation greater than 10
Highlight of patches with flow accumulation greater than 10, after we include the fill-sinks procedure

We should remember that this algorithm modifies our original DEM heightmap and costs more computation resources/time.

17.6 Implementing a feature to export and import world

We do not want to repeat this every time we initialise a simulation run. Therefore, we will export the entire map configuration to a file for later use. We do this quickly with “File > Export… > Export World” and selecting the data folder. We could write procedures specific for exporting (and importing) a subset of data. Still, this option is much faster, given that this is the initial spatial data we want for all further versions.

Still, if you need to do this several times and want to keep track of the directory and file you are using, you can add a button to the interface with the following code, which is equivalent to the built-in option in the menu:

The same can be done to import the same file. Inside a new button, add:

Now, you should be able to export and import your map with flows.

See the fully implemented version of this module: BlockC_module2_flows.nlogo.

For the sake of this example, we will assume our approximation to be sufficient. Still, tackling this kind of problem exploring other solutions in your own time could be an excellent exercise for improving your skills.