# Towards A Sponge City

By Rui Wang & Shuo Han

An interactive model of the floods formation and simulates how precipitation, drainage system, green ratio would collectively influence flooding in the city.

Intro

Under the circumstance of climate change, the weather gets more extreme and brings about disastrous consequences. On the other hand, the green lands in the city are being exploited for other uses, which in the end would deteriorate the condition. The model shows how the green lands can relieve the flooding to a certain degree and argues for proposals like Sponge City and City Farming to increase the city’s resilience to climate change.

Principle & Visulization:

The precipitation and green lands ratio can be controlled. If the precipitation excess the total amount of the drainage system, there will be dynamic flooding alert on the road plane. The water level is counted as m/20 days.

-Phase 1

Municipal drainage system works to drain away water if the precipitation is small. And you wouldn’t see flooding alert.

-Phase 2

The city begins to be flooding because of the large quantity of precipitation and the orginal municiple drainage is not enough. But by changing the green ratio, green lands could help drain away water to avoid flooding.

-Phase 3

When the green ratio comes to its largest capacity, the flooding couldn’t be avoided. But its still helpful to have green lands to help relieve.

Agents:

Greenland ratio (the component ‘plane’) and rainfall (the component ‘cube’)

Behavior:

In this interactive model we try to simulate the effect of urban green-land ratio on the phenomenon of flooding in urban areas. Green lands, as one kind of penetrable land cover, helps rainwater converge to the groundwater, preventing the city from flooding. As the ratio grows, the potential risk of flooding would decrease. Otherwise, it would increase.

Parameters:

Given that this is based on realistic statistics although it’s an abstract model, we adopted the widely-accepted formula and parameters for the two main value for our model, which is the rainfall and the overall drainage volume. Demonstration is as follows:

l Rainfall: The widely-accept way to measure daily precipitation is to use a measuring cylinder whose radius is 2 centimeters, the height of the rainwater in the cylinder after a whole day would be the daily precipitation, and the dimension would be millimeter. Define this data as DP (daily precipitation), and define the area of the measuring cylinder as A. If we want to figure out the volume of rainwater, and use the dimension of m³/s, the expression would be

[DP*10^(-2)*A]/(24*3600)

1.2*10^(-7)*A*DP …… …… …… ……E1

l Overall drainage volume:

This contains two parts, which refer to the part of green lands and the part of city drainage system.

The volume of rainwater penetrated to groundwater by green lands (V) per second would be:

V=αKJA’t

α- Comprehensive safety factor, 0.5–0.6

K- Soil permeability coefficient (m/s), we use an average value of 9.0*(10^-6) here

A’- Effective penetration area (㎡), which is greenland ratio (GR) multiply A

t-time (s)

The expression would be:

0.5*9.0*(10^-6)*GR*A

4.5*10^(-6)*A*GR …… …… …… ……E2

l The volume of rainwater emission by the city drainage system (V’) per second would be:

(0.00074*A)/200 …… …… …… ……E3

If the rainfall per second is greater than the overall drainage volume per second, there wold be risk of flooding in the city. In our model, if E1>E2+E3, a flooding alert would be triggered, and the color of the ground would turn red.

Given that DP and GR are controlled by the sliders, the minimum of them are 0, and the maximum are 1, so we remapped the parameters linearly. The final expression to justify if there’s risk of flooding is like this:

1.2*10^(-5)*DP>8.1*10^(-7)*GR+3.7*10^(-6)

Inputs:

The inputs refer to the 2 variables in the model, which is the green-land ratio and the rainfall, controlled by the two sliders.

Outputs

The outputs refer to the color of the land (component ‘plane’), which would turn red when there’s risk of flooding and remain gray when there’s no risk, and the flooding water (component ‘cube’), whose height would change according to the change of green-land ratio and rainfall.

Water Material

`Shader "Unlit/NewUnlitShader"{    Properties {        _Color ("Main Color", Color) = (0, 0.15, 0.115, 1)        _MainTex ("Base (RGB)", 2D) = "white" {}        _WaveMap ("Wave Map", 2D) = "bump" {}        _Cubemap ("Environment Cubemap", Cube) = "_Skybox" {}        _WaveXSpeed ("Wave Horizontal Speed", Range(-0.1, 0.1)) = 0.01        _WaveYSpeed ("Wave Vertical Speed", Range(-0.1, 0.1)) = 0.01        _Distortion ("Distortion", Range(0, 100)) = 10    }    SubShader {        Tags { "Queue"="Transparent" "RenderType"="Opaque" }        GrabPass { "_RefractionTex" }        Pass {            Tags { "LightMode"="ForwardBase" }            CGPROGRAM            #include "UnityCG.cginc"            #include "Lighting.cginc"            #pragma multi_compile_fwdbase            #pragma vertex vert            #pragma fragment frag            fixed4 _Color;            sampler2D _MainTex;            float4 _MainTex_ST;            sampler2D _WaveMap;            float4 _WaveMap_ST;            samplerCUBE _Cubemap;            fixed _WaveXSpeed;            fixed _WaveYSpeed;            float _Distortion;              sampler2D _RefractionTex;            float4 _RefractionTex_TexelSize;            struct a2v {                float4 vertex : POSITION;                float3 normal : NORMAL;                float4 tangent : TANGENT;                 float4 texcoord : TEXCOORD0;            };            struct v2f {                float4 pos : SV_POSITION;                float4 scrPos : TEXCOORD0;                float4 uv : TEXCOORD1;                float4 TtoW0 : TEXCOORD2;                  float4 TtoW1 : TEXCOORD3;                  float4 TtoW2 : TEXCOORD4;             };            v2f vert(a2v v) {                v2f o;                o.pos = UnityObjectToClipPos(v.vertex);                o.scrPos = ComputeGrabScreenPos(o.pos);                o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);                o.uv.zw = TRANSFORM_TEX(v.texcoord, _WaveMap);                float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;                  fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);                  fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);                  fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w;                 o.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);                  o.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);                  o.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);                  return o;            }            fixed4 frag(v2f i) : SV_Target {                float3 worldPos = float3(i.TtoW0.w, i.TtoW1.w, i.TtoW2.w);                fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));                float2 speed = _Time.y * float2(_WaveXSpeed, _WaveYSpeed);                fixed3 bump1 = UnpackNormal(tex2D(_WaveMap, i.uv.zw + speed)).rgb;                fixed3 bump2 = UnpackNormal(tex2D(_WaveMap, i.uv.zw - speed)).rgb;                fixed3 bump = normalize(bump1 + bump2);                float2 offset = bump.xy * _Distortion * _RefractionTex_TexelSize.xy;                i.scrPos.xy = offset * i.scrPos.z + i.scrPos.xy;                fixed3 refrCol = tex2D( _RefractionTex, i.scrPos.xy/i.scrPos.w).rgb;                bump = normalize(half3(dot(i.TtoW0.xyz, bump), dot(i.TtoW1.xyz, bump), dot(i.TtoW2.xyz, bump)));                fixed4 texColor = tex2D(_MainTex, i.uv.xy + speed);                fixed3 reflDir = reflect(-viewDir, bump);                fixed3 reflCol = texCUBE(_Cubemap, reflDir).rgb * texColor.rgb * _Color.rgb;                fixed fresnel = pow(1 - saturate(dot(viewDir, bump)), 4);                fixed3 finalColor = reflCol * fresnel + refrCol * (1 - fresnel);                return fixed4(finalColor, 1);            }            ENDCG        }    }    FallBack Off}`

Water Level

`public class RainQuantity : MonoBehaviour{    public Slider RQ;    public Slider GR;    public GameObject SQ;    public GameObject WL;    public GameObject FL;    public GameObject WH;    public Text SQT;    public Text WLT;    public Text FLT;    public Text ShowSpeed;    public Text ShowPercent;    float z1;    float z2;    // Start is called before the first frame update    void Start()    {          }    // Update is called once per frame    void Update()    {        z1 = (float) (1.0368 * RQ.value)*30;        var value = GR.value;        z2 = (float) (0.07 * value + 0.32)*30;        SQ.transform.localScale = new Vector3(10f, (float) (z1*0.5), 10f);        SQ.transform.position=new Vector3(-100f, (float) (0.25*z1), -120f);        WL.transform.localScale = new Vector3(10f, (float) (0.5*z2), 10f);        WL.transform.position=new Vector3(-75f, (float) (0.25*z2), -120f);        FL.transform.localScale = new Vector3(10f, (float) (0.5*(z1-z2)), 10f);        FL.transform.position=new Vector3(-50f, (float) (0.25*(z1-z2)), -120f);        WH.transform.localScale = new Vector3(200f, (float) (0.5*(z1-z2)), 200f);        WH.transform.position=new Vector3(0, (float) (0.25*(z1-z2)), 0);        SQT.transform.localPosition=new Vector3(100,-515+z1*2,0);        WLT.transform.localPosition=new Vector3(200,-570+z2*2,0);        FLT.transform.localPosition=new Vector3(300,-620+(z1-z2)*2,0);        SQT.text = (int) (100*z1)*0.01 + "m/20 D";        WLT.text = (int) (100*z2)*0.01 + "m/20 D";        FLT.text = (int) (100*(z1 - z2))*0.01 + "m/20 D";        ShowSpeed.text = (int) (100 * z1 / 30) * 0.01 + "m/24 h";        ShowPercent.text = (int) (100 * value) + "%";    }}`

`using System.Collections;using System.Collections.Generic;using UnityEngine;using System;using UnityEngine.UI;    public class Flooding : MonoBehaviour    {         public Slider GR;        public Slider RQ;                       private Material myMaterial;        // Start is called before the first frame update        float x;        float y;        float z1;        float z2;                                       void Start()        {            myMaterial = GetComponent<MeshRenderer>().material;                                }        // Update is called once per frame        void Update()        {            y = GR.value;            x = RQ.value;            z1 = (float) (1.2 * Math.Pow(10, -5) * x);            z2 = (float) (8.1 * Math.Pow(10, -7) * y + 3.7 * Math.Pow(10, -6));            if (z1> z2)            {                myMaterial.color = new Color((z1-z2)*900000, 0,0);            }            else if(z1<=z2)            {                myMaterial.color = new Color(0,0,0);            }`

Green Lands

`public class ScaleControl : MonoBehaviour{    public Slider Greenratio;    public GameObject Green1;    public GameObject Green2;    public GameObject Green3;    public GameObject Green4;    public GameObject Green5;    public GameObject Green6;    public GameObject Green7;    public GameObject Green8;    // Start is called before the first frame update    void Start()    {       }    // Update is called once per frame    void Update()    {        Green1.transform.localScale = new Vector3(Greenratio.value, 1.0f, Greenratio.value);        Green2.transform.localScale = new Vector3(Greenratio.value, 1.0f, Greenratio.value);        Green3.transform.localScale = new Vector3(Greenratio.value, 1.0f, Greenratio.value);        Green4.transform.localScale = new Vector3(Greenratio.value, 1.0f, Greenratio.value);        Green5.transform.localScale = new Vector3(Greenratio.value, 1.0f, Greenratio.value);        Green6.transform.localScale = new Vector3(Greenratio.value, 1.0f, Greenratio.value);        Green7.transform.localScale = new Vector3(Greenratio.value, 1.0f, Greenratio.value);        Green8.transform.localScale = new Vector3(Greenratio.value, 1.0f, Greenratio.value);            }`

## Data Mining the City

#### Graduate course at Columbia University GSAPP, taught by Violet Whitney and TA Zeid Ghawi 