Generated by Cython 3.0.10

Yellow lines hint at Python interaction.
Click on a line that starts with a "+" to see the C code that Cython generated for it.

Raw output: eroder.cpp

+0001: # distutils: language=c++
  __pyx_t_7 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_7) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
 0002: # cython: language_level=3, cdivision=True, boundscheck=False
 0003: 
 0004: from libcpp.vector cimport vector
 0005: from libc.math cimport sqrt, fabs
+0006: import numpy as np
  __pyx_t_7 = __Pyx_ImportDottedModule(__pyx_n_s_numpy, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 6, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_7) < 0) __PYX_ERR(0, 6, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
 0007: cimport numpy as cnp
 0008: from libc.stdlib cimport rand
 0009: from cython.parallel import prange
 0010: from libc.time cimport time,time_t
 0011: 
 0012: 
 0013: cdef extern from "stdlib.h":
 0014:     int RAND_MAX
+0015: cdef double BETTER_RAND_MAX = RAND_MAX
  __pyx_v_6eroder_BETTER_RAND_MAX = RAND_MAX;
 0016: 
 0017: 
 0018: ##################################################
 0019: # SOILS AND ROCKS
 0020: 
+0021: cdef struct Soil:
struct __pyx_t_6eroder_Soil {
  double organic;
  double rocks[4];
};
 0022:     double organic  # height of organic matter in soil, meters
 0023:     # 0 - sand
 0024:     # 1 - gravel
 0025:     # 2 - rocks
 0026:     # 3 - boulders
 0027:     double[4] rocks  # heights of various coarsenesses of materials, meters
 0028: 
 0029: 
+0030: cdef struct Bedrock:
struct __pyx_t_6eroder_Bedrock {
  double height;
  int type;
};
 0031:     double height
 0032:     int type
 0033: 
 0034: 
 0035: # "terrain horizon" is the name of the fact that various soils and rocks are ordered in layers
+0036: cdef struct Horizon:
struct __pyx_t_6eroder_Horizon {
  struct __pyx_t_6eroder_Soil topsoil;
  struct __pyx_t_6eroder_Soil subsoil;
  std::vector<struct __pyx_t_6eroder_Bedrock>  bedrock;
};
 0037:     Soil topsoil
 0038:     Soil subsoil
 0039:     vector[Bedrock] bedrock
 0040: 
 0041: 
+0042: cdef struct Water:
struct __pyx_t_6eroder_Water {
  double height;
  double previous;
  struct __pyx_t_6eroder_Soil regolith;
  struct __pyx_t_6eroder_Soil sediment;
  double velocity_x;
  double velocity_y;
};
 0043:     double height
 0044:     double previous
 0045:     Soil regolith
 0046:     Soil sediment;
 0047:     double velocity_x
 0048:     double velocity_y
 0049: 
 0050: 
 0051: ##################################################
 0052: # GEOLOGY CONSTANTS
 0053: 
 0054: cdef Soil EMPTY_SOIL
+0055: EMPTY_SOIL.organic = 0.0
  __pyx_v_6eroder_EMPTY_SOIL.organic = 0.0;
+0056: for i in range(4):
  for (__pyx_t_9 = 0; __pyx_t_9 < 4; __pyx_t_9+=1) {
    __pyx_t_7 = __Pyx_PyInt_From_long(__pyx_t_9); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 56, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    if (PyDict_SetItem(__pyx_d, __pyx_n_s_i, __pyx_t_7) < 0) __PYX_ERR(0, 56, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+0057:     EMPTY_SOIL.rocks[i] = 0.0
    __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_i); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 57, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 57, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    (__pyx_v_6eroder_EMPTY_SOIL.rocks[__pyx_t_10]) = 0.0;
  }
 0058: 
 0059: cdef Water EMPTY_WATER
+0060: EMPTY_WATER.height = 0.0
  __pyx_v_6eroder_EMPTY_WATER.height = 0.0;
+0061: EMPTY_WATER.previous = 0.0
  __pyx_v_6eroder_EMPTY_WATER.previous = 0.0;
+0062: EMPTY_WATER.regolith = EMPTY_SOIL
  __pyx_v_6eroder_EMPTY_WATER.regolith = __pyx_v_6eroder_EMPTY_SOIL;
+0063: EMPTY_WATER.sediment = EMPTY_SOIL
  __pyx_v_6eroder_EMPTY_WATER.sediment = __pyx_v_6eroder_EMPTY_SOIL;
+0064: EMPTY_WATER.velocity_x = 0.0
  __pyx_v_6eroder_EMPTY_WATER.velocity_x = 0.0;
+0065: EMPTY_WATER.velocity_y = 0.0
  __pyx_v_6eroder_EMPTY_WATER.velocity_y = 0.0;
 0066: 
 0067: 
+0068: cdef int ORGANIC = 4  # just the id in arrays
  __pyx_v_6eroder_ORGANIC = 4;
+0069: cdef double infinity = float("inf")
  __pyx_t_11 = __Pyx_PyUnicode_AsDouble(__pyx_n_u_inf); if (unlikely(__pyx_t_11 == ((double)((double)-1)) && PyErr_Occurred())) __PYX_ERR(0, 69, __pyx_L1_error)
  __pyx_v_6eroder_infinity = __pyx_t_11;
 0070: 
+0071: cdef double MAX_TOPSOIL_HEIGHT = 1.5
  __pyx_v_6eroder_MAX_TOPSOIL_HEIGHT = 1.5;
+0072: cdef double LAYER_HEIGHT_TO_BECOME_ERODETHROUGH = 0.1
  __pyx_v_6eroder_LAYER_HEIGHT_TO_BECOME_ERODETHROUGH = 0.1;
+0073: cdef double MIN_FRACTION_TO_ERODE = 0.1
  __pyx_v_6eroder_MIN_FRACTION_TO_ERODE = 0.1;
 0074: 
+0075: cdef double K_EROSION = 0.1
  __pyx_v_6eroder_K_EROSION = 0.1;
+0076: cdef double K_IN_EROSION = 0.5
  __pyx_v_6eroder_K_IN_EROSION = 0.5;
+0077: cdef double K_DEPOSITION = 0.25
  __pyx_v_6eroder_K_DEPOSITION = 0.25;
 0078: 
+0079: cdef double MAX_WATER_SPEED = 20.0  # source: made up
  __pyx_v_6eroder_MAX_WATER_SPEED = 20.0;
+0080: cdef double WATER_MAX_DEPTH_EROSION = 0.45
  __pyx_v_6eroder_WATER_MAX_DEPTH_EROSION = 0.45;
+0081: cdef double g = 9.81  # source: remembered from high school
  __pyx_v_6eroder_g = 9.81;
+0082: cdef double length = 1.0
  __pyx_v_6eroder_length = 1.0;
 0083: 
+0084: cdef double organic_constant = 0.12
  __pyx_v_6eroder_organic_constant = 0.12;
+0085: cdef double[4][4] rock_matrix_linear = [[0.3,   0.0,  0.0,  0.0],
  __pyx_t_12[0] = 0.3;
  __pyx_t_12[1] = 0.0;
  __pyx_t_12[2] = 0.0;
  __pyx_t_12[3] = 0.0;
/* … */
  memcpy(&(__pyx_t_16[0]), __pyx_t_12, sizeof(__pyx_t_16[0]));
  memcpy(&(__pyx_t_16[1]), __pyx_t_13, sizeof(__pyx_t_16[0]));
  memcpy(&(__pyx_t_16[2]), __pyx_t_14, sizeof(__pyx_t_16[0]));
  memcpy(&(__pyx_t_16[3]), __pyx_t_15, sizeof(__pyx_t_16[0]));
  memcpy(&(__pyx_v_6eroder_rock_matrix_linear[0]), __pyx_t_16, sizeof(__pyx_v_6eroder_rock_matrix_linear[0]) * (4));
+0086:                                         [0.02,  0.08, 0.0,  0.0],
  __pyx_t_13[0] = 0.02;
  __pyx_t_13[1] = 0.08;
  __pyx_t_13[2] = 0.0;
  __pyx_t_13[3] = 0.0;
+0087:                                         [0.02,  0.01, 0.04, 0.0],
  __pyx_t_14[0] = 0.02;
  __pyx_t_14[1] = 0.01;
  __pyx_t_14[2] = 0.04;
  __pyx_t_14[3] = 0.0;
+0088:                                         [0.02,  0.01, 0.01, 0.02]]
  __pyx_t_15[0] = 0.02;
  __pyx_t_15[1] = 0.01;
  __pyx_t_15[2] = 0.01;
  __pyx_t_15[3] = 0.02;
+0089: cdef double[4][4] rock_matrix_constant = [[ 0.0,  0.0,   0.0,  0.0],
  __pyx_t_17[0] = 0.0;
  __pyx_t_17[1] = 0.0;
  __pyx_t_17[2] = 0.0;
  __pyx_t_17[3] = 0.0;
/* … */
  memcpy(&(__pyx_t_21[0]), __pyx_t_17, sizeof(__pyx_t_21[0]));
  memcpy(&(__pyx_t_21[1]), __pyx_t_18, sizeof(__pyx_t_21[0]));
  memcpy(&(__pyx_t_21[2]), __pyx_t_19, sizeof(__pyx_t_21[0]));
  memcpy(&(__pyx_t_21[3]), __pyx_t_20, sizeof(__pyx_t_21[0]));
  memcpy(&(__pyx_v_6eroder_rock_matrix_constant[0]), __pyx_t_21, sizeof(__pyx_v_6eroder_rock_matrix_constant[0]) * (4));
+0090:                                          [-0.01, -0.1,   0.0,  0.0],
  __pyx_t_18[0] = -0.01;
  __pyx_t_18[1] = -0.1;
  __pyx_t_18[2] = 0.0;
  __pyx_t_18[3] = 0.0;
+0091:                                          [-0.02, -0.2,  -0.3,  0.0],
  __pyx_t_19[0] = -0.02;
  __pyx_t_19[1] = -0.2;
  __pyx_t_19[2] = -0.3;
  __pyx_t_19[3] = 0.0;
+0092:                                          [-0.03, -0.25, -0.4, -0.5]]
  __pyx_t_20[0] = -0.03;
  __pyx_t_20[1] = -0.25;
  __pyx_t_20[2] = -0.4;
  __pyx_t_20[3] = -0.5;
 0093: 
 0094: # first number is the number of rock types
+0095: cdef double[3][4] bedrock_erodability_linear = [[0.05, 0.01, 0.004, 0.002],  # soft rock
  __pyx_t_22[0] = 0.05;
  __pyx_t_22[1] = 0.01;
  __pyx_t_22[2] = 0.004;
  __pyx_t_22[3] = 0.002;
/* … */
  memcpy(&(__pyx_t_25[0]), __pyx_t_22, sizeof(__pyx_t_25[0]));
  memcpy(&(__pyx_t_25[1]), __pyx_t_23, sizeof(__pyx_t_25[0]));
  memcpy(&(__pyx_t_25[2]), __pyx_t_24, sizeof(__pyx_t_25[0]));
  memcpy(&(__pyx_v_6eroder_bedrock_erodability_linear[0]), __pyx_t_25, sizeof(__pyx_v_6eroder_bedrock_erodability_linear[0]) * (3));
+0096:                                                 [0.02, 0.005, 0.001, 0.0001],  # hard rock
  __pyx_t_23[0] = 0.02;
  __pyx_t_23[1] = 0.005;
  __pyx_t_23[2] = 0.001;
  __pyx_t_23[3] = 0.0001;
+0097:                                                 [0.002, 0.0005, 0.0, 0.0]]  # granite (or something)
  __pyx_t_24[0] = 0.002;
  __pyx_t_24[1] = 0.0005;
  __pyx_t_24[2] = 0.0;
  __pyx_t_24[3] = 0.0;
 0098: 
+0099: cdef double[3][4] bedrock_erodability_constant = [[0.0, -0.25, -0.4, -0.5],  # soft rock
  __pyx_t_26[0] = 0.0;
  __pyx_t_26[1] = -0.25;
  __pyx_t_26[2] = -0.4;
  __pyx_t_26[3] = -0.5;
/* … */
  memcpy(&(__pyx_t_29[0]), __pyx_t_26, sizeof(__pyx_t_29[0]));
  memcpy(&(__pyx_t_29[1]), __pyx_t_27, sizeof(__pyx_t_29[0]));
  memcpy(&(__pyx_t_29[2]), __pyx_t_28, sizeof(__pyx_t_29[0]));
  memcpy(&(__pyx_v_6eroder_bedrock_erodability_constant[0]), __pyx_t_29, sizeof(__pyx_v_6eroder_bedrock_erodability_constant[0]) * (3));
+0100:                                                 [0.0, -0.3, -0.5, -0.7],  # hard rock
  __pyx_t_27[0] = 0.0;
  __pyx_t_27[1] = -0.3;
  __pyx_t_27[2] = -0.5;
  __pyx_t_27[3] = -0.7;
+0101:                                                 [0.0, -0.5, 0.0, 0.0]]  # granite (or something)
  __pyx_t_28[0] = 0.0;
  __pyx_t_28[1] = -0.5;
  __pyx_t_28[2] = 0.0;
  __pyx_t_28[3] = 0.0;
 0102: 
+0103: cdef double[3] bedrock_taluses = [4.0, 10000000.0, 10000000.0]
  __pyx_t_30[0] = 4.0;
  __pyx_t_30[1] = 10000000.0;
  __pyx_t_30[2] = 10000000.0;
  memcpy(&(__pyx_v_6eroder_bedrock_taluses[0]), __pyx_t_30, sizeof(__pyx_v_6eroder_bedrock_taluses[0]) * (3));
 0104: 
+0105: cdef double critical_slope = 1.40
  __pyx_v_6eroder_critical_slope = 1.40;
+0106: cdef double MAX_CREEP_DENOMINATOR = 0.1
  __pyx_v_6eroder_MAX_CREEP_DENOMINATOR = 0.1;
 0107: 
+0108: cdef double ORGANIC_VEGETATION_MULIPLITER = 1.5
  __pyx_v_6eroder_ORGANIC_VEGETATION_MULIPLITER = 1.5;
+0109: cdef double[4] ROCK_VEGETATION_MULIPLITER = [0.2, 0, 0, 0]
  __pyx_t_31[0] = 0.2;
  __pyx_t_31[1] = 0.0;
  __pyx_t_31[2] = 0.0;
  __pyx_t_31[3] = 0.0;
  memcpy(&(__pyx_v_6eroder_ROCK_VEGETATION_MULIPLITER[0]), __pyx_t_31, sizeof(__pyx_v_6eroder_ROCK_VEGETATION_MULIPLITER[0]) * (4));
+0110: cdef double NEIGHBOR_VEGETATION_MULTIPLIER = 0.25
  __pyx_v_6eroder_NEIGHBOR_VEGETATION_MULTIPLIER = 0.25;
+0111: cdef double[4] ROCK_CONVERSION_RATE= [1, 0.2, 0.3, 0.4]
  __pyx_t_32[0] = 1.0;
  __pyx_t_32[1] = 0.2;
  __pyx_t_32[2] = 0.3;
  __pyx_t_32[3] = 0.4;
  memcpy(&(__pyx_v_6eroder_ROCK_CONVERSION_RATE[0]), __pyx_t_32, sizeof(__pyx_v_6eroder_ROCK_CONVERSION_RATE[0]) * (4));
 0112: 
+0113: cdef double[3] BEDROCK_CONVERSION_RATE= [1, 0.3, 0]
  __pyx_t_33[0] = 1.0;
  __pyx_t_33[1] = 0.3;
  __pyx_t_33[2] = 0.0;
  memcpy(&(__pyx_v_6eroder_BEDROCK_CONVERSION_RATE[0]), __pyx_t_33, sizeof(__pyx_v_6eroder_BEDROCK_CONVERSION_RATE[0]) * (3));
 0114: 
 0115: 
+0116: cdef inline Soil new_soil(double organic, double rock0, double rock1, double rock2, double rock3) noexcept nogil:
static CYTHON_INLINE struct __pyx_t_6eroder_Soil __pyx_f_6eroder_new_soil(double __pyx_v_organic, double __pyx_v_rock0, double __pyx_v_rock1, double __pyx_v_rock2, double __pyx_v_rock3) {
  struct __pyx_t_6eroder_Soil __pyx_v_soil;
  struct __pyx_t_6eroder_Soil __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
 0117:     cdef Soil soil
+0118:     soil.organic = organic
  __pyx_v_soil.organic = __pyx_v_organic;
+0119:     soil.rocks[0] = rock0
  (__pyx_v_soil.rocks[0]) = __pyx_v_rock0;
+0120:     soil.rocks[1] = rock1
  (__pyx_v_soil.rocks[1]) = __pyx_v_rock1;
+0121:     soil.rocks[2] = rock2
  (__pyx_v_soil.rocks[2]) = __pyx_v_rock2;
+0122:     soil.rocks[3] = rock3
  (__pyx_v_soil.rocks[3]) = __pyx_v_rock3;
+0123:     return soil
  __pyx_r = __pyx_v_soil;
  goto __pyx_L0;
 0124: 
 0125: 
+0126: cdef Soil[3] BEDROCK_CONVERT_TO = [new_soil(0.2, 0.0, 0.0, 0.1, 0.7), new_soil(0.2, 0.0, 0.0, 0.0, 0.8), EMPTY_SOIL]
  __pyx_t_34[0] = __pyx_f_6eroder_new_soil(0.2, 0.0, 0.0, 0.1, 0.7);
  __pyx_t_34[1] = __pyx_f_6eroder_new_soil(0.2, 0.0, 0.0, 0.0, 0.8);
  __pyx_t_34[2] = __pyx_v_6eroder_EMPTY_SOIL;
  memcpy(&(__pyx_v_6eroder_BEDROCK_CONVERT_TO[0]), __pyx_t_34, sizeof(__pyx_v_6eroder_BEDROCK_CONVERT_TO[0]) * (3));
 0127: 
 0128: 
 0129: ##################################################
 0130: # VARIOUS UTILS
 0131: 
+0132: cdef inline double random(double low=0.0, double high=1.0) nogil:
static CYTHON_INLINE double __pyx_f_6eroder_random(struct __pyx_opt_args_6eroder_random *__pyx_optional_args) {
  double __pyx_v_low = ((double)0.0);
  double __pyx_v_high = ((double)1.0);
  double __pyx_r;
  if (__pyx_optional_args) {
    if (__pyx_optional_args->__pyx_n > 0) {
      __pyx_v_low = __pyx_optional_args->low;
      if (__pyx_optional_args->__pyx_n > 1) {
        __pyx_v_high = __pyx_optional_args->high;
      }
    }
  }
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
/* … */
struct __pyx_opt_args_6eroder_random {
  int __pyx_n;
  double low;
  double high;
};
+0133:     return low + (rand() / BETTER_RAND_MAX) * (high - low)
  __pyx_r = (__pyx_v_low + ((((double)rand()) / __pyx_v_6eroder_BETTER_RAND_MAX) * (__pyx_v_high - __pyx_v_low)));
  goto __pyx_L0;
 0134: 
 0135: 
 0136: # this is needed because Cython sometimes thinks that -1 % 10 == -1
+0137: cdef inline unsigned int mod(int a, int b) nogil:
static CYTHON_INLINE unsigned int __pyx_f_6eroder_mod(int __pyx_v_a, int __pyx_v_b) {
  unsigned int __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0138:     return (a + b) % b
  __pyx_r = ((__pyx_v_a + __pyx_v_b) % __pyx_v_b);
  goto __pyx_L0;
 0139: 
 0140: 
 0141: # poor man's equality
+0142: cdef inline bint eq(double a, double b) nogil:
static CYTHON_INLINE int __pyx_f_6eroder_eq(double __pyx_v_a, double __pyx_v_b) {
  int __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0143:     if a - 0.00000001 < b < a + 0.00000001:
  __pyx_t_1 = ((__pyx_v_a - 0.00000001) < __pyx_v_b);
  if (__pyx_t_1) {
    __pyx_t_1 = (__pyx_v_b < (__pyx_v_a + 0.00000001));
  }
  if (__pyx_t_1) {
/* … */
  }
+0144:         return True
    __pyx_r = 1;
    goto __pyx_L0;
+0145:     return False
  __pyx_r = 0;
  goto __pyx_L0;
 0146: 
 0147: 
+0148: cdef inline double water_velocity(int x, int y, int size_x, int size_y, double[:, :, :] flow) noexcept nogil:
static CYTHON_INLINE double __pyx_f_6eroder_water_velocity(int __pyx_v_x, int __pyx_v_y, int __pyx_v_size_x, int __pyx_v_size_y, __Pyx_memviewslice __pyx_v_flow) {
  double __pyx_v_left;
  double __pyx_v_right;
  double __pyx_v_bottom;
  double __pyx_v_top;
  double __pyx_r;
/* … */
  /* function exit code */
  __pyx_L1_error:;
  #ifdef WITH_THREAD
  __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
  #endif
  __Pyx_WriteUnraisable("eroder.water_velocity", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
  __pyx_r = 0;
  #ifdef WITH_THREAD
  __Pyx_PyGILState_Release(__pyx_gilstate_save);
  #endif
  __pyx_L0:;
  return __pyx_r;
}
+0149:     cdef double left = flow[mod(x - 1, size_x)][y][0] - flow[x][y][2] # if x > 1 else 0.0
  __pyx_t_1 = __pyx_f_6eroder_mod((__pyx_v_x - 1), __pyx_v_size_x); if (unlikely(__pyx_t_1 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 149, __pyx_L1_error)
  __pyx_t_2 = __pyx_t_1;
  __pyx_t_3 = __pyx_v_y;
  __pyx_t_4 = 0;
  if (__pyx_t_3 < 0) __pyx_t_3 += __pyx_v_flow.shape[1];
  if (__pyx_t_4 < 0) __pyx_t_4 += __pyx_v_flow.shape[2];
  __pyx_t_5 = __pyx_v_x;
  __pyx_t_6 = __pyx_v_y;
  __pyx_t_7 = 2;
  if (__pyx_t_5 < 0) __pyx_t_5 += __pyx_v_flow.shape[0];
  if (__pyx_t_6 < 0) __pyx_t_6 += __pyx_v_flow.shape[1];
  if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_flow.shape[2];
  __pyx_v_left = ((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_2 * __pyx_v_flow.strides[0]) ) + __pyx_t_3 * __pyx_v_flow.strides[1]) ) + __pyx_t_4 * __pyx_v_flow.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_5 * __pyx_v_flow.strides[0]) ) + __pyx_t_6 * __pyx_v_flow.strides[1]) ) + __pyx_t_7 * __pyx_v_flow.strides[2]) ))));
+0150:     cdef double right = flow[x][y][0] - flow[mod(x + 1, size_x)][y][2] # if x < size_x - 1 else 0.0
  __pyx_t_7 = __pyx_v_x;
  __pyx_t_6 = __pyx_v_y;
  __pyx_t_5 = 0;
  if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_flow.shape[0];
  if (__pyx_t_6 < 0) __pyx_t_6 += __pyx_v_flow.shape[1];
  if (__pyx_t_5 < 0) __pyx_t_5 += __pyx_v_flow.shape[2];
  __pyx_t_1 = __pyx_f_6eroder_mod((__pyx_v_x + 1), __pyx_v_size_x); if (unlikely(__pyx_t_1 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 150, __pyx_L1_error)
  __pyx_t_2 = __pyx_t_1;
  __pyx_t_4 = __pyx_v_y;
  __pyx_t_3 = 2;
  if (__pyx_t_4 < 0) __pyx_t_4 += __pyx_v_flow.shape[1];
  if (__pyx_t_3 < 0) __pyx_t_3 += __pyx_v_flow.shape[2];
  __pyx_v_right = ((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_7 * __pyx_v_flow.strides[0]) ) + __pyx_t_6 * __pyx_v_flow.strides[1]) ) + __pyx_t_5 * __pyx_v_flow.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_2 * __pyx_v_flow.strides[0]) ) + __pyx_t_4 * __pyx_v_flow.strides[1]) ) + __pyx_t_3 * __pyx_v_flow.strides[2]) ))));
+0151:     cdef double bottom = flow[x][mod(y - 1, size_y)][1] - flow[x][y][3] # if y > 1 else 0.0
  __pyx_t_1 = __pyx_f_6eroder_mod((__pyx_v_y - 1), __pyx_v_size_y); if (unlikely(__pyx_t_1 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 151, __pyx_L1_error)
  __pyx_t_3 = __pyx_v_x;
  __pyx_t_2 = __pyx_t_1;
  __pyx_t_4 = 1;
  if (__pyx_t_3 < 0) __pyx_t_3 += __pyx_v_flow.shape[0];
  if (__pyx_t_4 < 0) __pyx_t_4 += __pyx_v_flow.shape[2];
  __pyx_t_5 = __pyx_v_x;
  __pyx_t_6 = __pyx_v_y;
  __pyx_t_7 = 3;
  if (__pyx_t_5 < 0) __pyx_t_5 += __pyx_v_flow.shape[0];
  if (__pyx_t_6 < 0) __pyx_t_6 += __pyx_v_flow.shape[1];
  if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_flow.shape[2];
  __pyx_v_bottom = ((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_3 * __pyx_v_flow.strides[0]) ) + __pyx_t_2 * __pyx_v_flow.strides[1]) ) + __pyx_t_4 * __pyx_v_flow.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_5 * __pyx_v_flow.strides[0]) ) + __pyx_t_6 * __pyx_v_flow.strides[1]) ) + __pyx_t_7 * __pyx_v_flow.strides[2]) ))));
+0152:     cdef double top = flow[x][y][1] - flow[x][mod(y + 1, size_y)][3] # if y < size_y - 1 else 0.0
  __pyx_t_7 = __pyx_v_x;
  __pyx_t_6 = __pyx_v_y;
  __pyx_t_5 = 1;
  if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_flow.shape[0];
  if (__pyx_t_6 < 0) __pyx_t_6 += __pyx_v_flow.shape[1];
  if (__pyx_t_5 < 0) __pyx_t_5 += __pyx_v_flow.shape[2];
  __pyx_t_1 = __pyx_f_6eroder_mod((__pyx_v_y + 1), __pyx_v_size_y); if (unlikely(__pyx_t_1 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 152, __pyx_L1_error)
  __pyx_t_4 = __pyx_v_x;
  __pyx_t_2 = __pyx_t_1;
  __pyx_t_3 = 3;
  if (__pyx_t_4 < 0) __pyx_t_4 += __pyx_v_flow.shape[0];
  if (__pyx_t_3 < 0) __pyx_t_3 += __pyx_v_flow.shape[2];
  __pyx_v_top = ((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_7 * __pyx_v_flow.strides[0]) ) + __pyx_t_6 * __pyx_v_flow.strides[1]) ) + __pyx_t_5 * __pyx_v_flow.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_4 * __pyx_v_flow.strides[0]) ) + __pyx_t_2 * __pyx_v_flow.strides[1]) ) + __pyx_t_3 * __pyx_v_flow.strides[2]) ))));
 0153: 
+0154:     return sqrt((0.5 * (left + right))**2 + (0.5 * (top + bottom))**2)
  __pyx_r = sqrt((pow((0.5 * (__pyx_v_left + __pyx_v_right)), 2.0) + pow((0.5 * (__pyx_v_top + __pyx_v_bottom)), 2.0)));
  goto __pyx_L0;
 0155: 
 0156: 
+0157: cdef (double, double) water_velocity_vector(int x, int y, int size_x, int size_y, double[:, :, :] flow) noexcept nogil:
static __pyx_ctuple_double__and_double __pyx_f_6eroder_water_velocity_vector(int __pyx_v_x, int __pyx_v_y, int __pyx_v_size_x, int __pyx_v_size_y, __Pyx_memviewslice __pyx_v_flow) {
  double __pyx_v_left;
  double __pyx_v_right;
  double __pyx_v_bottom;
  double __pyx_v_top;
  __pyx_ctuple_double__and_double __pyx_r;
/* … */
  /* function exit code */
  __pyx_L1_error:;
  #ifdef WITH_THREAD
  __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
  #endif
  __Pyx_WriteUnraisable("eroder.water_velocity_vector", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
  __Pyx_pretend_to_initialize(&__pyx_r);
  #ifdef WITH_THREAD
  __Pyx_PyGILState_Release(__pyx_gilstate_save);
  #endif
  __pyx_L0:;
  return __pyx_r;
}
/* … */
struct __pyx_ctuple_double__and_double {
  double f0;
  double f1;
};
+0158:     cdef double left = flow[mod(x - 1, size_x)][y][0] - flow[x][y][2] # if x > 1 else 0.0
  __pyx_t_1 = __pyx_f_6eroder_mod((__pyx_v_x - 1), __pyx_v_size_x); if (unlikely(__pyx_t_1 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 158, __pyx_L1_error)
  __pyx_t_2 = __pyx_t_1;
  __pyx_t_3 = __pyx_v_y;
  __pyx_t_4 = 0;
  if (__pyx_t_3 < 0) __pyx_t_3 += __pyx_v_flow.shape[1];
  if (__pyx_t_4 < 0) __pyx_t_4 += __pyx_v_flow.shape[2];
  __pyx_t_5 = __pyx_v_x;
  __pyx_t_6 = __pyx_v_y;
  __pyx_t_7 = 2;
  if (__pyx_t_5 < 0) __pyx_t_5 += __pyx_v_flow.shape[0];
  if (__pyx_t_6 < 0) __pyx_t_6 += __pyx_v_flow.shape[1];
  if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_flow.shape[2];
  __pyx_v_left = ((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_2 * __pyx_v_flow.strides[0]) ) + __pyx_t_3 * __pyx_v_flow.strides[1]) ) + __pyx_t_4 * __pyx_v_flow.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_5 * __pyx_v_flow.strides[0]) ) + __pyx_t_6 * __pyx_v_flow.strides[1]) ) + __pyx_t_7 * __pyx_v_flow.strides[2]) ))));
+0159:     cdef double right = flow[x][y][0] - flow[mod(x + 1, size_x)][y][2] # if x < size_x - 1 else 0.0
  __pyx_t_7 = __pyx_v_x;
  __pyx_t_6 = __pyx_v_y;
  __pyx_t_5 = 0;
  if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_flow.shape[0];
  if (__pyx_t_6 < 0) __pyx_t_6 += __pyx_v_flow.shape[1];
  if (__pyx_t_5 < 0) __pyx_t_5 += __pyx_v_flow.shape[2];
  __pyx_t_1 = __pyx_f_6eroder_mod((__pyx_v_x + 1), __pyx_v_size_x); if (unlikely(__pyx_t_1 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 159, __pyx_L1_error)
  __pyx_t_2 = __pyx_t_1;
  __pyx_t_4 = __pyx_v_y;
  __pyx_t_3 = 2;
  if (__pyx_t_4 < 0) __pyx_t_4 += __pyx_v_flow.shape[1];
  if (__pyx_t_3 < 0) __pyx_t_3 += __pyx_v_flow.shape[2];
  __pyx_v_right = ((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_7 * __pyx_v_flow.strides[0]) ) + __pyx_t_6 * __pyx_v_flow.strides[1]) ) + __pyx_t_5 * __pyx_v_flow.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_2 * __pyx_v_flow.strides[0]) ) + __pyx_t_4 * __pyx_v_flow.strides[1]) ) + __pyx_t_3 * __pyx_v_flow.strides[2]) ))));
+0160:     cdef double bottom = flow[x][mod(y - 1, size_y)][1] - flow[x][y][3] # if y > 1 else 0.0
  __pyx_t_1 = __pyx_f_6eroder_mod((__pyx_v_y - 1), __pyx_v_size_y); if (unlikely(__pyx_t_1 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 160, __pyx_L1_error)
  __pyx_t_3 = __pyx_v_x;
  __pyx_t_2 = __pyx_t_1;
  __pyx_t_4 = 1;
  if (__pyx_t_3 < 0) __pyx_t_3 += __pyx_v_flow.shape[0];
  if (__pyx_t_4 < 0) __pyx_t_4 += __pyx_v_flow.shape[2];
  __pyx_t_5 = __pyx_v_x;
  __pyx_t_6 = __pyx_v_y;
  __pyx_t_7 = 3;
  if (__pyx_t_5 < 0) __pyx_t_5 += __pyx_v_flow.shape[0];
  if (__pyx_t_6 < 0) __pyx_t_6 += __pyx_v_flow.shape[1];
  if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_flow.shape[2];
  __pyx_v_bottom = ((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_3 * __pyx_v_flow.strides[0]) ) + __pyx_t_2 * __pyx_v_flow.strides[1]) ) + __pyx_t_4 * __pyx_v_flow.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_5 * __pyx_v_flow.strides[0]) ) + __pyx_t_6 * __pyx_v_flow.strides[1]) ) + __pyx_t_7 * __pyx_v_flow.strides[2]) ))));
+0161:     cdef double top = flow[x][y][1] - flow[x][mod(y + 1, size_y)][3] # if y < size_y - 1 else 0.0
  __pyx_t_7 = __pyx_v_x;
  __pyx_t_6 = __pyx_v_y;
  __pyx_t_5 = 1;
  if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_flow.shape[0];
  if (__pyx_t_6 < 0) __pyx_t_6 += __pyx_v_flow.shape[1];
  if (__pyx_t_5 < 0) __pyx_t_5 += __pyx_v_flow.shape[2];
  __pyx_t_1 = __pyx_f_6eroder_mod((__pyx_v_y + 1), __pyx_v_size_y); if (unlikely(__pyx_t_1 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 161, __pyx_L1_error)
  __pyx_t_4 = __pyx_v_x;
  __pyx_t_2 = __pyx_t_1;
  __pyx_t_3 = 3;
  if (__pyx_t_4 < 0) __pyx_t_4 += __pyx_v_flow.shape[0];
  if (__pyx_t_3 < 0) __pyx_t_3 += __pyx_v_flow.shape[2];
  __pyx_v_top = ((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_7 * __pyx_v_flow.strides[0]) ) + __pyx_t_6 * __pyx_v_flow.strides[1]) ) + __pyx_t_5 * __pyx_v_flow.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_4 * __pyx_v_flow.strides[0]) ) + __pyx_t_2 * __pyx_v_flow.strides[1]) ) + __pyx_t_3 * __pyx_v_flow.strides[2]) ))));
 0162: 
+0163:     return (0.5 * (left + right), 0.5 * (top + bottom))
  __pyx_t_8.f0 = (0.5 * (__pyx_v_left + __pyx_v_right));
  __pyx_t_8.f1 = (0.5 * (__pyx_v_top + __pyx_v_bottom));
  __pyx_r = __pyx_t_8;
  goto __pyx_L0;
 0164: 
 0165: 
 0166: # I decided to code it in the same way normals are computed
 0167: # so the average steepness, or, the first derivative
 0168: # nvm, it's sine now
+0169: cdef inline double get_steepness(int x, int y, int size_x, int size_y, double[:, :] heightmap) noexcept nogil:
static CYTHON_INLINE double __pyx_f_6eroder_get_steepness(int __pyx_v_x, int __pyx_v_y, int __pyx_v_size_x, int __pyx_v_size_y, __Pyx_memviewslice __pyx_v_heightmap) {
  double __pyx_v_dx;
  double __pyx_v_dy;
  double __pyx_r;
/* … */
  /* function exit code */
  __pyx_L1_error:;
  #ifdef WITH_THREAD
  __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
  #endif
  __Pyx_WriteUnraisable("eroder.get_steepness", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
  __pyx_r = 0;
  #ifdef WITH_THREAD
  __Pyx_PyGILState_Release(__pyx_gilstate_save);
  #endif
  __pyx_L0:;
  return __pyx_r;
}
+0170:     cdef double dx = abs(heightmap[mod(x - 1, size_x)][y] - heightmap[mod(x + 1, size_x)][y])
  __pyx_t_1 = __pyx_f_6eroder_mod((__pyx_v_x - 1), __pyx_v_size_x); if (unlikely(__pyx_t_1 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 170, __pyx_L1_error)
  __pyx_t_2 = __pyx_t_1;
  __pyx_t_3 = __pyx_v_y;
  if (__pyx_t_3 < 0) __pyx_t_3 += __pyx_v_heightmap.shape[1];
  __pyx_t_4 = __pyx_f_6eroder_mod((__pyx_v_x + 1), __pyx_v_size_x); if (unlikely(__pyx_t_4 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 170, __pyx_L1_error)
  __pyx_t_5 = __pyx_t_4;
  __pyx_t_6 = __pyx_v_y;
  if (__pyx_t_6 < 0) __pyx_t_6 += __pyx_v_heightmap.shape[1];
  __pyx_v_dx = fabs(((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_2 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_3 * __pyx_v_heightmap.strides[1]) ))) - (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_5 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_6 * __pyx_v_heightmap.strides[1]) )))));
+0171:     cdef double dy = abs(heightmap[x][mod(y - 1, size_y)] - heightmap[x][mod(y + 1, size_y)])
  __pyx_t_4 = __pyx_f_6eroder_mod((__pyx_v_y - 1), __pyx_v_size_y); if (unlikely(__pyx_t_4 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 171, __pyx_L1_error)
  __pyx_t_6 = __pyx_v_x;
  __pyx_t_5 = __pyx_t_4;
  if (__pyx_t_6 < 0) __pyx_t_6 += __pyx_v_heightmap.shape[0];
  __pyx_t_1 = __pyx_f_6eroder_mod((__pyx_v_y + 1), __pyx_v_size_y); if (unlikely(__pyx_t_1 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 171, __pyx_L1_error)
  __pyx_t_3 = __pyx_v_x;
  __pyx_t_2 = __pyx_t_1;
  if (__pyx_t_3 < 0) __pyx_t_3 += __pyx_v_heightmap.shape[0];
  __pyx_v_dy = fabs(((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_6 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_5 * __pyx_v_heightmap.strides[1]) ))) - (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_3 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_2 * __pyx_v_heightmap.strides[1]) )))));
 0172: 
 0173:     # assumes length = 1.0
+0174:     return sqrt(dx**2 + dy**2) / sqrt(dx**2 + dy**2 + 1.0**2)
  __pyx_r = (sqrt((pow(__pyx_v_dx, 2.0) + pow(__pyx_v_dy, 2.0))) / sqrt(((pow(__pyx_v_dx, 2.0) + pow(__pyx_v_dy, 2.0)) + pow(1.0, 2.0))));
  goto __pyx_L0;
 0175: 
 0176: 
 0177: # similar to a second derivative
 0178: # positive = bump
 0179: # negative = hole
+0180: cdef double get_convexness(int x, int y, int size_x, int size_y, double[:, :] heightmap) noexcept nogil:
static double __pyx_f_6eroder_get_convexness(int __pyx_v_x, int __pyx_v_y, int __pyx_v_size_x, int __pyx_v_size_y, __Pyx_memviewslice __pyx_v_heightmap) {
  int __pyx_v_delta_x[4];
  int __pyx_v_delta_y[4];
  int __pyx_v_i;
  double __pyx_v_delta_h;
  double __pyx_v_cx;
  double __pyx_v_cy;
  double __pyx_r;
/* … */
  /* function exit code */
  __pyx_L1_error:;
  #ifdef WITH_THREAD
  __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
  #endif
  __Pyx_WriteUnraisable("eroder.get_convexness", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
  __pyx_r = 0;
  #ifdef WITH_THREAD
  __Pyx_PyGILState_Release(__pyx_gilstate_save);
  #endif
  __pyx_L0:;
  return __pyx_r;
}
+0181:     cdef int[4] delta_x = [ 1, 0, -1, 0 ]
  __pyx_t_1[0] = 1;
  __pyx_t_1[1] = 0;
  __pyx_t_1[2] = -1;
  __pyx_t_1[3] = 0;
  memcpy(&(__pyx_v_delta_x[0]), __pyx_t_1, sizeof(__pyx_v_delta_x[0]) * (4));
+0182:     cdef int[4] delta_y = [ 0, 1, 0, -1 ]
  __pyx_t_2[0] = 0;
  __pyx_t_2[1] = 1;
  __pyx_t_2[2] = 0;
  __pyx_t_2[3] = -1;
  memcpy(&(__pyx_v_delta_y[0]), __pyx_t_2, sizeof(__pyx_v_delta_y[0]) * (4));
+0183:     cdef int i = 0
  __pyx_v_i = 0;
 0184:     cdef double delta_h
 0185: 
 0186:     # x, y, magnitude
+0187:     cdef double cx = 0.0, cy = 0.0
  __pyx_v_cx = 0.0;
  __pyx_v_cy = 0.0;
 0188: 
+0189:     for i in range(4):
  for (__pyx_t_3 = 0; __pyx_t_3 < 4; __pyx_t_3+=1) {
    __pyx_v_i = __pyx_t_3;
 0190:         #if (0 <= x + delta_x[i] < size_x) and (0 <= y + delta_y[i] < size_y):
+0191:         delta_h = heightmap[x][y] - heightmap[mod(x + delta_x[i], size_x)][mod(y + delta_y[i], size_y)]
    __pyx_t_4 = __pyx_v_x;
    __pyx_t_5 = __pyx_v_y;
    if (__pyx_t_4 < 0) __pyx_t_4 += __pyx_v_heightmap.shape[0];
    if (__pyx_t_5 < 0) __pyx_t_5 += __pyx_v_heightmap.shape[1];
    __pyx_t_6 = __pyx_f_6eroder_mod((__pyx_v_x + (__pyx_v_delta_x[__pyx_v_i])), __pyx_v_size_x); if (unlikely(__pyx_t_6 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 191, __pyx_L1_error)
    __pyx_t_7 = __pyx_f_6eroder_mod((__pyx_v_y + (__pyx_v_delta_y[__pyx_v_i])), __pyx_v_size_y); if (unlikely(__pyx_t_7 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 191, __pyx_L1_error)
    __pyx_t_8 = __pyx_t_6;
    __pyx_t_9 = __pyx_t_7;
    __pyx_v_delta_h = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_4 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_5 * __pyx_v_heightmap.strides[1]) ))) - (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_8 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_9 * __pyx_v_heightmap.strides[1]) ))));
+0192:         cx += 0.5 * fabs(delta_x[i]) * delta_h
    __pyx_v_cx = (__pyx_v_cx + ((0.5 * fabs((__pyx_v_delta_x[__pyx_v_i]))) * __pyx_v_delta_h));
+0193:         cy += 0.5 * fabs(delta_y[i]) * delta_h
    __pyx_v_cy = (__pyx_v_cy + ((0.5 * fabs((__pyx_v_delta_y[__pyx_v_i]))) * __pyx_v_delta_h));
  }
 0194: 
 0195:     # assumes length = 1.0
+0196:     return 0.5 * (cx + cy) / sqrt((0.5 * (cx + cy))**2 + 1.0**2)
  __pyx_r = ((0.5 * (__pyx_v_cx + __pyx_v_cy)) / sqrt((pow((0.5 * (__pyx_v_cx + __pyx_v_cy)), 2.0) + pow(1.0, 2.0))));
  goto __pyx_L0;
 0197: 
 0198: 
 0199: # adding more water than the max_depth will not speed up the erosion
 0200: # source: that Balazs paper
+0201: cdef inline double max_erosion_depth(double depth) noexcept nogil:
static CYTHON_INLINE double __pyx_f_6eroder_max_erosion_depth(double __pyx_v_depth) {
  double __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0202:     if depth >= WATER_MAX_DEPTH_EROSION:
  __pyx_t_1 = (__pyx_v_depth >= __pyx_v_6eroder_WATER_MAX_DEPTH_EROSION);
  if (__pyx_t_1) {
/* … */
  }
+0203:         return 1.0
    __pyx_r = 1.0;
    goto __pyx_L0;
+0204:     elif 0 < depth < WATER_MAX_DEPTH_EROSION:
  __pyx_t_1 = (0.0 < __pyx_v_depth);
  if (__pyx_t_1) {
    __pyx_t_1 = (__pyx_v_depth < __pyx_v_6eroder_WATER_MAX_DEPTH_EROSION);
  }
  if (__pyx_t_1) {
/* … */
  }
+0205:         return 1.0 - (WATER_MAX_DEPTH_EROSION - depth) / WATER_MAX_DEPTH_EROSION
    __pyx_r = (1.0 - ((__pyx_v_6eroder_WATER_MAX_DEPTH_EROSION - __pyx_v_depth) / __pyx_v_6eroder_WATER_MAX_DEPTH_EROSION));
    goto __pyx_L0;
 0206:     else:
+0207:         return 0.0
  /*else*/ {
    __pyx_r = 0.0;
    goto __pyx_L0;
  }
 0208: 
 0209: 
 0210: 
 0211: ##################################################
 0212: # HELPER FUNCTIONS
 0213: 
 0214: 
+0215: cdef inline Soil new_soil_rock(double rock, int index) noexcept nogil:
static CYTHON_INLINE struct __pyx_t_6eroder_Soil __pyx_f_6eroder_new_soil_rock(double __pyx_v_rock, int __pyx_v_index) {
  struct __pyx_t_6eroder_Soil __pyx_v_soil;
  struct __pyx_t_6eroder_Soil __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0216:     cdef Soil soil = EMPTY_SOIL
  __pyx_v_soil = __pyx_v_6eroder_EMPTY_SOIL;
+0217:     soil.rocks[index] = rock
  (__pyx_v_soil.rocks[__pyx_v_index]) = __pyx_v_rock;
+0218:     return soil
  __pyx_r = __pyx_v_soil;
  goto __pyx_L0;
 0219: 
 0220: 
+0221: cdef inline Soil new_soil_from_bedrock_type(int bedrock_type, double amount) noexcept nogil:
static CYTHON_INLINE struct __pyx_t_6eroder_Soil __pyx_f_6eroder_new_soil_from_bedrock_type(int __pyx_v_bedrock_type, double __pyx_v_amount) {
  struct __pyx_t_6eroder_Soil __pyx_r;
/* … */
  /* function exit code */
  __Pyx_pretend_to_initialize(&__pyx_r);
  __pyx_L0:;
  return __pyx_r;
}
+0222:     if bedrock_type == 0:
  __pyx_t_1 = (__pyx_v_bedrock_type == 0);
  if (__pyx_t_1) {
/* … */
  }
+0223:         return new_soil(0, 0, 0.2 * amount, 0.3 * amount, 0.5 * amount)
    __pyx_r = __pyx_f_6eroder_new_soil(0.0, 0.0, (0.2 * __pyx_v_amount), (0.3 * __pyx_v_amount), (0.5 * __pyx_v_amount));
    goto __pyx_L0;
+0224:     if bedrock_type == 1:
  __pyx_t_1 = (__pyx_v_bedrock_type == 1);
  if (__pyx_t_1) {
/* … */
  }
+0225:         return new_soil(0, 0, 0.1 * amount, 0.2 * amount, 0.7 * amount)
    __pyx_r = __pyx_f_6eroder_new_soil(0.0, 0.0, (0.1 * __pyx_v_amount), (0.2 * __pyx_v_amount), (0.7 * __pyx_v_amount));
    goto __pyx_L0;
+0226:     if bedrock_type == 2:
  __pyx_t_1 = (__pyx_v_bedrock_type == 2);
  if (__pyx_t_1) {
/* … */
  }
+0227:         return new_soil(0, 0, 0.05 * amount, 0.15 * amount, 0.8 * amount)
    __pyx_r = __pyx_f_6eroder_new_soil(0.0, 0.0, (0.05 * __pyx_v_amount), (0.15 * __pyx_v_amount), (0.8 * __pyx_v_amount));
    goto __pyx_L0;
 0228: 
 0229: 
+0230: cdef inline double get_soil_height(Soil& soil) noexcept nogil:
static CYTHON_INLINE double __pyx_f_6eroder_get_soil_height(struct __pyx_t_6eroder_Soil &__pyx_v_soil) {
  double __pyx_v_h;
  unsigned int __pyx_v_i;
  double __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0231:     cdef double h = soil.organic
  __pyx_t_1 = __pyx_v_soil.organic;
  __pyx_v_h = __pyx_t_1;
 0232:     cdef unsigned int i
 0233: 
+0234:     for i in range(4):
  for (__pyx_t_2 = 0; __pyx_t_2 < 4; __pyx_t_2+=1) {
    __pyx_v_i = __pyx_t_2;
+0235:         h += soil.rocks[i]
    __pyx_v_h = (__pyx_v_h + (__pyx_v_soil.rocks[__pyx_v_i]));
  }
 0236: 
+0237:     return h
  __pyx_r = __pyx_v_h;
  goto __pyx_L0;
 0238: 
 0239: 
 0240: # returns Soil with same ratios, but with cummulative height of 1.0
+0241: cdef inline Soil normalized(Soil soil) noexcept nogil:
static CYTHON_INLINE struct __pyx_t_6eroder_Soil __pyx_f_6eroder_normalized(struct __pyx_t_6eroder_Soil __pyx_v_soil) {
  double __pyx_v_soil_height;
  long __pyx_v_i;
  struct __pyx_t_6eroder_Soil __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0242:     cdef double soil_height = get_soil_height(soil)
  __pyx_v_soil_height = __pyx_f_6eroder_get_soil_height(__pyx_v_soil);
 0243: 
+0244:     if soil_height == 0.0:
  __pyx_t_1 = (__pyx_v_soil_height == 0.0);
  if (__pyx_t_1) {
/* … */
  }
+0245:         return EMPTY_SOIL
    __pyx_r = __pyx_v_6eroder_EMPTY_SOIL;
    goto __pyx_L0;
 0246: 
+0247:     soil.organic /= soil_height
  __pyx_v_soil.organic = (__pyx_v_soil.organic / __pyx_v_soil_height);
+0248:     for i in range(4):
  for (__pyx_t_2 = 0; __pyx_t_2 < 4; __pyx_t_2+=1) {
    __pyx_v_i = __pyx_t_2;
+0249:         soil.rocks[i] /= soil_height
    __pyx_t_3 = __pyx_v_i;
    (__pyx_v_soil.rocks[__pyx_t_3]) = ((__pyx_v_soil.rocks[__pyx_t_3]) / __pyx_v_soil_height);
  }
 0250: 
+0251:     return soil
  __pyx_r = __pyx_v_soil;
  goto __pyx_L0;
 0252: 
 0253: 
 0254: # returns soil with average concentrations of all materials in a depth-deep column
+0255: cdef inline Soil get_soil_sample(Horizon& horizon, double depth) noexcept nogil:
static CYTHON_INLINE struct __pyx_t_6eroder_Soil __pyx_f_6eroder_get_soil_sample(struct __pyx_t_6eroder_Horizon &__pyx_v_horizon, double __pyx_v_depth) {
  struct __pyx_t_6eroder_Soil __pyx_v_result;
  double __pyx_v_fraction;
  struct __pyx_t_6eroder_Soil __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0256:     cdef Soil result = horizon.topsoil
  __pyx_t_1 = __pyx_v_horizon.topsoil;
  __pyx_v_result = __pyx_t_1;
 0257: 
+0258:     if get_soil_height(result) >= depth:
  __pyx_t_2 = (__pyx_f_6eroder_get_soil_height(__pyx_v_result) >= __pyx_v_depth);
  if (__pyx_t_2) {
/* … */
  }
 0259:         # we have everything
+0260:         return soil_fraction(result, depth / get_soil_height(result))
    __pyx_r = __pyx_f_6eroder_soil_fraction(__pyx_v_result, (__pyx_v_depth / __pyx_f_6eroder_get_soil_height(__pyx_v_result)));
    goto __pyx_L0;
 0261: 
+0262:     depth -= get_soil_height(result)
  __pyx_v_depth = (__pyx_v_depth - __pyx_f_6eroder_get_soil_height(__pyx_v_result));
 0263: 
+0264:     if get_soil_height(horizon.subsoil) <= 0.0:
  __pyx_t_2 = (__pyx_f_6eroder_get_soil_height(__pyx_v_horizon.subsoil) <= 0.0);
  if (__pyx_t_2) {
/* … */
  }
+0265:         return result
    __pyx_r = __pyx_v_result;
    goto __pyx_L0;
 0266: 
+0267:     cdef double fraction = min(1.0, depth / get_soil_height(horizon.subsoil))
  __pyx_t_3 = (__pyx_v_depth / __pyx_f_6eroder_get_soil_height(__pyx_v_horizon.subsoil));
  __pyx_t_4 = 1.0;
  __pyx_t_2 = (__pyx_t_3 < __pyx_t_4);
  if (__pyx_t_2) {
    __pyx_t_5 = __pyx_t_3;
  } else {
    __pyx_t_5 = __pyx_t_4;
  }
  __pyx_v_fraction = __pyx_t_5;
 0268: 
+0269:     add_to_soil(result, soil_fraction(horizon.subsoil, fraction))
  __pyx_f_6eroder_add_to_soil(__pyx_v_result, __pyx_f_6eroder_soil_fraction(__pyx_v_horizon.subsoil, __pyx_v_fraction));
 0270: 
+0271:     return result
  __pyx_r = __pyx_v_result;
  goto __pyx_L0;
 0272: 
 0273: 
 0274: # returns Soil with same ratios, but scaled by fraction
+0275: cdef inline Soil soil_fraction(Soil soil, double fraction) noexcept nogil:
static CYTHON_INLINE struct __pyx_t_6eroder_Soil __pyx_f_6eroder_soil_fraction(struct __pyx_t_6eroder_Soil __pyx_v_soil, double __pyx_v_fraction) {
  long __pyx_v_i;
  struct __pyx_t_6eroder_Soil __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
 0276:     #if not (0.0 <= fraction <= 1.0):
 0277:     #    print("Invalid fraction value: " + str(fraction))
 0278: 
 0279:     # sometimes 1.0000000000000002 comes up and I don't like it
+0280:     if fraction > 1.0:
  __pyx_t_1 = (__pyx_v_fraction > 1.0);
  if (__pyx_t_1) {
/* … */
  }
+0281:         fraction = 1.0
    __pyx_v_fraction = 1.0;
 0282: 
+0283:     soil.organic *= fraction
  __pyx_v_soil.organic = (__pyx_v_soil.organic * __pyx_v_fraction);
+0284:     for i in range(4):
  for (__pyx_t_2 = 0; __pyx_t_2 < 4; __pyx_t_2+=1) {
    __pyx_v_i = __pyx_t_2;
+0285:         soil.rocks[i] *= fraction
    __pyx_t_3 = __pyx_v_i;
    (__pyx_v_soil.rocks[__pyx_t_3]) = ((__pyx_v_soil.rocks[__pyx_t_3]) * __pyx_v_fraction);
  }
 0286: 
+0287:     return soil
  __pyx_r = __pyx_v_soil;
  goto __pyx_L0;
 0288: 
 0289: 
+0290: cdef inline Soil add_soil(Soil a, Soil b) noexcept nogil:
static CYTHON_INLINE struct __pyx_t_6eroder_Soil __pyx_f_6eroder_add_soil(struct __pyx_t_6eroder_Soil __pyx_v_a, struct __pyx_t_6eroder_Soil __pyx_v_b) {
  long __pyx_v_i;
  struct __pyx_t_6eroder_Soil __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0291:     a.organic += b.organic
  __pyx_v_a.organic = (__pyx_v_a.organic + __pyx_v_b.organic);
+0292:     for i in range(4):
  for (__pyx_t_1 = 0; __pyx_t_1 < 4; __pyx_t_1+=1) {
    __pyx_v_i = __pyx_t_1;
+0293:         a.rocks[i] += b.rocks[i]
    __pyx_t_2 = __pyx_v_i;
    (__pyx_v_a.rocks[__pyx_t_2]) = ((__pyx_v_a.rocks[__pyx_t_2]) + (__pyx_v_b.rocks[__pyx_v_i]));
  }
 0294: 
+0295:     return a
  __pyx_r = __pyx_v_a;
  goto __pyx_L0;
 0296: 
 0297: 
 0298: # MODIFIES ARGUMENT
+0299: cdef inline void add_to_soil(Soil& a, Soil b) noexcept nogil:
static CYTHON_INLINE void __pyx_f_6eroder_add_to_soil(struct __pyx_t_6eroder_Soil &__pyx_v_a, struct __pyx_t_6eroder_Soil __pyx_v_b) {
  long __pyx_v_i;
/* … */
  /* function exit code */
}
+0300:     a.organic += b.organic
  __pyx_v_a.organic = (__pyx_v_a.organic + __pyx_v_b.organic);
+0301:     for i in range(4):
  for (__pyx_t_1 = 0; __pyx_t_1 < 4; __pyx_t_1+=1) {
    __pyx_v_i = __pyx_t_1;
+0302:         a.rocks[i] += b.rocks[i]
    __pyx_t_2 = __pyx_v_i;
    (__pyx_v_a.rocks[__pyx_t_2]) = ((__pyx_v_a.rocks[__pyx_t_2]) + (__pyx_v_b.rocks[__pyx_v_i]));
  }
 0303: 
 0304: 
 0305: # makes sure that after needed_height of material is added, the topsoil doesn't go over the max height
 0306: # transfers part of topsoil into subsoil
 0307: # MODIFIES ARGUMENT
+0308: cdef void organize_horizon(Horizon& horizon, double needed_height) noexcept nogil:
static void __pyx_f_6eroder_organize_horizon(struct __pyx_t_6eroder_Horizon &__pyx_v_horizon, double __pyx_v_needed_height) {
  double __pyx_v_topsoil_height;
  double __pyx_v_fraction_remove;
  double __pyx_v_amount;
  long __pyx_v_i;
/* … */
  /* function exit code */
}
+0309:     cdef double topsoil_height = get_soil_height(horizon.topsoil)
  __pyx_v_topsoil_height = __pyx_f_6eroder_get_soil_height(__pyx_v_horizon.topsoil);
 0310:     cdef double fraction_remove
 0311:     cdef double amount
 0312: 
+0313:     if topsoil_height + needed_height > MAX_TOPSOIL_HEIGHT and topsoil_height > 0:
  __pyx_t_2 = ((__pyx_v_topsoil_height + __pyx_v_needed_height) > __pyx_v_6eroder_MAX_TOPSOIL_HEIGHT);
  if (__pyx_t_2) {
  } else {
    __pyx_t_1 = __pyx_t_2;
    goto __pyx_L4_bool_binop_done;
  }
  __pyx_t_2 = (__pyx_v_topsoil_height > 0.0);
  __pyx_t_1 = __pyx_t_2;
  __pyx_L4_bool_binop_done:;
  if (__pyx_t_1) {
/* … */
  }
 0314:         # fraction of topsoil which needs to get transferred to subsoil
+0315:         fraction_remove = max(min((topsoil_height + needed_height - MAX_TOPSOIL_HEIGHT) / topsoil_height, 1.0), 0.0)
    __pyx_t_3 = 0.0;
    __pyx_t_4 = 1.0;
    __pyx_t_5 = (((__pyx_v_topsoil_height + __pyx_v_needed_height) - __pyx_v_6eroder_MAX_TOPSOIL_HEIGHT) / __pyx_v_topsoil_height);
    __pyx_t_1 = (__pyx_t_4 < __pyx_t_5);
    if (__pyx_t_1) {
      __pyx_t_6 = __pyx_t_4;
    } else {
      __pyx_t_6 = __pyx_t_5;
    }
    __pyx_t_4 = __pyx_t_6;
    __pyx_t_1 = (__pyx_t_3 > __pyx_t_4);
    if (__pyx_t_1) {
      __pyx_t_6 = __pyx_t_3;
    } else {
      __pyx_t_6 = __pyx_t_4;
    }
    __pyx_v_fraction_remove = __pyx_t_6;
 0316: 
+0317:         amount = horizon.topsoil.organic * fraction_remove
    __pyx_v_amount = (__pyx_v_horizon.topsoil.organic * __pyx_v_fraction_remove);
+0318:         horizon.subsoil.organic += amount
    __pyx_v_horizon.subsoil.organic = (__pyx_v_horizon.subsoil.organic + __pyx_v_amount);
+0319:         horizon.topsoil.organic -= amount
    __pyx_v_horizon.topsoil.organic = (__pyx_v_horizon.topsoil.organic - __pyx_v_amount);
 0320: 
+0321:         for i in range(4):
    for (__pyx_t_7 = 0; __pyx_t_7 < 4; __pyx_t_7+=1) {
      __pyx_v_i = __pyx_t_7;
+0322:             amount = horizon.topsoil.rocks[i] * fraction_remove
      __pyx_v_amount = ((__pyx_v_horizon.topsoil.rocks[__pyx_v_i]) * __pyx_v_fraction_remove);
+0323:             horizon.subsoil.rocks[i] += amount
      __pyx_t_8 = __pyx_v_i;
      (__pyx_v_horizon.subsoil.rocks[__pyx_t_8]) = ((__pyx_v_horizon.subsoil.rocks[__pyx_t_8]) + __pyx_v_amount);
+0324:             horizon.topsoil.rocks[i] -= amount
      __pyx_t_8 = __pyx_v_i;
      (__pyx_v_horizon.topsoil.rocks[__pyx_t_8]) = ((__pyx_v_horizon.topsoil.rocks[__pyx_t_8]) - __pyx_v_amount);
    }
 0325: 
 0326: 
+0327: cdef double get_soil_talus(Soil soil, double vegetation) noexcept nogil:
static double __pyx_f_6eroder_get_soil_talus(struct __pyx_t_6eroder_Soil __pyx_v_soil, double __pyx_v_vegetation) {
  double __pyx_v_talus;
  double __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0328:     soil = normalized(soil)
  __pyx_v_soil = __pyx_f_6eroder_normalized(__pyx_v_soil);
 0329: 
+0330:     if get_soil_height(soil) <= 0.0:
  __pyx_t_1 = (__pyx_f_6eroder_get_soil_height(__pyx_v_soil) <= 0.0);
  if (__pyx_t_1) {
/* … */
  }
+0331:         return infinity
    __pyx_r = __pyx_v_6eroder_infinity;
    goto __pyx_L0;
 0332: 
+0333:     cdef double talus = 1.25 * soil.organic
  __pyx_v_talus = (1.25 * __pyx_v_soil.organic);
+0334:     talus += 0.7 * soil.rocks[0]
  __pyx_v_talus = (__pyx_v_talus + (0.7 * (__pyx_v_soil.rocks[0])));
+0335:     talus += 0.8 * soil.rocks[1]
  __pyx_v_talus = (__pyx_v_talus + (0.8 * (__pyx_v_soil.rocks[1])));
+0336:     talus += 1.0 * soil.rocks[2]
  __pyx_v_talus = (__pyx_v_talus + (1.0 * (__pyx_v_soil.rocks[2])));
+0337:     talus += 1.0 * soil.rocks[3]
  __pyx_v_talus = (__pyx_v_talus + (1.0 * (__pyx_v_soil.rocks[3])));
 0338: 
+0339:     return talus * (1 + 0.2 * vegetation)
  __pyx_r = (__pyx_v_talus * (1.0 + (0.2 * __pyx_v_vegetation)));
  goto __pyx_L0;
 0340: 
 0341: 
+0342: cdef inline Soil organification(Soil soil, double vegetation, double organification_speed, double delta_t) noexcept nogil:
static CYTHON_INLINE struct __pyx_t_6eroder_Soil __pyx_f_6eroder_organification(struct __pyx_t_6eroder_Soil __pyx_v_soil, double __pyx_v_vegetation, double __pyx_v_organification_speed, double __pyx_v_delta_t) {
  double __pyx_v_change_0_org;
  double __pyx_v_change_1_0;
  double __pyx_v_change_2_1;
  double __pyx_v_change_3_2;
  struct __pyx_t_6eroder_Soil __pyx_v_result;
  struct __pyx_t_6eroder_Soil __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0343:     cdef double change_0_org = min(delta_t * vegetation * 0.01 * organification_speed * ROCK_CONVERSION_RATE[0], soil.rocks[0])
  __pyx_t_1 = (__pyx_v_soil.rocks[0]);
  __pyx_t_2 = ((((__pyx_v_delta_t * __pyx_v_vegetation) * 0.01) * __pyx_v_organification_speed) * (__pyx_v_6eroder_ROCK_CONVERSION_RATE[0]));
  __pyx_t_4 = (__pyx_t_1 < __pyx_t_2);
  if (__pyx_t_4) {
    __pyx_t_3 = __pyx_t_1;
  } else {
    __pyx_t_3 = __pyx_t_2;
  }
  __pyx_v_change_0_org = __pyx_t_3;
+0344:     cdef double change_1_0 = min(delta_t * vegetation * 0.01 * organification_speed * ROCK_CONVERSION_RATE[1], soil.rocks[1])
  __pyx_t_3 = (__pyx_v_soil.rocks[1]);
  __pyx_t_1 = ((((__pyx_v_delta_t * __pyx_v_vegetation) * 0.01) * __pyx_v_organification_speed) * (__pyx_v_6eroder_ROCK_CONVERSION_RATE[1]));
  __pyx_t_4 = (__pyx_t_3 < __pyx_t_1);
  if (__pyx_t_4) {
    __pyx_t_2 = __pyx_t_3;
  } else {
    __pyx_t_2 = __pyx_t_1;
  }
  __pyx_v_change_1_0 = __pyx_t_2;
+0345:     cdef double change_2_1 = min(delta_t * vegetation * 0.01 * organification_speed * ROCK_CONVERSION_RATE[2], soil.rocks[2])
  __pyx_t_2 = (__pyx_v_soil.rocks[2]);
  __pyx_t_3 = ((((__pyx_v_delta_t * __pyx_v_vegetation) * 0.01) * __pyx_v_organification_speed) * (__pyx_v_6eroder_ROCK_CONVERSION_RATE[2]));
  __pyx_t_4 = (__pyx_t_2 < __pyx_t_3);
  if (__pyx_t_4) {
    __pyx_t_1 = __pyx_t_2;
  } else {
    __pyx_t_1 = __pyx_t_3;
  }
  __pyx_v_change_2_1 = __pyx_t_1;
+0346:     cdef double change_3_2 = min(delta_t * vegetation * 0.01 * organification_speed * ROCK_CONVERSION_RATE[3], soil.rocks[3])
  __pyx_t_1 = (__pyx_v_soil.rocks[3]);
  __pyx_t_2 = ((((__pyx_v_delta_t * __pyx_v_vegetation) * 0.01) * __pyx_v_organification_speed) * (__pyx_v_6eroder_ROCK_CONVERSION_RATE[3]));
  __pyx_t_4 = (__pyx_t_1 < __pyx_t_2);
  if (__pyx_t_4) {
    __pyx_t_3 = __pyx_t_1;
  } else {
    __pyx_t_3 = __pyx_t_2;
  }
  __pyx_v_change_3_2 = __pyx_t_3;
 0347: 
+0348:     cdef Soil result = EMPTY_SOIL
  __pyx_v_result = __pyx_v_6eroder_EMPTY_SOIL;
+0349:     result.organic = soil.organic + change_0_org
  __pyx_v_result.organic = (__pyx_v_soil.organic + __pyx_v_change_0_org);
+0350:     result.rocks[0] = soil.rocks[0] + change_1_0 - change_0_org
  (__pyx_v_result.rocks[0]) = (((__pyx_v_soil.rocks[0]) + __pyx_v_change_1_0) - __pyx_v_change_0_org);
+0351:     result.rocks[1] = soil.rocks[1] + change_2_1 - change_1_0
  (__pyx_v_result.rocks[1]) = (((__pyx_v_soil.rocks[1]) + __pyx_v_change_2_1) - __pyx_v_change_1_0);
+0352:     result.rocks[2] = soil.rocks[2] + change_3_2 - change_2_1
  (__pyx_v_result.rocks[2]) = (((__pyx_v_soil.rocks[2]) + __pyx_v_change_3_2) - __pyx_v_change_2_1);
+0353:     result.rocks[3] = soil.rocks[3] - change_3_2
  (__pyx_v_result.rocks[3]) = ((__pyx_v_soil.rocks[3]) - __pyx_v_change_3_2);
 0354: 
+0355:     return result
  __pyx_r = __pyx_v_result;
  goto __pyx_L0;
 0356: 
 0357: ##################################################
 0358: # WATER
 0359: 
 0360: # returns Water with same ratios, but scaled by fraction
+0361: cdef inline Water water_fraction(Water water, double fraction) noexcept nogil:
static CYTHON_INLINE struct __pyx_t_6eroder_Water __pyx_f_6eroder_water_fraction(struct __pyx_t_6eroder_Water __pyx_v_water, double __pyx_v_fraction) {
  struct __pyx_t_6eroder_Water __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
 0362:     #if not (0.0 <= fraction <= 1.0):
 0363:     #    print("Invalid fraction value: " + str(fraction))
 0364: 
 0365:     # sometimes 1.0000000000000002 comes up and I don't like it
+0366:     if fraction > 1.0:
  __pyx_t_1 = (__pyx_v_fraction > 1.0);
  if (__pyx_t_1) {
/* … */
  }
+0367:         fraction = 1.0
    __pyx_v_fraction = 1.0;
 0368: 
+0369:     water.height *= fraction
  __pyx_v_water.height = (__pyx_v_water.height * __pyx_v_fraction);
 0370:     # previous water is handled differently
+0371:     water.regolith = soil_fraction(water.regolith, fraction)
  __pyx_v_water.regolith = __pyx_f_6eroder_soil_fraction(__pyx_v_water.regolith, __pyx_v_fraction);
+0372:     water.sediment = soil_fraction(water.sediment, fraction)
  __pyx_v_water.sediment = __pyx_f_6eroder_soil_fraction(__pyx_v_water.sediment, __pyx_v_fraction);
 0373:     # velocity remains unchanged
 0374: 
+0375:     return water
  __pyx_r = __pyx_v_water;
  goto __pyx_L0;
 0376: 
 0377: 
+0378: cdef inline Water add_water(Water a, Water b) noexcept nogil:
static CYTHON_INLINE struct __pyx_t_6eroder_Water __pyx_f_6eroder_add_water(struct __pyx_t_6eroder_Water __pyx_v_a, struct __pyx_t_6eroder_Water __pyx_v_b) {
  struct __pyx_t_6eroder_Water __pyx_v_c;
  struct __pyx_t_6eroder_Water __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0379:     cdef Water c = a
  __pyx_v_c = __pyx_v_a;
+0380:     add_to_water(c, b)
  __pyx_f_6eroder_add_to_water(__pyx_v_c, __pyx_v_b);
+0381:     return c
  __pyx_r = __pyx_v_c;
  goto __pyx_L0;
 0382: 
 0383: 
 0384: # MODIFIES ARGUMENT
+0385: cdef void add_to_water(Water& a, Water b) noexcept nogil:
static void __pyx_f_6eroder_add_to_water(struct __pyx_t_6eroder_Water &__pyx_v_a, struct __pyx_t_6eroder_Water __pyx_v_b) {
  double __pyx_v_velocity_multiplier;
/* … */
  /* function exit code */
  __pyx_L0:;
}
+0386:     if b.height <= 0.0:
  __pyx_t_1 = (__pyx_v_b.height <= 0.0);
  if (__pyx_t_1) {
/* … */
  }
+0387:         return
    goto __pyx_L0;
 0388: 
+0389:     cdef double velocity_multiplier = a.height / (a.height + b.height)
  __pyx_v_velocity_multiplier = (__pyx_v_a.height / (__pyx_v_a.height + __pyx_v_b.height));
 0390: 
+0391:     a.height += b.height
  __pyx_v_a.height = (__pyx_v_a.height + __pyx_v_b.height);
+0392:     add_to_soil(a.regolith, b.regolith)
  __pyx_f_6eroder_add_to_soil(__pyx_v_a.regolith, __pyx_v_b.regolith);
+0393:     add_to_soil(a.sediment, b.sediment)
  __pyx_f_6eroder_add_to_soil(__pyx_v_a.sediment, __pyx_v_b.sediment);
 0394:     # previous water is handled differently
+0395:     a.velocity_x = a.velocity_x * velocity_multiplier + b.velocity_x * (1.0 - velocity_multiplier)
  __pyx_v_a.velocity_x = ((__pyx_v_a.velocity_x * __pyx_v_velocity_multiplier) + (__pyx_v_b.velocity_x * (1.0 - __pyx_v_velocity_multiplier)));
+0396:     a.velocity_y = a.velocity_y * velocity_multiplier + b.velocity_y * (1.0 - velocity_multiplier)
  __pyx_v_a.velocity_y = ((__pyx_v_a.velocity_y * __pyx_v_velocity_multiplier) + (__pyx_v_b.velocity_y * (1.0 - __pyx_v_velocity_multiplier)));
 0397: 
 0398: 
+0399: cdef inline Water speedup(Water water, double x, double y) noexcept nogil:
static CYTHON_INLINE struct __pyx_t_6eroder_Water __pyx_f_6eroder_speedup(struct __pyx_t_6eroder_Water __pyx_v_water, double __pyx_v_x, double __pyx_v_y) {
  struct __pyx_t_6eroder_Water __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0400:     water.velocity_x += x
  __pyx_v_water.velocity_x = (__pyx_v_water.velocity_x + __pyx_v_x);
+0401:     water.velocity_y += y
  __pyx_v_water.velocity_y = (__pyx_v_water.velocity_y + __pyx_v_y);
+0402:     return water
  __pyx_r = __pyx_v_water;
  goto __pyx_L0;
 0403: 
 0404: 
 0405: # MODIFIES ARGUMENT
+0406: cdef inline void slow_down(Water& water) noexcept nogil:
static CYTHON_INLINE void __pyx_f_6eroder_slow_down(struct __pyx_t_6eroder_Water &__pyx_v_water) {
  CYTHON_UNUSED double __pyx_v_scaling;
  double __pyx_v_velocity;
  double __pyx_v_resistance;
/* … */
  /* function exit code */
}
+0407:     cdef double scaling = 1.0
  __pyx_v_scaling = 1.0;
+0408:     cdef double velocity = sqrt(water.velocity_x**2 + water.velocity_y**2)
  __pyx_v_velocity = sqrt((pow(__pyx_v_water.velocity_x, 2.0) + pow(__pyx_v_water.velocity_y, 2.0)));
+0409:     cdef double resistance = 0.25 * (velocity / MAX_WATER_SPEED)**2
  __pyx_v_resistance = (0.25 * pow((__pyx_v_velocity / __pyx_v_6eroder_MAX_WATER_SPEED), 2.0));
 0410: 
 0411:     #if velocity > MAX_WATER_SPEED:
 0412:     #    scaling = MAX_WATER_SPEED / velocity
+0413:     water.velocity_x *= max(1 - resistance, 0)
  __pyx_t_1 = 0;
  __pyx_t_2 = (1.0 - __pyx_v_resistance);
  __pyx_t_4 = (__pyx_t_1 > __pyx_t_2);
  if (__pyx_t_4) {
    __pyx_t_3 = __pyx_t_1;
  } else {
    __pyx_t_3 = __pyx_t_2;
  }
  __pyx_v_water.velocity_x = (__pyx_v_water.velocity_x * __pyx_t_3);
+0414:     water.velocity_y *= max(1 - resistance, 0)
  __pyx_t_1 = 0;
  __pyx_t_3 = (1.0 - __pyx_v_resistance);
  __pyx_t_4 = (__pyx_t_1 > __pyx_t_3);
  if (__pyx_t_4) {
    __pyx_t_2 = __pyx_t_1;
  } else {
    __pyx_t_2 = __pyx_t_3;
  }
  __pyx_v_water.velocity_y = (__pyx_v_water.velocity_y * __pyx_t_2);
 0415: 
 0416: 
 0417: ##################################################
 0418: # EROSION AND DEPOSITION
 0419: 
 0420: 
 0421: # MODIFIES ARGUMENT
+0422: cdef void remove_soil(Horizon& horizon, double amount) noexcept nogil:
static void __pyx_f_6eroder_remove_soil(struct __pyx_t_6eroder_Horizon &__pyx_v_horizon, double __pyx_v_amount) {
  double __pyx_v_topsoil_height;
  double __pyx_v_fraction_remove;
  double __pyx_v_removed;
  double __pyx_v_subsoil_height;
  int __pyx_v_index;
/* … */
  /* function exit code */
}
+0423:     cdef double topsoil_height = get_soil_height(horizon.topsoil)
  __pyx_v_topsoil_height = __pyx_f_6eroder_get_soil_height(__pyx_v_horizon.topsoil);
+0424:     cdef double fraction_remove = 1.0
  __pyx_v_fraction_remove = 1.0;
+0425:     cdef double removed = 0.0
  __pyx_v_removed = 0.0;
 0426: 
 0427:     # topsoil
+0428:     if topsoil_height > 0:
  __pyx_t_1 = (__pyx_v_topsoil_height > 0.0);
  if (__pyx_t_1) {
/* … */
  }
+0429:         fraction_remove = min(amount / topsoil_height, 1.0)
    __pyx_t_2 = 1.0;
    __pyx_t_3 = (__pyx_v_amount / __pyx_v_topsoil_height);
    __pyx_t_1 = (__pyx_t_2 < __pyx_t_3);
    if (__pyx_t_1) {
      __pyx_t_4 = __pyx_t_2;
    } else {
      __pyx_t_4 = __pyx_t_3;
    }
    __pyx_v_fraction_remove = __pyx_t_4;
+0430:         horizon.topsoil = soil_fraction(horizon.topsoil, 1.0 - fraction_remove)
    __pyx_v_horizon.topsoil = __pyx_f_6eroder_soil_fraction(__pyx_v_horizon.topsoil, (1.0 - __pyx_v_fraction_remove));
+0431:         removed += fraction_remove * topsoil_height
    __pyx_v_removed = (__pyx_v_removed + (__pyx_v_fraction_remove * __pyx_v_topsoil_height));
 0432: 
 0433:     # and also subsoil
+0434:     cdef double subsoil_height = get_soil_height(horizon.subsoil)
  __pyx_v_subsoil_height = __pyx_f_6eroder_get_soil_height(__pyx_v_horizon.subsoil);
 0435: 
 0436:     # topsoil
+0437:     if amount > topsoil_height and subsoil_height > 0.0:
  __pyx_t_5 = (__pyx_v_amount > __pyx_v_topsoil_height);
  if (__pyx_t_5) {
  } else {
    __pyx_t_1 = __pyx_t_5;
    goto __pyx_L5_bool_binop_done;
  }
  __pyx_t_5 = (__pyx_v_subsoil_height > 0.0);
  __pyx_t_1 = __pyx_t_5;
  __pyx_L5_bool_binop_done:;
  if (__pyx_t_1) {
/* … */
  }
+0438:         fraction_remove = min((amount - topsoil_height) / subsoil_height, 1.0)
    __pyx_t_4 = 1.0;
    __pyx_t_2 = ((__pyx_v_amount - __pyx_v_topsoil_height) / __pyx_v_subsoil_height);
    __pyx_t_1 = (__pyx_t_4 < __pyx_t_2);
    if (__pyx_t_1) {
      __pyx_t_3 = __pyx_t_4;
    } else {
      __pyx_t_3 = __pyx_t_2;
    }
    __pyx_v_fraction_remove = __pyx_t_3;
+0439:         horizon.subsoil = soil_fraction(horizon.subsoil, 1.0 - fraction_remove)
    __pyx_v_horizon.subsoil = __pyx_f_6eroder_soil_fraction(__pyx_v_horizon.subsoil, (1.0 - __pyx_v_fraction_remove));
+0440:         removed += fraction_remove * subsoil_height
    __pyx_v_removed = (__pyx_v_removed + (__pyx_v_fraction_remove * __pyx_v_subsoil_height));
 0441: 
 0442:     """ if not eq(amount, removed):
 0443:         print("discrepancy! amount=" + str(amount) + ", removed=" + str(removed)) """
 0444: 
 0445:     # first non-empty
+0446:     cdef int index = 0
  __pyx_v_index = 0;
+0447:     while horizon.bedrock[index].height <= 0.0:
  while (1) {
    __pyx_t_1 = ((__pyx_v_horizon.bedrock[__pyx_v_index]).height <= 0.0);
    if (!__pyx_t_1) break;
+0448:         index += 1
    __pyx_v_index = (__pyx_v_index + 1);
  }
 0449: 
 0450:     # remove the rest from the bedrock
+0451:     horizon.bedrock[index].height -= amount - removed
  __pyx_t_6 = __pyx_v_index;
  (__pyx_v_horizon.bedrock[__pyx_t_6]).height = ((__pyx_v_horizon.bedrock[__pyx_t_6]).height - (__pyx_v_amount - __pyx_v_removed));
 0452: 
 0453: 
 0454: 
 0455: # MODIFIES ARGUMENT
+0456: cdef void deposit_soil(Horizon& destination, Soil& soil) noexcept nogil:
static void __pyx_f_6eroder_deposit_soil(struct __pyx_t_6eroder_Horizon &__pyx_v_destination, struct __pyx_t_6eroder_Soil &__pyx_v_soil) {
  unsigned int __pyx_v_i;
/* … */
  /* function exit code */
}
 0457:     cdef unsigned int i
 0458: 
 0459:     # prepare place in topsoil for new stuff
+0460:     organize_horizon(destination, get_soil_height(soil))
  __pyx_f_6eroder_organize_horizon(__pyx_v_destination, __pyx_f_6eroder_get_soil_height(__pyx_v_soil));
 0461: 
+0462:     destination.topsoil.organic += soil.organic
  __pyx_v_destination.topsoil.organic = (__pyx_v_destination.topsoil.organic + __pyx_v_soil.organic);
+0463:     for i in range(4):
  for (__pyx_t_1 = 0; __pyx_t_1 < 4; __pyx_t_1+=1) {
    __pyx_v_i = __pyx_t_1;
+0464:         destination.topsoil.rocks[i] += soil.rocks[i]
    __pyx_t_2 = __pyx_v_i;
    (__pyx_v_destination.topsoil.rocks[__pyx_t_2]) = ((__pyx_v_destination.topsoil.rocks[__pyx_t_2]) + (__pyx_v_soil.rocks[__pyx_v_i]));
  }
 0465: 
 0466:     # make sure topsoil is not too thick (might delete later)
+0467:     organize_horizon(destination, 0.0)
  __pyx_f_6eroder_organize_horizon(__pyx_v_destination, 0.0);
 0468: 
 0469: 
 0470: # MODIFIES ARGUMENT
+0471: cdef double erode_organic_amount(Horizon& horizon, double requested_amount) noexcept nogil:
static double __pyx_f_6eroder_erode_organic_amount(struct __pyx_t_6eroder_Horizon &__pyx_v_horizon, double __pyx_v_requested_amount) {
  double __pyx_v_amount_remove;
  double __pyx_v_removed;
  double __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0472:     cdef double amount_remove = 0.0
  __pyx_v_amount_remove = 0.0;
+0473:     cdef double removed = 0.0
  __pyx_v_removed = 0.0;
+0474:     requested_amount = max(0.0, requested_amount)
  __pyx_t_1 = __pyx_v_requested_amount;
  __pyx_t_2 = 0.0;
  __pyx_t_4 = (__pyx_t_1 > __pyx_t_2);
  if (__pyx_t_4) {
    __pyx_t_3 = __pyx_t_1;
  } else {
    __pyx_t_3 = __pyx_t_2;
  }
  __pyx_v_requested_amount = __pyx_t_3;
 0475: 
+0476:     if get_soil_height(horizon.topsoil) > 0.0:
  __pyx_t_4 = (__pyx_f_6eroder_get_soil_height(__pyx_v_horizon.topsoil) > 0.0);
  if (__pyx_t_4) {
/* … */
  }
+0477:         amount_remove = min(horizon.topsoil.organic, requested_amount)
    __pyx_t_3 = __pyx_v_requested_amount;
    __pyx_t_1 = __pyx_v_horizon.topsoil.organic;
    __pyx_t_4 = (__pyx_t_3 < __pyx_t_1);
    if (__pyx_t_4) {
      __pyx_t_2 = __pyx_t_3;
    } else {
      __pyx_t_2 = __pyx_t_1;
    }
    __pyx_v_amount_remove = __pyx_t_2;
+0478:         requested_amount -= amount_remove
    __pyx_v_requested_amount = (__pyx_v_requested_amount - __pyx_v_amount_remove);
+0479:         amount_remove *= max(MIN_FRACTION_TO_ERODE, horizon.topsoil.organic / get_soil_height(horizon.topsoil))
    __pyx_t_2 = (__pyx_v_horizon.topsoil.organic / __pyx_f_6eroder_get_soil_height(__pyx_v_horizon.topsoil));
    __pyx_t_3 = __pyx_v_6eroder_MIN_FRACTION_TO_ERODE;
    __pyx_t_4 = (__pyx_t_2 > __pyx_t_3);
    if (__pyx_t_4) {
      __pyx_t_1 = __pyx_t_2;
    } else {
      __pyx_t_1 = __pyx_t_3;
    }
    __pyx_v_amount_remove = (__pyx_v_amount_remove * __pyx_t_1);
+0480:         horizon.topsoil.organic -= amount_remove
    __pyx_v_horizon.topsoil.organic = (__pyx_v_horizon.topsoil.organic - __pyx_v_amount_remove);
+0481:         removed = amount_remove
    __pyx_v_removed = __pyx_v_amount_remove;
 0482:         # try eroding from the lower layer as well
+0483:         requested_amount *= max(0.0, 1 - (get_soil_height(horizon.topsoil) / LAYER_HEIGHT_TO_BECOME_ERODETHROUGH))
    __pyx_t_1 = (1.0 - (__pyx_f_6eroder_get_soil_height(__pyx_v_horizon.topsoil) / __pyx_v_6eroder_LAYER_HEIGHT_TO_BECOME_ERODETHROUGH));
    __pyx_t_2 = 0.0;
    __pyx_t_4 = (__pyx_t_1 > __pyx_t_2);
    if (__pyx_t_4) {
      __pyx_t_3 = __pyx_t_1;
    } else {
      __pyx_t_3 = __pyx_t_2;
    }
    __pyx_v_requested_amount = (__pyx_v_requested_amount * __pyx_t_3);
 0484: 
+0485:     if get_soil_height(horizon.subsoil) > 0.0 and requested_amount > 0.0:
  __pyx_t_5 = (__pyx_f_6eroder_get_soil_height(__pyx_v_horizon.subsoil) > 0.0);
  if (__pyx_t_5) {
  } else {
    __pyx_t_4 = __pyx_t_5;
    goto __pyx_L5_bool_binop_done;
  }
  __pyx_t_5 = (__pyx_v_requested_amount > 0.0);
  __pyx_t_4 = __pyx_t_5;
  __pyx_L5_bool_binop_done:;
  if (__pyx_t_4) {
/* … */
  }
+0486:         amount_remove = min(horizon.subsoil.organic, requested_amount)
    __pyx_t_3 = __pyx_v_requested_amount;
    __pyx_t_1 = __pyx_v_horizon.subsoil.organic;
    __pyx_t_4 = (__pyx_t_3 < __pyx_t_1);
    if (__pyx_t_4) {
      __pyx_t_2 = __pyx_t_3;
    } else {
      __pyx_t_2 = __pyx_t_1;
    }
    __pyx_v_amount_remove = __pyx_t_2;
+0487:         requested_amount -= amount_remove
    __pyx_v_requested_amount = (__pyx_v_requested_amount - __pyx_v_amount_remove);
+0488:         amount_remove *= max(MIN_FRACTION_TO_ERODE, horizon.subsoil.organic / get_soil_height(horizon.subsoil))
    __pyx_t_2 = (__pyx_v_horizon.subsoil.organic / __pyx_f_6eroder_get_soil_height(__pyx_v_horizon.subsoil));
    __pyx_t_3 = __pyx_v_6eroder_MIN_FRACTION_TO_ERODE;
    __pyx_t_4 = (__pyx_t_2 > __pyx_t_3);
    if (__pyx_t_4) {
      __pyx_t_1 = __pyx_t_2;
    } else {
      __pyx_t_1 = __pyx_t_3;
    }
    __pyx_v_amount_remove = (__pyx_v_amount_remove * __pyx_t_1);
+0489:         horizon.subsoil.organic -= amount_remove
    __pyx_v_horizon.subsoil.organic = (__pyx_v_horizon.subsoil.organic - __pyx_v_amount_remove);
 0490: 
 0491:     # no need to erode rocks, they aren't organic
+0492:     return amount_remove + removed
  __pyx_r = (__pyx_v_amount_remove + __pyx_v_removed);
  goto __pyx_L0;
 0493: 
 0494: 
 0495: # MODIFIES ARGUMENT
+0496: cdef double erode_rocks_amount(Horizon& horizon, double water_info, int type_result) noexcept nogil:
static double __pyx_f_6eroder_erode_rocks_amount(struct __pyx_t_6eroder_Horizon &__pyx_v_horizon, double __pyx_v_water_info, int __pyx_v_type_result) {
  double __pyx_v_amount_remove;
  double __pyx_v_removed;
  double __pyx_v_requested_amount;
  double __pyx_v_requested_residue;
  int __pyx_v_i;
  int __pyx_v_rock_type;
  double __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
 0497:     cdef double amount_remove
+0498:     cdef double removed = 0.0
  __pyx_v_removed = 0.0;
+0499:     cdef double requested_amount = 0.0
  __pyx_v_requested_amount = 0.0;
+0500:     cdef double requested_residue = 0.0
  __pyx_v_requested_residue = 0.0;
+0501:     cdef int i = 0
  __pyx_v_i = 0;
 0502: 
 0503: 
+0504:     for i in range(4):
  for (__pyx_t_1 = 0; __pyx_t_1 < 4; __pyx_t_1+=1) {
    __pyx_v_i = __pyx_t_1;
+0505:         requested_amount = K_EROSION * max(rock_matrix_linear[i][type_result] * water_info + rock_matrix_constant[i][type_result], 0.0)
    __pyx_t_2 = 0.0;
    __pyx_t_3 = ((((__pyx_v_6eroder_rock_matrix_linear[__pyx_v_i])[__pyx_v_type_result]) * __pyx_v_water_info) + ((__pyx_v_6eroder_rock_matrix_constant[__pyx_v_i])[__pyx_v_type_result]));
    __pyx_t_5 = (__pyx_t_2 > __pyx_t_3);
    if (__pyx_t_5) {
      __pyx_t_4 = __pyx_t_2;
    } else {
      __pyx_t_4 = __pyx_t_3;
    }
    __pyx_v_requested_amount = (__pyx_v_6eroder_K_EROSION * __pyx_t_4);
+0506:         if horizon.topsoil.rocks[i] > 0.0 and requested_amount > 0.0:
    __pyx_t_6 = ((__pyx_v_horizon.topsoil.rocks[__pyx_v_i]) > 0.0);
    if (__pyx_t_6) {
    } else {
      __pyx_t_5 = __pyx_t_6;
      goto __pyx_L6_bool_binop_done;
    }
    __pyx_t_6 = (__pyx_v_requested_amount > 0.0);
    __pyx_t_5 = __pyx_t_6;
    __pyx_L6_bool_binop_done:;
    if (__pyx_t_5) {
/* … */
    }
+0507:             amount_remove = min(horizon.topsoil.rocks[i], requested_amount)
      __pyx_t_4 = __pyx_v_requested_amount;
      __pyx_t_2 = (__pyx_v_horizon.topsoil.rocks[__pyx_v_i]);
      __pyx_t_5 = (__pyx_t_4 < __pyx_t_2);
      if (__pyx_t_5) {
        __pyx_t_3 = __pyx_t_4;
      } else {
        __pyx_t_3 = __pyx_t_2;
      }
      __pyx_v_amount_remove = __pyx_t_3;
+0508:             requested_amount -= amount_remove
      __pyx_v_requested_amount = (__pyx_v_requested_amount - __pyx_v_amount_remove);
+0509:             amount_remove *= max(MIN_FRACTION_TO_ERODE, horizon.topsoil.rocks[i] / get_soil_height(horizon.topsoil))
      __pyx_t_3 = ((__pyx_v_horizon.topsoil.rocks[__pyx_v_i]) / __pyx_f_6eroder_get_soil_height(__pyx_v_horizon.topsoil));
      __pyx_t_4 = __pyx_v_6eroder_MIN_FRACTION_TO_ERODE;
      __pyx_t_5 = (__pyx_t_3 > __pyx_t_4);
      if (__pyx_t_5) {
        __pyx_t_2 = __pyx_t_3;
      } else {
        __pyx_t_2 = __pyx_t_4;
      }
      __pyx_v_amount_remove = (__pyx_v_amount_remove * __pyx_t_2);
+0510:             horizon.topsoil.rocks[i] -= amount_remove
      __pyx_t_7 = __pyx_v_i;
      (__pyx_v_horizon.topsoil.rocks[__pyx_t_7]) = ((__pyx_v_horizon.topsoil.rocks[__pyx_t_7]) - __pyx_v_amount_remove);
+0511:             removed += amount_remove
      __pyx_v_removed = (__pyx_v_removed + __pyx_v_amount_remove);
 0512: 
 0513:             # try eroding from the lower layer as well
+0514:             requested_amount *= max(0.0, 1 - (get_soil_height(horizon.topsoil) / LAYER_HEIGHT_TO_BECOME_ERODETHROUGH))
      __pyx_t_2 = (1.0 - (__pyx_f_6eroder_get_soil_height(__pyx_v_horizon.topsoil) / __pyx_v_6eroder_LAYER_HEIGHT_TO_BECOME_ERODETHROUGH));
      __pyx_t_3 = 0.0;
      __pyx_t_5 = (__pyx_t_2 > __pyx_t_3);
      if (__pyx_t_5) {
        __pyx_t_4 = __pyx_t_2;
      } else {
        __pyx_t_4 = __pyx_t_3;
      }
      __pyx_v_requested_amount = (__pyx_v_requested_amount * __pyx_t_4);
 0515: 
 0516: 
+0517:         if horizon.subsoil.rocks[i] > 0.0 and requested_amount > 0.0:
    __pyx_t_6 = ((__pyx_v_horizon.subsoil.rocks[__pyx_v_i]) > 0.0);
    if (__pyx_t_6) {
    } else {
      __pyx_t_5 = __pyx_t_6;
      goto __pyx_L9_bool_binop_done;
    }
    __pyx_t_6 = (__pyx_v_requested_amount > 0.0);
    __pyx_t_5 = __pyx_t_6;
    __pyx_L9_bool_binop_done:;
    if (__pyx_t_5) {
/* … */
    }
+0518:             amount_remove = min(horizon.subsoil.rocks[i], requested_amount)
      __pyx_t_4 = __pyx_v_requested_amount;
      __pyx_t_2 = (__pyx_v_horizon.subsoil.rocks[__pyx_v_i]);
      __pyx_t_5 = (__pyx_t_4 < __pyx_t_2);
      if (__pyx_t_5) {
        __pyx_t_3 = __pyx_t_4;
      } else {
        __pyx_t_3 = __pyx_t_2;
      }
      __pyx_v_amount_remove = __pyx_t_3;
+0519:             requested_amount -= amount_remove
      __pyx_v_requested_amount = (__pyx_v_requested_amount - __pyx_v_amount_remove);
+0520:             amount_remove *= max(MIN_FRACTION_TO_ERODE, horizon.subsoil.rocks[i] / get_soil_height(horizon.subsoil))
      __pyx_t_3 = ((__pyx_v_horizon.subsoil.rocks[__pyx_v_i]) / __pyx_f_6eroder_get_soil_height(__pyx_v_horizon.subsoil));
      __pyx_t_4 = __pyx_v_6eroder_MIN_FRACTION_TO_ERODE;
      __pyx_t_5 = (__pyx_t_3 > __pyx_t_4);
      if (__pyx_t_5) {
        __pyx_t_2 = __pyx_t_3;
      } else {
        __pyx_t_2 = __pyx_t_4;
      }
      __pyx_v_amount_remove = (__pyx_v_amount_remove * __pyx_t_2);
+0521:             horizon.subsoil.rocks[i] -= amount_remove
      __pyx_t_7 = __pyx_v_i;
      (__pyx_v_horizon.subsoil.rocks[__pyx_t_7]) = ((__pyx_v_horizon.subsoil.rocks[__pyx_t_7]) - __pyx_v_amount_remove);
+0522:             removed += amount_remove
      __pyx_v_removed = (__pyx_v_removed + __pyx_v_amount_remove);
 0523: 
 0524:             # try eroding from the lower layer as well
+0525:             requested_amount *= max(0.0, 1 - (get_soil_height(horizon.subsoil) / LAYER_HEIGHT_TO_BECOME_ERODETHROUGH))
      __pyx_t_2 = (1.0 - (__pyx_f_6eroder_get_soil_height(__pyx_v_horizon.subsoil) / __pyx_v_6eroder_LAYER_HEIGHT_TO_BECOME_ERODETHROUGH));
      __pyx_t_3 = 0.0;
      __pyx_t_5 = (__pyx_t_2 > __pyx_t_3);
      if (__pyx_t_5) {
        __pyx_t_4 = __pyx_t_2;
      } else {
        __pyx_t_4 = __pyx_t_3;
      }
      __pyx_v_requested_amount = (__pyx_v_requested_amount * __pyx_t_4);
 0526: 
 0527:         # how much will it try to erode rocks
+0528:         requested_residue += requested_amount
    __pyx_v_requested_residue = (__pyx_v_requested_residue + __pyx_v_requested_amount);
  }
 0529: 
 0530:     # bedrock
+0531:     for i in range(horizon.bedrock.size()):
  __pyx_t_8 = __pyx_v_horizon.bedrock.size();
  __pyx_t_9 = __pyx_t_8;
  for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_9; __pyx_t_1+=1) {
    __pyx_v_i = __pyx_t_1;
+0532:         if horizon.bedrock[i].height <= 0.0:
    __pyx_t_5 = ((__pyx_v_horizon.bedrock[__pyx_v_i]).height <= 0.0);
    if (__pyx_t_5) {
/* … */
    }
+0533:             continue
      goto __pyx_L11_continue;
 0534: 
+0535:         rock_type = horizon.bedrock[i].type
    __pyx_t_7 = (__pyx_v_horizon.bedrock[__pyx_v_i]).type;
    __pyx_v_rock_type = __pyx_t_7;
+0536:         requested_amount = max(bedrock_erodability_linear[rock_type][type_result] * requested_residue + bedrock_erodability_constant[rock_type][type_result], 0.0)
    __pyx_t_4 = 0.0;
    __pyx_t_2 = ((((__pyx_v_6eroder_bedrock_erodability_linear[__pyx_v_rock_type])[__pyx_v_type_result]) * __pyx_v_requested_residue) + ((__pyx_v_6eroder_bedrock_erodability_constant[__pyx_v_rock_type])[__pyx_v_type_result]));
    __pyx_t_5 = (__pyx_t_4 > __pyx_t_2);
    if (__pyx_t_5) {
      __pyx_t_3 = __pyx_t_4;
    } else {
      __pyx_t_3 = __pyx_t_2;
    }
    __pyx_v_requested_amount = __pyx_t_3;
+0537:         if requested_amount > 0.0:
    __pyx_t_5 = (__pyx_v_requested_amount > 0.0);
    if (__pyx_t_5) {
/* … */
    }
    __pyx_L11_continue:;
  }
  __pyx_L12_break:;
+0538:             amount_remove = min(horizon.bedrock[i].height, requested_amount)
      __pyx_t_3 = __pyx_v_requested_amount;
      __pyx_t_4 = (__pyx_v_horizon.bedrock[__pyx_v_i]).height;
      __pyx_t_5 = (__pyx_t_3 < __pyx_t_4);
      if (__pyx_t_5) {
        __pyx_t_2 = __pyx_t_3;
      } else {
        __pyx_t_2 = __pyx_t_4;
      }
      __pyx_v_amount_remove = __pyx_t_2;
+0539:             horizon.bedrock[i].height -= amount_remove
      __pyx_t_7 = __pyx_v_i;
      (__pyx_v_horizon.bedrock[__pyx_t_7]).height = ((__pyx_v_horizon.bedrock[__pyx_t_7]).height - __pyx_v_amount_remove);
+0540:             removed += amount_remove
      __pyx_v_removed = (__pyx_v_removed + __pyx_v_amount_remove);
+0541:             break
      goto __pyx_L12_break;
 0542: 
+0543:     return removed
  __pyx_r = __pyx_v_removed;
  goto __pyx_L0;
 0544: 
 0545: 
 0546: # MODIFIES ARGUMENT
+0547: cdef Soil erode_regolith(Horizon& horizon, double requested_amount) noexcept nogil:
static struct __pyx_t_6eroder_Soil __pyx_f_6eroder_erode_regolith(struct __pyx_t_6eroder_Horizon &__pyx_v_horizon, double __pyx_v_requested_amount) {
  double __pyx_v_amount_remove_org;
  double __pyx_v_amount_remove_rock;
  double __pyx_v_removed_org;
  double __pyx_v_removed_rock;
  struct __pyx_t_6eroder_Soil __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+0548:     cdef double amount_remove_org = 0.0, amount_remove_rock = 0.0
  __pyx_v_amount_remove_org = 0.0;
  __pyx_v_amount_remove_rock = 0.0;
+0549:     cdef double removed_org = 0.0, removed_rock = 0.0
  __pyx_v_removed_org = 0.0;
  __pyx_v_removed_rock = 0.0;
+0550:     requested_amount = max(0.0, requested_amount)
  __pyx_t_1 = __pyx_v_requested_amount;
  __pyx_t_2 = 0.0;
  __pyx_t_4 = (__pyx_t_1 > __pyx_t_2);
  if (__pyx_t_4) {
    __pyx_t_3 = __pyx_t_1;
  } else {
    __pyx_t_3 = __pyx_t_2;
  }
  __pyx_v_requested_amount = __pyx_t_3;
 0551: 
+0552:     if get_soil_height(horizon.topsoil) > 0.0:
  __pyx_t_4 = (__pyx_f_6eroder_get_soil_height(__pyx_v_horizon.topsoil) > 0.0);
  if (__pyx_t_4) {
/* … */
  }
+0553:         amount_remove_org = min(horizon.topsoil.organic, 0.5 * requested_amount)
    __pyx_t_3 = (0.5 * __pyx_v_requested_amount);
    __pyx_t_1 = __pyx_v_horizon.topsoil.organic;
    __pyx_t_4 = (__pyx_t_3 < __pyx_t_1);
    if (__pyx_t_4) {
      __pyx_t_2 = __pyx_t_3;
    } else {
      __pyx_t_2 = __pyx_t_1;
    }
    __pyx_v_amount_remove_org = __pyx_t_2;
+0554:         amount_remove_rock = min(horizon.topsoil.rocks[0], 0.5 * requested_amount)
    __pyx_t_2 = (0.5 * __pyx_v_requested_amount);
    __pyx_t_3 = (__pyx_v_horizon.topsoil.rocks[0]);
    __pyx_t_4 = (__pyx_t_2 < __pyx_t_3);
    if (__pyx_t_4) {
      __pyx_t_1 = __pyx_t_2;
    } else {
      __pyx_t_1 = __pyx_t_3;
    }
    __pyx_v_amount_remove_rock = __pyx_t_1;
+0555:         requested_amount -= amount_remove_org + amount_remove_rock
    __pyx_v_requested_amount = (__pyx_v_requested_amount - (__pyx_v_amount_remove_org + __pyx_v_amount_remove_rock));
+0556:         amount_remove_org *= max(MIN_FRACTION_TO_ERODE, horizon.topsoil.organic / get_soil_height(horizon.topsoil))
    __pyx_t_1 = (__pyx_v_horizon.topsoil.organic / __pyx_f_6eroder_get_soil_height(__pyx_v_horizon.topsoil));
    __pyx_t_2 = __pyx_v_6eroder_MIN_FRACTION_TO_ERODE;
    __pyx_t_4 = (__pyx_t_1 > __pyx_t_2);
    if (__pyx_t_4) {
      __pyx_t_3 = __pyx_t_1;
    } else {
      __pyx_t_3 = __pyx_t_2;
    }
    __pyx_v_amount_remove_org = (__pyx_v_amount_remove_org * __pyx_t_3);
+0557:         amount_remove_rock *= max(MIN_FRACTION_TO_ERODE, horizon.topsoil.rocks[0] / get_soil_height(horizon.topsoil))
    __pyx_t_3 = ((__pyx_v_horizon.topsoil.rocks[0]) / __pyx_f_6eroder_get_soil_height(__pyx_v_horizon.topsoil));
    __pyx_t_1 = __pyx_v_6eroder_MIN_FRACTION_TO_ERODE;
    __pyx_t_4 = (__pyx_t_3 > __pyx_t_1);
    if (__pyx_t_4) {
      __pyx_t_2 = __pyx_t_3;
    } else {
      __pyx_t_2 = __pyx_t_1;
    }
    __pyx_v_amount_remove_rock = (__pyx_v_amount_remove_rock * __pyx_t_2);
+0558:         horizon.topsoil.organic -= amount_remove_org
    __pyx_v_horizon.topsoil.organic = (__pyx_v_horizon.topsoil.organic - __pyx_v_amount_remove_org);
+0559:         horizon.topsoil.rocks[0] -= amount_remove_rock
    __pyx_t_5 = 0;
    (__pyx_v_horizon.topsoil.rocks[__pyx_t_5]) = ((__pyx_v_horizon.topsoil.rocks[__pyx_t_5]) - __pyx_v_amount_remove_rock);
+0560:         removed_org = amount_remove_org
    __pyx_v_removed_org = __pyx_v_amount_remove_org;
+0561:         removed_rock = amount_remove_rock
    __pyx_v_removed_rock = __pyx_v_amount_remove_rock;
 0562:         # try eroding from the lower layer as well
+0563:         requested_amount *= max(0.0, 1 - (get_soil_height(horizon.topsoil) / LAYER_HEIGHT_TO_BECOME_ERODETHROUGH))
    __pyx_t_2 = (1.0 - (__pyx_f_6eroder_get_soil_height(__pyx_v_horizon.topsoil) / __pyx_v_6eroder_LAYER_HEIGHT_TO_BECOME_ERODETHROUGH));
    __pyx_t_3 = 0.0;
    __pyx_t_4 = (__pyx_t_2 > __pyx_t_3);
    if (__pyx_t_4) {
      __pyx_t_1 = __pyx_t_2;
    } else {
      __pyx_t_1 = __pyx_t_3;
    }
    __pyx_v_requested_amount = (__pyx_v_requested_amount * __pyx_t_1);
 0564: 
+0565:     if get_soil_height(horizon.subsoil) > 0.0 and requested_amount > 0.0:
  __pyx_t_6 = (__pyx_f_6eroder_get_soil_height(__pyx_v_horizon.subsoil) > 0.0);
  if (__pyx_t_6) {
  } else {
    __pyx_t_4 = __pyx_t_6;
    goto __pyx_L5_bool_binop_done;
  }
  __pyx_t_6 = (__pyx_v_requested_amount > 0.0);
  __pyx_t_4 = __pyx_t_6;
  __pyx_L5_bool_binop_done:;
  if (__pyx_t_4) {
/* … */
  }
+0566:         amount_remove_org = min(horizon.subsoil.organic, 0.5 * requested_amount)
    __pyx_t_1 = (0.5 * __pyx_v_requested_amount);
    __pyx_t_2 = __pyx_v_horizon.subsoil.organic;
    __pyx_t_4 = (__pyx_t_1 < __pyx_t_2);
    if (__pyx_t_4) {
      __pyx_t_3 = __pyx_t_1;
    } else {
      __pyx_t_3 = __pyx_t_2;
    }
    __pyx_v_amount_remove_org = __pyx_t_3;
+0567:         amount_remove_rock = min(horizon.subsoil.rocks[0], 0.5 * requested_amount)
    __pyx_t_3 = (0.5 * __pyx_v_requested_amount);
    __pyx_t_1 = (__pyx_v_horizon.subsoil.rocks[0]);
    __pyx_t_4 = (__pyx_t_3 < __pyx_t_1);
    if (__pyx_t_4) {
      __pyx_t_2 = __pyx_t_3;
    } else {
      __pyx_t_2 = __pyx_t_1;
    }
    __pyx_v_amount_remove_rock = __pyx_t_2;
+0568:         requested_amount -= amount_remove_org + amount_remove_rock
    __pyx_v_requested_amount = (__pyx_v_requested_amount - (__pyx_v_amount_remove_org + __pyx_v_amount_remove_rock));
+0569:         amount_remove_org *= max(MIN_FRACTION_TO_ERODE, horizon.subsoil.organic / get_soil_height(horizon.subsoil))
    __pyx_t_2 = (__pyx_v_horizon.subsoil.organic / __pyx_f_6eroder_get_soil_height(__pyx_v_horizon.subsoil));
    __pyx_t_3 = __pyx_v_6eroder_MIN_FRACTION_TO_ERODE;
    __pyx_t_4 = (__pyx_t_2 > __pyx_t_3);
    if (__pyx_t_4) {
      __pyx_t_1 = __pyx_t_2;
    } else {
      __pyx_t_1 = __pyx_t_3;
    }
    __pyx_v_amount_remove_org = (__pyx_v_amount_remove_org * __pyx_t_1);
+0570:         amount_remove_rock *= max(MIN_FRACTION_TO_ERODE, horizon.subsoil.rocks[0] / get_soil_height(horizon.subsoil))
    __pyx_t_1 = ((__pyx_v_horizon.subsoil.rocks[0]) / __pyx_f_6eroder_get_soil_height(__pyx_v_horizon.subsoil));
    __pyx_t_2 = __pyx_v_6eroder_MIN_FRACTION_TO_ERODE;
    __pyx_t_4 = (__pyx_t_1 > __pyx_t_2);
    if (__pyx_t_4) {
      __pyx_t_3 = __pyx_t_1;
    } else {
      __pyx_t_3 = __pyx_t_2;
    }
    __pyx_v_amount_remove_rock = (__pyx_v_amount_remove_rock * __pyx_t_3);
+0571:         horizon.subsoil.organic -= amount_remove_org
    __pyx_v_horizon.subsoil.organic = (__pyx_v_horizon.subsoil.organic - __pyx_v_amount_remove_org);
+0572:         horizon.subsoil.rocks[0] -= amount_remove_rock
    __pyx_t_5 = 0;
    (__pyx_v_horizon.subsoil.rocks[__pyx_t_5]) = ((__pyx_v_horizon.subsoil.rocks[__pyx_t_5]) - __pyx_v_amount_remove_rock);
 0573: 
 0574: 
 0575:     # no need to erode rocks, they can't get regolith layer
+0576:     return new_soil(amount_remove_org + removed_org, amount_remove_rock + removed_rock, 0, 0, 0)
  __pyx_r = __pyx_f_6eroder_new_soil((__pyx_v_amount_remove_org + __pyx_v_removed_org), (__pyx_v_amount_remove_rock + __pyx_v_removed_rock), 0.0, 0.0, 0.0);
  goto __pyx_L0;
 0577: 
 0578: 
 0579: # MODIFIES ARGUMENT
+0580: cdef double erode_organic_amount_only_from(Soil& soil, double requested_amount) noexcept nogil:
static double __pyx_f_6eroder_erode_organic_amount_only_from(struct __pyx_t_6eroder_Soil &__pyx_v_soil, double __pyx_v_requested_amount) {
  double __pyx_v_amount_remove;
  double __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
 0581:     cdef double amount_remove
+0582:     requested_amount = max(0.0, requested_amount)
  __pyx_t_1 = __pyx_v_requested_amount;
  __pyx_t_2 = 0.0;
  __pyx_t_4 = (__pyx_t_1 > __pyx_t_2);
  if (__pyx_t_4) {
    __pyx_t_3 = __pyx_t_1;
  } else {
    __pyx_t_3 = __pyx_t_2;
  }
  __pyx_v_requested_amount = __pyx_t_3;
 0583: 
+0584:     amount_remove = min(soil.organic, requested_amount)
  __pyx_t_3 = __pyx_v_requested_amount;
  __pyx_t_1 = __pyx_v_soil.organic;
  __pyx_t_4 = (__pyx_t_3 < __pyx_t_1);
  if (__pyx_t_4) {
    __pyx_t_2 = __pyx_t_3;
  } else {
    __pyx_t_2 = __pyx_t_1;
  }
  __pyx_v_amount_remove = __pyx_t_2;
+0585:     soil.organic -= amount_remove
  __pyx_v_soil.organic = (__pyx_v_soil.organic - __pyx_v_amount_remove);
+0586:     return amount_remove
  __pyx_r = __pyx_v_amount_remove;
  goto __pyx_L0;
 0587: 
 0588: 
 0589: # MODIFIES ARGUMENT
+0590: cdef double erode_rocks_amount_only_from(Soil& soil, double requested_amount, int index) noexcept nogil:
static double __pyx_f_6eroder_erode_rocks_amount_only_from(struct __pyx_t_6eroder_Soil &__pyx_v_soil, double __pyx_v_requested_amount, int __pyx_v_index) {
  double __pyx_v_amount_remove;
  double __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
 0591:     cdef double amount_remove
+0592:     requested_amount = max(0.0, requested_amount)
  __pyx_t_1 = __pyx_v_requested_amount;
  __pyx_t_2 = 0.0;
  __pyx_t_4 = (__pyx_t_1 > __pyx_t_2);
  if (__pyx_t_4) {
    __pyx_t_3 = __pyx_t_1;
  } else {
    __pyx_t_3 = __pyx_t_2;
  }
  __pyx_v_requested_amount = __pyx_t_3;
 0593: 
+0594:     amount_remove = min(soil.rocks[index], requested_amount)
  __pyx_t_3 = __pyx_v_requested_amount;
  __pyx_t_1 = (__pyx_v_soil.rocks[__pyx_v_index]);
  __pyx_t_4 = (__pyx_t_3 < __pyx_t_1);
  if (__pyx_t_4) {
    __pyx_t_2 = __pyx_t_3;
  } else {
    __pyx_t_2 = __pyx_t_1;
  }
  __pyx_v_amount_remove = __pyx_t_2;
+0595:     soil.rocks[index] -= amount_remove
  __pyx_t_5 = __pyx_v_index;
  (__pyx_v_soil.rocks[__pyx_t_5]) = ((__pyx_v_soil.rocks[__pyx_t_5]) - __pyx_v_amount_remove);
+0596:     return amount_remove
  __pyx_r = __pyx_v_amount_remove;
  goto __pyx_L0;
 0597: 
 0598: 
 0599: # this function exists because it some-fricking-how interfered with Gravitational erosion and I couldn't find a fix
 0600: # MODIFIES ARGUMENTS
+0601: cdef void gravitational_erosion(int size_x, int size_y, double delta_t, double downhill_creep_constant, vector[vector[Horizon]]& terrain, double[:, :]& heightmap, double[:, :]& vegetation) noexcept nogil:
static void __pyx_f_6eroder_gravitational_erosion(int __pyx_v_size_x, int __pyx_v_size_y, CYTHON_UNUSED double __pyx_v_delta_t, CYTHON_UNUSED double __pyx_v_downhill_creep_constant, std::vector<std::vector<struct __pyx_t_6eroder_Horizon> >  &__pyx_v_terrain, __Pyx_memviewslice &__pyx_v_heightmap, __Pyx_memviewslice &__pyx_v_vegetation) {
  std::vector<std::vector<std::vector<std::vector<struct __pyx_t_6eroder_Soil> > > >  __pyx_v_soil_flow;
  std::vector<std::vector<double> >  __pyx_v_heightmap2;
  int __pyx_v_x;
  int __pyx_v_y;
  int __pyx_v_si;
  int __pyx_v_sj;
  int __pyx_v_i;
  int __pyx_v_index;
  double __pyx_v_fraction;
  double __pyx_v_to_distribute;
  double __pyx_v_height_fraction;
  double __pyx_v_part;
  double __pyx_v_delta_h_sum;
  struct __pyx_t_6eroder_Soil __pyx_v_soil;
  double __pyx_v_neighbors_delta_height[3][3];
  double __pyx_v_talus;
  double __pyx_v_max_delta;
  double __pyx_v_delta;
  double __pyx_v_soil_height;
/* … */
  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  #ifdef WITH_THREAD
  __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
  #endif
  __Pyx_WriteUnraisable("eroder.gravitational_erosion", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
  #ifdef WITH_THREAD
  __Pyx_PyGILState_Release(__pyx_gilstate_save);
  #endif
  __pyx_L0:;
}
 0602:     cdef vector[vector[vector[vector[Soil]]]] soil_flow
 0603:     cdef vector[vector[double]] heightmap2
 0604:     cdef int x, y, si, sj, i, index
 0605:     cdef double fraction, total_quantity, slope, denominator, q, to_distribute, height_fraction, part, delta_h_sum
 0606:     cdef Soil soil
 0607:     cdef double[3][3] neighbors_delta_height
 0608: 
+0609:     heightmap2.resize(size_x)
  try {
    __pyx_v_heightmap2.resize(__pyx_v_size_x);
  } catch(...) {
    #ifdef WITH_THREAD
    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
    #endif
    __Pyx_CppExn2PyErr();
    #ifdef WITH_THREAD
    __Pyx_PyGILState_Release(__pyx_gilstate_save);
    #endif
    __PYX_ERR(0, 609, __pyx_L1_error)
  }
+0610:     soil_flow.resize(size_x)
  try {
    __pyx_v_soil_flow.resize(__pyx_v_size_x);
  } catch(...) {
    #ifdef WITH_THREAD
    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
    #endif
    __Pyx_CppExn2PyErr();
    #ifdef WITH_THREAD
    __Pyx_PyGILState_Release(__pyx_gilstate_save);
    #endif
    __PYX_ERR(0, 610, __pyx_L1_error)
  }
 0611: 
+0612:     for x in range(size_x):
  __pyx_t_1 = __pyx_v_size_x;
  __pyx_t_2 = __pyx_t_1;
  for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
    __pyx_v_x = __pyx_t_3;
+0613:         heightmap2.at(x).resize(size_y, 0.0)
    try {
      __pyx_t_4 = __pyx_v_heightmap2.at(__pyx_v_x);
    } catch(...) {
      #ifdef WITH_THREAD
      PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
      #endif
      __Pyx_CppExn2PyErr();
      #ifdef WITH_THREAD
      __Pyx_PyGILState_Release(__pyx_gilstate_save);
      #endif
      __PYX_ERR(0, 613, __pyx_L1_error)
    }
    try {
      __pyx_t_4->resize(__pyx_v_size_y, 0.0);
    } catch(...) {
      #ifdef WITH_THREAD
      PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
      #endif
      __Pyx_CppExn2PyErr();
      #ifdef WITH_THREAD
      __Pyx_PyGILState_Release(__pyx_gilstate_save);
      #endif
      __PYX_ERR(0, 613, __pyx_L1_error)
    }
+0614:         soil_flow.at(x).resize(size_y)
    try {
      __pyx_t_5 = __pyx_v_soil_flow.at(__pyx_v_x);
    } catch(...) {
      #ifdef WITH_THREAD
      PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
      #endif
      __Pyx_CppExn2PyErr();
      #ifdef WITH_THREAD
      __Pyx_PyGILState_Release(__pyx_gilstate_save);
      #endif
      __PYX_ERR(0, 614, __pyx_L1_error)
    }
    try {
      __pyx_t_5->resize(__pyx_v_size_y);
    } catch(...) {
      #ifdef WITH_THREAD
      PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
      #endif
      __Pyx_CppExn2PyErr();
      #ifdef WITH_THREAD
      __Pyx_PyGILState_Release(__pyx_gilstate_save);
      #endif
      __PYX_ERR(0, 614, __pyx_L1_error)
    }
+0615:         for y in range(size_y):
    __pyx_t_6 = __pyx_v_size_y;
    __pyx_t_7 = __pyx_t_6;
    for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
      __pyx_v_y = __pyx_t_8;
+0616:             soil_flow[x][y].resize(3)
      try {
        ((__pyx_v_soil_flow[__pyx_v_x])[__pyx_v_y]).resize(3);
      } catch(...) {
        #ifdef WITH_THREAD
        PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
        #endif
        __Pyx_CppExn2PyErr();
        #ifdef WITH_THREAD
        __Pyx_PyGILState_Release(__pyx_gilstate_save);
        #endif
        __PYX_ERR(0, 616, __pyx_L1_error)
      }
+0617:             for si in range(3):
      for (__pyx_t_9 = 0; __pyx_t_9 < 3; __pyx_t_9+=1) {
        __pyx_v_si = __pyx_t_9;
+0618:                 soil_flow[x][y][si].resize(3, EMPTY_SOIL)
        try {
          (((__pyx_v_soil_flow[__pyx_v_x])[__pyx_v_y])[__pyx_v_si]).resize(3, __pyx_v_6eroder_EMPTY_SOIL);
        } catch(...) {
          #ifdef WITH_THREAD
          PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
          #endif
          __Pyx_CppExn2PyErr();
          #ifdef WITH_THREAD
          __Pyx_PyGILState_Release(__pyx_gilstate_save);
          #endif
          __PYX_ERR(0, 618, __pyx_L1_error)
        }
      }
    }
  }
 0619: 
 0620: 
+0621:     for x in range(size_x):
  __pyx_t_1 = __pyx_v_size_x;
  __pyx_t_2 = __pyx_t_1;
  for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
    __pyx_v_x = __pyx_t_3;
+0622:         for y in range(size_y):
    __pyx_t_6 = __pyx_v_size_y;
    __pyx_t_7 = __pyx_t_6;
    for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
      __pyx_v_y = __pyx_t_8;
 0623:             # clear flows
+0624:             heightmap2[x][y] = 0.0
      ((__pyx_v_heightmap2[__pyx_v_x])[__pyx_v_y]) = 0.0;
+0625:             for si in range(-1, 2):
      for (__pyx_t_9 = -1; __pyx_t_9 < 2; __pyx_t_9+=1) {
        __pyx_v_si = __pyx_t_9;
+0626:                 for sj in range(-1, 2):
        for (__pyx_t_10 = -1; __pyx_t_10 < 2; __pyx_t_10+=1) {
          __pyx_v_sj = __pyx_t_10;
+0627:                     soil_flow[x][y][si + 1][sj + 1] = EMPTY_SOIL
          ((((__pyx_v_soil_flow[__pyx_v_x])[__pyx_v_y])[(__pyx_v_si + 1)])[(__pyx_v_sj + 1)]) = __pyx_v_6eroder_EMPTY_SOIL;
        }
      }
 0628: 
 0629:             # talus angle will be the smaller of the 2 soils
+0630:             talus = get_soil_talus(terrain[x][y].topsoil, vegetation[x][y])
      __pyx_t_11 = __pyx_v_x;
      __pyx_t_12 = __pyx_v_y;
      if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_vegetation.shape[0];
      if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_vegetation.shape[1];
      __pyx_v_talus = __pyx_f_6eroder_get_soil_talus(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil, (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_11 * __pyx_v_vegetation.strides[0]) ) + __pyx_t_12 * __pyx_v_vegetation.strides[1]) ))));
+0631:             if get_soil_talus(terrain[x][y].subsoil, vegetation[x][y]) * 1.25 < talus:
      __pyx_t_12 = __pyx_v_x;
      __pyx_t_11 = __pyx_v_y;
      if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_vegetation.shape[0];
      if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_vegetation.shape[1];
      __pyx_t_13 = ((__pyx_f_6eroder_get_soil_talus(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil, (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_12 * __pyx_v_vegetation.strides[0]) ) + __pyx_t_11 * __pyx_v_vegetation.strides[1]) )))) * 1.25) < __pyx_v_talus);
      if (__pyx_t_13) {
/* … */
      }
+0632:                 talus = get_soil_talus(terrain[x][y].subsoil, vegetation[x][y]) * 1.25
        __pyx_t_11 = __pyx_v_x;
        __pyx_t_12 = __pyx_v_y;
        if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_vegetation.shape[0];
        if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_vegetation.shape[1];
        __pyx_v_talus = (__pyx_f_6eroder_get_soil_talus(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil, (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_11 * __pyx_v_vegetation.strides[0]) ) + __pyx_t_12 * __pyx_v_vegetation.strides[1]) )))) * 1.25);
 0633: 
 0634: 
 0635: 
 0636:             # which neighbors will get a piece of our terrain
+0637:             soil = terrain[x][y].topsoil
      __pyx_t_14 = ((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil;
      __pyx_v_soil = __pyx_t_14;
+0638:             for i in range(2):
      for (__pyx_t_9 = 0; __pyx_t_9 < 2; __pyx_t_9+=1) {
        __pyx_v_i = __pyx_t_9;
 0639: 
+0640:                 delta_h_sum = 0.0
        __pyx_v_delta_h_sum = 0.0;
+0641:                 max_delta = 0.0
        __pyx_v_max_delta = 0.0;
 0642: 
+0643:                 if get_soil_height(soil) > 0.0:
        __pyx_t_13 = (__pyx_f_6eroder_get_soil_height(__pyx_v_soil) > 0.0);
        if (__pyx_t_13) {
/* … */
        }
+0644:                     neighbors_delta_height = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]
          __pyx_t_15[0] = 0.0;
          __pyx_t_15[1] = 0.0;
          __pyx_t_15[2] = 0.0;
          __pyx_t_16[0] = 0.0;
          __pyx_t_16[1] = 0.0;
          __pyx_t_16[2] = 0.0;
          __pyx_t_17[0] = 0.0;
          __pyx_t_17[1] = 0.0;
          __pyx_t_17[2] = 0.0;
          memcpy(&(__pyx_t_18[0]), __pyx_t_15, sizeof(__pyx_t_18[0]));
          memcpy(&(__pyx_t_18[1]), __pyx_t_16, sizeof(__pyx_t_18[0]));
          memcpy(&(__pyx_t_18[2]), __pyx_t_17, sizeof(__pyx_t_18[0]));
          memcpy(&(__pyx_v_neighbors_delta_height[0]), __pyx_t_18, sizeof(__pyx_v_neighbors_delta_height[0]) * (3));
+0645:                     for si in range(-1, 2):
          for (__pyx_t_10 = -1; __pyx_t_10 < 2; __pyx_t_10+=1) {
            __pyx_v_si = __pyx_t_10;
+0646:                         for sj in range(-1, 2):
            for (__pyx_t_19 = -1; __pyx_t_19 < 2; __pyx_t_19+=1) {
              __pyx_v_sj = __pyx_t_19;
+0647:                             if si != 0 or sj != 0:
              __pyx_t_20 = (__pyx_v_si != 0);
              if (!__pyx_t_20) {
              } else {
                __pyx_t_13 = __pyx_t_20;
                goto __pyx_L26_bool_binop_done;
              }
              __pyx_t_20 = (__pyx_v_sj != 0);
              __pyx_t_13 = __pyx_t_20;
              __pyx_L26_bool_binop_done:;
              if (__pyx_t_13) {
/* … */
              }
            }
          }
+0648:                                 delta = heightmap[x][y] - heightmap[mod(x + si, size_x)][mod(y + sj, size_y)]
                __pyx_t_12 = __pyx_v_x;
                __pyx_t_11 = __pyx_v_y;
                if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_heightmap.shape[0];
                if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_heightmap.shape[1];
                __pyx_t_21 = __pyx_f_6eroder_mod((__pyx_v_x + __pyx_v_si), __pyx_v_size_x); if (unlikely(__pyx_t_21 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 648, __pyx_L1_error)
                __pyx_t_22 = __pyx_f_6eroder_mod((__pyx_v_y + __pyx_v_sj), __pyx_v_size_y); if (unlikely(__pyx_t_22 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 648, __pyx_L1_error)
                __pyx_t_23 = __pyx_t_21;
                __pyx_t_24 = __pyx_t_22;
                __pyx_v_delta = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_12 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_11 * __pyx_v_heightmap.strides[1]) ))) - (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_23 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_24 * __pyx_v_heightmap.strides[1]) ))));
 0649: 
 0650:                                 # if should erode
+0651:                                 if delta / (length * sqrt(si**2 + sj**2)) >= talus:
                __pyx_t_13 = ((__pyx_v_delta / (__pyx_v_6eroder_length * sqrt((__Pyx_pow_long(((long)__pyx_v_si), 2) + __Pyx_pow_long(((long)__pyx_v_sj), 2))))) >= __pyx_v_talus);
                if (__pyx_t_13) {
/* … */
                }
 0652:                                     # largest difference
+0653:                                     if delta > max_delta:
                  __pyx_t_13 = (__pyx_v_delta > __pyx_v_max_delta);
                  if (__pyx_t_13) {
/* … */
                  }
+0654:                                         max_delta = delta
                    __pyx_v_max_delta = __pyx_v_delta;
 0655: 
 0656:                                     # save for later reference
+0657:                                     neighbors_delta_height[si + 1][sj + 1] = delta
                  ((__pyx_v_neighbors_delta_height[(__pyx_v_si + 1)])[(__pyx_v_sj + 1)]) = __pyx_v_delta;
+0658:                                     delta_h_sum += delta
                  __pyx_v_delta_h_sum = (__pyx_v_delta_h_sum + __pyx_v_delta);
 0659: 
 0660: 
+0661:                     to_distribute = min(0.5 * max_delta * random(0.9, 1.0), get_soil_height(soil))
          __pyx_t_25 = __pyx_f_6eroder_get_soil_height(__pyx_v_soil);
          __pyx_t_27.__pyx_n = 2;
          __pyx_t_27.low = 0.9;
          __pyx_t_27.high = 1.0;
          __pyx_t_26 = __pyx_f_6eroder_random(&__pyx_t_27); if (unlikely(__pyx_t_26 == ((double)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 661, __pyx_L1_error)
          __pyx_t_28 = ((0.5 * __pyx_v_max_delta) * __pyx_t_26);
          __pyx_t_13 = (__pyx_t_25 < __pyx_t_28);
          if (__pyx_t_13) {
            __pyx_t_26 = __pyx_t_25;
          } else {
            __pyx_t_26 = __pyx_t_28;
          }
          __pyx_v_to_distribute = __pyx_t_26;
 0662: 
+0663:                     height_fraction = to_distribute / get_soil_height(soil)
          __pyx_v_height_fraction = (__pyx_v_to_distribute / __pyx_f_6eroder_get_soil_height(__pyx_v_soil));
 0664: 
 0665:                     # how much will flow OUT of this cell later
 0666:                     # misusing this array
+0667:                     heightmap2[x][y] = to_distribute
          ((__pyx_v_heightmap2[__pyx_v_x])[__pyx_v_y]) = __pyx_v_to_distribute;
 0668: 
 0669:                     # assign flows
+0670:                     if delta_h_sum > 0:
          __pyx_t_13 = (__pyx_v_delta_h_sum > 0.0);
          if (__pyx_t_13) {
/* … */
          }
+0671:                         for si in range(-1, 2):
            for (__pyx_t_10 = -1; __pyx_t_10 < 2; __pyx_t_10+=1) {
              __pyx_v_si = __pyx_t_10;
+0672:                             for sj in range(-1, 2):
              for (__pyx_t_19 = -1; __pyx_t_19 < 2; __pyx_t_19+=1) {
                __pyx_v_sj = __pyx_t_19;
+0673:                                 if si != 0 or sj != 0:
                __pyx_t_20 = (__pyx_v_si != 0);
                if (!__pyx_t_20) {
                } else {
                  __pyx_t_13 = __pyx_t_20;
                  goto __pyx_L36_bool_binop_done;
                }
                __pyx_t_20 = (__pyx_v_sj != 0);
                __pyx_t_13 = __pyx_t_20;
                __pyx_L36_bool_binop_done:;
                if (__pyx_t_13) {
/* … */
                }
              }
            }
+0674:                                     fraction = height_fraction * neighbors_delta_height[si + 1][sj + 1] / delta_h_sum
                  __pyx_v_fraction = ((__pyx_v_height_fraction * ((__pyx_v_neighbors_delta_height[(__pyx_v_si + 1)])[(__pyx_v_sj + 1)])) / __pyx_v_delta_h_sum);
+0675:                                     soil_flow[x][y][si + 1][sj + 1] = soil_fraction(soil, fraction)
                  ((((__pyx_v_soil_flow[__pyx_v_x])[__pyx_v_y])[(__pyx_v_si + 1)])[(__pyx_v_sj + 1)]) = __pyx_f_6eroder_soil_fraction(__pyx_v_soil, __pyx_v_fraction);
 0676: 
 0677:                     # erode only the topsoil
+0678:                     break
          goto __pyx_L19_break;
 0679:                 else:
+0680:                     soil = terrain[x][y].subsoil
        /*else*/ {
          __pyx_t_14 = ((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil;
          __pyx_v_soil = __pyx_t_14;
        }
      }
      __pyx_L19_break:;
 0681: 
 0682: 
 0683:             # BEDROCK only if there is nothing above us
+0684:             if get_soil_height(terrain[x][y].topsoil) + get_soil_height(terrain[x][y].subsoil) <= 0.0:
      __pyx_t_13 = ((__pyx_f_6eroder_get_soil_height(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil) + __pyx_f_6eroder_get_soil_height(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil)) <= 0.0);
      if (__pyx_t_13) {
/* … */
      }
    }
  }
+0685:                 talus = infinity
        __pyx_v_talus = __pyx_v_6eroder_infinity;
+0686:                 for i in range(terrain[x][y].bedrock.size()):
        __pyx_t_29 = ((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock.size();
        __pyx_t_30 = __pyx_t_29;
        for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_30; __pyx_t_9+=1) {
          __pyx_v_i = __pyx_t_9;
+0687:                     if bedrock_taluses[terrain[x][y].bedrock[i].type] < talus and terrain[x][y].bedrock[i].height > 0.0:
          __pyx_t_20 = ((__pyx_v_6eroder_bedrock_taluses[(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock[__pyx_v_i]).type]) < __pyx_v_talus);
          if (__pyx_t_20) {
          } else {
            __pyx_t_13 = __pyx_t_20;
            goto __pyx_L42_bool_binop_done;
          }
          __pyx_t_20 = ((((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock[__pyx_v_i]).height > 0.0);
          __pyx_t_13 = __pyx_t_20;
          __pyx_L42_bool_binop_done:;
          if (__pyx_t_13) {
/* … */
          }
        }
+0688:                         talus = bedrock_taluses[terrain[x][y].bedrock[i].type]
            __pyx_v_talus = (__pyx_v_6eroder_bedrock_taluses[(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock[__pyx_v_i]).type]);
 0689: 
+0690:                 delta_h_sum = 0.0
        __pyx_v_delta_h_sum = 0.0;
+0691:                 max_delta = 0.0
        __pyx_v_max_delta = 0.0;
 0692: 
 0693:                 # first nonempty
+0694:                 index = 0
        __pyx_v_index = 0;
+0695:                 while terrain[x][y].bedrock[index].height <= 0.0:
        while (1) {
          __pyx_t_13 = ((((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock[__pyx_v_index]).height <= 0.0);
          if (!__pyx_t_13) break;
+0696:                     index += 1
          __pyx_v_index = (__pyx_v_index + 1);
        }
 0697: 
 0698: 
+0699:                 neighbors_delta_height = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]
        __pyx_t_31[0] = 0.0;
        __pyx_t_31[1] = 0.0;
        __pyx_t_31[2] = 0.0;
        __pyx_t_32[0] = 0.0;
        __pyx_t_32[1] = 0.0;
        __pyx_t_32[2] = 0.0;
        __pyx_t_33[0] = 0.0;
        __pyx_t_33[1] = 0.0;
        __pyx_t_33[2] = 0.0;
        memcpy(&(__pyx_t_34[0]), __pyx_t_31, sizeof(__pyx_t_34[0]));
        memcpy(&(__pyx_t_34[1]), __pyx_t_32, sizeof(__pyx_t_34[0]));
        memcpy(&(__pyx_t_34[2]), __pyx_t_33, sizeof(__pyx_t_34[0]));
        memcpy(&(__pyx_v_neighbors_delta_height[0]), __pyx_t_34, sizeof(__pyx_v_neighbors_delta_height[0]) * (3));
+0700:                 for si in range(-1, 2):
        for (__pyx_t_9 = -1; __pyx_t_9 < 2; __pyx_t_9+=1) {
          __pyx_v_si = __pyx_t_9;
+0701:                     for sj in range(-1, 2):
          for (__pyx_t_10 = -1; __pyx_t_10 < 2; __pyx_t_10+=1) {
            __pyx_v_sj = __pyx_t_10;
+0702:                         if si != 0 or sj != 0:
            __pyx_t_20 = (__pyx_v_si != 0);
            if (!__pyx_t_20) {
            } else {
              __pyx_t_13 = __pyx_t_20;
              goto __pyx_L51_bool_binop_done;
            }
            __pyx_t_20 = (__pyx_v_sj != 0);
            __pyx_t_13 = __pyx_t_20;
            __pyx_L51_bool_binop_done:;
            if (__pyx_t_13) {
/* … */
            }
          }
        }
+0703:                             delta = heightmap[x][y] - heightmap[mod(x + si, size_x)][mod(y + sj, size_y)]
              __pyx_t_11 = __pyx_v_x;
              __pyx_t_12 = __pyx_v_y;
              if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_heightmap.shape[0];
              if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_heightmap.shape[1];
              __pyx_t_22 = __pyx_f_6eroder_mod((__pyx_v_x + __pyx_v_si), __pyx_v_size_x); if (unlikely(__pyx_t_22 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 703, __pyx_L1_error)
              __pyx_t_21 = __pyx_f_6eroder_mod((__pyx_v_y + __pyx_v_sj), __pyx_v_size_y); if (unlikely(__pyx_t_21 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 703, __pyx_L1_error)
              __pyx_t_24 = __pyx_t_22;
              __pyx_t_23 = __pyx_t_21;
              __pyx_v_delta = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_11 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_12 * __pyx_v_heightmap.strides[1]) ))) - (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_24 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_23 * __pyx_v_heightmap.strides[1]) ))));
 0704: 
 0705:                             # if should erode
+0706:                             if delta / (length * sqrt(si**2 + sj**2)) >= talus:
              __pyx_t_13 = ((__pyx_v_delta / (__pyx_v_6eroder_length * sqrt((__Pyx_pow_long(((long)__pyx_v_si), 2) + __Pyx_pow_long(((long)__pyx_v_sj), 2))))) >= __pyx_v_talus);
              if (__pyx_t_13) {
/* … */
              }
 0707:                                 # largest difference
+0708:                                 if delta > max_delta:
                __pyx_t_13 = (__pyx_v_delta > __pyx_v_max_delta);
                if (__pyx_t_13) {
/* … */
                }
+0709:                                     max_delta = delta
                  __pyx_v_max_delta = __pyx_v_delta;
 0710: 
 0711:                                 # save for later reference
+0712:                                 neighbors_delta_height[si + 1][sj + 1] = delta
                ((__pyx_v_neighbors_delta_height[(__pyx_v_si + 1)])[(__pyx_v_sj + 1)]) = __pyx_v_delta;
+0713:                                 delta_h_sum += delta
                __pyx_v_delta_h_sum = (__pyx_v_delta_h_sum + __pyx_v_delta);
 0714: 
 0715: 
+0716:                 to_distribute = min(0.5 * max_delta * random(0.9, 1.0), terrain[x][y].bedrock[index].height)
        __pyx_t_26 = (((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock[__pyx_v_index]).height;
        __pyx_t_27.__pyx_n = 2;
        __pyx_t_27.low = 0.9;
        __pyx_t_27.high = 1.0;
        __pyx_t_25 = __pyx_f_6eroder_random(&__pyx_t_27); if (unlikely(__pyx_t_25 == ((double)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 716, __pyx_L1_error)
        __pyx_t_28 = ((0.5 * __pyx_v_max_delta) * __pyx_t_25);
        __pyx_t_13 = (__pyx_t_26 < __pyx_t_28);
        if (__pyx_t_13) {
          __pyx_t_25 = __pyx_t_26;
        } else {
          __pyx_t_25 = __pyx_t_28;
        }
        __pyx_v_to_distribute = __pyx_t_25;
 0717: 
 0718:                 # how much will flow OUT of this cell later
 0719:                 # misusing this array
+0720:                 heightmap2[x][y] = to_distribute
        ((__pyx_v_heightmap2[__pyx_v_x])[__pyx_v_y]) = __pyx_v_to_distribute;
 0721: 
 0722:                 # assign flows
+0723:                 if delta_h_sum > 0:
        __pyx_t_13 = (__pyx_v_delta_h_sum > 0.0);
        if (__pyx_t_13) {
/* … */
        }
+0724:                     for si in range(-1, 2):
          for (__pyx_t_9 = -1; __pyx_t_9 < 2; __pyx_t_9+=1) {
            __pyx_v_si = __pyx_t_9;
+0725:                         for sj in range(-1, 2):
            for (__pyx_t_10 = -1; __pyx_t_10 < 2; __pyx_t_10+=1) {
              __pyx_v_sj = __pyx_t_10;
+0726:                             if si != 0 or sj != 0:
              __pyx_t_20 = (__pyx_v_si != 0);
              if (!__pyx_t_20) {
              } else {
                __pyx_t_13 = __pyx_t_20;
                goto __pyx_L61_bool_binop_done;
              }
              __pyx_t_20 = (__pyx_v_sj != 0);
              __pyx_t_13 = __pyx_t_20;
              __pyx_L61_bool_binop_done:;
              if (__pyx_t_13) {
/* … */
              }
            }
          }
+0727:                                 part = to_distribute * neighbors_delta_height[si + 1][sj + 1] / delta_h_sum
                __pyx_v_part = ((__pyx_v_to_distribute * ((__pyx_v_neighbors_delta_height[(__pyx_v_si + 1)])[(__pyx_v_sj + 1)])) / __pyx_v_delta_h_sum);
+0728:                                 soil_flow[x][y][si + 1][sj + 1] = new_soil_from_bedrock_type(index, part)
                ((((__pyx_v_soil_flow[__pyx_v_x])[__pyx_v_y])[(__pyx_v_si + 1)])[(__pyx_v_sj + 1)]) = __pyx_f_6eroder_new_soil_from_bedrock_type(__pyx_v_index, __pyx_v_part);
 0729: 
 0730: 
 0731:     # assign flows
+0732:     for x in range(size_x):
  __pyx_t_1 = __pyx_v_size_x;
  __pyx_t_2 = __pyx_t_1;
  for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
    __pyx_v_x = __pyx_t_3;
+0733:         for y in range(size_y):
    __pyx_t_6 = __pyx_v_size_y;
    __pyx_t_7 = __pyx_t_6;
    for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
      __pyx_v_y = __pyx_t_8;
 0734:             # remove soil from this column
+0735:             remove_soil(terrain[x][y], heightmap2[x][y])
      __pyx_f_6eroder_remove_soil(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]), ((__pyx_v_heightmap2[__pyx_v_x])[__pyx_v_y]));
+0736:             heightmap[x][y] -= heightmap2[x][y]
      __pyx_t_12 = __pyx_v_x;
      __pyx_t_11 = __pyx_v_y;
      if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_heightmap.shape[0];
      if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_heightmap.shape[1];
      *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_12 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_11 * __pyx_v_heightmap.strides[1]) )) -= ((__pyx_v_heightmap2[__pyx_v_x])[__pyx_v_y]);
 0737: 
 0738:             # kills vegetation
+0739:             if heightmap2[x][y] > 0.0:
      __pyx_t_13 = (((__pyx_v_heightmap2[__pyx_v_x])[__pyx_v_y]) > 0.0);
      if (__pyx_t_13) {
/* … */
      }
+0740:                 vegetation[x][y] = 0.0
        __pyx_t_11 = __pyx_v_x;
        __pyx_t_12 = __pyx_v_y;
        if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_vegetation.shape[0];
        if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_vegetation.shape[1];
        *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_11 * __pyx_v_vegetation.strides[0]) ) + __pyx_t_12 * __pyx_v_vegetation.strides[1]) )) = 0.0;
 0741: 
 0742:             # deposit soil from neighbors
+0743:             for si in range(-1, 2):
      for (__pyx_t_9 = -1; __pyx_t_9 < 2; __pyx_t_9+=1) {
        __pyx_v_si = __pyx_t_9;
+0744:                 for sj in range(-1, 2):
        for (__pyx_t_10 = -1; __pyx_t_10 < 2; __pyx_t_10+=1) {
          __pyx_v_sj = __pyx_t_10;
+0745:                     if si != 0 or sj != 0:
          __pyx_t_20 = (__pyx_v_si != 0);
          if (!__pyx_t_20) {
          } else {
            __pyx_t_13 = __pyx_t_20;
            goto __pyx_L73_bool_binop_done;
          }
          __pyx_t_20 = (__pyx_v_sj != 0);
          __pyx_t_13 = __pyx_t_20;
          __pyx_L73_bool_binop_done:;
          if (__pyx_t_13) {
/* … */
          }
        }
      }
    }
  }
+0746:                         deposit_soil(terrain[x][y], soil_flow[mod(x + si, size_x)][mod(y + sj, size_y)][1 - si][1 - sj])
            __pyx_t_21 = __pyx_f_6eroder_mod((__pyx_v_x + __pyx_v_si), __pyx_v_size_x); if (unlikely(__pyx_t_21 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 746, __pyx_L1_error)
            __pyx_t_22 = __pyx_f_6eroder_mod((__pyx_v_y + __pyx_v_sj), __pyx_v_size_y); if (unlikely(__pyx_t_22 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 746, __pyx_L1_error)
            __pyx_f_6eroder_deposit_soil(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]), ((((__pyx_v_soil_flow[__pyx_t_21])[__pyx_t_22])[(1 - __pyx_v_si)])[(1 - __pyx_v_sj)]));
+0747:                         soil_height = get_soil_height(soil_flow[mod(x + si, size_x)][mod(y + sj, size_y)][1 - si][1 - sj])
            __pyx_t_22 = __pyx_f_6eroder_mod((__pyx_v_x + __pyx_v_si), __pyx_v_size_x); if (unlikely(__pyx_t_22 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 747, __pyx_L1_error)
            __pyx_t_21 = __pyx_f_6eroder_mod((__pyx_v_y + __pyx_v_sj), __pyx_v_size_y); if (unlikely(__pyx_t_21 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 747, __pyx_L1_error)
            __pyx_v_soil_height = __pyx_f_6eroder_get_soil_height(((((__pyx_v_soil_flow[__pyx_t_22])[__pyx_t_21])[(1 - __pyx_v_si)])[(1 - __pyx_v_sj)]));
+0748:                         heightmap[x][y] += soil_height
            __pyx_t_12 = __pyx_v_x;
            __pyx_t_11 = __pyx_v_y;
            if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_heightmap.shape[0];
            if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_heightmap.shape[1];
            *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_12 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_11 * __pyx_v_heightmap.strides[1]) )) += __pyx_v_soil_height;
 0749: 
 0750:                         # kills vegetation
+0751:                         if soil_height > 0.0:
            __pyx_t_13 = (__pyx_v_soil_height > 0.0);
            if (__pyx_t_13) {
/* … */
            }
+0752:                             vegetation[x][y] = 0.0
              __pyx_t_11 = __pyx_v_x;
              __pyx_t_12 = __pyx_v_y;
              if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_vegetation.shape[0];
              if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_vegetation.shape[1];
              *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_11 * __pyx_v_vegetation.strides[0]) ) + __pyx_t_12 * __pyx_v_vegetation.strides[1]) )) = 0.0;
 0753: 
 0754: 
 0755: # this function exists because it some-fricking-how interfered with Gravitational erosion and I couldn't find a fix
 0756: # MODIFIES ARGUMENTS
+0757: cdef void downhill_creep(int size_x, int size_y, double delta_t, double downhill_creep_constant, vector[vector[Horizon]]& terrain, double[:, :]& heightmap) noexcept nogil:
static void __pyx_f_6eroder_downhill_creep(int __pyx_v_size_x, int __pyx_v_size_y, double __pyx_v_delta_t, double __pyx_v_downhill_creep_constant, std::vector<std::vector<struct __pyx_t_6eroder_Horizon> >  &__pyx_v_terrain, __Pyx_memviewslice &__pyx_v_heightmap) {
  std::vector<std::vector<std::vector<std::vector<struct __pyx_t_6eroder_Soil> > > >  __pyx_v_soil_flow;
  std::vector<std::vector<double> >  __pyx_v_heightmap2;
  int __pyx_v_x;
  int __pyx_v_y;
  int __pyx_v_si;
  int __pyx_v_sj;
  double __pyx_v_fraction;
  double __pyx_v_total_quantity;
  double __pyx_v_slope;
  double __pyx_v_denominator;
  double __pyx_v_q;
  double __pyx_v_to_distribute;
  double __pyx_v_height_fraction;
  struct __pyx_t_6eroder_Soil __pyx_v_soil;
  double __pyx_v_neighbors_quantity[3][3];
  CYTHON_UNUSED long __pyx_v_i;
/* … */
  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  #ifdef WITH_THREAD
  __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
  #endif
  __Pyx_WriteUnraisable("eroder.downhill_creep", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
  #ifdef WITH_THREAD
  __Pyx_PyGILState_Release(__pyx_gilstate_save);
  #endif
  __pyx_L0:;
}
 0758:     cdef vector[vector[vector[vector[Soil]]]] soil_flow
 0759:     cdef vector[vector[double]] heightmap2
 0760:     cdef int x, y, si, sj
 0761:     cdef double fraction, total_quantity, slope, denominator, q, to_distribute, height_fraction
 0762:     cdef Soil soil
 0763:     cdef double[3][3] neighbors_quantity
 0764: 
+0765:     heightmap2.resize(size_x)
  try {
    __pyx_v_heightmap2.resize(__pyx_v_size_x);
  } catch(...) {
    #ifdef WITH_THREAD
    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
    #endif
    __Pyx_CppExn2PyErr();
    #ifdef WITH_THREAD
    __Pyx_PyGILState_Release(__pyx_gilstate_save);
    #endif
    __PYX_ERR(0, 765, __pyx_L1_error)
  }
+0766:     soil_flow.resize(size_x)
  try {
    __pyx_v_soil_flow.resize(__pyx_v_size_x);
  } catch(...) {
    #ifdef WITH_THREAD
    PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
    #endif
    __Pyx_CppExn2PyErr();
    #ifdef WITH_THREAD
    __Pyx_PyGILState_Release(__pyx_gilstate_save);
    #endif
    __PYX_ERR(0, 766, __pyx_L1_error)
  }
 0767: 
+0768:     for x in range(size_x):
  __pyx_t_1 = __pyx_v_size_x;
  __pyx_t_2 = __pyx_t_1;
  for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
    __pyx_v_x = __pyx_t_3;
+0769:         heightmap2.at(x).resize(size_y, 0.0)
    try {
      __pyx_t_4 = __pyx_v_heightmap2.at(__pyx_v_x);
    } catch(...) {
      #ifdef WITH_THREAD
      PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
      #endif
      __Pyx_CppExn2PyErr();
      #ifdef WITH_THREAD
      __Pyx_PyGILState_Release(__pyx_gilstate_save);
      #endif
      __PYX_ERR(0, 769, __pyx_L1_error)
    }
    try {
      __pyx_t_4->resize(__pyx_v_size_y, 0.0);
    } catch(...) {
      #ifdef WITH_THREAD
      PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
      #endif
      __Pyx_CppExn2PyErr();
      #ifdef WITH_THREAD
      __Pyx_PyGILState_Release(__pyx_gilstate_save);
      #endif
      __PYX_ERR(0, 769, __pyx_L1_error)
    }
+0770:         soil_flow.at(x).resize(size_y)
    try {
      __pyx_t_5 = __pyx_v_soil_flow.at(__pyx_v_x);
    } catch(...) {
      #ifdef WITH_THREAD
      PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
      #endif
      __Pyx_CppExn2PyErr();
      #ifdef WITH_THREAD
      __Pyx_PyGILState_Release(__pyx_gilstate_save);
      #endif
      __PYX_ERR(0, 770, __pyx_L1_error)
    }
    try {
      __pyx_t_5->resize(__pyx_v_size_y);
    } catch(...) {
      #ifdef WITH_THREAD
      PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
      #endif
      __Pyx_CppExn2PyErr();
      #ifdef WITH_THREAD
      __Pyx_PyGILState_Release(__pyx_gilstate_save);
      #endif
      __PYX_ERR(0, 770, __pyx_L1_error)
    }
+0771:         for y in range(size_y):
    __pyx_t_6 = __pyx_v_size_y;
    __pyx_t_7 = __pyx_t_6;
    for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
      __pyx_v_y = __pyx_t_8;
+0772:             soil_flow[x][y].resize(3)
      try {
        ((__pyx_v_soil_flow[__pyx_v_x])[__pyx_v_y]).resize(3);
      } catch(...) {
        #ifdef WITH_THREAD
        PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
        #endif
        __Pyx_CppExn2PyErr();
        #ifdef WITH_THREAD
        __Pyx_PyGILState_Release(__pyx_gilstate_save);
        #endif
        __PYX_ERR(0, 772, __pyx_L1_error)
      }
+0773:             for si in range(3):
      for (__pyx_t_9 = 0; __pyx_t_9 < 3; __pyx_t_9+=1) {
        __pyx_v_si = __pyx_t_9;
+0774:                 soil_flow[x][y][si].resize(3, EMPTY_SOIL)
        try {
          (((__pyx_v_soil_flow[__pyx_v_x])[__pyx_v_y])[__pyx_v_si]).resize(3, __pyx_v_6eroder_EMPTY_SOIL);
        } catch(...) {
          #ifdef WITH_THREAD
          PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
          #endif
          __Pyx_CppExn2PyErr();
          #ifdef WITH_THREAD
          __Pyx_PyGILState_Release(__pyx_gilstate_save);
          #endif
          __PYX_ERR(0, 774, __pyx_L1_error)
        }
      }
    }
  }
 0775: 
 0776: 
+0777:     for x in range(size_x):
  __pyx_t_1 = __pyx_v_size_x;
  __pyx_t_2 = __pyx_t_1;
  for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
    __pyx_v_x = __pyx_t_3;
+0778:         for y in range(size_y):
    __pyx_t_6 = __pyx_v_size_y;
    __pyx_t_7 = __pyx_t_6;
    for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
      __pyx_v_y = __pyx_t_8;
 0779:             # clear flows
+0780:             heightmap2[x][y] = 0.0
      ((__pyx_v_heightmap2[__pyx_v_x])[__pyx_v_y]) = 0.0;
+0781:             for si in range(-1, 2):
      for (__pyx_t_9 = -1; __pyx_t_9 < 2; __pyx_t_9+=1) {
        __pyx_v_si = __pyx_t_9;
+0782:                 for sj in range(-1, 2):
        for (__pyx_t_10 = -1; __pyx_t_10 < 2; __pyx_t_10+=1) {
          __pyx_v_sj = __pyx_t_10;
+0783:                     soil_flow[x][y][si + 1][sj + 1] = EMPTY_SOIL
          ((((__pyx_v_soil_flow[__pyx_v_x])[__pyx_v_y])[(__pyx_v_si + 1)])[(__pyx_v_sj + 1)]) = __pyx_v_6eroder_EMPTY_SOIL;
        }
      }
 0784: 
 0785:             # which neighbors will get a piece of our terrain
+0786:             soil = terrain[x][y].topsoil
      __pyx_t_11 = ((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil;
      __pyx_v_soil = __pyx_t_11;
+0787:             for i in range(2):
      for (__pyx_t_12 = 0; __pyx_t_12 < 2; __pyx_t_12+=1) {
        __pyx_v_i = __pyx_t_12;
 0788: 
+0789:                 total_quantity = 0.0
        __pyx_v_total_quantity = 0.0;
 0790: 
+0791:                 if get_soil_height(soil) > 0.0:
        __pyx_t_13 = (__pyx_f_6eroder_get_soil_height(__pyx_v_soil) > 0.0);
        if (__pyx_t_13) {
/* … */
        }
+0792:                     neighbors_quantity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]
          __pyx_t_14[0] = 0.0;
          __pyx_t_14[1] = 0.0;
          __pyx_t_14[2] = 0.0;
          __pyx_t_15[0] = 0.0;
          __pyx_t_15[1] = 0.0;
          __pyx_t_15[2] = 0.0;
          __pyx_t_16[0] = 0.0;
          __pyx_t_16[1] = 0.0;
          __pyx_t_16[2] = 0.0;
          memcpy(&(__pyx_t_17[0]), __pyx_t_14, sizeof(__pyx_t_17[0]));
          memcpy(&(__pyx_t_17[1]), __pyx_t_15, sizeof(__pyx_t_17[0]));
          memcpy(&(__pyx_t_17[2]), __pyx_t_16, sizeof(__pyx_t_17[0]));
          memcpy(&(__pyx_v_neighbors_quantity[0]), __pyx_t_17, sizeof(__pyx_v_neighbors_quantity[0]) * (3));
+0793:                     for si in range(-1, 2):
          for (__pyx_t_9 = -1; __pyx_t_9 < 2; __pyx_t_9+=1) {
            __pyx_v_si = __pyx_t_9;
+0794:                         for sj in range(-1, 2):
            for (__pyx_t_10 = -1; __pyx_t_10 < 2; __pyx_t_10+=1) {
              __pyx_v_sj = __pyx_t_10;
+0795:                             if si != 0 or sj != 0:
              __pyx_t_18 = (__pyx_v_si != 0);
              if (!__pyx_t_18) {
              } else {
                __pyx_t_13 = __pyx_t_18;
                goto __pyx_L25_bool_binop_done;
              }
              __pyx_t_18 = (__pyx_v_sj != 0);
              __pyx_t_13 = __pyx_t_18;
              __pyx_L25_bool_binop_done:;
              if (__pyx_t_13) {
/* … */
              }
            }
          }
+0796:                                 slope = heightmap[x][y] - heightmap[mod(x + si, size_x)][mod(y + sj, size_y)]
                __pyx_t_19 = __pyx_v_x;
                __pyx_t_20 = __pyx_v_y;
                if (__pyx_t_19 < 0) __pyx_t_19 += __pyx_v_heightmap.shape[0];
                if (__pyx_t_20 < 0) __pyx_t_20 += __pyx_v_heightmap.shape[1];
                __pyx_t_21 = __pyx_f_6eroder_mod((__pyx_v_x + __pyx_v_si), __pyx_v_size_x); if (unlikely(__pyx_t_21 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 796, __pyx_L1_error)
                __pyx_t_22 = __pyx_f_6eroder_mod((__pyx_v_y + __pyx_v_sj), __pyx_v_size_y); if (unlikely(__pyx_t_22 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 796, __pyx_L1_error)
                __pyx_t_23 = __pyx_t_21;
                __pyx_t_24 = __pyx_t_22;
                __pyx_v_slope = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_19 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_20 * __pyx_v_heightmap.strides[1]) ))) - (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_23 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_24 * __pyx_v_heightmap.strides[1]) ))));
+0797:                                 if slope > 0.0:
                __pyx_t_13 = (__pyx_v_slope > 0.0);
                if (__pyx_t_13) {
/* … */
                }
+0798:                                     if si != 0 and sj != 0:
                  __pyx_t_18 = (__pyx_v_si != 0);
                  if (__pyx_t_18) {
                  } else {
                    __pyx_t_13 = __pyx_t_18;
                    goto __pyx_L29_bool_binop_done;
                  }
                  __pyx_t_18 = (__pyx_v_sj != 0);
                  __pyx_t_13 = __pyx_t_18;
                  __pyx_L29_bool_binop_done:;
                  if (__pyx_t_13) {
/* … */
                    goto __pyx_L28;
                  }
+0799:                                         slope /= sqrt(2) * length
                    __pyx_v_slope = (__pyx_v_slope / (sqrt(2.0) * __pyx_v_6eroder_length));
 0800:                                     else:
+0801:                                         slope /= length
                  /*else*/ {
                    __pyx_v_slope = (__pyx_v_slope / __pyx_v_6eroder_length);
                  }
                  __pyx_L28:;
 0802: 
+0803:                                     denominator = 1 - (slope / critical_slope)**2
                  __pyx_v_denominator = (1.0 - pow((__pyx_v_slope / __pyx_v_6eroder_critical_slope), 2.0));
 0804: 
 0805:                                     # if it's less than 0 it's too steep, should've gotten eroded by gravitational erosion anyway
+0806:                                     denominator = max(denominator, MAX_CREEP_DENOMINATOR)
                  __pyx_t_25 = __pyx_v_6eroder_MAX_CREEP_DENOMINATOR;
                  __pyx_t_26 = __pyx_v_denominator;
                  __pyx_t_13 = (__pyx_t_25 > __pyx_t_26);
                  if (__pyx_t_13) {
                    __pyx_t_27 = __pyx_t_25;
                  } else {
                    __pyx_t_27 = __pyx_t_26;
                  }
                  __pyx_v_denominator = __pyx_t_27;
 0807: 
+0808:                                     q = downhill_creep_constant * slope / denominator
                  __pyx_v_q = ((__pyx_v_downhill_creep_constant * __pyx_v_slope) / __pyx_v_denominator);
 0809: 
 0810:                                     # save for later reference
+0811:                                     neighbors_quantity[si + 1][sj + 1] = q
                  ((__pyx_v_neighbors_quantity[(__pyx_v_si + 1)])[(__pyx_v_sj + 1)]) = __pyx_v_q;
+0812:                                     total_quantity += q
                  __pyx_v_total_quantity = (__pyx_v_total_quantity + __pyx_v_q);
 0813: 
+0814:                     to_distribute = min(delta_t * 0.5 * total_quantity * soil.organic / get_soil_height(soil), get_soil_height(soil))
          __pyx_t_27 = __pyx_f_6eroder_get_soil_height(__pyx_v_soil);
          __pyx_t_25 = ((((__pyx_v_delta_t * 0.5) * __pyx_v_total_quantity) * __pyx_v_soil.organic) / __pyx_f_6eroder_get_soil_height(__pyx_v_soil));
          __pyx_t_13 = (__pyx_t_27 < __pyx_t_25);
          if (__pyx_t_13) {
            __pyx_t_26 = __pyx_t_27;
          } else {
            __pyx_t_26 = __pyx_t_25;
          }
          __pyx_v_to_distribute = __pyx_t_26;
 0815: 
+0816:                     height_fraction = to_distribute / get_soil_height(soil)
          __pyx_v_height_fraction = (__pyx_v_to_distribute / __pyx_f_6eroder_get_soil_height(__pyx_v_soil));
 0817: 
 0818:                     # how much will flow OUT of this cell later
 0819:                     # misusing this array
+0820:                     heightmap2[x][y] = to_distribute
          ((__pyx_v_heightmap2[__pyx_v_x])[__pyx_v_y]) = __pyx_v_to_distribute;
 0821: 
 0822:                     # assign flows
+0823:                     if to_distribute > 0:
          __pyx_t_13 = (__pyx_v_to_distribute > 0.0);
          if (__pyx_t_13) {
/* … */
          }
+0824:                         for si in range(-1, 2):
            for (__pyx_t_9 = -1; __pyx_t_9 < 2; __pyx_t_9+=1) {
              __pyx_v_si = __pyx_t_9;
+0825:                             for sj in range(-1, 2):
              for (__pyx_t_10 = -1; __pyx_t_10 < 2; __pyx_t_10+=1) {
                __pyx_v_sj = __pyx_t_10;
+0826:                                 if si != 0 or sj != 0:
                __pyx_t_18 = (__pyx_v_si != 0);
                if (!__pyx_t_18) {
                } else {
                  __pyx_t_13 = __pyx_t_18;
                  goto __pyx_L37_bool_binop_done;
                }
                __pyx_t_18 = (__pyx_v_sj != 0);
                __pyx_t_13 = __pyx_t_18;
                __pyx_L37_bool_binop_done:;
                if (__pyx_t_13) {
/* … */
                }
              }
            }
+0827:                                     fraction = height_fraction * neighbors_quantity[si + 1][sj + 1] / total_quantity
                  __pyx_v_fraction = ((__pyx_v_height_fraction * ((__pyx_v_neighbors_quantity[(__pyx_v_si + 1)])[(__pyx_v_sj + 1)])) / __pyx_v_total_quantity);
+0828:                                     soil_flow[x][y][si + 1][sj + 1] = soil_fraction(soil, fraction)
                  ((((__pyx_v_soil_flow[__pyx_v_x])[__pyx_v_y])[(__pyx_v_si + 1)])[(__pyx_v_sj + 1)]) = __pyx_f_6eroder_soil_fraction(__pyx_v_soil, __pyx_v_fraction);
 0829: 
 0830:                     # erode only the topsoil
+0831:                     break
          goto __pyx_L18_break;
 0832:                 else:
+0833:                     soil = terrain[x][y].subsoil
        /*else*/ {
          __pyx_t_11 = ((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil;
          __pyx_v_soil = __pyx_t_11;
        }
      }
      __pyx_L18_break:;
    }
  }
 0834: 
 0835:     # assign flows
+0836:     for x in range(size_x):
  __pyx_t_1 = __pyx_v_size_x;
  __pyx_t_2 = __pyx_t_1;
  for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
    __pyx_v_x = __pyx_t_3;
+0837:         for y in range(size_y):
    __pyx_t_6 = __pyx_v_size_y;
    __pyx_t_7 = __pyx_t_6;
    for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
      __pyx_v_y = __pyx_t_8;
 0838:             # remove soil from this column
+0839:             remove_soil(terrain[x][y], heightmap2[x][y])
      __pyx_f_6eroder_remove_soil(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]), ((__pyx_v_heightmap2[__pyx_v_x])[__pyx_v_y]));
+0840:             heightmap[x][y] -= heightmap2[x][y]
      __pyx_t_20 = __pyx_v_x;
      __pyx_t_19 = __pyx_v_y;
      if (__pyx_t_20 < 0) __pyx_t_20 += __pyx_v_heightmap.shape[0];
      if (__pyx_t_19 < 0) __pyx_t_19 += __pyx_v_heightmap.shape[1];
      *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_20 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_19 * __pyx_v_heightmap.strides[1]) )) -= ((__pyx_v_heightmap2[__pyx_v_x])[__pyx_v_y]);
 0841: 
 0842:             # deposit soil from neighbors
+0843:             for si in range(-1, 2):
      for (__pyx_t_9 = -1; __pyx_t_9 < 2; __pyx_t_9+=1) {
        __pyx_v_si = __pyx_t_9;
+0844:                 for sj in range(-1, 2):
        for (__pyx_t_10 = -1; __pyx_t_10 < 2; __pyx_t_10+=1) {
          __pyx_v_sj = __pyx_t_10;
+0845:                     if si != 0 or sj != 0:
          __pyx_t_18 = (__pyx_v_si != 0);
          if (!__pyx_t_18) {
          } else {
            __pyx_t_13 = __pyx_t_18;
            goto __pyx_L48_bool_binop_done;
          }
          __pyx_t_18 = (__pyx_v_sj != 0);
          __pyx_t_13 = __pyx_t_18;
          __pyx_L48_bool_binop_done:;
          if (__pyx_t_13) {
/* … */
          }
        }
      }
    }
  }
+0846:                         deposit_soil(terrain[x][y], soil_flow[mod(x + si, size_x)][mod(y + sj, size_y)][1 - si][1 - sj])
            __pyx_t_22 = __pyx_f_6eroder_mod((__pyx_v_x + __pyx_v_si), __pyx_v_size_x); if (unlikely(__pyx_t_22 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 846, __pyx_L1_error)
            __pyx_t_21 = __pyx_f_6eroder_mod((__pyx_v_y + __pyx_v_sj), __pyx_v_size_y); if (unlikely(__pyx_t_21 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 846, __pyx_L1_error)
            __pyx_f_6eroder_deposit_soil(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]), ((((__pyx_v_soil_flow[__pyx_t_22])[__pyx_t_21])[(1 - __pyx_v_si)])[(1 - __pyx_v_sj)]));
+0847:                         heightmap[x][y] += get_soil_height(soil_flow[mod(x + si, size_x)][mod(y + sj, size_y)][1 - si][1 - sj])
            __pyx_t_21 = __pyx_f_6eroder_mod((__pyx_v_x + __pyx_v_si), __pyx_v_size_x); if (unlikely(__pyx_t_21 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 847, __pyx_L1_error)
            __pyx_t_22 = __pyx_f_6eroder_mod((__pyx_v_y + __pyx_v_sj), __pyx_v_size_y); if (unlikely(__pyx_t_22 == ((unsigned int)-1) && __Pyx_ErrOccurredWithGIL())) __PYX_ERR(0, 847, __pyx_L1_error)
            __pyx_t_19 = __pyx_v_x;
            __pyx_t_20 = __pyx_v_y;
            if (__pyx_t_19 < 0) __pyx_t_19 += __pyx_v_heightmap.shape[0];
            if (__pyx_t_20 < 0) __pyx_t_20 += __pyx_v_heightmap.shape[1];
            *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_19 * __pyx_v_heightmap.strides[0]) ) + __pyx_t_20 * __pyx_v_heightmap.strides[1]) )) += __pyx_f_6eroder_get_soil_height(((((__pyx_v_soil_flow[__pyx_t_21])[__pyx_t_22])[(1 - __pyx_v_si)])[(1 - __pyx_v_sj)]));
 0848: 
 0849: 
 0850: ##################################################
 0851: ##################################################
+0852: cpdef erode(unsigned int steps, double delta_t, double erosion_constant, double max_penetration_depth, double inertial_erosion_constant, double downhill_creep_constant, double vegetation_spread_speed, double vegetation_base, double organification_speed, double soilification_speed, bint is_river, double source_height, unsigned int size_x, unsigned int size_y, list _heightmap, list _water, list _previous_water, list _sediment, list _flow, list _regolith, list _topsoil, list _subsoil, list _bedrock, list _bedrock_types, list _velocity_x, list _velocity_y, list _wet, list _vegetation):
static PyObject *__pyx_pw_6eroder_1erode(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
static PyObject *__pyx_f_6eroder_erode(unsigned int __pyx_v_steps, double __pyx_v_delta_t, double __pyx_v_erosion_constant, double __pyx_v_max_penetration_depth, double __pyx_v_inertial_erosion_constant, double __pyx_v_downhill_creep_constant, double __pyx_v_vegetation_spread_speed, double __pyx_v_vegetation_base, double __pyx_v_organification_speed, double __pyx_v_soilification_speed, int __pyx_v_is_river, double __pyx_v_source_height, unsigned int __pyx_v_size_x, unsigned int __pyx_v_size_y, PyObject *__pyx_v__heightmap, PyObject *__pyx_v__water, PyObject *__pyx_v__previous_water, PyObject *__pyx_v__sediment, PyObject *__pyx_v__flow, PyObject *__pyx_v__regolith, PyObject *__pyx_v__topsoil, PyObject *__pyx_v__subsoil, PyObject *__pyx_v__bedrock, PyObject *__pyx_v__bedrock_types, PyObject *__pyx_v__velocity_x, PyObject *__pyx_v__velocity_y, PyObject *__pyx_v__wet, PyObject *__pyx_v__vegetation, CYTHON_UNUSED int __pyx_skip_dispatch) {
  unsigned int __pyx_v_i;
  unsigned int __pyx_v_x;
  unsigned int __pyx_v_y;
  int __pyx_v_si;
  int __pyx_v_sj;
  PyArrayObject *__pyx_v___heightmap = 0;
  __Pyx_memviewslice __pyx_v_heightmap = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyArrayObject *__pyx_v___flow = 0;
  __Pyx_memviewslice __pyx_v_flow = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_wet = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_vegetation = { 0, 0, { 0 }, { 0 }, { 0 } };
  unsigned int __pyx_v_step;
  CYTHON_UNUSED int __pyx_v_neighbors[4][3];
  double __pyx_v_area;
  int __pyx_v_delta_x[4];
  int __pyx_v_delta_y[4];
  std::vector<std::vector<struct __pyx_t_6eroder_Water> >  __pyx_v_water;
  std::vector<std::vector<struct __pyx_t_6eroder_Water> >  __pyx_v_water2;
  std::vector<std::vector<struct __pyx_t_6eroder_Horizon> >  __pyx_v_terrain;
  std::vector<std::vector<std::vector<struct __pyx_t_6eroder_Water> > >  __pyx_v_water_flow;
  std::vector<std::vector<std::vector<std::vector<struct __pyx_t_6eroder_Soil> > > >  __pyx_v_soil_flow;
  std::vector<std::vector<double> >  __pyx_v_heightmap2;
  std::vector<std::vector<double> >  __pyx_v_vegetation2;
  struct __pyx_t_6eroder_Soil __pyx_v_soil;
  Py_ssize_t __pyx_v_vector_size;
  time_t __pyx_v_time_start;
  double __pyx_v_height_here;
  PyObject *__pyx_v_acceleration = NULL;
  double __pyx_v_out_volume_sum;
  double __pyx_v_height_neighbor;
  double __pyx_v_delta_height;
  PyObject *__pyx_v_velocity_in_direction = NULL;
  double __pyx_v_scaling;
  double __pyx_v_column_water;
  PyObject *__pyx_v_delta_v_x = NULL;
  PyObject *__pyx_v_delta_v_y = NULL;
  double __pyx_v_fraction;
  double __pyx_v_previous;
  double __pyx_v_average_height;
  double __pyx_v_flow_velocity;
  double __pyx_v_water_info;
  PyObject *__pyx_v_sediment_capacity = NULL;
  PyObject *__pyx_v_requested_amount = NULL;
  PyObject *__pyx_v_amount = NULL;
  long __pyx_v_rock;
  PyObject *__pyx_v_velocity = NULL;
  double __pyx_v_water_top;
  double __pyx_v_water_bottom;
  double __pyx_v_height_top;
  double __pyx_v_height_bottom;
  double __pyx_v_contact_top;
  double __pyx_v_contact_bottom;
  double __pyx_v_contact_area;
  PyObject *__pyx_v_erosion_capacity = NULL;
  long __pyx_v_original;
  long __pyx_v_sedimented;
  double __pyx_v_total_contact_volume;
  double __pyx_v_max_regolith_thickness;
  double __pyx_v_base;
  double __pyx_v_neighbor_vegetation;
  struct __pyx_t_6eroder_Soil __pyx_v_average_soil_shallow;
  struct __pyx_t_6eroder_Soil __pyx_v_average_soil_deep;
  double __pyx_v_rocks_shallow;
  double __pyx_v_rocks_deep;
  double __pyx_v_soil_conditions;
  double __pyx_v_bedrock_depth;
  PyObject *__pyx_v_index = NULL;
  time_t __pyx_v_time_end;
  int __pyx_v_neighbors_count;
  double __pyx_v_height_sum;
  __Pyx_memviewslice __pyx_v_texture_type = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_texture_organic = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_texture_rock0 = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_texture_rock1 = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_texture_rock2 = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_texture_rock3 = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_texture_bedrock0 = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_texture_bedrock1 = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_texture_bedrock2 = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_texture_vegetation = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_texture_water = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_texture_velocity = { 0, 0, { 0 }, { 0 }, { 0 } };
  CYTHON_UNUSED double __pyx_v_color_topsoil[4];
  struct __pyx_t_6eroder_Soil __pyx_v_render_soil;
  double __pyx_v_multiplier;
  double __pyx_v_height;
  unsigned int __pyx_7genexpr__pyx_v_y;
  unsigned int __pyx_7genexpr__pyx_v_x;
  unsigned int __pyx_8genexpr1__pyx_v_y;
  unsigned int __pyx_8genexpr1__pyx_v_x;
  unsigned int __pyx_8genexpr2__pyx_v_y;
  unsigned int __pyx_8genexpr2__pyx_v_x;
  unsigned int __pyx_8genexpr3__pyx_v_i;
  unsigned int __pyx_8genexpr4__pyx_v_y;
  unsigned int __pyx_8genexpr4__pyx_v_x;
  unsigned int __pyx_8genexpr5__pyx_v_x;
  unsigned int __pyx_8genexpr6__pyx_v_y;
  unsigned int __pyx_8genexpr7__pyx_v_x;
  unsigned int __pyx_8genexpr8__pyx_v_y;
  unsigned int __pyx_8genexpr9__pyx_v_y;
  unsigned int __pyx_8genexpr9__pyx_v_x;
  __Pyx_LocalBuf_ND __pyx_pybuffernd___flow;
  __Pyx_Buffer __pyx_pybuffer___flow;
  __Pyx_LocalBuf_ND __pyx_pybuffernd___heightmap;
  __Pyx_Buffer __pyx_pybuffer___heightmap;
  PyObject *__pyx_r = NULL;
  __Pyx_INCREF(__pyx_v__water);
  __Pyx_INCREF(__pyx_v__previous_water);
  __Pyx_INCREF(__pyx_v__sediment);
  __Pyx_INCREF(__pyx_v__regolith);
  __Pyx_INCREF(__pyx_v__topsoil);
  __Pyx_INCREF(__pyx_v__subsoil);
  __Pyx_INCREF(__pyx_v__bedrock);
  __pyx_pybuffer___heightmap.pybuffer.buf = NULL;
  __pyx_pybuffer___heightmap.refcount = 0;
  __pyx_pybuffernd___heightmap.data = NULL;
  __pyx_pybuffernd___heightmap.rcbuffer = &__pyx_pybuffer___heightmap;
  __pyx_pybuffer___flow.pybuffer.buf = NULL;
  __pyx_pybuffer___flow.refcount = 0;
  __pyx_pybuffernd___flow.data = NULL;
  __pyx_pybuffernd___flow.rcbuffer = &__pyx_pybuffer___flow;
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_7, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_9, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_t_58, 1);
  __Pyx_XDECREF(__pyx_t_61);
  __Pyx_XDECREF(__pyx_t_62);
  __Pyx_XDECREF(__pyx_t_63);
  __Pyx_XDECREF(__pyx_t_64);
  __Pyx_XDECREF(__pyx_t_65);
  __Pyx_XDECREF(__pyx_t_66);
  __Pyx_XDECREF(__pyx_t_67);
  __Pyx_XDECREF(__pyx_t_68);
  __Pyx_XDECREF(__pyx_t_69);
  __Pyx_XDECREF(__pyx_t_70);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_PyThreadState_declare
    __Pyx_PyThreadState_assign
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd___flow.rcbuffer->pybuffer);
    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd___heightmap.rcbuffer->pybuffer);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("eroder.erode", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd___flow.rcbuffer->pybuffer);
  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd___heightmap.rcbuffer->pybuffer);
  __pyx_L2:;
  __Pyx_XDECREF((PyObject *)__pyx_v___heightmap);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_heightmap, 1);
  __Pyx_XDECREF((PyObject *)__pyx_v___flow);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_flow, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_wet, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_vegetation, 1);
  __Pyx_XDECREF(__pyx_v_acceleration);
  __Pyx_XDECREF(__pyx_v_velocity_in_direction);
  __Pyx_XDECREF(__pyx_v_delta_v_x);
  __Pyx_XDECREF(__pyx_v_delta_v_y);
  __Pyx_XDECREF(__pyx_v_sediment_capacity);
  __Pyx_XDECREF(__pyx_v_requested_amount);
  __Pyx_XDECREF(__pyx_v_amount);
  __Pyx_XDECREF(__pyx_v_velocity);
  __Pyx_XDECREF(__pyx_v_erosion_capacity);
  __Pyx_XDECREF(__pyx_v_index);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_texture_type, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_texture_organic, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_texture_rock0, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_texture_rock1, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_texture_rock2, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_texture_rock3, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_texture_bedrock0, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_texture_bedrock1, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_texture_bedrock2, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_texture_vegetation, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_texture_water, 1);
  __PYX_XCLEAR_MEMVIEW(&__pyx_v_texture_velocity, 1);
  __Pyx_XDECREF(__pyx_v__water);
  __Pyx_XDECREF(__pyx_v__previous_water);
  __Pyx_XDECREF(__pyx_v__sediment);
  __Pyx_XDECREF(__pyx_v__regolith);
  __Pyx_XDECREF(__pyx_v__topsoil);
  __Pyx_XDECREF(__pyx_v__subsoil);
  __Pyx_XDECREF(__pyx_v__bedrock);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* Python wrapper */
static PyObject *__pyx_pw_6eroder_1erode(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
static PyMethodDef __pyx_mdef_6eroder_1erode = {"erode", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_6eroder_1erode, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_6eroder_1erode(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  unsigned int __pyx_v_steps;
  double __pyx_v_delta_t;
  double __pyx_v_erosion_constant;
  double __pyx_v_max_penetration_depth;
  double __pyx_v_inertial_erosion_constant;
  double __pyx_v_downhill_creep_constant;
  double __pyx_v_vegetation_spread_speed;
  double __pyx_v_vegetation_base;
  double __pyx_v_organification_speed;
  double __pyx_v_soilification_speed;
  int __pyx_v_is_river;
  double __pyx_v_source_height;
  unsigned int __pyx_v_size_x;
  unsigned int __pyx_v_size_y;
  PyObject *__pyx_v__heightmap = 0;
  PyObject *__pyx_v__water = 0;
  PyObject *__pyx_v__previous_water = 0;
  PyObject *__pyx_v__sediment = 0;
  PyObject *__pyx_v__flow = 0;
  PyObject *__pyx_v__regolith = 0;
  PyObject *__pyx_v__topsoil = 0;
  PyObject *__pyx_v__subsoil = 0;
  PyObject *__pyx_v__bedrock = 0;
  PyObject *__pyx_v__bedrock_types = 0;
  PyObject *__pyx_v__velocity_x = 0;
  PyObject *__pyx_v__velocity_y = 0;
  PyObject *__pyx_v__wet = 0;
  PyObject *__pyx_v__vegetation = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("erode (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_steps,&__pyx_n_s_delta_t,&__pyx_n_s_erosion_constant,&__pyx_n_s_max_penetration_depth,&__pyx_n_s_inertial_erosion_constant,&__pyx_n_s_downhill_creep_constant,&__pyx_n_s_vegetation_spread_speed,&__pyx_n_s_vegetation_base,&__pyx_n_s_organification_speed,&__pyx_n_s_soilification_speed,&__pyx_n_s_is_river,&__pyx_n_s_source_height,&__pyx_n_s_size_x,&__pyx_n_s_size_y,&__pyx_n_s_heightmap,&__pyx_n_s_water,&__pyx_n_s_previous_water,&__pyx_n_s_sediment,&__pyx_n_s_flow,&__pyx_n_s_regolith,&__pyx_n_s_topsoil,&__pyx_n_s_subsoil,&__pyx_n_s_bedrock,&__pyx_n_s_bedrock_types,&__pyx_n_s_velocity_x,&__pyx_n_s_velocity_y,&__pyx_n_s_wet,&__pyx_n_s_vegetation,0};
  PyObject* values[28] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case 28: values[27] = __Pyx_Arg_FASTCALL(__pyx_args, 27);
        CYTHON_FALLTHROUGH;
        case 27: values[26] = __Pyx_Arg_FASTCALL(__pyx_args, 26);
        CYTHON_FALLTHROUGH;
        case 26: values[25] = __Pyx_Arg_FASTCALL(__pyx_args, 25);
        CYTHON_FALLTHROUGH;
        case 25: values[24] = __Pyx_Arg_FASTCALL(__pyx_args, 24);
        CYTHON_FALLTHROUGH;
        case 24: values[23] = __Pyx_Arg_FASTCALL(__pyx_args, 23);
        CYTHON_FALLTHROUGH;
        case 23: values[22] = __Pyx_Arg_FASTCALL(__pyx_args, 22);
        CYTHON_FALLTHROUGH;
        case 22: values[21] = __Pyx_Arg_FASTCALL(__pyx_args, 21);
        CYTHON_FALLTHROUGH;
        case 21: values[20] = __Pyx_Arg_FASTCALL(__pyx_args, 20);
        CYTHON_FALLTHROUGH;
        case 20: values[19] = __Pyx_Arg_FASTCALL(__pyx_args, 19);
        CYTHON_FALLTHROUGH;
        case 19: values[18] = __Pyx_Arg_FASTCALL(__pyx_args, 18);
        CYTHON_FALLTHROUGH;
        case 18: values[17] = __Pyx_Arg_FASTCALL(__pyx_args, 17);
        CYTHON_FALLTHROUGH;
        case 17: values[16] = __Pyx_Arg_FASTCALL(__pyx_args, 16);
        CYTHON_FALLTHROUGH;
        case 16: values[15] = __Pyx_Arg_FASTCALL(__pyx_args, 15);
        CYTHON_FALLTHROUGH;
        case 15: values[14] = __Pyx_Arg_FASTCALL(__pyx_args, 14);
        CYTHON_FALLTHROUGH;
        case 14: values[13] = __Pyx_Arg_FASTCALL(__pyx_args, 13);
        CYTHON_FALLTHROUGH;
        case 13: values[12] = __Pyx_Arg_FASTCALL(__pyx_args, 12);
        CYTHON_FALLTHROUGH;
        case 12: values[11] = __Pyx_Arg_FASTCALL(__pyx_args, 11);
        CYTHON_FALLTHROUGH;
        case 11: values[10] = __Pyx_Arg_FASTCALL(__pyx_args, 10);
        CYTHON_FALLTHROUGH;
        case 10: values[9] = __Pyx_Arg_FASTCALL(__pyx_args, 9);
        CYTHON_FALLTHROUGH;
        case  9: values[8] = __Pyx_Arg_FASTCALL(__pyx_args, 8);
        CYTHON_FALLTHROUGH;
        case  8: values[7] = __Pyx_Arg_FASTCALL(__pyx_args, 7);
        CYTHON_FALLTHROUGH;
        case  7: values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6);
        CYTHON_FALLTHROUGH;
        case  6: values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_steps)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_delta_t)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 1); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_erosion_constant)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[2]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 2); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_max_penetration_depth)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[3]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 3); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_inertial_erosion_constant)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[4]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 4); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  5:
        if (likely((values[5] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_downhill_creep_constant)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[5]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 5); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  6:
        if (likely((values[6] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_vegetation_spread_speed)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[6]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 6); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  7:
        if (likely((values[7] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_vegetation_base)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[7]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 7); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  8:
        if (likely((values[8] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_organification_speed)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[8]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 8); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  9:
        if (likely((values[9] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_soilification_speed)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[9]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 9); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 10:
        if (likely((values[10] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_is_river)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[10]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 10); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 11:
        if (likely((values[11] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_source_height)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[11]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 11); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 12:
        if (likely((values[12] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_size_x)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[12]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 12); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 13:
        if (likely((values[13] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_size_y)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[13]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 13); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 14:
        if (likely((values[14] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_heightmap)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[14]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 14); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 15:
        if (likely((values[15] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_water)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[15]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 15); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 16:
        if (likely((values[16] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_previous_water)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[16]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 16); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 17:
        if (likely((values[17] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_sediment)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[17]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 17); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 18:
        if (likely((values[18] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_flow)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[18]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 18); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 19:
        if (likely((values[19] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_regolith)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[19]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 19); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 20:
        if (likely((values[20] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_topsoil)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[20]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 20); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 21:
        if (likely((values[21] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_subsoil)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[21]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 21); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 22:
        if (likely((values[22] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_bedrock)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[22]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 22); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 23:
        if (likely((values[23] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_bedrock_types)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[23]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 23); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 24:
        if (likely((values[24] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_velocity_x)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[24]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 24); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 25:
        if (likely((values[25] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_velocity_y)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[25]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 25); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 26:
        if (likely((values[26] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_wet)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[26]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 26); __PYX_ERR(0, 852, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case 27:
        if (likely((values[27] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_vegetation)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[27]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, 27); __PYX_ERR(0, 852, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "erode") < 0)) __PYX_ERR(0, 852, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 28)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
      values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
      values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
      values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4);
      values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5);
      values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6);
      values[7] = __Pyx_Arg_FASTCALL(__pyx_args, 7);
      values[8] = __Pyx_Arg_FASTCALL(__pyx_args, 8);
      values[9] = __Pyx_Arg_FASTCALL(__pyx_args, 9);
      values[10] = __Pyx_Arg_FASTCALL(__pyx_args, 10);
      values[11] = __Pyx_Arg_FASTCALL(__pyx_args, 11);
      values[12] = __Pyx_Arg_FASTCALL(__pyx_args, 12);
      values[13] = __Pyx_Arg_FASTCALL(__pyx_args, 13);
      values[14] = __Pyx_Arg_FASTCALL(__pyx_args, 14);
      values[15] = __Pyx_Arg_FASTCALL(__pyx_args, 15);
      values[16] = __Pyx_Arg_FASTCALL(__pyx_args, 16);
      values[17] = __Pyx_Arg_FASTCALL(__pyx_args, 17);
      values[18] = __Pyx_Arg_FASTCALL(__pyx_args, 18);
      values[19] = __Pyx_Arg_FASTCALL(__pyx_args, 19);
      values[20] = __Pyx_Arg_FASTCALL(__pyx_args, 20);
      values[21] = __Pyx_Arg_FASTCALL(__pyx_args, 21);
      values[22] = __Pyx_Arg_FASTCALL(__pyx_args, 22);
      values[23] = __Pyx_Arg_FASTCALL(__pyx_args, 23);
      values[24] = __Pyx_Arg_FASTCALL(__pyx_args, 24);
      values[25] = __Pyx_Arg_FASTCALL(__pyx_args, 25);
      values[26] = __Pyx_Arg_FASTCALL(__pyx_args, 26);
      values[27] = __Pyx_Arg_FASTCALL(__pyx_args, 27);
    }
    __pyx_v_steps = __Pyx_PyInt_As_unsigned_int(values[0]); if (unlikely((__pyx_v_steps == (unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v_delta_t = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_delta_t == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v_erosion_constant = __pyx_PyFloat_AsDouble(values[2]); if (unlikely((__pyx_v_erosion_constant == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v_max_penetration_depth = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_max_penetration_depth == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v_inertial_erosion_constant = __pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_inertial_erosion_constant == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v_downhill_creep_constant = __pyx_PyFloat_AsDouble(values[5]); if (unlikely((__pyx_v_downhill_creep_constant == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v_vegetation_spread_speed = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_vegetation_spread_speed == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v_vegetation_base = __pyx_PyFloat_AsDouble(values[7]); if (unlikely((__pyx_v_vegetation_base == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v_organification_speed = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_organification_speed == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v_soilification_speed = __pyx_PyFloat_AsDouble(values[9]); if (unlikely((__pyx_v_soilification_speed == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v_is_river = __Pyx_PyObject_IsTrue(values[10]); if (unlikely((__pyx_v_is_river == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v_source_height = __pyx_PyFloat_AsDouble(values[11]); if (unlikely((__pyx_v_source_height == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v_size_x = __Pyx_PyInt_As_unsigned_int(values[12]); if (unlikely((__pyx_v_size_x == (unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v_size_y = __Pyx_PyInt_As_unsigned_int(values[13]); if (unlikely((__pyx_v_size_y == (unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 852, __pyx_L3_error)
    __pyx_v__heightmap = ((PyObject*)values[14]);
    __pyx_v__water = ((PyObject*)values[15]);
    __pyx_v__previous_water = ((PyObject*)values[16]);
    __pyx_v__sediment = ((PyObject*)values[17]);
    __pyx_v__flow = ((PyObject*)values[18]);
    __pyx_v__regolith = ((PyObject*)values[19]);
    __pyx_v__topsoil = ((PyObject*)values[20]);
    __pyx_v__subsoil = ((PyObject*)values[21]);
    __pyx_v__bedrock = ((PyObject*)values[22]);
    __pyx_v__bedrock_types = ((PyObject*)values[23]);
    __pyx_v__velocity_x = ((PyObject*)values[24]);
    __pyx_v__velocity_y = ((PyObject*)values[25]);
    __pyx_v__wet = ((PyObject*)values[26]);
    __pyx_v__vegetation = ((PyObject*)values[27]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("erode", 1, 28, 28, __pyx_nargs); __PYX_ERR(0, 852, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("eroder.erode", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__heightmap), (&PyList_Type), 1, "_heightmap", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__water), (&PyList_Type), 1, "_water", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__previous_water), (&PyList_Type), 1, "_previous_water", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__sediment), (&PyList_Type), 1, "_sediment", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__flow), (&PyList_Type), 1, "_flow", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__regolith), (&PyList_Type), 1, "_regolith", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__topsoil), (&PyList_Type), 1, "_topsoil", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__subsoil), (&PyList_Type), 1, "_subsoil", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__bedrock), (&PyList_Type), 1, "_bedrock", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__bedrock_types), (&PyList_Type), 1, "_bedrock_types", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__velocity_x), (&PyList_Type), 1, "_velocity_x", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__velocity_y), (&PyList_Type), 1, "_velocity_y", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__wet), (&PyList_Type), 1, "_wet", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v__vegetation), (&PyList_Type), 1, "_vegetation", 1))) __PYX_ERR(0, 852, __pyx_L1_error)
  __pyx_r = __pyx_pf_6eroder_erode(__pyx_self, __pyx_v_steps, __pyx_v_delta_t, __pyx_v_erosion_constant, __pyx_v_max_penetration_depth, __pyx_v_inertial_erosion_constant, __pyx_v_downhill_creep_constant, __pyx_v_vegetation_spread_speed, __pyx_v_vegetation_base, __pyx_v_organification_speed, __pyx_v_soilification_speed, __pyx_v_is_river, __pyx_v_source_height, __pyx_v_size_x, __pyx_v_size_y, __pyx_v__heightmap, __pyx_v__water, __pyx_v__previous_water, __pyx_v__sediment, __pyx_v__flow, __pyx_v__regolith, __pyx_v__topsoil, __pyx_v__subsoil, __pyx_v__bedrock, __pyx_v__bedrock_types, __pyx_v__velocity_x, __pyx_v__velocity_y, __pyx_v__wet, __pyx_v__vegetation);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_6eroder_erode(CYTHON_UNUSED PyObject *__pyx_self, unsigned int __pyx_v_steps, double __pyx_v_delta_t, double __pyx_v_erosion_constant, double __pyx_v_max_penetration_depth, double __pyx_v_inertial_erosion_constant, double __pyx_v_downhill_creep_constant, double __pyx_v_vegetation_spread_speed, double __pyx_v_vegetation_base, double __pyx_v_organification_speed, double __pyx_v_soilification_speed, int __pyx_v_is_river, double __pyx_v_source_height, unsigned int __pyx_v_size_x, unsigned int __pyx_v_size_y, PyObject *__pyx_v__heightmap, PyObject *__pyx_v__water, PyObject *__pyx_v__previous_water, PyObject *__pyx_v__sediment, PyObject *__pyx_v__flow, PyObject *__pyx_v__regolith, PyObject *__pyx_v__topsoil, PyObject *__pyx_v__subsoil, PyObject *__pyx_v__bedrock, PyObject *__pyx_v__bedrock_types, PyObject *__pyx_v__velocity_x, PyObject *__pyx_v__velocity_y, PyObject *__pyx_v__wet, PyObject *__pyx_v__vegetation) {
  PyObject *__pyx_r = NULL;
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = __pyx_f_6eroder_erode(__pyx_v_steps, __pyx_v_delta_t, __pyx_v_erosion_constant, __pyx_v_max_penetration_depth, __pyx_v_inertial_erosion_constant, __pyx_v_downhill_creep_constant, __pyx_v_vegetation_spread_speed, __pyx_v_vegetation_base, __pyx_v_organification_speed, __pyx_v_soilification_speed, __pyx_v_is_river, __pyx_v_source_height, __pyx_v_size_x, __pyx_v_size_y, __pyx_v__heightmap, __pyx_v__water, __pyx_v__previous_water, __pyx_v__sediment, __pyx_v__flow, __pyx_v__regolith, __pyx_v__topsoil, __pyx_v__subsoil, __pyx_v__bedrock, __pyx_v__bedrock_types, __pyx_v__velocity_x, __pyx_v__velocity_y, __pyx_v__wet, __pyx_v__vegetation, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 852, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_AddTraceback("eroder.erode", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__27 = PyTuple_Pack(28, __pyx_n_s_steps, __pyx_n_s_delta_t, __pyx_n_s_erosion_constant, __pyx_n_s_max_penetration_depth, __pyx_n_s_inertial_erosion_constant, __pyx_n_s_downhill_creep_constant, __pyx_n_s_vegetation_spread_speed, __pyx_n_s_vegetation_base, __pyx_n_s_organification_speed, __pyx_n_s_soilification_speed, __pyx_n_s_is_river, __pyx_n_s_source_height, __pyx_n_s_size_x, __pyx_n_s_size_y, __pyx_n_s_heightmap, __pyx_n_s_water, __pyx_n_s_previous_water, __pyx_n_s_sediment, __pyx_n_s_flow, __pyx_n_s_regolith, __pyx_n_s_topsoil, __pyx_n_s_subsoil, __pyx_n_s_bedrock, __pyx_n_s_bedrock_types, __pyx_n_s_velocity_x, __pyx_n_s_velocity_y, __pyx_n_s_wet, __pyx_n_s_vegetation); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(0, 852, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__27);
  __Pyx_GIVEREF(__pyx_tuple__27);
/* … */
  __pyx_t_7 = __Pyx_CyFunction_New(&__pyx_mdef_6eroder_1erode, 0, __pyx_n_s_erode, NULL, __pyx_n_s_eroder, __pyx_d, ((PyObject *)__pyx_codeobj__28)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 852, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_erode, __pyx_t_7) < 0) __PYX_ERR(0, 852, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
 0853:     # our universal iterators
 0854:     cdef unsigned int i, j, x, y
 0855:     cdef int si, sj
 0856: 
 0857:     # this is edited manually, I just use it to make sure that Blender loads the correct file (often doesn't)
+0858:     print("eroder version = 23")
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 858, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
  __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_u_eroder_version_23); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(0, 858, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__13);
  __Pyx_GIVEREF(__pyx_tuple__13);
 0859: 
 0860:     # converts lists into memory views
+0861:     cdef cnp.ndarray[cnp.float64_t, ndim=2] __heightmap = np.array(_heightmap, dtype=np.float64)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 861, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_array); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 861, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 861, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_INCREF(__pyx_v__heightmap);
  __Pyx_GIVEREF(__pyx_v__heightmap);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v__heightmap)) __PYX_ERR(0, 861, __pyx_L1_error);
  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 861, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 861, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 861, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_5) < 0) __PYX_ERR(0, 861, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 861, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 861, __pyx_L1_error)
  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);
  {
    __Pyx_BufFmt_StackElem __pyx_stack[1];
    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd___heightmap.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {
      __pyx_v___heightmap = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd___heightmap.rcbuffer->pybuffer.buf = NULL;
      __PYX_ERR(0, 861, __pyx_L1_error)
    } else {__pyx_pybuffernd___heightmap.diminfo[0].strides = __pyx_pybuffernd___heightmap.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd___heightmap.diminfo[0].shape = __pyx_pybuffernd___heightmap.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd___heightmap.diminfo[1].strides = __pyx_pybuffernd___heightmap.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd___heightmap.diminfo[1].shape = __pyx_pybuffernd___heightmap.rcbuffer->pybuffer.shape[1];
    }
  }
  __pyx_t_6 = 0;
  __pyx_v___heightmap = ((PyArrayObject *)__pyx_t_5);
  __pyx_t_5 = 0;
+0862:     cdef double[:, ::1] heightmap = __heightmap
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_double(((PyObject *)__pyx_v___heightmap), PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 862, __pyx_L1_error)
  __pyx_v_heightmap = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
+0863:     cdef cnp.ndarray[cnp.float64_t, ndim=3] __flow = np.array(_flow, dtype=np.float64)
  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 863, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_array); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 863, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 863, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_INCREF(__pyx_v__flow);
  __Pyx_GIVEREF(__pyx_v__flow);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v__flow)) __PYX_ERR(0, 863, __pyx_L1_error);
  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 863, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 863, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_float64); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 863, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_4) < 0) __PYX_ERR(0, 863, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 863, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 863, __pyx_L1_error)
  __pyx_t_8 = ((PyArrayObject *)__pyx_t_4);
  {
    __Pyx_BufFmt_StackElem __pyx_stack[1];
    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd___flow.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 3, 0, __pyx_stack) == -1)) {
      __pyx_v___flow = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd___flow.rcbuffer->pybuffer.buf = NULL;
      __PYX_ERR(0, 863, __pyx_L1_error)
    } else {__pyx_pybuffernd___flow.diminfo[0].strides = __pyx_pybuffernd___flow.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd___flow.diminfo[0].shape = __pyx_pybuffernd___flow.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd___flow.diminfo[1].strides = __pyx_pybuffernd___flow.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd___flow.diminfo[1].shape = __pyx_pybuffernd___flow.rcbuffer->pybuffer.shape[1]; __pyx_pybuffernd___flow.diminfo[2].strides = __pyx_pybuffernd___flow.rcbuffer->pybuffer.strides[2]; __pyx_pybuffernd___flow.diminfo[2].shape = __pyx_pybuffernd___flow.rcbuffer->pybuffer.shape[2];
    }
  }
  __pyx_t_8 = 0;
  __pyx_v___flow = ((PyArrayObject *)__pyx_t_4);
  __pyx_t_4 = 0;
+0864:     cdef double[:, :, :] flow = __flow
  __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_double(((PyObject *)__pyx_v___flow), PyBUF_WRITABLE); if (unlikely(!__pyx_t_9.memview)) __PYX_ERR(0, 864, __pyx_L1_error)
  __pyx_v_flow = __pyx_t_9;
  __pyx_t_9.memview = NULL;
  __pyx_t_9.data = NULL;
+0865:     cdef double[:, ::1] wet = np.array(_wet, dtype=np.float64)
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 865, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_array); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 865, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 865, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_INCREF(__pyx_v__wet);
  __Pyx_GIVEREF(__pyx_v__wet);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v__wet)) __PYX_ERR(0, 865, __pyx_L1_error);
  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 865, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 865, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_float64); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 865, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 865, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 865, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_double(__pyx_t_2, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 865, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_wet = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
+0866:     cdef double[:, ::1] vegetation = np.array(_vegetation, dtype=np.float64)
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 866, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 866, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 866, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_INCREF(__pyx_v__vegetation);
  __Pyx_GIVEREF(__pyx_v__vegetation);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v__vegetation)) __PYX_ERR(0, 866, __pyx_L1_error);
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 866, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 866, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float64); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 866, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_3) < 0) __PYX_ERR(0, 866, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 866, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_double(__pyx_t_3, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 866, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_vegetation = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 0867: 
 0868: 
+0869:     cdef unsigned int step = 0
  __pyx_v_step = 0;
+0870:     cdef int[4][3] neighbors = [[1, 0, 0], [0, 1, 1], [-1, 0, 2], [0, -1, 3]]
  __pyx_t_10[0] = 1;
  __pyx_t_10[1] = 0;
  __pyx_t_10[2] = 0;
  __pyx_t_11[0] = 0;
  __pyx_t_11[1] = 1;
  __pyx_t_11[2] = 1;
  __pyx_t_12[0] = -1;
  __pyx_t_12[1] = 0;
  __pyx_t_12[2] = 2;
  __pyx_t_13[0] = 0;
  __pyx_t_13[1] = -1;
  __pyx_t_13[2] = 3;
  memcpy(&(__pyx_t_14[0]), __pyx_t_10, sizeof(__pyx_t_14[0]));
  memcpy(&(__pyx_t_14[1]), __pyx_t_11, sizeof(__pyx_t_14[0]));
  memcpy(&(__pyx_t_14[2]), __pyx_t_12, sizeof(__pyx_t_14[0]));
  memcpy(&(__pyx_t_14[3]), __pyx_t_13, sizeof(__pyx_t_14[0]));
  memcpy(&(__pyx_v_neighbors[0]), __pyx_t_14, sizeof(__pyx_v_neighbors[0]) * (4));
+0871:     cdef double area = length * length
  __pyx_v_area = (__pyx_v_6eroder_length * __pyx_v_6eroder_length);
+0872:     cdef int[4] delta_x = [ 1, 0, -1, 0 ]
  __pyx_t_15[0] = 1;
  __pyx_t_15[1] = 0;
  __pyx_t_15[2] = -1;
  __pyx_t_15[3] = 0;
  memcpy(&(__pyx_v_delta_x[0]), __pyx_t_15, sizeof(__pyx_v_delta_x[0]) * (4));
+0873:     cdef int[4] delta_y = [ 0, 1, 0, -1 ]
  __pyx_t_16[0] = 0;
  __pyx_t_16[1] = 1;
  __pyx_t_16[2] = 0;
  __pyx_t_16[3] = -1;
  memcpy(&(__pyx_v_delta_y[0]), __pyx_t_16, sizeof(__pyx_v_delta_y[0]) * (4));
 0874: 
 0875: 
 0876: 
 0877:     cdef vector[vector[Water]] water
 0878:     cdef vector[vector[Water]] water2
 0879:     cdef vector[vector[Horizon]] terrain
 0880:     cdef vector[vector[vector[Water]]] water_flow
 0881:     cdef vector[vector[vector[vector[Soil]]]] soil_flow
 0882:     cdef vector[vector[double]] heightmap2
 0883:     cdef vector[vector[double]] vegetation2
 0884:     """ cdef double[4] acceleration = [0.0, 0.0, 0.0, 0.0]
 0885:     cdef double delta_height
 0886:     cdef double scaling
 0887:     cdef double flow_velocity
 0888:     cdef double local_shape_factor
 0889:     cdef double sediment_capacity
 0890:     cdef double out_volume_sum
 0891:     cdef double[3][3] neighbors_delta_height"""
 0892:     cdef Soil soil
 0893: 
+0894:     print("starting erosion...")
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 894, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
/* … */
  __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_u_starting_erosion); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(0, 894, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__14);
  __Pyx_GIVEREF(__pyx_tuple__14);
 0895: 
 0896:     # initialize vectors
+0897:     water.resize(size_x)
  try {
    __pyx_v_water.resize(__pyx_v_size_x);
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 897, __pyx_L1_error)
  }
+0898:     water2.resize(size_x)
  try {
    __pyx_v_water2.resize(__pyx_v_size_x);
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 898, __pyx_L1_error)
  }
+0899:     terrain.resize(size_x)
  try {
    __pyx_v_terrain.resize(__pyx_v_size_x);
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 899, __pyx_L1_error)
  }
+0900:     soil_flow.resize(size_x)
  try {
    __pyx_v_soil_flow.resize(__pyx_v_size_x);
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 900, __pyx_L1_error)
  }
+0901:     water_flow.resize(size_x)
  try {
    __pyx_v_water_flow.resize(__pyx_v_size_x);
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 901, __pyx_L1_error)
  }
+0902:     heightmap2.resize(size_x)
  try {
    __pyx_v_heightmap2.resize(__pyx_v_size_x);
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 902, __pyx_L1_error)
  }
+0903:     vegetation2.resize(size_x)
  try {
    __pyx_v_vegetation2.resize(__pyx_v_size_x);
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 903, __pyx_L1_error)
  }
 0904: 
+0905:     for x in range(size_x):
  __pyx_t_17 = __pyx_v_size_x;
  __pyx_t_18 = __pyx_t_17;
  for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
    __pyx_v_x = __pyx_t_19;
+0906:         water.at(x).resize(size_y, EMPTY_WATER)
    try {
      __pyx_t_20 = __pyx_v_water.at(__pyx_v_x);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 906, __pyx_L1_error)
    }
    try {
      __pyx_t_20->resize(__pyx_v_size_y, __pyx_v_6eroder_EMPTY_WATER);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 906, __pyx_L1_error)
    }
+0907:         water2.at(x).resize(size_y, EMPTY_WATER)
    try {
      __pyx_t_21 = __pyx_v_water2.at(__pyx_v_x);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 907, __pyx_L1_error)
    }
    try {
      __pyx_t_21->resize(__pyx_v_size_y, __pyx_v_6eroder_EMPTY_WATER);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 907, __pyx_L1_error)
    }
+0908:         soil_flow.at(x).resize(size_y)
    try {
      __pyx_t_22 = __pyx_v_soil_flow.at(__pyx_v_x);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 908, __pyx_L1_error)
    }
    try {
      __pyx_t_22->resize(__pyx_v_size_y);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 908, __pyx_L1_error)
    }
+0909:         water_flow.at(x).resize(size_y)
    try {
      __pyx_t_23 = __pyx_v_water_flow.at(__pyx_v_x);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 909, __pyx_L1_error)
    }
    try {
      __pyx_t_23->resize(__pyx_v_size_y);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 909, __pyx_L1_error)
    }
+0910:         terrain.at(x).resize(size_y)
    try {
      __pyx_t_24 = __pyx_v_terrain.at(__pyx_v_x);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 910, __pyx_L1_error)
    }
    try {
      __pyx_t_24->resize(__pyx_v_size_y);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 910, __pyx_L1_error)
    }
+0911:         heightmap2.at(x).resize(size_y, 0.0)
    try {
      __pyx_t_25 = __pyx_v_heightmap2.at(__pyx_v_x);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 911, __pyx_L1_error)
    }
    try {
      __pyx_t_25->resize(__pyx_v_size_y, 0.0);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 911, __pyx_L1_error)
    }
+0912:         vegetation2.at(x).resize(size_y, 0.0)
    try {
      __pyx_t_26 = __pyx_v_vegetation2.at(__pyx_v_x);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 912, __pyx_L1_error)
    }
    try {
      __pyx_t_26->resize(__pyx_v_size_y, 0.0);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 912, __pyx_L1_error)
    }
+0913:         for y in range(size_y):
    __pyx_t_27 = __pyx_v_size_y;
    __pyx_t_28 = __pyx_t_27;
    for (__pyx_t_29 = 0; __pyx_t_29 < __pyx_t_28; __pyx_t_29+=1) {
      __pyx_v_y = __pyx_t_29;
 0914:             # water
+0915:             water[x][y].height = _water[x][y]
      if (unlikely(__pyx_v__water == Py_None)) {
        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
        __PYX_ERR(0, 915, __pyx_L1_error)
      }
      __pyx_t_3 = __Pyx_GetItemInt(PyList_GET_ITEM(__pyx_v__water, __pyx_v_x), __pyx_v_y, unsigned int, 0, __Pyx_PyInt_From_unsigned_int, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 915, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 915, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height = __pyx_t_30;
+0916:             if water[x][y].height < 0.0:
      __pyx_t_31 = (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height < 0.0);
      if (__pyx_t_31) {
/* … */
      }
+0917:                 water[x][y].height = 0.0
        ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height = 0.0;
 0918: 
+0919:             water[x][y].previous = _previous_water[x][y]
      if (unlikely(__pyx_v__previous_water == Py_None)) {
        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
        __PYX_ERR(0, 919, __pyx_L1_error)
      }
      __pyx_t_3 = __Pyx_GetItemInt(PyList_GET_ITEM(__pyx_v__previous_water, __pyx_v_x), __pyx_v_y, unsigned int, 0, __Pyx_PyInt_From_unsigned_int, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 919, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 919, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).previous = __pyx_t_30;
 0920: 
+0921:             water[x][y].sediment.organic = _sediment[x + size_x * y][ORGANIC]
      if (unlikely(__pyx_v__sediment == Py_None)) {
        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
        __PYX_ERR(0, 921, __pyx_L1_error)
      }
      __pyx_t_32 = (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y));
      __pyx_t_3 = __Pyx_GetItemInt(PyList_GET_ITEM(__pyx_v__sediment, __pyx_t_32), __pyx_v_6eroder_ORGANIC, int, 1, __Pyx_PyInt_From_int, 0, 1, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 921, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 921, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).sediment.organic = __pyx_t_30;
+0922:             for i in range(4):
      for (__pyx_t_32 = 0; __pyx_t_32 < 4; __pyx_t_32+=1) {
        __pyx_v_i = __pyx_t_32;
+0923:                 water[x][y].sediment.rocks[i] = _sediment[x + size_x * y][i]
        if (unlikely(__pyx_v__sediment == Py_None)) {
          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
          __PYX_ERR(0, 923, __pyx_L1_error)
        }
        __pyx_t_33 = (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y));
        __pyx_t_3 = __Pyx_GetItemInt(PyList_GET_ITEM(__pyx_v__sediment, __pyx_t_33), __pyx_v_i, unsigned int, 0, __Pyx_PyInt_From_unsigned_int, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 923, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 923, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).sediment.rocks[__pyx_v_i]) = __pyx_t_30;
      }
 0924: 
+0925:             water[x][y].regolith.organic = _regolith[x + size_x * y][0]
      if (unlikely(__pyx_v__regolith == Py_None)) {
        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
        __PYX_ERR(0, 925, __pyx_L1_error)
      }
      __pyx_t_32 = (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y));
      __pyx_t_3 = __Pyx_GetItemInt(PyList_GET_ITEM(__pyx_v__regolith, __pyx_t_32), 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 925, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 925, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).regolith.organic = __pyx_t_30;
+0926:             water[x][y].regolith.rocks[0] = _regolith[x + size_x * y][1]
      if (unlikely(__pyx_v__regolith == Py_None)) {
        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
        __PYX_ERR(0, 926, __pyx_L1_error)
      }
      __pyx_t_32 = (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y));
      __pyx_t_3 = __Pyx_GetItemInt(PyList_GET_ITEM(__pyx_v__regolith, __pyx_t_32), 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 926, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 926, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).regolith.rocks[0]) = __pyx_t_30;
+0927:             for i in range(1, 4):
      for (__pyx_t_32 = 1; __pyx_t_32 < 4; __pyx_t_32+=1) {
        __pyx_v_i = __pyx_t_32;
+0928:                 water[x][y].regolith.rocks[i] = 0.0
        (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).regolith.rocks[__pyx_v_i]) = 0.0;
      }
 0929: 
+0930:             water[x][y].velocity_x = _velocity_x[x][y]
      if (unlikely(__pyx_v__velocity_x == Py_None)) {
        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
        __PYX_ERR(0, 930, __pyx_L1_error)
      }
      __pyx_t_3 = __Pyx_GetItemInt(PyList_GET_ITEM(__pyx_v__velocity_x, __pyx_v_x), __pyx_v_y, unsigned int, 0, __Pyx_PyInt_From_unsigned_int, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 930, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 930, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).velocity_x = __pyx_t_30;
+0931:             water[x][y].velocity_y = _velocity_y[x][y]
      if (unlikely(__pyx_v__velocity_y == Py_None)) {
        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
        __PYX_ERR(0, 931, __pyx_L1_error)
      }
      __pyx_t_3 = __Pyx_GetItemInt(PyList_GET_ITEM(__pyx_v__velocity_y, __pyx_v_x), __pyx_v_y, unsigned int, 0, __Pyx_PyInt_From_unsigned_int, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 931, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 931, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).velocity_y = __pyx_t_30;
 0932: 
 0933:             # soil flow
+0934:             water_flow[x][y].resize(4, EMPTY_WATER)
      try {
        ((__pyx_v_water_flow[__pyx_v_x])[__pyx_v_y]).resize(4, __pyx_v_6eroder_EMPTY_WATER);
      } catch(...) {
        __Pyx_CppExn2PyErr();
        __PYX_ERR(0, 934, __pyx_L1_error)
      }
+0935:             soil_flow[x][y].resize(3)
      try {
        ((__pyx_v_soil_flow[__pyx_v_x])[__pyx_v_y]).resize(3);
      } catch(...) {
        __Pyx_CppExn2PyErr();
        __PYX_ERR(0, 935, __pyx_L1_error)
      }
+0936:             for i in range(3):
      for (__pyx_t_32 = 0; __pyx_t_32 < 3; __pyx_t_32+=1) {
        __pyx_v_i = __pyx_t_32;
+0937:                 soil_flow[x][y][i].resize(3)
        try {
          (((__pyx_v_soil_flow[__pyx_v_x])[__pyx_v_y])[__pyx_v_i]).resize(3);
        } catch(...) {
          __Pyx_CppExn2PyErr();
          __PYX_ERR(0, 937, __pyx_L1_error)
        }
      }
 0938: 
 0939:             # init terrain
+0940:             terrain[x][y].topsoil.organic = _topsoil[x + size_x * y][ORGANIC]
      if (unlikely(__pyx_v__topsoil == Py_None)) {
        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
        __PYX_ERR(0, 940, __pyx_L1_error)
      }
      __pyx_t_32 = (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y));
      __pyx_t_3 = __Pyx_GetItemInt(PyList_GET_ITEM(__pyx_v__topsoil, __pyx_t_32), __pyx_v_6eroder_ORGANIC, int, 1, __Pyx_PyInt_From_int, 0, 1, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 940, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 940, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      ((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil.organic = __pyx_t_30;
+0941:             for i in range(4):
      for (__pyx_t_32 = 0; __pyx_t_32 < 4; __pyx_t_32+=1) {
        __pyx_v_i = __pyx_t_32;
+0942:                 terrain[x][y].topsoil.rocks[i] = _topsoil[x + size_x * y][i]
        if (unlikely(__pyx_v__topsoil == Py_None)) {
          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
          __PYX_ERR(0, 942, __pyx_L1_error)
        }
        __pyx_t_33 = (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y));
        __pyx_t_3 = __Pyx_GetItemInt(PyList_GET_ITEM(__pyx_v__topsoil, __pyx_t_33), __pyx_v_i, unsigned int, 0, __Pyx_PyInt_From_unsigned_int, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 942, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 942, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        (((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil.rocks[__pyx_v_i]) = __pyx_t_30;
      }
 0943: 
+0944:             terrain[x][y].subsoil.organic = _subsoil[x + size_x * y][ORGANIC]
      if (unlikely(__pyx_v__subsoil == Py_None)) {
        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
        __PYX_ERR(0, 944, __pyx_L1_error)
      }
      __pyx_t_32 = (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y));
      __pyx_t_3 = __Pyx_GetItemInt(PyList_GET_ITEM(__pyx_v__subsoil, __pyx_t_32), __pyx_v_6eroder_ORGANIC, int, 1, __Pyx_PyInt_From_int, 0, 1, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 944, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 944, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      ((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil.organic = __pyx_t_30;
+0945:             for i in range(4):
      for (__pyx_t_32 = 0; __pyx_t_32 < 4; __pyx_t_32+=1) {
        __pyx_v_i = __pyx_t_32;
+0946:                 terrain[x][y].subsoil.rocks[i] = _subsoil[x + size_x * y][i]
        if (unlikely(__pyx_v__subsoil == Py_None)) {
          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
          __PYX_ERR(0, 946, __pyx_L1_error)
        }
        __pyx_t_33 = (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y));
        __pyx_t_3 = __Pyx_GetItemInt(PyList_GET_ITEM(__pyx_v__subsoil, __pyx_t_33), __pyx_v_i, unsigned int, 0, __Pyx_PyInt_From_unsigned_int, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 946, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 946, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        (((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil.rocks[__pyx_v_i]) = __pyx_t_30;
      }
 0947: 
+0948:             vector_size = len(_bedrock[x + size_x * y])
      if (unlikely(__pyx_v__bedrock == Py_None)) {
        PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
        __PYX_ERR(0, 948, __pyx_L1_error)
      }
      __pyx_t_32 = (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y));
      __pyx_t_3 = PyList_GET_ITEM(__pyx_v__bedrock, __pyx_t_32);
      __Pyx_INCREF(__pyx_t_3);
      __pyx_t_34 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_34 == ((Py_ssize_t)-1))) __PYX_ERR(0, 948, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_v_vector_size = __pyx_t_34;
+0949:             terrain[x][y].bedrock.resize(vector_size)
      try {
        ((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock.resize(__pyx_v_vector_size);
      } catch(...) {
        __Pyx_CppExn2PyErr();
        __PYX_ERR(0, 949, __pyx_L1_error)
      }
+0950:             for i in range(vector_size):
      __pyx_t_34 = __pyx_v_vector_size;
      __pyx_t_35 = __pyx_t_34;
      for (__pyx_t_32 = 0; __pyx_t_32 < __pyx_t_35; __pyx_t_32+=1) {
        __pyx_v_i = __pyx_t_32;
+0951:                 terrain[x][y].bedrock[i].type = round(_bedrock_types[i])
        if (unlikely(__pyx_v__bedrock_types == Py_None)) {
          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
          __PYX_ERR(0, 951, __pyx_L1_error)
        }
        __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_round, PyList_GET_ITEM(__pyx_v__bedrock_types, __pyx_v_i)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 951, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __pyx_t_36 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_36 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 951, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        (((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock[__pyx_v_i]).type = __pyx_t_36;
+0952:                 terrain[x][y].bedrock[i].height = _bedrock[x + size_x * y][i]
        if (unlikely(__pyx_v__bedrock == Py_None)) {
          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
          __PYX_ERR(0, 952, __pyx_L1_error)
        }
        __pyx_t_33 = (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y));
        __pyx_t_3 = __Pyx_GetItemInt(PyList_GET_ITEM(__pyx_v__bedrock, __pyx_t_33), __pyx_v_i, unsigned int, 0, __Pyx_PyInt_From_unsigned_int, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 952, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 952, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        (((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock[__pyx_v_i]).height = __pyx_t_30;
      }
    }
  }
 0953: 
 0954:     # timing
+0955:     cdef time_t time_start = time(NULL)
  __pyx_v_time_start = time(NULL);
 0956: 
+0957:     for step in range(steps):
  __pyx_t_17 = __pyx_v_steps;
  __pyx_t_18 = __pyx_t_17;
  for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
    __pyx_v_step = __pyx_t_19;
+0958:         print("step no. " + str(step))
    __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_step); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 958, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_4 = __Pyx_PyObject_Str(__pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 958, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_3 = PyNumber_Add(__pyx_kp_u_step_no, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 958, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 958, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 0959: 
 0960:         ######################################################
 0961:         # RIVER MODE
 0962:         ######################################################
 0963: 
+0964:         if is_river:
    if (__pyx_v_is_river) {
/* … */
    }
 0965:             # source
+0966:             water[size_x / 2][size_y / 16].height = source_height
      ((__pyx_v_water[(((long)__pyx_v_size_x) / 2)])[(((long)__pyx_v_size_y) / 16)]).height = __pyx_v_source_height;
 0967: 
+0968:             for x in prange(size_x, nogil=True, schedule='dynamic', chunksize=1):
      {
          #ifdef WITH_THREAD
          PyThreadState *_save;
          _save = NULL;
          Py_UNBLOCK_THREADS
          __Pyx_FastGIL_Remember();
          #endif
          /*try:*/ {
            __pyx_t_27 = __pyx_v_size_x;
            {
                #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
                    #undef likely
                    #undef unlikely
                    #define likely(x)   (x)
                    #define unlikely(x) (x)
                #endif
                __pyx_t_29 = (__pyx_t_27 - 0 + 1 - 1/abs(1)) / 1;
                if (__pyx_t_29 > 0)
                {
                    #ifdef _OPENMP
                    #pragma omp parallel
                    #endif /* _OPENMP */
                    {
                        #ifdef _OPENMP
                        #pragma omp for firstprivate(__pyx_v_x) lastprivate(__pyx_v_x) lastprivate(__pyx_v_y)            __pyx_t_27 = __pyx_v_size_x;
            {
                #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
                    #undef likely
                    #undef unlikely
                    #define likely(x)   (x)
                    #define unlikely(x) (x)
                #endif
                __pyx_t_29 = (__pyx_t_27 - 0 + 1 - 1/abs(1)) / 1;
                if (__pyx_t_29 > 0)
                {
                    #ifdef _OPENMP
                    #pragma omp parallel
                    #endif /* _OPENMP */
                    {
                        #ifdef _OPENMP
                        #pragma omp for firstprivate(__pyx_v_x) lastprivate(__pyx_v_x) lastprivate(__pyx_v_y) schedule(dynamic, __pyx_t_36)
                        #endif /* _OPENMP */
                        for (__pyx_t_28 = 0; __pyx_t_28 < __pyx_t_29; __pyx_t_28++){
                            {
                                __pyx_v_x = (unsigned int)(0 + 1 * __pyx_t_28);
                                /* Initialize private variables to invalid values */
                                __pyx_v_y = ((unsigned int)0xbad0bad0);
/* … */
          /*finally:*/ {
            /*normal exit:*/{
              #ifdef WITH_THREAD
              __Pyx_FastGIL_Forget();
              Py_BLOCK_THREADS
              #endif
              goto __pyx_L27;
            }
            __pyx_L27:;
          }
      }
+0969:                 for y in range(15 * size_y / 16, size_y):
                                __pyx_t_32 = __pyx_v_size_y;
                                __pyx_t_33 = __pyx_t_32;
                                for (__pyx_t_37 = ((15 * __pyx_v_size_y) / 16); __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
                                  __pyx_v_y = __pyx_t_37;
+0970:                     water[x][y] = EMPTY_WATER
                                  ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]) = __pyx_v_6eroder_EMPTY_WATER;
                                }
                            }
                        }
                    }
                }
            }
            #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
                #undef likely
                #undef unlikely
                #define likely(x)   __builtin_expect(!!(x), 1)
                #define unlikely(x) __builtin_expect(!!(x), 0)
            #endif
          }
 0971: 
 0972: 
 0973:         ######################################################
 0974:         # DOWNHILL CREEP
 0975:         ######################################################
 0976: 
+0977:         downhill_creep(size_x, size_y, delta_t, downhill_creep_constant, terrain, heightmap)
    __pyx_f_6eroder_downhill_creep(__pyx_v_size_x, __pyx_v_size_y, __pyx_v_delta_t, __pyx_v_downhill_creep_constant, __pyx_v_terrain, ((__Pyx_memviewslice &)__pyx_v_heightmap));
 0978: 
 0979:         ######################################################
 0980:         # GRAVITATIONAL EROSION
 0981:         ######################################################
 0982: 
+0983:         gravitational_erosion(size_x, size_y, delta_t, downhill_creep_constant, terrain, heightmap, vegetation)
    __pyx_f_6eroder_gravitational_erosion(__pyx_v_size_x, __pyx_v_size_y, __pyx_v_delta_t, __pyx_v_downhill_creep_constant, __pyx_v_terrain, ((__Pyx_memviewslice &)__pyx_v_heightmap), ((__Pyx_memviewslice &)__pyx_v_vegetation));
 0984: 
 0985:         ######################################################
 0986:         # MOVE WATER
 0987:         ######################################################
 0988: 
+0989:         for x in range(size_x):
    __pyx_t_29 = __pyx_v_size_x;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_x = __pyx_t_27;
+0990:             for y in range(size_y):
      __pyx_t_32 = __pyx_v_size_y;
      __pyx_t_33 = __pyx_t_32;
      for (__pyx_t_37 = 0; __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
        __pyx_v_y = __pyx_t_37;
+0991:                 water2[x][y] = EMPTY_WATER
        ((__pyx_v_water2[__pyx_v_x])[__pyx_v_y]) = __pyx_v_6eroder_EMPTY_WATER;
+0992:                 for i in range(4):
        for (__pyx_t_38 = 0; __pyx_t_38 < 4; __pyx_t_38+=1) {
          __pyx_v_i = __pyx_t_38;
+0993:                     water_flow[x][y][i] = EMPTY_WATER
          (((__pyx_v_water_flow[__pyx_v_x])[__pyx_v_y])[__pyx_v_i]) = __pyx_v_6eroder_EMPTY_WATER;
        }
      }
    }
 0994: 
+0995:         for x in range(size_x):
    __pyx_t_29 = __pyx_v_size_x;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_x = __pyx_t_27;
+0996:             for y in range(size_y):
      __pyx_t_32 = __pyx_v_size_y;
      __pyx_t_33 = __pyx_t_32;
      for (__pyx_t_37 = 0; __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
        __pyx_v_y = __pyx_t_37;
+0997:                 if water[x][y].height > 0:
        __pyx_t_31 = (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height > 0.0);
        if (__pyx_t_31) {
/* … */
        }
      }
    }
+0998:                     height_here = heightmap[x][y] + water[x][y].height
          __pyx_t_39 = __pyx_v_x;
          __pyx_t_40 = __pyx_v_y;
          __pyx_v_height_here = ((*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_39 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_40)) ))) + ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height);
+0999:                     acceleration = [0.0, 0.0, 0.0, 0.0]
          __pyx_t_4 = PyList_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 999, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_4);
          __Pyx_INCREF(__pyx_float_0_0);
          __Pyx_GIVEREF(__pyx_float_0_0);
          if (__Pyx_PyList_SET_ITEM(__pyx_t_4, 0, __pyx_float_0_0)) __PYX_ERR(0, 999, __pyx_L1_error);
          __Pyx_INCREF(__pyx_float_0_0);
          __Pyx_GIVEREF(__pyx_float_0_0);
          if (__Pyx_PyList_SET_ITEM(__pyx_t_4, 1, __pyx_float_0_0)) __PYX_ERR(0, 999, __pyx_L1_error);
          __Pyx_INCREF(__pyx_float_0_0);
          __Pyx_GIVEREF(__pyx_float_0_0);
          if (__Pyx_PyList_SET_ITEM(__pyx_t_4, 2, __pyx_float_0_0)) __PYX_ERR(0, 999, __pyx_L1_error);
          __Pyx_INCREF(__pyx_float_0_0);
          __Pyx_GIVEREF(__pyx_float_0_0);
          if (__Pyx_PyList_SET_ITEM(__pyx_t_4, 3, __pyx_float_0_0)) __PYX_ERR(0, 999, __pyx_L1_error);
          __Pyx_XDECREF_SET(__pyx_v_acceleration, ((PyObject*)__pyx_t_4));
          __pyx_t_4 = 0;
+1000:                     out_volume_sum = 0.0
          __pyx_v_out_volume_sum = 0.0;
 1001: 
 1002:                     # calculate the height differences with neighbors and flow
+1003:                     for i in range(4):
          for (__pyx_t_38 = 0; __pyx_t_38 < 4; __pyx_t_38+=1) {
            __pyx_v_i = __pyx_t_38;
 1004:                         #if (0 <= x + delta_x[i] < size_x) and (0 <= y + delta_y[i] < size_y):
+1005:                         height_neighbor = heightmap[mod(x + delta_x[i], size_x)][mod(y + delta_y[i], size_y)] + water[mod(x + delta_x[i], size_x)][mod(y + delta_y[i], size_y)].height
            __pyx_t_41 = __pyx_f_6eroder_mod((__pyx_v_x + (__pyx_v_delta_x[__pyx_v_i])), __pyx_v_size_x); if (unlikely(__pyx_t_41 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1005, __pyx_L1_error)
            __pyx_t_42 = __pyx_f_6eroder_mod((__pyx_v_y + (__pyx_v_delta_y[__pyx_v_i])), __pyx_v_size_y); if (unlikely(__pyx_t_42 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1005, __pyx_L1_error)
            __pyx_t_40 = __pyx_t_41;
            __pyx_t_39 = __pyx_t_42;
            __pyx_t_43 = __pyx_f_6eroder_mod((__pyx_v_x + (__pyx_v_delta_x[__pyx_v_i])), __pyx_v_size_x); if (unlikely(__pyx_t_43 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1005, __pyx_L1_error)
            __pyx_t_44 = __pyx_f_6eroder_mod((__pyx_v_y + (__pyx_v_delta_y[__pyx_v_i])), __pyx_v_size_y); if (unlikely(__pyx_t_44 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1005, __pyx_L1_error)
            __pyx_v_height_neighbor = ((*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_40 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_39)) ))) + ((__pyx_v_water[__pyx_t_43])[__pyx_t_44]).height);
+1006:                         delta_height = height_here - height_neighbor
            __pyx_v_delta_height = (__pyx_v_height_here - __pyx_v_height_neighbor);
+1007:                         acceleration[i] = g * delta_height / length
            __pyx_t_4 = PyFloat_FromDouble(((__pyx_v_6eroder_g * __pyx_v_delta_height) / __pyx_v_6eroder_length)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1007, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_4);
            if (unlikely((__Pyx_SetItemInt(__pyx_v_acceleration, __pyx_v_i, __pyx_t_4, unsigned int, 0, __Pyx_PyInt_From_unsigned_int, 1, 0, 0) < 0))) __PYX_ERR(0, 1007, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 1008: 
+1009:                         velocity_in_direction = max(0.0, water[x][y].velocity_x*delta_x[i] + water[x][y].velocity_y*delta_y[i])
            __pyx_t_30 = ((((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).velocity_x * (__pyx_v_delta_x[__pyx_v_i])) + (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).velocity_y * (__pyx_v_delta_y[__pyx_v_i])));
            __pyx_t_45 = 0.0;
            __pyx_t_31 = (__pyx_t_30 > __pyx_t_45);
            if (__pyx_t_31) {
              __pyx_t_46 = __pyx_t_30;
            } else {
              __pyx_t_46 = __pyx_t_45;
            }
            __pyx_t_4 = PyFloat_FromDouble(__pyx_t_46); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1009, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_4);
            __Pyx_XDECREF_SET(__pyx_v_velocity_in_direction, __pyx_t_4);
            __pyx_t_4 = 0;
+1010:                         flow[x][y][i] = max(0.0, flow[x][y][i] + ((delta_t * acceleration[i]) * length * length))
            __pyx_t_39 = __pyx_v_x;
            __pyx_t_40 = __pyx_v_y;
            __pyx_t_47 = __pyx_v_i;
            __pyx_t_4 = PyFloat_FromDouble((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_39 * __pyx_v_flow.strides[0]) ) + __pyx_t_40 * __pyx_v_flow.strides[1]) ) + __pyx_t_47 * __pyx_v_flow.strides[2]) )))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1010, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_4);
            __pyx_t_3 = PyFloat_FromDouble(__pyx_v_delta_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1010, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __pyx_t_2 = PyNumber_Multiply(__pyx_t_3, PyList_GET_ITEM(__pyx_v_acceleration, __pyx_v_i)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1010, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __pyx_t_3 = PyFloat_FromDouble(__pyx_v_6eroder_length); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1010, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __pyx_t_5 = PyNumber_Multiply(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1010, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __pyx_t_3 = PyFloat_FromDouble(__pyx_v_6eroder_length); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1010, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __pyx_t_2 = PyNumber_Multiply(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1010, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __pyx_t_3 = PyNumber_Add(__pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1010, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __pyx_t_46 = 0.0;
            __pyx_t_4 = PyFloat_FromDouble(__pyx_t_46); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1010, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_4);
            __pyx_t_5 = PyObject_RichCompare(__pyx_t_3, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1010, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
            __pyx_t_31 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_31 < 0))) __PYX_ERR(0, 1010, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            if (__pyx_t_31) {
              __Pyx_INCREF(__pyx_t_3);
              __pyx_t_2 = __pyx_t_3;
            } else {
              __pyx_t_5 = PyFloat_FromDouble(__pyx_t_46); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1010, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_5);
              __pyx_t_2 = __pyx_t_5;
              __pyx_t_5 = 0;
            }
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __pyx_t_46 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_46 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1010, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __pyx_t_47 = __pyx_v_x;
            __pyx_t_40 = __pyx_v_y;
            __pyx_t_39 = __pyx_v_i;
            *((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_47 * __pyx_v_flow.strides[0]) ) + __pyx_t_40 * __pyx_v_flow.strides[1]) ) + __pyx_t_39 * __pyx_v_flow.strides[2]) )) = __pyx_t_46;
+1011:                         out_volume_sum += delta_t * flow[x][y][i]
            __pyx_t_39 = __pyx_v_x;
            __pyx_t_40 = __pyx_v_y;
            __pyx_t_47 = __pyx_v_i;
            __pyx_v_out_volume_sum = (__pyx_v_out_volume_sum + (__pyx_v_delta_t * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_39 * __pyx_v_flow.strides[0]) ) + __pyx_t_40 * __pyx_v_flow.strides[1]) ) + __pyx_t_47 * __pyx_v_flow.strides[2]) )))));
          }
 1012: 
 1013:                         """ if velocity_in_direction > 0:
 1014:                             print(velocity_in_direction) """
 1015: 
 1016:                     # scale flow
+1017:                     scaling = 1.0
          __pyx_v_scaling = 1.0;
+1018:                     column_water = length * length * water[x][y].height
          __pyx_v_column_water = ((__pyx_v_6eroder_length * __pyx_v_6eroder_length) * ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height);
 1019: 
+1020:                     if out_volume_sum > column_water and out_volume_sum > 0:
          __pyx_t_48 = (__pyx_v_out_volume_sum > __pyx_v_column_water);
          if (__pyx_t_48) {
          } else {
            __pyx_t_31 = __pyx_t_48;
            goto __pyx_L50_bool_binop_done;
          }
          __pyx_t_48 = (__pyx_v_out_volume_sum > 0.0);
          __pyx_t_31 = __pyx_t_48;
          __pyx_L50_bool_binop_done:;
          if (__pyx_t_31) {
/* … */
          }
+1021:                         scaling = column_water / out_volume_sum
            __pyx_v_scaling = (__pyx_v_column_water / __pyx_v_out_volume_sum);
+1022:                         out_volume_sum = column_water
            __pyx_v_out_volume_sum = __pyx_v_column_water;
 1023: 
 1024:                     # add to neighbors
+1025:                     for i in range(4):
          for (__pyx_t_38 = 0; __pyx_t_38 < 4; __pyx_t_38+=1) {
            __pyx_v_i = __pyx_t_38;
+1026:                         flow[x][y][i] *= scaling
            __pyx_t_47 = __pyx_v_x;
            __pyx_t_40 = __pyx_v_y;
            __pyx_t_39 = __pyx_v_i;
            *((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_47 * __pyx_v_flow.strides[0]) ) + __pyx_t_40 * __pyx_v_flow.strides[1]) ) + __pyx_t_39 * __pyx_v_flow.strides[2]) )) *= __pyx_v_scaling;
 1027: 
+1028:                         delta_v_x = delta_t * acceleration[i] * delta_x[i]
            __pyx_t_2 = PyFloat_FromDouble(__pyx_v_delta_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1028, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __pyx_t_3 = PyNumber_Multiply(__pyx_t_2, PyList_GET_ITEM(__pyx_v_acceleration, __pyx_v_i)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1028, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __pyx_t_2 = __Pyx_PyInt_From_int((__pyx_v_delta_x[__pyx_v_i])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1028, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __pyx_t_5 = PyNumber_Multiply(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1028, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __Pyx_XDECREF_SET(__pyx_v_delta_v_x, __pyx_t_5);
            __pyx_t_5 = 0;
+1029:                         delta_v_y = delta_t * acceleration[i] * delta_y[i]
            __pyx_t_5 = PyFloat_FromDouble(__pyx_v_delta_t); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1029, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __pyx_t_2 = PyNumber_Multiply(__pyx_t_5, PyList_GET_ITEM(__pyx_v_acceleration, __pyx_v_i)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1029, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            __pyx_t_5 = __Pyx_PyInt_From_int((__pyx_v_delta_y[__pyx_v_i])); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1029, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __pyx_t_3 = PyNumber_Multiply(__pyx_t_2, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1029, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            __Pyx_XDECREF_SET(__pyx_v_delta_v_y, __pyx_t_3);
            __pyx_t_3 = 0;
 1030: 
 1031:                         # move sediment
+1032:                         fraction = flow[x][y][i] * delta_t / column_water
            __pyx_t_39 = __pyx_v_x;
            __pyx_t_40 = __pyx_v_y;
            __pyx_t_47 = __pyx_v_i;
            __pyx_v_fraction = (((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_flow.data + __pyx_t_39 * __pyx_v_flow.strides[0]) ) + __pyx_t_40 * __pyx_v_flow.strides[1]) ) + __pyx_t_47 * __pyx_v_flow.strides[2]) ))) * __pyx_v_delta_t) / __pyx_v_column_water);
+1033:                         water_flow[x][y][i] = speedup(water_fraction(water[x][y], fraction), delta_v_x, delta_v_y)
            __pyx_t_46 = __pyx_PyFloat_AsDouble(__pyx_v_delta_v_x); if (unlikely((__pyx_t_46 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1033, __pyx_L1_error)
            __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_v_delta_v_y); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1033, __pyx_L1_error)
            (((__pyx_v_water_flow[__pyx_v_x])[__pyx_v_y])[__pyx_v_i]) = __pyx_f_6eroder_speedup(__pyx_f_6eroder_water_fraction(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]), __pyx_v_fraction), __pyx_t_46, __pyx_t_30);
          }
 1034:                     # what remains here
+1035:                     add_to_water(water2[x][y], water_fraction(water[x][y], 1 - out_volume_sum/column_water))
          __pyx_f_6eroder_add_to_water(((__pyx_v_water2[__pyx_v_x])[__pyx_v_y]), __pyx_f_6eroder_water_fraction(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]), (1.0 - (__pyx_v_out_volume_sum / __pyx_v_column_water))));
 1036: 
 1037: 
 1038:         # assign
+1039:         for x in range(size_x):
    __pyx_t_29 = __pyx_v_size_x;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_x = __pyx_t_27;
+1040:             for y in range(size_y):
      __pyx_t_32 = __pyx_v_size_y;
      __pyx_t_33 = __pyx_t_32;
      for (__pyx_t_37 = 0; __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
        __pyx_v_y = __pyx_t_37;
+1041:                 for i in range(4):
        for (__pyx_t_38 = 0; __pyx_t_38 < 4; __pyx_t_38+=1) {
          __pyx_v_i = __pyx_t_38;
+1042:                     add_to_water(water2[x][y], water_flow[mod(x - delta_x[i], size_x)][mod(y - delta_y[i], size_y)][i])
          __pyx_t_44 = __pyx_f_6eroder_mod((__pyx_v_x - (__pyx_v_delta_x[__pyx_v_i])), __pyx_v_size_x); if (unlikely(__pyx_t_44 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1042, __pyx_L1_error)
          __pyx_t_43 = __pyx_f_6eroder_mod((__pyx_v_y - (__pyx_v_delta_y[__pyx_v_i])), __pyx_v_size_y); if (unlikely(__pyx_t_43 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1042, __pyx_L1_error)
          __pyx_f_6eroder_add_to_water(((__pyx_v_water2[__pyx_v_x])[__pyx_v_y]), (((__pyx_v_water_flow[__pyx_t_44])[__pyx_t_43])[__pyx_v_i]));
        }
 1043: 
+1044:                 previous = water[x][y].height
        __pyx_t_30 = ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height;
        __pyx_v_previous = __pyx_t_30;
+1045:                 water[x][y] = water2[x][y]
        ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]) = ((__pyx_v_water2[__pyx_v_x])[__pyx_v_y]);
+1046:                 water[x][y].previous = previous
        ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).previous = __pyx_v_previous;
+1047:                 slow_down(water[x][y])
        __pyx_f_6eroder_slow_down(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]));
      }
    }
 1048: 
 1049: 
 1050:         ######################################################
 1051:         # FORCE EROSION
 1052:         ######################################################
+1053:         for x in range(size_x):
    __pyx_t_29 = __pyx_v_size_x;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_x = __pyx_t_27;
+1054:             for y in range(size_y):
      __pyx_t_32 = __pyx_v_size_y;
      __pyx_t_33 = __pyx_t_32;
      for (__pyx_t_37 = 0; __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
        __pyx_v_y = __pyx_t_37;
+1055:                 if water[x][y].height > 0:
        __pyx_t_31 = (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height > 0.0);
        if (__pyx_t_31) {
/* … */
        }
      }
    }
+1056:                     average_height = 0.5 * (water[x][y].height + water[x][y].previous)
          __pyx_v_average_height = (0.5 * (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height + ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).previous));
 1057: 
 1058:                     # this max function doesn't really have a physical basis, but it makes sure that small amounts of water don't erode ridiculous amounts
+1059:                     average_height = max(average_height, 0.05) # 0.05
          __pyx_t_30 = 0.05;
          __pyx_t_46 = __pyx_v_average_height;
          __pyx_t_31 = (__pyx_t_30 > __pyx_t_46);
          if (__pyx_t_31) {
            __pyx_t_45 = __pyx_t_30;
          } else {
            __pyx_t_45 = __pyx_t_46;
          }
          __pyx_v_average_height = __pyx_t_45;
 1060: 
+1061:                     flow_velocity = water_velocity(x, y, size_x, size_y, flow) / (length * average_height)
          __pyx_v_flow_velocity = (__pyx_f_6eroder_water_velocity(__pyx_v_x, __pyx_v_y, __pyx_v_size_x, __pyx_v_size_y, __pyx_v_flow) / (__pyx_v_6eroder_length * __pyx_v_average_height));
 1062: 
 1063:                     # steepness and convexness
 1064:                     #local_shape_factor = max(0.0, 1.0 * max(0.05, get_steepness(x, y, size_x, size_y, heightmap)) + 0.0 * get_convexness(x, y, size_x, size_y, heightmap))
 1065:                     # no erosion_constant
+1066:                     water_info = erosion_constant * flow_velocity * max(0.05, get_steepness(x, y, size_x, size_y, heightmap)) * max_erosion_depth(water[x][y].height) * (1 / (1 + 0.2 * vegetation[x][y]))
          __pyx_t_45 = __pyx_f_6eroder_get_steepness(__pyx_v_x, __pyx_v_y, __pyx_v_size_x, __pyx_v_size_y, __pyx_v_heightmap);
          __pyx_t_30 = 0.05;
          __pyx_t_31 = (__pyx_t_45 > __pyx_t_30);
          if (__pyx_t_31) {
            __pyx_t_46 = __pyx_t_45;
          } else {
            __pyx_t_46 = __pyx_t_30;
          }
          __pyx_t_47 = __pyx_v_x;
          __pyx_t_40 = __pyx_v_y;
          __pyx_v_water_info = ((((__pyx_v_erosion_constant * __pyx_v_flow_velocity) * __pyx_t_46) * __pyx_f_6eroder_max_erosion_depth(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height)) * (1.0 / (1.0 + (0.2 * (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_47 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_40)) )))))));
 1067: 
 1068:                     # organic
+1069:                     sediment_capacity = organic_constant * water_info
          __pyx_t_3 = PyFloat_FromDouble((__pyx_v_6eroder_organic_constant * __pyx_v_water_info)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1069, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          __Pyx_XDECREF_SET(__pyx_v_sediment_capacity, __pyx_t_3);
          __pyx_t_3 = 0;
+1070:                     if water[x][y].sediment.organic <= sediment_capacity:
          __pyx_t_3 = PyFloat_FromDouble(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).sediment.organic); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1070, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          __pyx_t_5 = PyObject_RichCompare(__pyx_t_3, __pyx_v_sediment_capacity, Py_LE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1070, __pyx_L1_error)
          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
          __pyx_t_31 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_31 < 0))) __PYX_ERR(0, 1070, __pyx_L1_error)
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          if (__pyx_t_31) {
/* … */
            goto __pyx_L65;
          }
 1071:                         # erode
+1072:                         requested_amount = K_EROSION * (sediment_capacity - water[x][y].sediment.organic)
            __pyx_t_5 = PyFloat_FromDouble(__pyx_v_6eroder_K_EROSION); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1072, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __pyx_t_3 = PyFloat_FromDouble(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).sediment.organic); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1072, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __pyx_t_2 = PyNumber_Subtract(__pyx_v_sediment_capacity, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1072, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __pyx_t_3 = PyNumber_Multiply(__pyx_t_5, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1072, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __Pyx_XDECREF_SET(__pyx_v_requested_amount, __pyx_t_3);
            __pyx_t_3 = 0;
+1073:                         amount = erode_organic_amount(terrain[x][y], requested_amount)
            __pyx_t_46 = __pyx_PyFloat_AsDouble(__pyx_v_requested_amount); if (unlikely((__pyx_t_46 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1073, __pyx_L1_error)
            __pyx_t_3 = PyFloat_FromDouble(__pyx_f_6eroder_erode_organic_amount(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]), __pyx_t_46)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1073, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __Pyx_XDECREF_SET(__pyx_v_amount, __pyx_t_3);
            __pyx_t_3 = 0;
+1074:                         heightmap[x][y] -= amount
            __pyx_t_46 = __pyx_PyFloat_AsDouble(__pyx_v_amount); if (unlikely((__pyx_t_46 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1074, __pyx_L1_error)
            __pyx_t_40 = __pyx_v_x;
            __pyx_t_47 = __pyx_v_y;
            *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_40 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_47)) )) -= __pyx_t_46;
+1075:                         water[x][y].sediment.organic += amount
            __pyx_t_38 = __pyx_v_x;
            __pyx_t_43 = __pyx_v_y;
            __pyx_t_3 = PyFloat_FromDouble(((__pyx_v_water[__pyx_t_38])[__pyx_t_43]).sediment.organic); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1075, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_v_amount); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1075, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __pyx_t_46 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_46 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1075, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            ((__pyx_v_water[__pyx_t_38])[__pyx_t_43]).sediment.organic = __pyx_t_46;
 1076:                         #water[x][y] += amount
 1077:                     else:
 1078:                         # deposit
+1079:                         amount = K_DEPOSITION * (water[x][y].sediment.organic - sediment_capacity)
          /*else*/ {
            __pyx_t_2 = PyFloat_FromDouble(__pyx_v_6eroder_K_DEPOSITION); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1079, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __pyx_t_3 = PyFloat_FromDouble(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).sediment.organic); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1079, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __pyx_t_5 = PyNumber_Subtract(__pyx_t_3, __pyx_v_sediment_capacity); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1079, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __pyx_t_3 = PyNumber_Multiply(__pyx_t_2, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1079, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            __Pyx_XDECREF_SET(__pyx_v_amount, __pyx_t_3);
            __pyx_t_3 = 0;
+1080:                         soil = new_soil(amount, 0, 0, 0, 0)
            __pyx_t_46 = __pyx_PyFloat_AsDouble(__pyx_v_amount); if (unlikely((__pyx_t_46 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1080, __pyx_L1_error)
            __pyx_v_soil = __pyx_f_6eroder_new_soil(__pyx_t_46, 0.0, 0.0, 0.0, 0.0);
+1081:                         deposit_soil(terrain[x][y], soil)
            __pyx_f_6eroder_deposit_soil(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]), __pyx_v_soil);
+1082:                         heightmap[x][y] += amount
            __pyx_t_46 = __pyx_PyFloat_AsDouble(__pyx_v_amount); if (unlikely((__pyx_t_46 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1082, __pyx_L1_error)
            __pyx_t_47 = __pyx_v_x;
            __pyx_t_40 = __pyx_v_y;
            *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_47 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_40)) )) += __pyx_t_46;
+1083:                         water[x][y].sediment.organic -= amount
            __pyx_t_38 = __pyx_v_x;
            __pyx_t_43 = __pyx_v_y;
            __pyx_t_3 = PyFloat_FromDouble(((__pyx_v_water[__pyx_t_38])[__pyx_t_43]).sediment.organic); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1083, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __pyx_t_5 = PyNumber_InPlaceSubtract(__pyx_t_3, __pyx_v_amount); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1083, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __pyx_t_46 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_46 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1083, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            ((__pyx_v_water[__pyx_t_38])[__pyx_t_43]).sediment.organic = __pyx_t_46;
          }
          __pyx_L65:;
 1084:                         #water[x][y] -= amount
 1085: 
 1086:                     # erode rocks
+1087:                     for rock in range(4):
          for (__pyx_t_49 = 0; __pyx_t_49 < 4; __pyx_t_49+=1) {
            __pyx_v_rock = __pyx_t_49;
 1088:                         # erode
+1089:                         amount = erode_rocks_amount(terrain[x][y], water_info, rock)
            __pyx_t_5 = PyFloat_FromDouble(__pyx_f_6eroder_erode_rocks_amount(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]), __pyx_v_water_info, __pyx_v_rock)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1089, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __Pyx_DECREF_SET(__pyx_v_amount, __pyx_t_5);
            __pyx_t_5 = 0;
+1090:                         heightmap[x][y] -= amount
            __pyx_t_46 = __pyx_PyFloat_AsDouble(__pyx_v_amount); if (unlikely((__pyx_t_46 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1090, __pyx_L1_error)
            __pyx_t_40 = __pyx_v_x;
            __pyx_t_47 = __pyx_v_y;
            *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_40 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_47)) )) -= __pyx_t_46;
+1091:                         water[x][y].sediment.rocks[rock] += amount
            __pyx_t_38 = __pyx_v_x;
            __pyx_t_43 = __pyx_v_y;
            __pyx_t_50 = __pyx_v_rock;
            __pyx_t_5 = PyFloat_FromDouble((((__pyx_v_water[__pyx_t_38])[__pyx_t_43]).sediment.rocks[__pyx_t_50])); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1091, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_t_5, __pyx_v_amount); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1091, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            __pyx_t_46 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_46 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1091, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            (((__pyx_v_water[__pyx_t_38])[__pyx_t_43]).sediment.rocks[__pyx_t_50]) = __pyx_t_46;
          }
 1092:                         #water[x][y] += amount
 1093: 
 1094:                     # deposit rocks
+1095:                     for rock in range(4):
          for (__pyx_t_49 = 0; __pyx_t_49 < 4; __pyx_t_49+=1) {
            __pyx_v_rock = __pyx_t_49;
+1096:                         sediment_capacity = max(rock_matrix_linear[rock][rock] * water_info + rock_matrix_constant[rock][rock], 0.0)
            __pyx_t_46 = 0.0;
            __pyx_t_45 = ((((__pyx_v_6eroder_rock_matrix_linear[__pyx_v_rock])[__pyx_v_rock]) * __pyx_v_water_info) + ((__pyx_v_6eroder_rock_matrix_constant[__pyx_v_rock])[__pyx_v_rock]));
            __pyx_t_31 = (__pyx_t_46 > __pyx_t_45);
            if (__pyx_t_31) {
              __pyx_t_30 = __pyx_t_46;
            } else {
              __pyx_t_30 = __pyx_t_45;
            }
            __pyx_t_3 = PyFloat_FromDouble(__pyx_t_30); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1096, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __Pyx_DECREF_SET(__pyx_v_sediment_capacity, __pyx_t_3);
            __pyx_t_3 = 0;
+1097:                         if water[x][y].sediment.rocks[rock] > sediment_capacity:
            __pyx_t_3 = PyFloat_FromDouble((((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).sediment.rocks[__pyx_v_rock])); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1097, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __pyx_t_5 = PyObject_RichCompare(__pyx_t_3, __pyx_v_sediment_capacity, Py_GT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1097, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __pyx_t_31 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_31 < 0))) __PYX_ERR(0, 1097, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            if (__pyx_t_31) {
/* … */
            }
          }
 1098: 
 1099:                             # deposit
+1100:                             amount = K_DEPOSITION * (water[x][y].sediment.rocks[rock] - sediment_capacity)
              __pyx_t_5 = PyFloat_FromDouble(__pyx_v_6eroder_K_DEPOSITION); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1100, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_5);
              __pyx_t_3 = PyFloat_FromDouble((((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).sediment.rocks[__pyx_v_rock])); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1100, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_3);
              __pyx_t_2 = PyNumber_Subtract(__pyx_t_3, __pyx_v_sediment_capacity); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1100, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
              __pyx_t_3 = PyNumber_Multiply(__pyx_t_5, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1100, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_3);
              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
              __Pyx_DECREF_SET(__pyx_v_amount, __pyx_t_3);
              __pyx_t_3 = 0;
+1101:                             soil = new_soil_rock(amount, rock)
              __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_v_amount); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1101, __pyx_L1_error)
              __pyx_v_soil = __pyx_f_6eroder_new_soil_rock(__pyx_t_30, __pyx_v_rock);
+1102:                             deposit_soil(terrain[x][y], soil)
              __pyx_f_6eroder_deposit_soil(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]), __pyx_v_soil);
+1103:                             heightmap[x][y] += amount
              __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_v_amount); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1103, __pyx_L1_error)
              __pyx_t_47 = __pyx_v_x;
              __pyx_t_40 = __pyx_v_y;
              *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_47 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_40)) )) += __pyx_t_30;
+1104:                             water[x][y].sediment.rocks[rock] -= amount
              __pyx_t_38 = __pyx_v_x;
              __pyx_t_43 = __pyx_v_y;
              __pyx_t_50 = __pyx_v_rock;
              __pyx_t_3 = PyFloat_FromDouble((((__pyx_v_water[__pyx_t_38])[__pyx_t_43]).sediment.rocks[__pyx_t_50])); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1104, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_3);
              __pyx_t_2 = PyNumber_InPlaceSubtract(__pyx_t_3, __pyx_v_amount); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1104, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
              __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1104, __pyx_L1_error)
              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
              (((__pyx_v_water[__pyx_t_38])[__pyx_t_43]).sediment.rocks[__pyx_t_50]) = __pyx_t_30;
 1105:                             #water[x][y] -= amount
 1106: 
 1107: 
 1108:         ######################################################
 1109:         # INERTIAL EROSION
 1110:         ######################################################
+1111:         for x in range(size_x):
    __pyx_t_29 = __pyx_v_size_x;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_x = __pyx_t_27;
+1112:             for y in range(size_y):
      __pyx_t_32 = __pyx_v_size_y;
      __pyx_t_33 = __pyx_t_32;
      for (__pyx_t_37 = 0; __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
        __pyx_v_y = __pyx_t_37;
+1113:                 if water[x][y].height > 0.0:
        __pyx_t_31 = (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height > 0.0);
        if (__pyx_t_31) {
/* … */
        }
      }
    }
+1114:                     average_height = 0.5 * (water[x][y].height + water[x][y].previous)
          __pyx_v_average_height = (0.5 * (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height + ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).previous));
 1115: 
 1116:                     # this max function doesn't really have a physical basis, but it makes sure that small amounts of water don't erode ridiculous amounts
+1117:                     average_height = max(average_height, 0.05)
          __pyx_t_30 = 0.05;
          __pyx_t_46 = __pyx_v_average_height;
          __pyx_t_31 = (__pyx_t_30 > __pyx_t_46);
          if (__pyx_t_31) {
            __pyx_t_45 = __pyx_t_30;
          } else {
            __pyx_t_45 = __pyx_t_46;
          }
          __pyx_v_average_height = __pyx_t_45;
 1118: 
+1119:                     velocity = water_velocity_vector(x, y, size_x, size_y, flow) #/ (length * average_height)
          __pyx_t_2 = __pyx_convert__to_py___pyx_ctuple_double__and_double(__pyx_f_6eroder_water_velocity_vector(__pyx_v_x, __pyx_v_y, __pyx_v_size_x, __pyx_v_size_y, __pyx_v_flow)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1119, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_2);
          __Pyx_XDECREF_SET(__pyx_v_velocity, __pyx_t_2);
          __pyx_t_2 = 0;
 1120: 
 1121: 
 1122: 
+1123:                     water_top = heightmap[x][y] + water[x][y].height
          __pyx_t_40 = __pyx_v_x;
          __pyx_t_47 = __pyx_v_y;
          __pyx_v_water_top = ((*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_40 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_47)) ))) + ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height);
+1124:                     water_bottom = heightmap[x][y]
          __pyx_t_47 = __pyx_v_x;
          __pyx_t_40 = __pyx_v_y;
          __pyx_v_water_bottom = (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_47 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_40)) )));
 1125: 
+1126:                     for i in range(4):
          for (__pyx_t_38 = 0; __pyx_t_38 < 4; __pyx_t_38+=1) {
            __pyx_v_i = __pyx_t_38;
 1127:                         #velocity_in_direction = max(0.0, water[x][y].velocity_x*delta_x[i] + water[x][y].velocity_y*delta_y[i])
+1128:                         velocity_in_direction = max(0.0, velocity[0]*delta_x[i] + velocity[1]*delta_y[i])
            __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_velocity, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1128, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_delta_x[__pyx_v_i])); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1128, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __pyx_t_5 = PyNumber_Multiply(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1128, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_velocity, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1128, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __pyx_t_2 = __Pyx_PyInt_From_int((__pyx_v_delta_y[__pyx_v_i])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1128, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __pyx_t_4 = PyNumber_Multiply(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1128, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_4);
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __pyx_t_2 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1128, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
            __pyx_t_45 = 0.0;
            __pyx_t_5 = PyFloat_FromDouble(__pyx_t_45); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1128, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_t_5, Py_GT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1128, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            __pyx_t_31 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_31 < 0))) __PYX_ERR(0, 1128, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            if (__pyx_t_31) {
              __Pyx_INCREF(__pyx_t_2);
              __pyx_t_4 = __pyx_t_2;
            } else {
              __pyx_t_3 = PyFloat_FromDouble(__pyx_t_45); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1128, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_3);
              __pyx_t_4 = __pyx_t_3;
              __pyx_t_3 = 0;
            }
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __pyx_t_2 = __pyx_t_4;
            __Pyx_INCREF(__pyx_t_2);
            __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
            __Pyx_XDECREF_SET(__pyx_v_velocity_in_direction, __pyx_t_2);
            __pyx_t_2 = 0;
 1129: 
+1130:                         height_top = heightmap[mod(x + delta_x[i], size_x)][mod(y + delta_y[i], size_y)]
            __pyx_t_43 = __pyx_f_6eroder_mod((__pyx_v_x + (__pyx_v_delta_x[__pyx_v_i])), __pyx_v_size_x); if (unlikely(__pyx_t_43 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1130, __pyx_L1_error)
            __pyx_t_44 = __pyx_f_6eroder_mod((__pyx_v_y + (__pyx_v_delta_y[__pyx_v_i])), __pyx_v_size_y); if (unlikely(__pyx_t_44 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1130, __pyx_L1_error)
            __pyx_t_40 = __pyx_t_43;
            __pyx_t_47 = __pyx_t_44;
            __pyx_v_height_top = (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_40 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_47)) )));
+1131:                         height_bottom = height_top - get_soil_height(terrain[x][y].topsoil)
            __pyx_v_height_bottom = (__pyx_v_height_top - __pyx_f_6eroder_get_soil_height(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil));
 1132: 
 1133:                         # TOPSOIL
 1134:                         # calculate contact area
+1135:                         contact_top = min(water_top, height_top)
            __pyx_t_45 = __pyx_v_height_top;
            __pyx_t_30 = __pyx_v_water_top;
            __pyx_t_31 = (__pyx_t_45 < __pyx_t_30);
            if (__pyx_t_31) {
              __pyx_t_46 = __pyx_t_45;
            } else {
              __pyx_t_46 = __pyx_t_30;
            }
            __pyx_v_contact_top = __pyx_t_46;
+1136:                         contact_bottom = max(water_bottom, height_bottom)
            __pyx_t_46 = __pyx_v_height_bottom;
            __pyx_t_45 = __pyx_v_water_bottom;
            __pyx_t_31 = (__pyx_t_46 > __pyx_t_45);
            if (__pyx_t_31) {
              __pyx_t_30 = __pyx_t_46;
            } else {
              __pyx_t_30 = __pyx_t_45;
            }
            __pyx_v_contact_bottom = __pyx_t_30;
+1137:                         contact_area = max(0.0, contact_top - contact_bottom) * length
            __pyx_t_30 = (__pyx_v_contact_top - __pyx_v_contact_bottom);
            __pyx_t_46 = 0.0;
            __pyx_t_31 = (__pyx_t_30 > __pyx_t_46);
            if (__pyx_t_31) {
              __pyx_t_45 = __pyx_t_30;
            } else {
              __pyx_t_45 = __pyx_t_46;
            }
            __pyx_v_contact_area = (__pyx_t_45 * __pyx_v_6eroder_length);
 1138: 
+1139:                         erosion_capacity = inertial_erosion_constant * velocity_in_direction * contact_area  # / MAX_WATER_SPEED
            __pyx_t_2 = PyFloat_FromDouble(__pyx_v_inertial_erosion_constant); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1139, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __pyx_t_4 = PyNumber_Multiply(__pyx_t_2, __pyx_v_velocity_in_direction); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1139, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_4);
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __pyx_t_2 = PyFloat_FromDouble(__pyx_v_contact_area); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1139, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __pyx_t_3 = PyNumber_Multiply(__pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1139, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __Pyx_XDECREF_SET(__pyx_v_erosion_capacity, __pyx_t_3);
            __pyx_t_3 = 0;
 1140: 
+1141:                         if erosion_capacity > 0.0:
            __pyx_t_3 = PyObject_RichCompare(__pyx_v_erosion_capacity, __pyx_float_0_0, Py_GT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1141, __pyx_L1_error)
            __pyx_t_31 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_31 < 0))) __PYX_ERR(0, 1141, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            if (__pyx_t_31) {
/* … */
            }
          }
 1142: 
 1143:                             # organic
+1144:                             sediment_capacity = organic_constant * erosion_capacity
              __pyx_t_3 = PyFloat_FromDouble(__pyx_v_6eroder_organic_constant); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1144, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_3);
              __pyx_t_2 = PyNumber_Multiply(__pyx_t_3, __pyx_v_erosion_capacity); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1144, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
              __Pyx_XDECREF_SET(__pyx_v_sediment_capacity, __pyx_t_2);
              __pyx_t_2 = 0;
 1145:                             #if water[x][y].sediment.organic <= sediment_capacity:
 1146:                             # erode
+1147:                             requested_amount = K_IN_EROSION* sediment_capacity
              __pyx_t_2 = PyFloat_FromDouble(__pyx_v_6eroder_K_IN_EROSION); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1147, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __pyx_t_3 = PyNumber_Multiply(__pyx_t_2, __pyx_v_sediment_capacity); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1147, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_3);
              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
              __Pyx_XDECREF_SET(__pyx_v_requested_amount, __pyx_t_3);
              __pyx_t_3 = 0;
+1148:                             amount = erode_organic_amount_only_from(terrain[x][y].topsoil, requested_amount)
              __pyx_t_45 = __pyx_PyFloat_AsDouble(__pyx_v_requested_amount); if (unlikely((__pyx_t_45 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1148, __pyx_L1_error)
              __pyx_t_3 = PyFloat_FromDouble(__pyx_f_6eroder_erode_organic_amount_only_from(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil, __pyx_t_45)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1148, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_3);
              __Pyx_XDECREF_SET(__pyx_v_amount, __pyx_t_3);
              __pyx_t_3 = 0;
 1149: 
+1150:                             heightmap[mod(x + delta_x[i], size_x)][mod(y + delta_y[i], size_y)] -= amount
              __pyx_t_45 = __pyx_PyFloat_AsDouble(__pyx_v_amount); if (unlikely((__pyx_t_45 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1150, __pyx_L1_error)
              __pyx_t_44 = __pyx_f_6eroder_mod((__pyx_v_x + (__pyx_v_delta_x[__pyx_v_i])), __pyx_v_size_x); if (unlikely(__pyx_t_44 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1150, __pyx_L1_error)
              __pyx_t_43 = __pyx_f_6eroder_mod((__pyx_v_y + (__pyx_v_delta_y[__pyx_v_i])), __pyx_v_size_y); if (unlikely(__pyx_t_43 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1150, __pyx_L1_error)
              __pyx_t_47 = __pyx_t_44;
              __pyx_t_40 = __pyx_t_43;
              *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_47 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_40)) )) -= __pyx_t_45;
+1151:                             water[x][y].sediment.organic += amount
              __pyx_t_43 = __pyx_v_x;
              __pyx_t_44 = __pyx_v_y;
              __pyx_t_3 = PyFloat_FromDouble(((__pyx_v_water[__pyx_t_43])[__pyx_t_44]).sediment.organic); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1151, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_3);
              __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_v_amount); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1151, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
              __pyx_t_45 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_45 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1151, __pyx_L1_error)
              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
              ((__pyx_v_water[__pyx_t_43])[__pyx_t_44]).sediment.organic = __pyx_t_45;
 1152: 
 1153:                             # erode rocks
+1154:                             for original in range(4):
              for (__pyx_t_49 = 0; __pyx_t_49 < 4; __pyx_t_49+=1) {
                __pyx_v_original = __pyx_t_49;
+1155:                                 for sedimented in range(4):
                for (__pyx_t_50 = 0; __pyx_t_50 < 4; __pyx_t_50+=1) {
                  __pyx_v_sedimented = __pyx_t_50;
+1156:                                     sediment_capacity = max(rock_matrix_linear[original][sedimented] * erosion_capacity + rock_matrix_constant[original][sedimented], 0.0)
                  __pyx_t_45 = 0.0;
                  __pyx_t_2 = PyFloat_FromDouble(((__pyx_v_6eroder_rock_matrix_linear[__pyx_v_original])[__pyx_v_sedimented])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1156, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_2);
                  __pyx_t_3 = PyNumber_Multiply(__pyx_t_2, __pyx_v_erosion_capacity); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1156, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_3);
                  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
                  __pyx_t_2 = PyFloat_FromDouble(((__pyx_v_6eroder_rock_matrix_constant[__pyx_v_original])[__pyx_v_sedimented])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1156, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_2);
                  __pyx_t_4 = PyNumber_Add(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1156, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_4);
                  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
                  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
                  __pyx_t_3 = PyFloat_FromDouble(__pyx_t_45); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1156, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_3);
                  __pyx_t_5 = PyObject_RichCompare(__pyx_t_3, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1156, __pyx_L1_error)
                  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
                  __pyx_t_31 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_31 < 0))) __PYX_ERR(0, 1156, __pyx_L1_error)
                  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
                  if (__pyx_t_31) {
                    __pyx_t_5 = PyFloat_FromDouble(__pyx_t_45); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1156, __pyx_L1_error)
                    __Pyx_GOTREF(__pyx_t_5);
                    __pyx_t_2 = __pyx_t_5;
                    __pyx_t_5 = 0;
                  } else {
                    __Pyx_INCREF(__pyx_t_4);
                    __pyx_t_2 = __pyx_t_4;
                  }
                  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
                  __pyx_t_4 = __pyx_t_2;
                  __Pyx_INCREF(__pyx_t_4);
                  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
                  __Pyx_DECREF_SET(__pyx_v_sediment_capacity, __pyx_t_4);
                  __pyx_t_4 = 0;
 1157:                                     #if water[x][y].sediment.rocks[sedimented] <= sediment_capacity:
 1158:                                     # erode
+1159:                                     requested_amount = K_IN_EROSION * sediment_capacity
                  __pyx_t_4 = PyFloat_FromDouble(__pyx_v_6eroder_K_IN_EROSION); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1159, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_4);
                  __pyx_t_2 = PyNumber_Multiply(__pyx_t_4, __pyx_v_sediment_capacity); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1159, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_2);
                  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
                  __Pyx_DECREF_SET(__pyx_v_requested_amount, __pyx_t_2);
                  __pyx_t_2 = 0;
+1160:                                     amount = erode_rocks_amount_only_from(terrain[x][y].topsoil, requested_amount, original)
                  __pyx_t_45 = __pyx_PyFloat_AsDouble(__pyx_v_requested_amount); if (unlikely((__pyx_t_45 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1160, __pyx_L1_error)
                  __pyx_t_2 = PyFloat_FromDouble(__pyx_f_6eroder_erode_rocks_amount_only_from(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil, __pyx_t_45, __pyx_v_original)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1160, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_2);
                  __Pyx_DECREF_SET(__pyx_v_amount, __pyx_t_2);
                  __pyx_t_2 = 0;
+1161:                                     heightmap[mod(x + delta_x[i], size_x)][mod(y + delta_y[i], size_y)] -= amount
                  __pyx_t_45 = __pyx_PyFloat_AsDouble(__pyx_v_amount); if (unlikely((__pyx_t_45 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1161, __pyx_L1_error)
                  __pyx_t_43 = __pyx_f_6eroder_mod((__pyx_v_x + (__pyx_v_delta_x[__pyx_v_i])), __pyx_v_size_x); if (unlikely(__pyx_t_43 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1161, __pyx_L1_error)
                  __pyx_t_44 = __pyx_f_6eroder_mod((__pyx_v_y + (__pyx_v_delta_y[__pyx_v_i])), __pyx_v_size_y); if (unlikely(__pyx_t_44 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1161, __pyx_L1_error)
                  __pyx_t_40 = __pyx_t_43;
                  __pyx_t_47 = __pyx_t_44;
                  *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_40 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_47)) )) -= __pyx_t_45;
+1162:                                     water[x][y].sediment.rocks[sedimented] += amount
                  __pyx_t_44 = __pyx_v_x;
                  __pyx_t_43 = __pyx_v_y;
                  __pyx_t_51 = __pyx_v_sedimented;
                  __pyx_t_2 = PyFloat_FromDouble((((__pyx_v_water[__pyx_t_44])[__pyx_t_43]).sediment.rocks[__pyx_t_51])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1162, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_2);
                  __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_v_amount); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1162, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_4);
                  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
                  __pyx_t_45 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_45 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1162, __pyx_L1_error)
                  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
                  (((__pyx_v_water[__pyx_t_44])[__pyx_t_43]).sediment.rocks[__pyx_t_51]) = __pyx_t_45;
                }
              }
 1163: 
 1164:                             # SUBSOIL
 1165:                             # calculate contact area
+1166:                             contact_top = min(water_top, height_bottom)
              __pyx_t_45 = __pyx_v_height_bottom;
              __pyx_t_30 = __pyx_v_water_top;
              __pyx_t_31 = (__pyx_t_45 < __pyx_t_30);
              if (__pyx_t_31) {
                __pyx_t_46 = __pyx_t_45;
              } else {
                __pyx_t_46 = __pyx_t_30;
              }
              __pyx_v_contact_top = __pyx_t_46;
+1167:                             contact_bottom = max(water_bottom, height_bottom - get_soil_height(terrain[x][y].subsoil))
              __pyx_t_46 = (__pyx_v_height_bottom - __pyx_f_6eroder_get_soil_height(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil));
              __pyx_t_45 = __pyx_v_water_bottom;
              __pyx_t_31 = (__pyx_t_46 > __pyx_t_45);
              if (__pyx_t_31) {
                __pyx_t_30 = __pyx_t_46;
              } else {
                __pyx_t_30 = __pyx_t_45;
              }
              __pyx_v_contact_bottom = __pyx_t_30;
+1168:                             contact_area = max(0.0, contact_top - contact_bottom) * length
              __pyx_t_30 = (__pyx_v_contact_top - __pyx_v_contact_bottom);
              __pyx_t_46 = 0.0;
              __pyx_t_31 = (__pyx_t_30 > __pyx_t_46);
              if (__pyx_t_31) {
                __pyx_t_45 = __pyx_t_30;
              } else {
                __pyx_t_45 = __pyx_t_46;
              }
              __pyx_v_contact_area = (__pyx_t_45 * __pyx_v_6eroder_length);
 1169: 
+1170:                             erosion_capacity = inertial_erosion_constant * velocity_in_direction * contact_area / MAX_WATER_SPEED
              __pyx_t_4 = PyFloat_FromDouble(__pyx_v_inertial_erosion_constant); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1170, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_4);
              __pyx_t_2 = PyNumber_Multiply(__pyx_t_4, __pyx_v_velocity_in_direction); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1170, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
              __pyx_t_4 = PyFloat_FromDouble(__pyx_v_contact_area); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1170, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_4);
              __pyx_t_5 = PyNumber_Multiply(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1170, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_5);
              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
              __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
              __pyx_t_4 = PyFloat_FromDouble(__pyx_v_6eroder_MAX_WATER_SPEED); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1170, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_4);
              __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1170, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
              __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
              __Pyx_DECREF_SET(__pyx_v_erosion_capacity, __pyx_t_2);
              __pyx_t_2 = 0;
 1171: 
 1172:                             # organic
+1173:                             sediment_capacity = organic_constant * erosion_capacity
              __pyx_t_2 = PyFloat_FromDouble(__pyx_v_6eroder_organic_constant); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1173, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __pyx_t_4 = PyNumber_Multiply(__pyx_t_2, __pyx_v_erosion_capacity); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1173, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_4);
              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
              __Pyx_DECREF_SET(__pyx_v_sediment_capacity, __pyx_t_4);
              __pyx_t_4 = 0;
 1174:                             #if water[x][y].sediment.organic <= sediment_capacity:
 1175:                             # erode
+1176:                             requested_amount = 0.5 * sediment_capacity
              __pyx_t_4 = PyNumber_Multiply(__pyx_float_0_5, __pyx_v_sediment_capacity); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1176, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_4);
              __Pyx_DECREF_SET(__pyx_v_requested_amount, __pyx_t_4);
              __pyx_t_4 = 0;
+1177:                             amount = erode_organic_amount_only_from(terrain[x][y].subsoil, requested_amount)
              __pyx_t_45 = __pyx_PyFloat_AsDouble(__pyx_v_requested_amount); if (unlikely((__pyx_t_45 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1177, __pyx_L1_error)
              __pyx_t_4 = PyFloat_FromDouble(__pyx_f_6eroder_erode_organic_amount_only_from(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil, __pyx_t_45)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1177, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_4);
              __Pyx_DECREF_SET(__pyx_v_amount, __pyx_t_4);
              __pyx_t_4 = 0;
 1178: 
+1179:                             heightmap[mod(x + delta_x[i], size_x)][mod(y + delta_y[i], size_y)] -= amount
              __pyx_t_45 = __pyx_PyFloat_AsDouble(__pyx_v_amount); if (unlikely((__pyx_t_45 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1179, __pyx_L1_error)
              __pyx_t_44 = __pyx_f_6eroder_mod((__pyx_v_x + (__pyx_v_delta_x[__pyx_v_i])), __pyx_v_size_x); if (unlikely(__pyx_t_44 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1179, __pyx_L1_error)
              __pyx_t_43 = __pyx_f_6eroder_mod((__pyx_v_y + (__pyx_v_delta_y[__pyx_v_i])), __pyx_v_size_y); if (unlikely(__pyx_t_43 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1179, __pyx_L1_error)
              __pyx_t_47 = __pyx_t_44;
              __pyx_t_40 = __pyx_t_43;
              *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_47 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_40)) )) -= __pyx_t_45;
+1180:                             water[x][y].sediment.organic += amount
              __pyx_t_43 = __pyx_v_x;
              __pyx_t_44 = __pyx_v_y;
              __pyx_t_4 = PyFloat_FromDouble(((__pyx_v_water[__pyx_t_43])[__pyx_t_44]).sediment.organic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1180, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_4);
              __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_v_amount); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1180, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
              __pyx_t_45 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_45 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1180, __pyx_L1_error)
              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
              ((__pyx_v_water[__pyx_t_43])[__pyx_t_44]).sediment.organic = __pyx_t_45;
 1181: 
 1182:                             # erode rocks
+1183:                             for original in range(4):
              for (__pyx_t_49 = 0; __pyx_t_49 < 4; __pyx_t_49+=1) {
                __pyx_v_original = __pyx_t_49;
+1184:                                 for sedimented in range(4):
                for (__pyx_t_50 = 0; __pyx_t_50 < 4; __pyx_t_50+=1) {
                  __pyx_v_sedimented = __pyx_t_50;
+1185:                                     sediment_capacity = max(rock_matrix_linear[original][sedimented] * erosion_capacity + rock_matrix_constant[original][sedimented], 0.0)
                  __pyx_t_45 = 0.0;
                  __pyx_t_2 = PyFloat_FromDouble(((__pyx_v_6eroder_rock_matrix_linear[__pyx_v_original])[__pyx_v_sedimented])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1185, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_2);
                  __pyx_t_4 = PyNumber_Multiply(__pyx_t_2, __pyx_v_erosion_capacity); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1185, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_4);
                  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
                  __pyx_t_2 = PyFloat_FromDouble(((__pyx_v_6eroder_rock_matrix_constant[__pyx_v_original])[__pyx_v_sedimented])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1185, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_2);
                  __pyx_t_5 = PyNumber_Add(__pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1185, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_5);
                  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
                  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
                  __pyx_t_4 = PyFloat_FromDouble(__pyx_t_45); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1185, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_4);
                  __pyx_t_3 = PyObject_RichCompare(__pyx_t_4, __pyx_t_5, Py_GT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1185, __pyx_L1_error)
                  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
                  __pyx_t_31 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_31 < 0))) __PYX_ERR(0, 1185, __pyx_L1_error)
                  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
                  if (__pyx_t_31) {
                    __pyx_t_3 = PyFloat_FromDouble(__pyx_t_45); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1185, __pyx_L1_error)
                    __Pyx_GOTREF(__pyx_t_3);
                    __pyx_t_2 = __pyx_t_3;
                    __pyx_t_3 = 0;
                  } else {
                    __Pyx_INCREF(__pyx_t_5);
                    __pyx_t_2 = __pyx_t_5;
                  }
                  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
                  __pyx_t_5 = __pyx_t_2;
                  __Pyx_INCREF(__pyx_t_5);
                  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
                  __Pyx_DECREF_SET(__pyx_v_sediment_capacity, __pyx_t_5);
                  __pyx_t_5 = 0;
 1186:                                     #if water[x][y].sediment.rocks[sedimented] <= sediment_capacity:
 1187:                                     # erode
+1188:                                     requested_amount = 0.5 * sediment_capacity
                  __pyx_t_5 = PyNumber_Multiply(__pyx_float_0_5, __pyx_v_sediment_capacity); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1188, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_5);
                  __Pyx_DECREF_SET(__pyx_v_requested_amount, __pyx_t_5);
                  __pyx_t_5 = 0;
+1189:                                     amount = erode_rocks_amount_only_from(terrain[x][y].subsoil, requested_amount, original)
                  __pyx_t_45 = __pyx_PyFloat_AsDouble(__pyx_v_requested_amount); if (unlikely((__pyx_t_45 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1189, __pyx_L1_error)
                  __pyx_t_5 = PyFloat_FromDouble(__pyx_f_6eroder_erode_rocks_amount_only_from(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil, __pyx_t_45, __pyx_v_original)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1189, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_5);
                  __Pyx_DECREF_SET(__pyx_v_amount, __pyx_t_5);
                  __pyx_t_5 = 0;
+1190:                                     heightmap[mod(x + delta_x[i], size_x)][mod(y + delta_y[i], size_y)] -= amount
                  __pyx_t_45 = __pyx_PyFloat_AsDouble(__pyx_v_amount); if (unlikely((__pyx_t_45 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1190, __pyx_L1_error)
                  __pyx_t_43 = __pyx_f_6eroder_mod((__pyx_v_x + (__pyx_v_delta_x[__pyx_v_i])), __pyx_v_size_x); if (unlikely(__pyx_t_43 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1190, __pyx_L1_error)
                  __pyx_t_44 = __pyx_f_6eroder_mod((__pyx_v_y + (__pyx_v_delta_y[__pyx_v_i])), __pyx_v_size_y); if (unlikely(__pyx_t_44 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1190, __pyx_L1_error)
                  __pyx_t_40 = __pyx_t_43;
                  __pyx_t_47 = __pyx_t_44;
                  *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_40 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_47)) )) -= __pyx_t_45;
+1191:                                     water[x][y].sediment.rocks[sedimented] += amount
                  __pyx_t_44 = __pyx_v_x;
                  __pyx_t_43 = __pyx_v_y;
                  __pyx_t_51 = __pyx_v_sedimented;
                  __pyx_t_5 = PyFloat_FromDouble((((__pyx_v_water[__pyx_t_44])[__pyx_t_43]).sediment.rocks[__pyx_t_51])); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1191, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_5);
                  __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_5, __pyx_v_amount); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1191, __pyx_L1_error)
                  __Pyx_GOTREF(__pyx_t_2);
                  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
                  __pyx_t_45 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_45 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1191, __pyx_L1_error)
                  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
                  (((__pyx_v_water[__pyx_t_44])[__pyx_t_43]).sediment.rocks[__pyx_t_51]) = __pyx_t_45;
                }
              }
 1192: 
 1193:                             # slow down water
+1194:                             total_contact_volume = max(min(heightmap[mod(x + delta_x[i], size_x)][mod(y + delta_y[i], size_y)] - heightmap[x][y], water[x][y].height) * area, 0.0)
              __pyx_t_45 = 0.0;
              __pyx_t_30 = ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height;
              __pyx_t_44 = __pyx_f_6eroder_mod((__pyx_v_x + (__pyx_v_delta_x[__pyx_v_i])), __pyx_v_size_x); if (unlikely(__pyx_t_44 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1194, __pyx_L1_error)
              __pyx_t_43 = __pyx_f_6eroder_mod((__pyx_v_y + (__pyx_v_delta_y[__pyx_v_i])), __pyx_v_size_y); if (unlikely(__pyx_t_43 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1194, __pyx_L1_error)
              __pyx_t_47 = __pyx_t_44;
              __pyx_t_40 = __pyx_t_43;
              __pyx_t_39 = __pyx_v_x;
              __pyx_t_52 = __pyx_v_y;
              __pyx_t_46 = ((*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_47 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_40)) ))) - (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_39 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_52)) ))));
              __pyx_t_31 = (__pyx_t_30 < __pyx_t_46);
              if (__pyx_t_31) {
                __pyx_t_53 = __pyx_t_30;
              } else {
                __pyx_t_53 = __pyx_t_46;
              }
              __pyx_t_30 = (__pyx_t_53 * __pyx_v_area);
              __pyx_t_31 = (__pyx_t_45 > __pyx_t_30);
              if (__pyx_t_31) {
                __pyx_t_53 = __pyx_t_45;
              } else {
                __pyx_t_53 = __pyx_t_30;
              }
              __pyx_v_total_contact_volume = __pyx_t_53;
 1195: 
+1196:                             fraction = total_contact_volume / (water[x][y].height * area)
              __pyx_v_fraction = (__pyx_v_total_contact_volume / (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height * __pyx_v_area));
 1197: 
+1198:                             water[x][y].velocity_x *= abs(delta_x[i]) * (1.0 - fraction)
              __pyx_t_43 = __pyx_v_x;
              __pyx_t_44 = __pyx_v_y;
              __pyx_t_36 = abs((__pyx_v_delta_x[__pyx_v_i])); if (unlikely(__pyx_t_36 == ((int)-1))) __PYX_ERR(0, 1198, __pyx_L1_error)
              ((__pyx_v_water[__pyx_t_43])[__pyx_t_44]).velocity_x = (((__pyx_v_water[__pyx_t_43])[__pyx_t_44]).velocity_x * (__pyx_t_36 * (1.0 - __pyx_v_fraction)));
+1199:                             water[x][y].velocity_y *= abs(delta_y[i]) * (1.0 - fraction)
              __pyx_t_43 = __pyx_v_x;
              __pyx_t_44 = __pyx_v_y;
              __pyx_t_36 = abs((__pyx_v_delta_y[__pyx_v_i])); if (unlikely(__pyx_t_36 == ((int)-1))) __PYX_ERR(0, 1199, __pyx_L1_error)
              ((__pyx_v_water[__pyx_t_43])[__pyx_t_44]).velocity_y = (((__pyx_v_water[__pyx_t_43])[__pyx_t_44]).velocity_y * (__pyx_t_36 * (1.0 - __pyx_v_fraction)));
 1200: 
 1201: 
 1202: 
 1203: 
 1204:         ######################################################
 1205:         # DISSOLUTION/REGOLITH EROSION
 1206:         ######################################################
+1207:         if max_penetration_depth > 0.0:
    __pyx_t_31 = (__pyx_v_max_penetration_depth > 0.0);
    if (__pyx_t_31) {
/* … */
    }
+1208:             for x in range(size_x):
      __pyx_t_29 = __pyx_v_size_x;
      __pyx_t_28 = __pyx_t_29;
      for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
        __pyx_v_x = __pyx_t_27;
+1209:                 for y in range(size_y):
        __pyx_t_32 = __pyx_v_size_y;
        __pyx_t_33 = __pyx_t_32;
        for (__pyx_t_37 = 0; __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
          __pyx_v_y = __pyx_t_37;
+1210:                     if water[x][y].height > 0:
          __pyx_t_31 = (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height > 0.0);
          if (__pyx_t_31) {
/* … */
          }
        }
      }
 1211:                         # max regolith
+1212:                         max_regolith_thickness = max_penetration_depth
            __pyx_v_max_regolith_thickness = __pyx_v_max_penetration_depth;
+1213:                         if water[x][y].height < max_penetration_depth:
            __pyx_t_31 = (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height < __pyx_v_max_penetration_depth);
            if (__pyx_t_31) {
/* … */
            }
+1214:                             max_regolith_thickness = water[x][y].height
              __pyx_t_53 = ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height;
              __pyx_v_max_regolith_thickness = __pyx_t_53;
 1215: 
 1216:                         # always maintain max regolith (no idea why)
+1217:                         if get_soil_height(water[x][y].regolith) < max_regolith_thickness:
            __pyx_t_31 = (__pyx_f_6eroder_get_soil_height(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).regolith) < __pyx_v_max_regolith_thickness);
            if (__pyx_t_31) {
/* … */
              goto __pyx_L94;
            }
 1218:                             # regolithise (not a real word)
+1219:                             amount = erode_regolith(terrain[x][y], max_regolith_thickness - get_soil_height(water[x][y].regolith))
              __pyx_t_2 = __pyx_convert__to_py_struct____pyx_t_6eroder_Soil(__pyx_f_6eroder_erode_regolith(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]), (__pyx_v_max_regolith_thickness - __pyx_f_6eroder_get_soil_height(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).regolith)))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1219, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_XDECREF_SET(__pyx_v_amount, __pyx_t_2);
              __pyx_t_2 = 0;
+1220:                             heightmap[x][y] -= get_soil_height(amount)
              __pyx_t_54 = __pyx_convert__from_py_struct____pyx_t_6eroder_Soil(__pyx_v_amount); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1220, __pyx_L1_error)
              __pyx_t_52 = __pyx_v_x;
              __pyx_t_39 = __pyx_v_y;
              *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_52 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_39)) )) -= __pyx_f_6eroder_get_soil_height(__pyx_t_54);
+1221:                             add_to_soil(water[x][y].regolith, amount)
              __pyx_t_54 = __pyx_convert__from_py_struct____pyx_t_6eroder_Soil(__pyx_v_amount); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1221, __pyx_L1_error)
              __pyx_f_6eroder_add_to_soil(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).regolith, __pyx_t_54);
 1222:                         else:
 1223:                             # deposit
+1224:                             amount = get_soil_height(water[x][y].regolith) - max_regolith_thickness
            /*else*/ {
              __pyx_t_2 = PyFloat_FromDouble((__pyx_f_6eroder_get_soil_height(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).regolith) - __pyx_v_max_regolith_thickness)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1224, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_XDECREF_SET(__pyx_v_amount, __pyx_t_2);
              __pyx_t_2 = 0;
+1225:                             soil = soil_fraction(water[x][y].regolith, amount / get_soil_height(water[x][y].regolith))
              __pyx_t_2 = PyFloat_FromDouble(__pyx_f_6eroder_get_soil_height(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).regolith)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1225, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __pyx_t_5 = __Pyx_PyNumber_Divide(__pyx_v_amount, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1225, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_5);
              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
              __pyx_t_53 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_53 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1225, __pyx_L1_error)
              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
              __pyx_v_soil = __pyx_f_6eroder_soil_fraction(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).regolith, __pyx_t_53);
+1226:                             deposit_soil(terrain[x][y], soil)
              __pyx_f_6eroder_deposit_soil(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]), __pyx_v_soil);
+1227:                             heightmap[x][y] += amount
              __pyx_t_53 = __pyx_PyFloat_AsDouble(__pyx_v_amount); if (unlikely((__pyx_t_53 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1227, __pyx_L1_error)
              __pyx_t_39 = __pyx_v_x;
              __pyx_t_52 = __pyx_v_y;
              *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_39 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_52)) )) += __pyx_t_53;
+1228:                             water[x][y].regolith = soil_fraction(water[x][y].regolith, 1 - amount / get_soil_height(water[x][y].regolith))
              __pyx_t_5 = PyFloat_FromDouble(__pyx_f_6eroder_get_soil_height(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).regolith)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1228, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_5);
              __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_v_amount, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1228, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
              __pyx_t_5 = __Pyx_PyInt_SubtractCObj(__pyx_int_1, __pyx_t_2, 1, 0, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1228, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_5);
              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
              __pyx_t_53 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_53 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1228, __pyx_L1_error)
              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
              ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).regolith = __pyx_f_6eroder_soil_fraction(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).regolith, __pyx_t_53);
            }
            __pyx_L94:;
 1229: 
 1230: 
 1231:         ######################################################
 1232:         # DIFFUSE SEDIMENT
 1233:         ######################################################
+1234:         for x in range(size_x):
    __pyx_t_29 = __pyx_v_size_x;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_x = __pyx_t_27;
+1235:             for y in range(size_y):
      __pyx_t_32 = __pyx_v_size_y;
      __pyx_t_33 = __pyx_t_32;
      for (__pyx_t_37 = 0; __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
        __pyx_v_y = __pyx_t_37;
+1236:                 water2[x][y] = water[x][y]
        ((__pyx_v_water2[__pyx_v_x])[__pyx_v_y]) = ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]);
+1237:                 water2[x][y].sediment = EMPTY_SOIL
        ((__pyx_v_water2[__pyx_v_x])[__pyx_v_y]).sediment = __pyx_v_6eroder_EMPTY_SOIL;
      }
    }
 1238: 
+1239:         for x in range(size_x):
    __pyx_t_29 = __pyx_v_size_x;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_x = __pyx_t_27;
+1240:             for y in range(size_y):
      __pyx_t_32 = __pyx_v_size_y;
      __pyx_t_33 = __pyx_t_32;
      for (__pyx_t_37 = 0; __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
        __pyx_v_y = __pyx_t_37;
 1241:                 # using a filter where the neighbors have weights of 0.5 and the column itself has a weight of 1.0
 1242:                 # so the sum is 1.0 + 4*0.5 = 3.0
+1243:                 base = 1.0 * water[x][y].height
        __pyx_v_base = (1.0 * ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height);
+1244:                 for i in range(4):
        for (__pyx_t_38 = 0; __pyx_t_38 < 4; __pyx_t_38+=1) {
          __pyx_v_i = __pyx_t_38;
+1245:                     base += 0.5 * water[mod(x + delta_x[i], size_x)][mod(y + delta_y[i], size_y)].height
          __pyx_t_43 = __pyx_f_6eroder_mod((__pyx_v_x + (__pyx_v_delta_x[__pyx_v_i])), __pyx_v_size_x); if (unlikely(__pyx_t_43 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1245, __pyx_L1_error)
          __pyx_t_44 = __pyx_f_6eroder_mod((__pyx_v_y + (__pyx_v_delta_y[__pyx_v_i])), __pyx_v_size_y); if (unlikely(__pyx_t_44 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1245, __pyx_L1_error)
          __pyx_v_base = (__pyx_v_base + (0.5 * ((__pyx_v_water[__pyx_t_43])[__pyx_t_44]).height));
        }
 1246: 
+1247:                 if base > 0:
        __pyx_t_31 = (__pyx_v_base > 0.0);
        if (__pyx_t_31) {
/* … */
          goto __pyx_L105;
        }
+1248:                     add_to_soil(water2[x][y].sediment, soil_fraction(water[x][y].sediment, 1.0 * water[x][y].height / base))
          __pyx_f_6eroder_add_to_soil(((__pyx_v_water2[__pyx_v_x])[__pyx_v_y]).sediment, __pyx_f_6eroder_soil_fraction(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).sediment, ((1.0 * ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height) / __pyx_v_base)));
 1249:                     #water2[x][y] -= water[x][y].sediment * (1.0 - (1.0 * water[x][y] / base))
+1250:                     for i in range(4):
          for (__pyx_t_38 = 0; __pyx_t_38 < 4; __pyx_t_38+=1) {
            __pyx_v_i = __pyx_t_38;
+1251:                         fraction = 0.5 * water[mod(x + delta_x[i], size_x)][mod(y + delta_y[i], size_y)].height / base
            __pyx_t_44 = __pyx_f_6eroder_mod((__pyx_v_x + (__pyx_v_delta_x[__pyx_v_i])), __pyx_v_size_x); if (unlikely(__pyx_t_44 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1251, __pyx_L1_error)
            __pyx_t_43 = __pyx_f_6eroder_mod((__pyx_v_y + (__pyx_v_delta_y[__pyx_v_i])), __pyx_v_size_y); if (unlikely(__pyx_t_43 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1251, __pyx_L1_error)
            __pyx_v_fraction = ((0.5 * ((__pyx_v_water[__pyx_t_44])[__pyx_t_43]).height) / __pyx_v_base);
+1252:                         add_to_soil(water2[mod(x + delta_x[i], size_x)][mod(y + delta_y[i], size_y)].sediment, soil_fraction(water[x][y].sediment, fraction))
            __pyx_t_43 = __pyx_f_6eroder_mod((__pyx_v_x + (__pyx_v_delta_x[__pyx_v_i])), __pyx_v_size_x); if (unlikely(__pyx_t_43 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1252, __pyx_L1_error)
            __pyx_t_44 = __pyx_f_6eroder_mod((__pyx_v_y + (__pyx_v_delta_y[__pyx_v_i])), __pyx_v_size_y); if (unlikely(__pyx_t_44 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1252, __pyx_L1_error)
            __pyx_f_6eroder_add_to_soil(((__pyx_v_water2[__pyx_t_43])[__pyx_t_44]).sediment, __pyx_f_6eroder_soil_fraction(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).sediment, __pyx_v_fraction));
          }
 1253:                         #water2[mod(x + delta_x[i], size_x)][mod(y + delta_y[i], size_y)] += amount
 1254:                 else:
+1255:                     add_to_soil(water2[x][y].sediment, water[x][y].sediment)
        /*else*/ {
          __pyx_f_6eroder_add_to_soil(((__pyx_v_water2[__pyx_v_x])[__pyx_v_y]).sediment, ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).sediment);
        }
        __pyx_L105:;
      }
    }
 1256: 
 1257: 
 1258:         # update sediment again
+1259:         for x in range(size_x):
    __pyx_t_29 = __pyx_v_size_x;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_x = __pyx_t_27;
+1260:             for y in range(size_y):
      __pyx_t_32 = __pyx_v_size_y;
      __pyx_t_33 = __pyx_t_32;
      for (__pyx_t_37 = 0; __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
        __pyx_v_y = __pyx_t_37;
+1261:                 water[x][y] = water2[x][y]
        ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]) = ((__pyx_v_water2[__pyx_v_x])[__pyx_v_y]);
      }
    }
 1262: 
 1263: 
 1264:         ######################################################
 1265:         # WETNESS
 1266:         ######################################################
 1267: 
+1268:         for x in range(size_x):
    __pyx_t_29 = __pyx_v_size_x;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_x = __pyx_t_27;
+1269:             for y in range(size_y):
      __pyx_t_32 = __pyx_v_size_y;
      __pyx_t_33 = __pyx_t_32;
      for (__pyx_t_37 = 0; __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
        __pyx_v_y = __pyx_t_37;
+1270:                 if water[x][y].height > 0.0:
        __pyx_t_31 = (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height > 0.0);
        if (__pyx_t_31) {
/* … */
          goto __pyx_L116;
        }
+1271:                     wet[x][y] += delta_t * water[x][y].height
          __pyx_t_52 = __pyx_v_x;
          __pyx_t_39 = __pyx_v_y;
          *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_wet.data + __pyx_t_52 * __pyx_v_wet.strides[0]) )) + __pyx_t_39)) )) += (__pyx_v_delta_t * ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height);
 1272:                 else:
+1273:                     wet[x][y] *= 0.5**delta_t
        /*else*/ {
          __pyx_t_39 = __pyx_v_x;
          __pyx_t_52 = __pyx_v_y;
          *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_wet.data + __pyx_t_39 * __pyx_v_wet.strides[0]) )) + __pyx_t_52)) )) *= pow(0.5, __pyx_v_delta_t);
        }
        __pyx_L116:;
      }
    }
 1274: 
 1275:         ######################################################
 1276:         # VEGETATION
 1277:         ######################################################
 1278: 
+1279:         for x in range(size_x):
    __pyx_t_29 = __pyx_v_size_x;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_x = __pyx_t_27;
+1280:             for y in range(size_y):
      __pyx_t_32 = __pyx_v_size_y;
      __pyx_t_33 = __pyx_t_32;
      for (__pyx_t_37 = 0; __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
        __pyx_v_y = __pyx_t_37;
 1281:                 # dying
+1282:                 if wet[x][y] > 1.0:
        __pyx_t_52 = __pyx_v_x;
        __pyx_t_39 = __pyx_v_y;
        __pyx_t_31 = ((*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_wet.data + __pyx_t_52 * __pyx_v_wet.strides[0]) )) + __pyx_t_39)) ))) > 1.0);
        if (__pyx_t_31) {
/* … */
          goto __pyx_L121;
        }
 1283:                     # death from floods
+1284:                     vegetation[x][y] = 0.0
          __pyx_t_39 = __pyx_v_x;
          __pyx_t_52 = __pyx_v_y;
          *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_39 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_52)) )) = 0.0;
+1285:                 elif terrain[x][y].topsoil.organic + terrain[x][y].subsoil.organic == 0.0:
        __pyx_t_31 = ((((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil.organic + ((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil.organic) == 0.0);
        if (__pyx_t_31) {
/* … */
          goto __pyx_L121;
        }
 1286:                     # death from no soil
+1287:                     vegetation[x][y] = 0.0
          __pyx_t_52 = __pyx_v_x;
          __pyx_t_39 = __pyx_v_y;
          *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_52 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_39)) )) = 0.0;
 1288:                 else:
 1289:                 # growing
 1290:                     #if vegetation[x][y] == 0.0:
 1291: 
 1292:                     # count neighbors
+1293:                     neighbor_vegetation = 0.0
        /*else*/ {
          __pyx_v_neighbor_vegetation = 0.0;
+1294:                     for si in range(-1, 2):
          for (__pyx_t_36 = -1; __pyx_t_36 < 2; __pyx_t_36+=1) {
            __pyx_v_si = __pyx_t_36;
+1295:                         for sj in range(-1, 2):
            for (__pyx_t_55 = -1; __pyx_t_55 < 2; __pyx_t_55+=1) {
              __pyx_v_sj = __pyx_t_55;
+1296:                             neighbor_vegetation += vegetation[mod(x + si, size_x)][mod(y + sj, size_y)]
              __pyx_t_38 = __pyx_f_6eroder_mod((__pyx_v_x + __pyx_v_si), __pyx_v_size_x); if (unlikely(__pyx_t_38 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1296, __pyx_L1_error)
              __pyx_t_44 = __pyx_f_6eroder_mod((__pyx_v_y + __pyx_v_sj), __pyx_v_size_y); if (unlikely(__pyx_t_44 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1296, __pyx_L1_error)
              __pyx_t_39 = __pyx_t_38;
              __pyx_t_52 = __pyx_t_44;
              __pyx_v_neighbor_vegetation = (__pyx_v_neighbor_vegetation + (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_39 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_52)) ))));
            }
          }
 1297: 
 1298:                     # soil conditions
+1299:                     average_soil_shallow = get_soil_sample(terrain[x][y], 0.25)
          __pyx_v_average_soil_shallow = __pyx_f_6eroder_get_soil_sample(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]), 0.25);
+1300:                     average_soil_deep = get_soil_sample(terrain[x][y], 2.0)
          __pyx_v_average_soil_deep = __pyx_f_6eroder_get_soil_sample(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]), 2.0);
 1301: 
 1302:                     # set to 1 if greater than 1
+1303:                     if get_soil_height(average_soil_shallow) > 1:
          __pyx_t_31 = (__pyx_f_6eroder_get_soil_height(__pyx_v_average_soil_shallow) > 1.0);
          if (__pyx_t_31) {
/* … */
          }
+1304:                         average_soil_shallow = normalized(average_soil_shallow)
            __pyx_v_average_soil_shallow = __pyx_f_6eroder_normalized(__pyx_v_average_soil_shallow);
 1305: 
+1306:                     if get_soil_height(average_soil_deep) > 1:
          __pyx_t_31 = (__pyx_f_6eroder_get_soil_height(__pyx_v_average_soil_deep) > 1.0);
          if (__pyx_t_31) {
/* … */
          }
+1307:                         average_soil_deep = normalized(average_soil_deep)
            __pyx_v_average_soil_deep = __pyx_f_6eroder_normalized(__pyx_v_average_soil_deep);
 1308: 
+1309:                     rocks_shallow = 0.0
          __pyx_v_rocks_shallow = 0.0;
+1310:                     for i in range(4):
          for (__pyx_t_44 = 0; __pyx_t_44 < 4; __pyx_t_44+=1) {
            __pyx_v_i = __pyx_t_44;
+1311:                         rocks_shallow += ROCK_VEGETATION_MULIPLITER[i] * average_soil_shallow.rocks[i]
            __pyx_v_rocks_shallow = (__pyx_v_rocks_shallow + ((__pyx_v_6eroder_ROCK_VEGETATION_MULIPLITER[__pyx_v_i]) * (__pyx_v_average_soil_shallow.rocks[__pyx_v_i])));
          }
 1312: 
+1313:                     rocks_deep = 0.0
          __pyx_v_rocks_deep = 0.0;
+1314:                     for i in range(4):
          for (__pyx_t_44 = 0; __pyx_t_44 < 4; __pyx_t_44+=1) {
            __pyx_v_i = __pyx_t_44;
+1315:                         rocks_deep += ROCK_VEGETATION_MULIPLITER[i] * average_soil_deep.rocks[i]
            __pyx_v_rocks_deep = (__pyx_v_rocks_deep + ((__pyx_v_6eroder_ROCK_VEGETATION_MULIPLITER[__pyx_v_i]) * (__pyx_v_average_soil_deep.rocks[__pyx_v_i])));
          }
 1316: 
 1317:                     # how good the soil is for the plants
+1318:                     soil_conditions = (1 - vegetation[x][y]) * (ORGANIC_VEGETATION_MULIPLITER * average_soil_shallow.organic + rocks_shallow) + vegetation[x][y] * (ORGANIC_VEGETATION_MULIPLITER * average_soil_deep.organic + rocks_deep) - vegetation_base
          __pyx_t_52 = __pyx_v_x;
          __pyx_t_39 = __pyx_v_y;
          __pyx_t_40 = __pyx_v_x;
          __pyx_t_47 = __pyx_v_y;
          __pyx_v_soil_conditions = ((((1.0 - (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_52 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_39)) )))) * ((__pyx_v_6eroder_ORGANIC_VEGETATION_MULIPLITER * __pyx_v_average_soil_shallow.organic) + __pyx_v_rocks_shallow)) + ((*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_40 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_47)) ))) * ((__pyx_v_6eroder_ORGANIC_VEGETATION_MULIPLITER * __pyx_v_average_soil_deep.organic) + __pyx_v_rocks_deep))) - __pyx_v_vegetation_base);
 1319: 
+1320:                     vegetation2[x][y] = min(max(0.0, vegetation[x][y] + random(0, 1) * delta_t * vegetation_spread_speed * (soil_conditions - 0.8 * vegetation[x][y] + NEIGHBOR_VEGETATION_MULTIPLIER * neighbor_vegetation)), 1.0)
          __pyx_t_53 = 1.0;
          __pyx_t_47 = __pyx_v_x;
          __pyx_t_40 = __pyx_v_y;
          __pyx_t_56.__pyx_n = 2;
          __pyx_t_56.low = 0.0;
          __pyx_t_56.high = 1.0;
          __pyx_t_45 = __pyx_f_6eroder_random(&__pyx_t_56); if (unlikely(__pyx_t_45 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1320, __pyx_L1_error)
          __pyx_t_39 = __pyx_v_x;
          __pyx_t_52 = __pyx_v_y;
          __pyx_t_30 = ((*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_47 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_40)) ))) + (((__pyx_t_45 * __pyx_v_delta_t) * __pyx_v_vegetation_spread_speed) * ((__pyx_v_soil_conditions - (0.8 * (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_39 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_52)) ))))) + (__pyx_v_6eroder_NEIGHBOR_VEGETATION_MULTIPLIER * __pyx_v_neighbor_vegetation))));
          __pyx_t_45 = 0.0;
          __pyx_t_31 = (__pyx_t_30 > __pyx_t_45);
          if (__pyx_t_31) {
            __pyx_t_46 = __pyx_t_30;
          } else {
            __pyx_t_46 = __pyx_t_45;
          }
          __pyx_t_30 = __pyx_t_46;
          __pyx_t_31 = (__pyx_t_53 < __pyx_t_30);
          if (__pyx_t_31) {
            __pyx_t_46 = __pyx_t_53;
          } else {
            __pyx_t_46 = __pyx_t_30;
          }
          ((__pyx_v_vegetation2[__pyx_v_x])[__pyx_v_y]) = __pyx_t_46;
        }
        __pyx_L121:;
      }
    }
 1321: 
+1322:         for x in range(size_x):
    __pyx_t_29 = __pyx_v_size_x;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_x = __pyx_t_27;
+1323:             for y in range(size_y):
      __pyx_t_32 = __pyx_v_size_y;
      __pyx_t_33 = __pyx_t_32;
      for (__pyx_t_37 = 0; __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
        __pyx_v_y = __pyx_t_37;
+1324:                 vegetation[x][y] = vegetation2[x][y]
        __pyx_t_52 = __pyx_v_x;
        __pyx_t_39 = __pyx_v_y;
        *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_52 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_39)) )) = ((__pyx_v_vegetation2[__pyx_v_x])[__pyx_v_y]);
      }
    }
 1325: 
 1326:         ######################################################
 1327:         # ROCK CONVERSION
 1328:         ######################################################
 1329: 
 1330: 
+1331:         for x in range(size_x):
    __pyx_t_29 = __pyx_v_size_x;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_x = __pyx_t_27;
+1332:             for y in range(size_y):
      __pyx_t_32 = __pyx_v_size_y;
      __pyx_t_33 = __pyx_t_32;
      for (__pyx_t_37 = 0; __pyx_t_37 < __pyx_t_33; __pyx_t_37+=1) {
        __pyx_v_y = __pyx_t_37;
+1333:                 if vegetation[x][y] > 0.0:
        __pyx_t_39 = __pyx_v_x;
        __pyx_t_52 = __pyx_v_y;
        __pyx_t_31 = ((*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_39 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_52)) ))) > 0.0);
        if (__pyx_t_31) {
/* … */
        }
      }
    }
  }
 1334:                     # change soil rocks into organic or break them down
+1335:                     terrain[x][y].topsoil = organification(terrain[x][y].topsoil, vegetation[x][y], organification_speed, delta_t)
          __pyx_t_52 = __pyx_v_x;
          __pyx_t_39 = __pyx_v_y;
          ((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil = __pyx_f_6eroder_organification(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil, (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_52 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_39)) ))), __pyx_v_organification_speed, __pyx_v_delta_t);
+1336:                     terrain[x][y].subsoil = organification(terrain[x][y].subsoil, vegetation[x][y], organification_speed, delta_t)
          __pyx_t_39 = __pyx_v_x;
          __pyx_t_52 = __pyx_v_y;
          ((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil = __pyx_f_6eroder_organification(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil, (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_39 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_52)) ))), __pyx_v_organification_speed, __pyx_v_delta_t);
 1337: 
 1338:                     # change bedrock into soil
+1339:                     bedrock_depth = get_soil_height(terrain[x][y].topsoil) + get_soil_height(terrain[x][y].subsoil)
          __pyx_v_bedrock_depth = (__pyx_f_6eroder_get_soil_height(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil) + __pyx_f_6eroder_get_soil_height(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil));
+1340:                     if bedrock_depth <= 4.0:
          __pyx_t_31 = (__pyx_v_bedrock_depth <= 4.0);
          if (__pyx_t_31) {
/* … */
          }
 1341:                         # first nonempty
+1342:                         index = 0
            __Pyx_INCREF(__pyx_int_0);
            __Pyx_XDECREF_SET(__pyx_v_index, __pyx_int_0);
+1343:                         while terrain[x][y].bedrock[index].height <= 0.0:
            while (1) {
              __pyx_t_57 = __Pyx_PyInt_As_size_t(__pyx_v_index); if (unlikely((__pyx_t_57 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1343, __pyx_L1_error)
              __pyx_t_31 = ((((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock[__pyx_t_57]).height <= 0.0);
              if (!__pyx_t_31) break;
+1344:                             index += 1
              __pyx_t_5 = __Pyx_PyInt_AddObjC(__pyx_v_index, __pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1344, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_5);
              __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_5);
              __pyx_t_5 = 0;
            }
 1345: 
+1346:                         amount = min(delta_t * vegetation[x][y] * 0.01 * soilification_speed * BEDROCK_CONVERSION_RATE[terrain[x][y].bedrock[index].type], terrain[x][y].bedrock[index].height)
            __pyx_t_57 = __Pyx_PyInt_As_size_t(__pyx_v_index); if (unlikely((__pyx_t_57 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1346, __pyx_L1_error)
            __pyx_t_46 = (((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock[__pyx_t_57]).height;
            __pyx_t_52 = __pyx_v_x;
            __pyx_t_39 = __pyx_v_y;
            __pyx_t_57 = __Pyx_PyInt_As_size_t(__pyx_v_index); if (unlikely((__pyx_t_57 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1346, __pyx_L1_error)
            __pyx_t_53 = ((((__pyx_v_delta_t * (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_52 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_39)) )))) * 0.01) * __pyx_v_soilification_speed) * (__pyx_v_6eroder_BEDROCK_CONVERSION_RATE[(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock[__pyx_t_57]).type]));
            __pyx_t_31 = (__pyx_t_46 < __pyx_t_53);
            if (__pyx_t_31) {
              __pyx_t_30 = __pyx_t_46;
            } else {
              __pyx_t_30 = __pyx_t_53;
            }
            __pyx_t_5 = PyFloat_FromDouble(__pyx_t_30); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1346, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __Pyx_XDECREF_SET(__pyx_v_amount, __pyx_t_5);
            __pyx_t_5 = 0;
+1347:                         soil = soil_fraction(BEDROCK_CONVERT_TO[terrain[x][y].bedrock[index].type], amount)
            __pyx_t_57 = __Pyx_PyInt_As_size_t(__pyx_v_index); if (unlikely((__pyx_t_57 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1347, __pyx_L1_error)
            __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_v_amount); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1347, __pyx_L1_error)
            __pyx_v_soil = __pyx_f_6eroder_soil_fraction((__pyx_v_6eroder_BEDROCK_CONVERT_TO[(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock[__pyx_t_57]).type]), __pyx_t_30);
 1348: 
 1349:                         # transfer soil
+1350:                         terrain[x][y].bedrock[index].height -= amount
            __pyx_t_44 = __pyx_v_x;
            __pyx_t_38 = __pyx_v_y;
            __pyx_t_57 = __Pyx_PyInt_As_size_t(__pyx_v_index); if (unlikely((__pyx_t_57 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1350, __pyx_L1_error)
            __pyx_t_5 = PyFloat_FromDouble((((__pyx_v_terrain[__pyx_t_44])[__pyx_t_38]).bedrock[__pyx_t_57]).height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1350, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __pyx_t_2 = PyNumber_InPlaceSubtract(__pyx_t_5, __pyx_v_amount); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1350, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            __pyx_t_30 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_30 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1350, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            (((__pyx_v_terrain[__pyx_t_44])[__pyx_t_38]).bedrock[__pyx_t_57]).height = __pyx_t_30;
+1351:                         add_to_soil(terrain[x][y].subsoil, soil)
            __pyx_f_6eroder_add_to_soil(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil, __pyx_v_soil);
 1352: 
 1353: 
 1354: 
+1355:     print("done")
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1355, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
/* … */
  __pyx_tuple__15 = PyTuple_Pack(1, __pyx_n_u_done); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(0, 1355, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__15);
  __Pyx_GIVEREF(__pyx_tuple__15);
 1356: 
 1357:     # timing
+1358:     cdef time_t time_end = time(NULL)
  __pyx_v_time_end = time(NULL);
+1359:     print("The cycle took " + str(time_end - time_start) + " seconds, or " + str((time_end - time_start) / (1.0 * steps)) + " seconds per step")
  __pyx_t_2 = __Pyx_PyInt_From_time_t((__pyx_v_time_end - __pyx_v_time_start)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1359, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_5 = __Pyx_PyObject_Str(__pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1359, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = PyNumber_Add(__pyx_kp_u_The_cycle_took, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1359, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyUnicode_ConcatInPlace(__pyx_t_2, __pyx_kp_u_seconds_or); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1359, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = PyFloat_FromDouble((((double)(__pyx_v_time_end - __pyx_v_time_start)) / (1.0 * __pyx_v_steps))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1359, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_Str(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1359, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = PyNumber_Add(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1359, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyUnicode_ConcatInPlace(__pyx_t_2, __pyx_kp_u_seconds_per_step); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1359, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1359, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 1360: 
 1361:     #####################################
 1362:     # POSTPROCESSING (misusing the name, I know)
 1363: 
 1364:     # visually lower water which is zero in height
+1365:     cdef int neighbors_count = 0
  __pyx_v_neighbors_count = 0;
+1366:     cdef double height_sum = 0.0
  __pyx_v_height_sum = 0.0;
+1367:     for x in range(size_x):
  __pyx_t_17 = __pyx_v_size_x;
  __pyx_t_18 = __pyx_t_17;
  for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
    __pyx_v_x = __pyx_t_19;
+1368:         for y in range(size_y):
    __pyx_t_29 = __pyx_v_size_y;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_y = __pyx_t_27;
+1369:             if water[x][y].height <= 0.0:
      __pyx_t_31 = (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height <= 0.0);
      if (__pyx_t_31) {
/* … */
      }
    }
  }
 1370:                 # calculate average height of neighbors
+1371:                 neighbors_count = 0
        __pyx_v_neighbors_count = 0;
+1372:                 height_sum = 0.0
        __pyx_v_height_sum = 0.0;
+1373:                 for si in range(-1, 2):
        for (__pyx_t_36 = -1; __pyx_t_36 < 2; __pyx_t_36+=1) {
          __pyx_v_si = __pyx_t_36;
+1374:                     for sj in range(-1, 2):
          for (__pyx_t_55 = -1; __pyx_t_55 < 2; __pyx_t_55+=1) {
            __pyx_v_sj = __pyx_t_55;
+1375:                         if water[mod(x+si, size_x)][mod(y+sj, size_y)].height > 0.0:
            __pyx_t_32 = __pyx_f_6eroder_mod((__pyx_v_x + __pyx_v_si), __pyx_v_size_x); if (unlikely(__pyx_t_32 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1375, __pyx_L1_error)
            __pyx_t_33 = __pyx_f_6eroder_mod((__pyx_v_y + __pyx_v_sj), __pyx_v_size_y); if (unlikely(__pyx_t_33 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1375, __pyx_L1_error)
            __pyx_t_31 = (((__pyx_v_water[__pyx_t_32])[__pyx_t_33]).height > 0.0);
            if (__pyx_t_31) {
/* … */
            }
          }
        }
+1376:                             neighbors_count += 1
              __pyx_v_neighbors_count = (__pyx_v_neighbors_count + 1);
+1377:                             height_sum += water[mod(x+si, size_x)][mod(y+sj, size_y)].height + heightmap[mod(x+si, size_x)][mod(y+sj, size_y)]
              __pyx_t_33 = __pyx_f_6eroder_mod((__pyx_v_x + __pyx_v_si), __pyx_v_size_x); if (unlikely(__pyx_t_33 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1377, __pyx_L1_error)
              __pyx_t_32 = __pyx_f_6eroder_mod((__pyx_v_y + __pyx_v_sj), __pyx_v_size_y); if (unlikely(__pyx_t_32 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1377, __pyx_L1_error)
              __pyx_t_37 = __pyx_f_6eroder_mod((__pyx_v_x + __pyx_v_si), __pyx_v_size_x); if (unlikely(__pyx_t_37 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1377, __pyx_L1_error)
              __pyx_t_44 = __pyx_f_6eroder_mod((__pyx_v_y + __pyx_v_sj), __pyx_v_size_y); if (unlikely(__pyx_t_44 == ((unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1377, __pyx_L1_error)
              __pyx_t_39 = __pyx_t_37;
              __pyx_t_52 = __pyx_t_44;
              __pyx_v_height_sum = (__pyx_v_height_sum + (((__pyx_v_water[__pyx_t_33])[__pyx_t_32]).height + (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_39 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_52)) )))));
 1378: 
 1379:                 # set water height to average of the neighbors, if below 0
+1380:                 if neighbors_count > 0:
        __pyx_t_31 = (__pyx_v_neighbors_count > 0);
        if (__pyx_t_31) {
/* … */
        }
+1381:                     water[x][y].height = min(0.0, height_sum / neighbors_count - heightmap[x][y])
          __pyx_t_52 = __pyx_v_x;
          __pyx_t_39 = __pyx_v_y;
          __pyx_t_30 = ((__pyx_v_height_sum / ((double)__pyx_v_neighbors_count)) - (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_heightmap.data + __pyx_t_52 * __pyx_v_heightmap.strides[0]) )) + __pyx_t_39)) ))));
          __pyx_t_46 = 0.0;
          __pyx_t_31 = (__pyx_t_30 < __pyx_t_46);
          if (__pyx_t_31) {
            __pyx_t_53 = __pyx_t_30;
          } else {
            __pyx_t_53 = __pyx_t_46;
          }
          ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height = __pyx_t_53;
 1382: 
 1383:                 # if all neighbors are dry or too high
+1384:                 if neighbors_count == 0 or water[x][y].height == 0.0:
        __pyx_t_48 = (__pyx_v_neighbors_count == 0);
        if (!__pyx_t_48) {
        } else {
          __pyx_t_31 = __pyx_t_48;
          goto __pyx_L156_bool_binop_done;
        }
        __pyx_t_48 = (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height == 0.0);
        __pyx_t_31 = __pyx_t_48;
        __pyx_L156_bool_binop_done:;
        if (__pyx_t_31) {
/* … */
        }
+1385:                     water[x][y].height = -1.0  # just put it deep down
          ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height = -1.0;
 1386: 
 1387: 
 1388:     # create pixel data for images
 1389:     #cdef cnp.ndarray[cnp.float64_t, ndim=1] _topsoil_texture =
+1390:     cdef double[:] texture_type = np.zeros(shape=(4 * size_x * size_y))
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1390, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1390, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1390, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_5 = __Pyx_PyInt_From_long(((4 * __pyx_v_size_x) * __pyx_v_size_y)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1390, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_shape, __pyx_t_5) < 0) __PYX_ERR(0, 1390, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1390, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_58 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_58.memview)) __PYX_ERR(0, 1390, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_texture_type = __pyx_t_58;
  __pyx_t_58.memview = NULL;
  __pyx_t_58.data = NULL;
 1391: 
+1392:     cdef double[:] texture_organic = np.zeros(shape=(4 * size_x * size_y))
  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1392, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1392, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1392, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_3 = __Pyx_PyInt_From_long(((4 * __pyx_v_size_x) * __pyx_v_size_y)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1392, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_shape, __pyx_t_3) < 0) __PYX_ERR(0, 1392, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_empty_tuple, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1392, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_58 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_3, PyBUF_WRITABLE); if (unlikely(!__pyx_t_58.memview)) __PYX_ERR(0, 1392, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_texture_organic = __pyx_t_58;
  __pyx_t_58.memview = NULL;
  __pyx_t_58.data = NULL;
+1393:     cdef double[:] texture_rock0 = np.zeros(shape=(4 * size_x * size_y))
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1393, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_zeros); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1393, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1393, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_2 = __Pyx_PyInt_From_long(((4 * __pyx_v_size_x) * __pyx_v_size_y)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1393, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_shape, __pyx_t_2) < 0) __PYX_ERR(0, 1393, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1393, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_58 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_2, PyBUF_WRITABLE); if (unlikely(!__pyx_t_58.memview)) __PYX_ERR(0, 1393, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_texture_rock0 = __pyx_t_58;
  __pyx_t_58.memview = NULL;
  __pyx_t_58.data = NULL;
+1394:     cdef double[:] texture_rock1 = np.zeros(shape=(4 * size_x * size_y))
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1394, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1394, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1394, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_5 = __Pyx_PyInt_From_long(((4 * __pyx_v_size_x) * __pyx_v_size_y)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1394, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_shape, __pyx_t_5) < 0) __PYX_ERR(0, 1394, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1394, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_58 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_58.memview)) __PYX_ERR(0, 1394, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_texture_rock1 = __pyx_t_58;
  __pyx_t_58.memview = NULL;
  __pyx_t_58.data = NULL;
+1395:     cdef double[:] texture_rock2 = np.zeros(shape=(4 * size_x * size_y))
  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1395, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1395, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1395, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_3 = __Pyx_PyInt_From_long(((4 * __pyx_v_size_x) * __pyx_v_size_y)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1395, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_shape, __pyx_t_3) < 0) __PYX_ERR(0, 1395, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_empty_tuple, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1395, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_58 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_3, PyBUF_WRITABLE); if (unlikely(!__pyx_t_58.memview)) __PYX_ERR(0, 1395, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_texture_rock2 = __pyx_t_58;
  __pyx_t_58.memview = NULL;
  __pyx_t_58.data = NULL;
+1396:     cdef double[:] texture_rock3 = np.zeros(shape=(4 * size_x * size_y))
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1396, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_zeros); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1396, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1396, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_2 = __Pyx_PyInt_From_long(((4 * __pyx_v_size_x) * __pyx_v_size_y)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1396, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_shape, __pyx_t_2) < 0) __PYX_ERR(0, 1396, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1396, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_58 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_2, PyBUF_WRITABLE); if (unlikely(!__pyx_t_58.memview)) __PYX_ERR(0, 1396, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_texture_rock3 = __pyx_t_58;
  __pyx_t_58.memview = NULL;
  __pyx_t_58.data = NULL;
+1397:     cdef double[:] texture_bedrock0 = np.zeros(shape=(4 * size_x * size_y))
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1397, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1397, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1397, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_5 = __Pyx_PyInt_From_long(((4 * __pyx_v_size_x) * __pyx_v_size_y)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1397, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_shape, __pyx_t_5) < 0) __PYX_ERR(0, 1397, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1397, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_58 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_58.memview)) __PYX_ERR(0, 1397, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_texture_bedrock0 = __pyx_t_58;
  __pyx_t_58.memview = NULL;
  __pyx_t_58.data = NULL;
+1398:     cdef double[:] texture_bedrock1 = np.zeros(shape=(4 * size_x * size_y))
  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1398, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1398, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1398, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_3 = __Pyx_PyInt_From_long(((4 * __pyx_v_size_x) * __pyx_v_size_y)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1398, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_shape, __pyx_t_3) < 0) __PYX_ERR(0, 1398, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_empty_tuple, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1398, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_58 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_3, PyBUF_WRITABLE); if (unlikely(!__pyx_t_58.memview)) __PYX_ERR(0, 1398, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_texture_bedrock1 = __pyx_t_58;
  __pyx_t_58.memview = NULL;
  __pyx_t_58.data = NULL;
+1399:     cdef double[:] texture_bedrock2 = np.zeros(shape=(4 * size_x * size_y))
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1399, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_zeros); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1399, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1399, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_2 = __Pyx_PyInt_From_long(((4 * __pyx_v_size_x) * __pyx_v_size_y)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1399, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_shape, __pyx_t_2) < 0) __PYX_ERR(0, 1399, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1399, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_58 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_2, PyBUF_WRITABLE); if (unlikely(!__pyx_t_58.memview)) __PYX_ERR(0, 1399, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_texture_bedrock2 = __pyx_t_58;
  __pyx_t_58.memview = NULL;
  __pyx_t_58.data = NULL;
 1400: 
+1401:     cdef double[:] texture_vegetation = np.zeros(shape=(4 * size_x * size_y))
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1401, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1401, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1401, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_5 = __Pyx_PyInt_From_long(((4 * __pyx_v_size_x) * __pyx_v_size_y)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1401, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_shape, __pyx_t_5) < 0) __PYX_ERR(0, 1401, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1401, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_58 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_58.memview)) __PYX_ERR(0, 1401, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_texture_vegetation = __pyx_t_58;
  __pyx_t_58.memview = NULL;
  __pyx_t_58.data = NULL;
 1402: 
+1403:     cdef double[:] texture_water = np.zeros(shape=(4 * size_x * size_y))
  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1403, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1403, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1403, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_3 = __Pyx_PyInt_From_long(((4 * __pyx_v_size_x) * __pyx_v_size_y)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1403, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_shape, __pyx_t_3) < 0) __PYX_ERR(0, 1403, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_empty_tuple, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1403, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_58 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_3, PyBUF_WRITABLE); if (unlikely(!__pyx_t_58.memview)) __PYX_ERR(0, 1403, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_texture_water = __pyx_t_58;
  __pyx_t_58.memview = NULL;
  __pyx_t_58.data = NULL;
 1404: 
+1405:     cdef double[:] texture_velocity = np.zeros(shape=(4 * size_x * size_y))
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1405, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_zeros); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1405, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1405, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_2 = __Pyx_PyInt_From_long(((4 * __pyx_v_size_x) * __pyx_v_size_y)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1405, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_shape, __pyx_t_2) < 0) __PYX_ERR(0, 1405, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1405, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_58 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_2, PyBUF_WRITABLE); if (unlikely(!__pyx_t_58.memview)) __PYX_ERR(0, 1405, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_texture_velocity = __pyx_t_58;
  __pyx_t_58.memview = NULL;
  __pyx_t_58.data = NULL;
 1406: 
 1407:     # RGBA
+1408:     cdef double[4] color_topsoil = [1.0, 1.0, 0.0, 1.0]
  __pyx_t_59[0] = 1.0;
  __pyx_t_59[1] = 1.0;
  __pyx_t_59[2] = 0.0;
  __pyx_t_59[3] = 1.0;
  memcpy(&(__pyx_v_color_topsoil[0]), __pyx_t_59, sizeof(__pyx_v_color_topsoil[0]) * (4));
 1409: 
+1410:     for x in range(size_x):
  __pyx_t_17 = __pyx_v_size_x;
  __pyx_t_18 = __pyx_t_17;
  for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
    __pyx_v_x = __pyx_t_19;
+1411:         for y in range(size_y):
    __pyx_t_29 = __pyx_v_size_y;
    __pyx_t_28 = __pyx_t_29;
    for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
      __pyx_v_y = __pyx_t_27;
 1412:             # velocity
+1413:             texture_velocity[4 * (x + size_x * y)] = max(min(0.5*sqrt(water[x][y].velocity_y**2 + water[x][y].velocity_x**2), 1.0), 0.0)
      __pyx_t_53 = 0.0;
      __pyx_t_30 = 1.0;
      __pyx_t_46 = (0.5 * sqrt((pow(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).velocity_y, 2.0) + pow(((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).velocity_x, 2.0))));
      __pyx_t_31 = (__pyx_t_30 < __pyx_t_46);
      if (__pyx_t_31) {
        __pyx_t_45 = __pyx_t_30;
      } else {
        __pyx_t_45 = __pyx_t_46;
      }
      __pyx_t_30 = __pyx_t_45;
      __pyx_t_31 = (__pyx_t_53 > __pyx_t_30);
      if (__pyx_t_31) {
        __pyx_t_45 = __pyx_t_53;
      } else {
        __pyx_t_45 = __pyx_t_30;
      }
      __pyx_t_60 = (4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y)));
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_velocity.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_velocity.data + __pyx_t_60 * __pyx_v_texture_velocity.strides[0]) )) = __pyx_t_45;
+1414:             texture_velocity[4 * (x + size_x * y) + 1] = max(min(0.5*water[x][y].velocity_y, 1.0), 0.0)
      __pyx_t_45 = 0.0;
      __pyx_t_53 = 1.0;
      __pyx_t_30 = (0.5 * ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).velocity_y);
      __pyx_t_31 = (__pyx_t_53 < __pyx_t_30);
      if (__pyx_t_31) {
        __pyx_t_46 = __pyx_t_53;
      } else {
        __pyx_t_46 = __pyx_t_30;
      }
      __pyx_t_53 = __pyx_t_46;
      __pyx_t_31 = (__pyx_t_45 > __pyx_t_53);
      if (__pyx_t_31) {
        __pyx_t_46 = __pyx_t_45;
      } else {
        __pyx_t_46 = __pyx_t_53;
      }
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 1);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_velocity.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_velocity.data + __pyx_t_60 * __pyx_v_texture_velocity.strides[0]) )) = __pyx_t_46;
+1415:             texture_velocity[4 * (x + size_x * y) + 2] = max(min(-0.5*water[x][y].velocity_y, 1.0), 0.0)
      __pyx_t_46 = 0.0;
      __pyx_t_45 = 1.0;
      __pyx_t_53 = (-0.5 * ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).velocity_y);
      __pyx_t_31 = (__pyx_t_45 < __pyx_t_53);
      if (__pyx_t_31) {
        __pyx_t_30 = __pyx_t_45;
      } else {
        __pyx_t_30 = __pyx_t_53;
      }
      __pyx_t_45 = __pyx_t_30;
      __pyx_t_31 = (__pyx_t_46 > __pyx_t_45);
      if (__pyx_t_31) {
        __pyx_t_30 = __pyx_t_46;
      } else {
        __pyx_t_30 = __pyx_t_45;
      }
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 2);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_velocity.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_velocity.data + __pyx_t_60 * __pyx_v_texture_velocity.strides[0]) )) = __pyx_t_30;
+1416:             texture_velocity[4 * (x + size_x * y) + 3] = 1.0  # Alpha channel
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 3);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_velocity.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_velocity.data + __pyx_t_60 * __pyx_v_texture_velocity.strides[0]) )) = 1.0;
 1417: 
 1418:             # topsoil texture
+1419:             texture_type[4 * (x + size_x * y) + 1] = min(1.0, get_soil_height(terrain[x][y].topsoil))
      __pyx_t_30 = __pyx_f_6eroder_get_soil_height(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil);
      __pyx_t_46 = 1.0;
      __pyx_t_31 = (__pyx_t_30 < __pyx_t_46);
      if (__pyx_t_31) {
        __pyx_t_45 = __pyx_t_30;
      } else {
        __pyx_t_45 = __pyx_t_46;
      }
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 1);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_type.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_type.data + __pyx_t_60 * __pyx_v_texture_type.strides[0]) )) = __pyx_t_45;
+1420:             texture_type[4 * (x + size_x * y) + 0] = min(1.0, get_soil_height(terrain[x][y].subsoil))
      __pyx_t_45 = __pyx_f_6eroder_get_soil_height(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil);
      __pyx_t_30 = 1.0;
      __pyx_t_31 = (__pyx_t_45 < __pyx_t_30);
      if (__pyx_t_31) {
        __pyx_t_46 = __pyx_t_45;
      } else {
        __pyx_t_46 = __pyx_t_30;
      }
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 0);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_type.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_type.data + __pyx_t_60 * __pyx_v_texture_type.strides[0]) )) = __pyx_t_46;
+1421:             texture_type[4 * (x + size_x * y) + 3] = 1.0  # Alpha channel
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 3);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_type.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_type.data + __pyx_t_60 * __pyx_v_texture_type.strides[0]) )) = 1.0;
 1422: 
 1423:                 #for i in range(4):
 1424:                 #    topsoil_texture[4 * (x + size_x * y) + i] = color_topsoil[i]
 1425: 
 1426: 
 1427:             # material textures
+1428:             render_soil = EMPTY_SOIL
      __pyx_v_render_soil = __pyx_v_6eroder_EMPTY_SOIL;
+1429:             multiplier = 1.0
      __pyx_v_multiplier = 1.0;
 1430: 
 1431:             # topsoil
+1432:             height = get_soil_height(terrain[x][y].topsoil)
      __pyx_v_height = __pyx_f_6eroder_get_soil_height(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil);
 1433: 
+1434:             if height > 0.0:
      __pyx_t_31 = (__pyx_v_height > 0.0);
      if (__pyx_t_31) {
/* … */
      }
+1435:                 render_soil.organic = terrain[x][y].topsoil.organic / height
        __pyx_v_render_soil.organic = (((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil.organic / __pyx_v_height);
+1436:                 for i in range(4):
        for (__pyx_t_44 = 0; __pyx_t_44 < 4; __pyx_t_44+=1) {
          __pyx_v_i = __pyx_t_44;
+1437:                     render_soil.rocks[i] = terrain[x][y].topsoil.rocks[i] / height
          (__pyx_v_render_soil.rocks[__pyx_v_i]) = ((((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).topsoil.rocks[__pyx_v_i]) / __pyx_v_height);
        }
 1438:                 # how transparent
+1439:                 multiplier *= max(0.0, 1 - (height / LAYER_HEIGHT_TO_BECOME_ERODETHROUGH))
        __pyx_t_46 = (1.0 - (__pyx_v_height / __pyx_v_6eroder_LAYER_HEIGHT_TO_BECOME_ERODETHROUGH));
        __pyx_t_45 = 0.0;
        __pyx_t_31 = (__pyx_t_46 > __pyx_t_45);
        if (__pyx_t_31) {
          __pyx_t_30 = __pyx_t_46;
        } else {
          __pyx_t_30 = __pyx_t_45;
        }
        __pyx_v_multiplier = (__pyx_v_multiplier * __pyx_t_30);
 1440: 
 1441:             # subsoil
+1442:             height = get_soil_height(terrain[x][y].subsoil)
      __pyx_v_height = __pyx_f_6eroder_get_soil_height(((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil);
 1443: 
+1444:             if height > 0.0 and multiplier > 0.0:
      __pyx_t_48 = (__pyx_v_height > 0.0);
      if (__pyx_t_48) {
      } else {
        __pyx_t_31 = __pyx_t_48;
        goto __pyx_L166_bool_binop_done;
      }
      __pyx_t_48 = (__pyx_v_multiplier > 0.0);
      __pyx_t_31 = __pyx_t_48;
      __pyx_L166_bool_binop_done:;
      if (__pyx_t_31) {
/* … */
      }
+1445:                 render_soil.organic += terrain[x][y].subsoil.organic / height
        __pyx_v_render_soil.organic = (__pyx_v_render_soil.organic + (((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil.organic / __pyx_v_height));
+1446:                 for i in range(4):
        for (__pyx_t_44 = 0; __pyx_t_44 < 4; __pyx_t_44+=1) {
          __pyx_v_i = __pyx_t_44;
+1447:                     render_soil.rocks[i] += multiplier * terrain[x][y].subsoil.rocks[i] / height
          __pyx_t_37 = __pyx_v_i;
          (__pyx_v_render_soil.rocks[__pyx_t_37]) = ((__pyx_v_render_soil.rocks[__pyx_t_37]) + ((__pyx_v_multiplier * (((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).subsoil.rocks[__pyx_v_i])) / __pyx_v_height));
        }
 1448:                 # how transparent
+1449:                 multiplier *= max(0.0, 1 - (height / LAYER_HEIGHT_TO_BECOME_ERODETHROUGH))
        __pyx_t_30 = (1.0 - (__pyx_v_height / __pyx_v_6eroder_LAYER_HEIGHT_TO_BECOME_ERODETHROUGH));
        __pyx_t_46 = 0.0;
        __pyx_t_31 = (__pyx_t_30 > __pyx_t_46);
        if (__pyx_t_31) {
          __pyx_t_45 = __pyx_t_30;
        } else {
          __pyx_t_45 = __pyx_t_46;
        }
        __pyx_v_multiplier = (__pyx_v_multiplier * __pyx_t_45);
 1450: 
+1451:             render_soil = normalized(render_soil)
      __pyx_v_render_soil = __pyx_f_6eroder_normalized(__pyx_v_render_soil);
+1452:             render_soil = soil_fraction(render_soil, 1 - multiplier)
      __pyx_v_render_soil = __pyx_f_6eroder_soil_fraction(__pyx_v_render_soil, (1.0 - __pyx_v_multiplier));
 1453: 
 1454:             # write to textures
+1455:             texture_organic[4 * (x + size_x * y)] = render_soil.organic
      __pyx_t_45 = __pyx_v_render_soil.organic;
      __pyx_t_60 = (4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y)));
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_organic.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_organic.data + __pyx_t_60 * __pyx_v_texture_organic.strides[0]) )) = __pyx_t_45;
+1456:             texture_organic[4 * (x + size_x * y) + 1] = render_soil.organic
      __pyx_t_45 = __pyx_v_render_soil.organic;
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 1);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_organic.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_organic.data + __pyx_t_60 * __pyx_v_texture_organic.strides[0]) )) = __pyx_t_45;
+1457:             texture_organic[4 * (x + size_x * y) + 2] = render_soil.organic
      __pyx_t_45 = __pyx_v_render_soil.organic;
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 2);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_organic.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_organic.data + __pyx_t_60 * __pyx_v_texture_organic.strides[0]) )) = __pyx_t_45;
+1458:             texture_organic[4 * (x + size_x * y) + 3] = 1.0
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 3);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_organic.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_organic.data + __pyx_t_60 * __pyx_v_texture_organic.strides[0]) )) = 1.0;
 1459: 
 1460: 
+1461:             texture_rock0[4 * (x + size_x * y)] = render_soil.rocks[0]
      __pyx_t_60 = (4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y)));
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock0.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock0.data + __pyx_t_60 * __pyx_v_texture_rock0.strides[0]) )) = (__pyx_v_render_soil.rocks[0]);
+1462:             texture_rock0[4 * (x + size_x * y) + 1] = render_soil.rocks[0]
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 1);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock0.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock0.data + __pyx_t_60 * __pyx_v_texture_rock0.strides[0]) )) = (__pyx_v_render_soil.rocks[0]);
+1463:             texture_rock0[4 * (x + size_x * y) + 2] = render_soil.rocks[0]
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 2);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock0.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock0.data + __pyx_t_60 * __pyx_v_texture_rock0.strides[0]) )) = (__pyx_v_render_soil.rocks[0]);
+1464:             texture_rock0[4 * (x + size_x * y) + 3] = 1.0
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 3);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock0.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock0.data + __pyx_t_60 * __pyx_v_texture_rock0.strides[0]) )) = 1.0;
 1465: 
+1466:             texture_rock1[4 * (x + size_x * y)] = render_soil.rocks[1]
      __pyx_t_60 = (4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y)));
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock1.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock1.data + __pyx_t_60 * __pyx_v_texture_rock1.strides[0]) )) = (__pyx_v_render_soil.rocks[1]);
+1467:             texture_rock1[4 * (x + size_x * y) + 1] = render_soil.rocks[1]
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 1);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock1.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock1.data + __pyx_t_60 * __pyx_v_texture_rock1.strides[0]) )) = (__pyx_v_render_soil.rocks[1]);
+1468:             texture_rock1[4 * (x + size_x * y) + 2] = render_soil.rocks[1]
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 2);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock1.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock1.data + __pyx_t_60 * __pyx_v_texture_rock1.strides[0]) )) = (__pyx_v_render_soil.rocks[1]);
+1469:             texture_rock1[4 * (x + size_x * y) + 3] = 1.0
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 3);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock1.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock1.data + __pyx_t_60 * __pyx_v_texture_rock1.strides[0]) )) = 1.0;
 1470: 
+1471:             texture_rock2[4 * (x + size_x * y)] = render_soil.rocks[2]
      __pyx_t_60 = (4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y)));
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock2.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock2.data + __pyx_t_60 * __pyx_v_texture_rock2.strides[0]) )) = (__pyx_v_render_soil.rocks[2]);
+1472:             texture_rock2[4 * (x + size_x * y) + 1] = render_soil.rocks[2]
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 1);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock2.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock2.data + __pyx_t_60 * __pyx_v_texture_rock2.strides[0]) )) = (__pyx_v_render_soil.rocks[2]);
+1473:             texture_rock2[4 * (x + size_x * y) + 2] = render_soil.rocks[2]
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 2);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock2.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock2.data + __pyx_t_60 * __pyx_v_texture_rock2.strides[0]) )) = (__pyx_v_render_soil.rocks[2]);
+1474:             texture_rock2[4 * (x + size_x * y) + 3] = 1.0
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 3);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock2.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock2.data + __pyx_t_60 * __pyx_v_texture_rock2.strides[0]) )) = 1.0;
 1475: 
+1476:             texture_rock3[4 * (x + size_x * y)] = render_soil.rocks[3]
      __pyx_t_60 = (4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y)));
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock3.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock3.data + __pyx_t_60 * __pyx_v_texture_rock3.strides[0]) )) = (__pyx_v_render_soil.rocks[3]);
+1477:             texture_rock3[4 * (x + size_x * y) + 1] = render_soil.rocks[3]
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 1);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock3.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock3.data + __pyx_t_60 * __pyx_v_texture_rock3.strides[0]) )) = (__pyx_v_render_soil.rocks[3]);
+1478:             texture_rock3[4 * (x + size_x * y) + 2] = render_soil.rocks[3]
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 2);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock3.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock3.data + __pyx_t_60 * __pyx_v_texture_rock3.strides[0]) )) = (__pyx_v_render_soil.rocks[3]);
+1479:             texture_rock3[4 * (x + size_x * y) + 3] = 1.0
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 3);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_rock3.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_rock3.data + __pyx_t_60 * __pyx_v_texture_rock3.strides[0]) )) = 1.0;
 1480: 
 1481:             # water and wetness
+1482:             if water[x][y].height > 0.0:
      __pyx_t_31 = (((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height > 0.0);
      if (__pyx_t_31) {
/* … */
      }
+1483:                 texture_water[4 * (x + size_x * y)] = min(water[x][y].height, 1.0)
        __pyx_t_45 = 1.0;
        __pyx_t_30 = ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height;
        __pyx_t_31 = (__pyx_t_45 < __pyx_t_30);
        if (__pyx_t_31) {
          __pyx_t_46 = __pyx_t_45;
        } else {
          __pyx_t_46 = __pyx_t_30;
        }
        __pyx_t_60 = (4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y)));
        if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_water.shape[0];
        *((double *) ( /* dim=0 */ (__pyx_v_texture_water.data + __pyx_t_60 * __pyx_v_texture_water.strides[0]) )) = __pyx_t_46;
+1484:                 texture_water[4 * (x + size_x * y) + 1] = min(water[x][y].height, 1.0)
        __pyx_t_46 = 1.0;
        __pyx_t_45 = ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height;
        __pyx_t_31 = (__pyx_t_46 < __pyx_t_45);
        if (__pyx_t_31) {
          __pyx_t_30 = __pyx_t_46;
        } else {
          __pyx_t_30 = __pyx_t_45;
        }
        __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 1);
        if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_water.shape[0];
        *((double *) ( /* dim=0 */ (__pyx_v_texture_water.data + __pyx_t_60 * __pyx_v_texture_water.strides[0]) )) = __pyx_t_30;
+1485:                 texture_water[4 * (x + size_x * y) + 2] = min(water[x][y].height, 1.0)
        __pyx_t_30 = 1.0;
        __pyx_t_46 = ((__pyx_v_water[__pyx_v_x])[__pyx_v_y]).height;
        __pyx_t_31 = (__pyx_t_30 < __pyx_t_46);
        if (__pyx_t_31) {
          __pyx_t_45 = __pyx_t_30;
        } else {
          __pyx_t_45 = __pyx_t_46;
        }
        __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 2);
        if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_water.shape[0];
        *((double *) ( /* dim=0 */ (__pyx_v_texture_water.data + __pyx_t_60 * __pyx_v_texture_water.strides[0]) )) = __pyx_t_45;
+1486:             texture_water[4 * (x + size_x * y) + 3] = 1.0
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 3);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_water.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_water.data + __pyx_t_60 * __pyx_v_texture_water.strides[0]) )) = 1.0;
 1487: 
 1488: 
 1489: 
 1490:             # bedrock
+1491:             if multiplier > 0.0:
      __pyx_t_31 = (__pyx_v_multiplier > 0.0);
      if (__pyx_t_31) {
/* … */
      }
 1492:                 # first non-empty
+1493:                 i = 0
        __pyx_v_i = 0;
+1494:                 while terrain[x][y].bedrock[i].height <= 0.0:
        while (1) {
          __pyx_t_31 = ((((__pyx_v_terrain[__pyx_v_x])[__pyx_v_y]).bedrock[__pyx_v_i]).height <= 0.0);
          if (!__pyx_t_31) break;
+1495:                     i += 1
          __pyx_v_i = (__pyx_v_i + 1);
        }
 1496: 
+1497:                 if i == 0:
        switch (__pyx_v_i) {
          case 0:
/* … */
          break;
          case 1:
+1498:                     texture_bedrock0[4 * (x + size_x * y)] = multiplier
          __pyx_t_60 = (4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y)));
          if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_bedrock0.shape[0];
          *((double *) ( /* dim=0 */ (__pyx_v_texture_bedrock0.data + __pyx_t_60 * __pyx_v_texture_bedrock0.strides[0]) )) = __pyx_v_multiplier;
+1499:                     texture_bedrock0[4 * (x + size_x * y) + 1] = multiplier
          __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 1);
          if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_bedrock0.shape[0];
          *((double *) ( /* dim=0 */ (__pyx_v_texture_bedrock0.data + __pyx_t_60 * __pyx_v_texture_bedrock0.strides[0]) )) = __pyx_v_multiplier;
+1500:                     texture_bedrock0[4 * (x + size_x * y) + 2] = multiplier
          __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 2);
          if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_bedrock0.shape[0];
          *((double *) ( /* dim=0 */ (__pyx_v_texture_bedrock0.data + __pyx_t_60 * __pyx_v_texture_bedrock0.strides[0]) )) = __pyx_v_multiplier;
+1501:                 elif i == 1:
          break;
          case 2:
+1502:                     texture_bedrock1[4 * (x + size_x * y)] = multiplier
          __pyx_t_60 = (4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y)));
          if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_bedrock1.shape[0];
          *((double *) ( /* dim=0 */ (__pyx_v_texture_bedrock1.data + __pyx_t_60 * __pyx_v_texture_bedrock1.strides[0]) )) = __pyx_v_multiplier;
+1503:                     texture_bedrock1[4 * (x + size_x * y) + 1] = multiplier
          __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 1);
          if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_bedrock1.shape[0];
          *((double *) ( /* dim=0 */ (__pyx_v_texture_bedrock1.data + __pyx_t_60 * __pyx_v_texture_bedrock1.strides[0]) )) = __pyx_v_multiplier;
+1504:                     texture_bedrock1[4 * (x + size_x * y) + 2] = multiplier
          __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 2);
          if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_bedrock1.shape[0];
          *((double *) ( /* dim=0 */ (__pyx_v_texture_bedrock1.data + __pyx_t_60 * __pyx_v_texture_bedrock1.strides[0]) )) = __pyx_v_multiplier;
+1505:                 elif i == 2:
          break;
          default: break;
        }
+1506:                     texture_bedrock2[4 * (x + size_x * y)] = multiplier
          __pyx_t_60 = (4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y)));
          if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_bedrock2.shape[0];
          *((double *) ( /* dim=0 */ (__pyx_v_texture_bedrock2.data + __pyx_t_60 * __pyx_v_texture_bedrock2.strides[0]) )) = __pyx_v_multiplier;
+1507:                     texture_bedrock2[4 * (x + size_x * y) + 1] = multiplier
          __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 1);
          if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_bedrock2.shape[0];
          *((double *) ( /* dim=0 */ (__pyx_v_texture_bedrock2.data + __pyx_t_60 * __pyx_v_texture_bedrock2.strides[0]) )) = __pyx_v_multiplier;
+1508:                     texture_bedrock2[4 * (x + size_x * y) + 2] = multiplier
          __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 2);
          if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_bedrock2.shape[0];
          *((double *) ( /* dim=0 */ (__pyx_v_texture_bedrock2.data + __pyx_t_60 * __pyx_v_texture_bedrock2.strides[0]) )) = __pyx_v_multiplier;
+1509:             texture_bedrock0[4 * (x + size_x * y) + 3] = 1.0  # transparency
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 3);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_bedrock0.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_bedrock0.data + __pyx_t_60 * __pyx_v_texture_bedrock0.strides[0]) )) = 1.0;
+1510:             texture_bedrock1[4 * (x + size_x * y) + 3] = 1.0  # transparency
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 3);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_bedrock1.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_bedrock1.data + __pyx_t_60 * __pyx_v_texture_bedrock1.strides[0]) )) = 1.0;
+1511:             texture_bedrock2[4 * (x + size_x * y) + 3] = 1.0  # transparency
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 3);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_bedrock2.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_bedrock2.data + __pyx_t_60 * __pyx_v_texture_bedrock2.strides[0]) )) = 1.0;
 1512: 
 1513: 
 1514:             # vegetation
+1515:             texture_vegetation[4 * (x + size_x * y)] = vegetation[x][y]
      __pyx_t_39 = __pyx_v_x;
      __pyx_t_52 = __pyx_v_y;
      __pyx_t_60 = (4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y)));
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_vegetation.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_vegetation.data + __pyx_t_60 * __pyx_v_texture_vegetation.strides[0]) )) = (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_39 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_52)) )));
+1516:             texture_vegetation[4 * (x + size_x * y) + 1] = vegetation[x][y]
      __pyx_t_52 = __pyx_v_x;
      __pyx_t_39 = __pyx_v_y;
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 1);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_vegetation.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_vegetation.data + __pyx_t_60 * __pyx_v_texture_vegetation.strides[0]) )) = (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_52 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_39)) )));
+1517:             texture_vegetation[4 * (x + size_x * y) + 2] = vegetation[x][y]
      __pyx_t_39 = __pyx_v_x;
      __pyx_t_52 = __pyx_v_y;
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 2);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_vegetation.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_vegetation.data + __pyx_t_60 * __pyx_v_texture_vegetation.strides[0]) )) = (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_vegetation.data + __pyx_t_39 * __pyx_v_vegetation.strides[0]) )) + __pyx_t_52)) )));
+1518:             texture_vegetation[4 * (x + size_x * y) + 3] = 1.0
      __pyx_t_60 = ((4 * (__pyx_v_x + (__pyx_v_size_x * __pyx_v_y))) + 3);
      if (__pyx_t_60 < 0) __pyx_t_60 += __pyx_v_texture_vegetation.shape[0];
      *((double *) ( /* dim=0 */ (__pyx_v_texture_vegetation.data + __pyx_t_60 * __pyx_v_texture_vegetation.strides[0]) )) = 1.0;
    }
  }
 1519: 
 1520: 
 1521: 
 1522:     # create Python lists
+1523:     _topsoil = [[terrain[x][y].topsoil.rocks[0],
  { /* enter inner scope */
    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1523, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
/* … */
        __pyx_t_3 = PyFloat_FromDouble((((__pyx_v_terrain[__pyx_7genexpr__pyx_v_x])[__pyx_7genexpr__pyx_v_y]).topsoil.rocks[0])); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1523, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
/* … */
        __pyx_t_62 = PyList_New(5); if (unlikely(!__pyx_t_62)) __PYX_ERR(0, 1523, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_62);
        __Pyx_GIVEREF(__pyx_t_3);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_62, 0, __pyx_t_3)) __PYX_ERR(0, 1523, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_5);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_62, 1, __pyx_t_5)) __PYX_ERR(0, 1523, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_4);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_62, 2, __pyx_t_4)) __PYX_ERR(0, 1523, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_1);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_62, 3, __pyx_t_1)) __PYX_ERR(0, 1523, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_61);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_62, 4, __pyx_t_61)) __PYX_ERR(0, 1523, __pyx_L1_error);
        __pyx_t_3 = 0;
        __pyx_t_5 = 0;
        __pyx_t_4 = 0;
        __pyx_t_1 = 0;
        __pyx_t_61 = 0;
        if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_62))) __PYX_ERR(0, 1523, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_62); __pyx_t_62 = 0;
      }
    }
  } /* exit inner scope */
  __Pyx_DECREF_SET(__pyx_v__topsoil, ((PyObject*)__pyx_t_2));
  __pyx_t_2 = 0;
+1524:                   terrain[x][y].topsoil.rocks[1],
        __pyx_t_5 = PyFloat_FromDouble((((__pyx_v_terrain[__pyx_7genexpr__pyx_v_x])[__pyx_7genexpr__pyx_v_y]).topsoil.rocks[1])); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1524, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
+1525:                   terrain[x][y].topsoil.rocks[2],
        __pyx_t_4 = PyFloat_FromDouble((((__pyx_v_terrain[__pyx_7genexpr__pyx_v_x])[__pyx_7genexpr__pyx_v_y]).topsoil.rocks[2])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1525, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
+1526:                   terrain[x][y].topsoil.rocks[3],
        __pyx_t_1 = PyFloat_FromDouble((((__pyx_v_terrain[__pyx_7genexpr__pyx_v_x])[__pyx_7genexpr__pyx_v_y]).topsoil.rocks[3])); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1526, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
+1527:                   terrain[x][y].topsoil.organic] for y in range(size_y) for x in range(size_x)]
    __pyx_t_17 = __pyx_v_size_y;
    __pyx_t_18 = __pyx_t_17;
    for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_7genexpr__pyx_v_y = __pyx_t_19;
      __pyx_t_29 = __pyx_v_size_x;
      __pyx_t_28 = __pyx_t_29;
      for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
        __pyx_7genexpr__pyx_v_x = __pyx_t_27;
/* … */
        __pyx_t_61 = PyFloat_FromDouble(((__pyx_v_terrain[__pyx_7genexpr__pyx_v_x])[__pyx_7genexpr__pyx_v_y]).topsoil.organic); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1527, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_61);
 1528: 
+1529:     _subsoil = [[terrain[x][y].subsoil.rocks[0],
  { /* enter inner scope */
    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1529, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
/* … */
        __pyx_t_62 = PyFloat_FromDouble((((__pyx_v_terrain[__pyx_8genexpr1__pyx_v_x])[__pyx_8genexpr1__pyx_v_y]).subsoil.rocks[0])); if (unlikely(!__pyx_t_62)) __PYX_ERR(0, 1529, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_62);
/* … */
        __pyx_t_3 = PyList_New(5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1529, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __Pyx_GIVEREF(__pyx_t_62);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 0, __pyx_t_62)) __PYX_ERR(0, 1529, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_61);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 1, __pyx_t_61)) __PYX_ERR(0, 1529, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_1);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 2, __pyx_t_1)) __PYX_ERR(0, 1529, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_4);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 3, __pyx_t_4)) __PYX_ERR(0, 1529, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_5);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 4, __pyx_t_5)) __PYX_ERR(0, 1529, __pyx_L1_error);
        __pyx_t_62 = 0;
        __pyx_t_61 = 0;
        __pyx_t_1 = 0;
        __pyx_t_4 = 0;
        __pyx_t_5 = 0;
        if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_3))) __PYX_ERR(0, 1529, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      }
    }
  } /* exit inner scope */
  __Pyx_DECREF_SET(__pyx_v__subsoil, ((PyObject*)__pyx_t_2));
  __pyx_t_2 = 0;
+1530:                   terrain[x][y].subsoil.rocks[1],
        __pyx_t_61 = PyFloat_FromDouble((((__pyx_v_terrain[__pyx_8genexpr1__pyx_v_x])[__pyx_8genexpr1__pyx_v_y]).subsoil.rocks[1])); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1530, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_61);
+1531:                   terrain[x][y].subsoil.rocks[2],
        __pyx_t_1 = PyFloat_FromDouble((((__pyx_v_terrain[__pyx_8genexpr1__pyx_v_x])[__pyx_8genexpr1__pyx_v_y]).subsoil.rocks[2])); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1531, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
+1532:                   terrain[x][y].subsoil.rocks[3],
        __pyx_t_4 = PyFloat_FromDouble((((__pyx_v_terrain[__pyx_8genexpr1__pyx_v_x])[__pyx_8genexpr1__pyx_v_y]).subsoil.rocks[3])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1532, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
+1533:                   terrain[x][y].subsoil.organic] for y in range(size_y) for x in range(size_x)]
    __pyx_t_17 = __pyx_v_size_y;
    __pyx_t_18 = __pyx_t_17;
    for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_8genexpr1__pyx_v_y = __pyx_t_19;
      __pyx_t_29 = __pyx_v_size_x;
      __pyx_t_28 = __pyx_t_29;
      for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
        __pyx_8genexpr1__pyx_v_x = __pyx_t_27;
/* … */
        __pyx_t_5 = PyFloat_FromDouble(((__pyx_v_terrain[__pyx_8genexpr1__pyx_v_x])[__pyx_8genexpr1__pyx_v_y]).subsoil.organic); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1533, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
 1534: 
+1535:     _bedrock = [[terrain[x][y].bedrock[i].height
  { /* enter inner scope */
    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1535, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
/* … */
          __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1535, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
/* … */
            __pyx_t_5 = PyFloat_FromDouble((((__pyx_v_terrain[__pyx_8genexpr2__pyx_v_x])[__pyx_8genexpr2__pyx_v_y]).bedrock[__pyx_8genexpr3__pyx_v_i]).height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1535, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_5))) __PYX_ERR(0, 1535, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          }
        } /* exit inner scope */
        if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_3))) __PYX_ERR(0, 1535, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      }
    }
  } /* exit inner scope */
  __Pyx_DECREF_SET(__pyx_v__bedrock, ((PyObject*)__pyx_t_2));
  __pyx_t_2 = 0;
+1536:                  for i in range(len(terrain[x][y].bedrock))] for y in range(size_y) for x in range(size_x)]
    __pyx_t_17 = __pyx_v_size_y;
    __pyx_t_18 = __pyx_t_17;
    for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_8genexpr2__pyx_v_y = __pyx_t_19;
      __pyx_t_29 = __pyx_v_size_x;
      __pyx_t_28 = __pyx_t_29;
      for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
        __pyx_8genexpr2__pyx_v_x = __pyx_t_27;
        { /* enter inner scope */
/* … */
          __pyx_t_5 = __pyx_convert_vector_to_py_struct____pyx_t_6eroder_Bedrock(((__pyx_v_terrain[__pyx_8genexpr2__pyx_v_x])[__pyx_8genexpr2__pyx_v_y]).bedrock); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1536, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_5);
          __pyx_t_34 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_34 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1536, __pyx_L1_error)
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          __pyx_t_35 = __pyx_t_34;
          for (__pyx_t_44 = 0; __pyx_t_44 < __pyx_t_35; __pyx_t_44+=1) {
            __pyx_8genexpr3__pyx_v_i = __pyx_t_44;
 1537: 
+1538:     _sediment = [[water[x][y].sediment.rocks[0],
  { /* enter inner scope */
    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1538, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
/* … */
        __pyx_t_3 = PyFloat_FromDouble((((__pyx_v_water[__pyx_8genexpr4__pyx_v_x])[__pyx_8genexpr4__pyx_v_y]).sediment.rocks[0])); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1538, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
/* … */
        __pyx_t_62 = PyList_New(5); if (unlikely(!__pyx_t_62)) __PYX_ERR(0, 1538, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_62);
        __Pyx_GIVEREF(__pyx_t_3);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_62, 0, __pyx_t_3)) __PYX_ERR(0, 1538, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_5);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_62, 1, __pyx_t_5)) __PYX_ERR(0, 1538, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_4);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_62, 2, __pyx_t_4)) __PYX_ERR(0, 1538, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_1);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_62, 3, __pyx_t_1)) __PYX_ERR(0, 1538, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_61);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_62, 4, __pyx_t_61)) __PYX_ERR(0, 1538, __pyx_L1_error);
        __pyx_t_3 = 0;
        __pyx_t_5 = 0;
        __pyx_t_4 = 0;
        __pyx_t_1 = 0;
        __pyx_t_61 = 0;
        if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_62))) __PYX_ERR(0, 1538, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_62); __pyx_t_62 = 0;
      }
    }
  } /* exit inner scope */
  __Pyx_DECREF_SET(__pyx_v__sediment, ((PyObject*)__pyx_t_2));
  __pyx_t_2 = 0;
+1539:                    water[x][y].sediment.rocks[1],
        __pyx_t_5 = PyFloat_FromDouble((((__pyx_v_water[__pyx_8genexpr4__pyx_v_x])[__pyx_8genexpr4__pyx_v_y]).sediment.rocks[1])); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1539, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
+1540:                    water[x][y].sediment.rocks[2],
        __pyx_t_4 = PyFloat_FromDouble((((__pyx_v_water[__pyx_8genexpr4__pyx_v_x])[__pyx_8genexpr4__pyx_v_y]).sediment.rocks[2])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1540, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
+1541:                    water[x][y].sediment.rocks[3],
        __pyx_t_1 = PyFloat_FromDouble((((__pyx_v_water[__pyx_8genexpr4__pyx_v_x])[__pyx_8genexpr4__pyx_v_y]).sediment.rocks[3])); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1541, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
+1542:                    water[x][y].sediment.organic] for y in range(size_y) for x in range(size_x)]
    __pyx_t_17 = __pyx_v_size_y;
    __pyx_t_18 = __pyx_t_17;
    for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_8genexpr4__pyx_v_y = __pyx_t_19;
      __pyx_t_29 = __pyx_v_size_x;
      __pyx_t_28 = __pyx_t_29;
      for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
        __pyx_8genexpr4__pyx_v_x = __pyx_t_27;
/* … */
        __pyx_t_61 = PyFloat_FromDouble(((__pyx_v_water[__pyx_8genexpr4__pyx_v_x])[__pyx_8genexpr4__pyx_v_y]).sediment.organic); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1542, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_61);
 1543: 
+1544:     _water = [[water[x][y].height for y in range(size_y)] for x in range(size_x)]
  { /* enter inner scope */
    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1544, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_17 = __pyx_v_size_x;
    __pyx_t_18 = __pyx_t_17;
    for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_8genexpr5__pyx_v_x = __pyx_t_19;
      { /* enter inner scope */
        __pyx_t_62 = PyList_New(0); if (unlikely(!__pyx_t_62)) __PYX_ERR(0, 1544, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_62);
        __pyx_t_29 = __pyx_v_size_y;
        __pyx_t_28 = __pyx_t_29;
        for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
          __pyx_8genexpr6__pyx_v_y = __pyx_t_27;
          __pyx_t_61 = PyFloat_FromDouble(((__pyx_v_water[__pyx_8genexpr5__pyx_v_x])[__pyx_8genexpr6__pyx_v_y]).height); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1544, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_61);
          if (unlikely(__Pyx_ListComp_Append(__pyx_t_62, (PyObject*)__pyx_t_61))) __PYX_ERR(0, 1544, __pyx_L1_error)
          __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
        }
      } /* exit inner scope */
      if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_62))) __PYX_ERR(0, 1544, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_62); __pyx_t_62 = 0;
    }
  } /* exit inner scope */
  __Pyx_DECREF_SET(__pyx_v__water, ((PyObject*)__pyx_t_2));
  __pyx_t_2 = 0;
+1545:     _previous_water = [[water[x][y].previous for y in range(size_y)] for x in range(size_x)]
  { /* enter inner scope */
    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1545, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_17 = __pyx_v_size_x;
    __pyx_t_18 = __pyx_t_17;
    for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_8genexpr7__pyx_v_x = __pyx_t_19;
      { /* enter inner scope */
        __pyx_t_62 = PyList_New(0); if (unlikely(!__pyx_t_62)) __PYX_ERR(0, 1545, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_62);
        __pyx_t_29 = __pyx_v_size_y;
        __pyx_t_28 = __pyx_t_29;
        for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
          __pyx_8genexpr8__pyx_v_y = __pyx_t_27;
          __pyx_t_61 = PyFloat_FromDouble(((__pyx_v_water[__pyx_8genexpr7__pyx_v_x])[__pyx_8genexpr8__pyx_v_y]).previous); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1545, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_61);
          if (unlikely(__Pyx_ListComp_Append(__pyx_t_62, (PyObject*)__pyx_t_61))) __PYX_ERR(0, 1545, __pyx_L1_error)
          __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
        }
      } /* exit inner scope */
      if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_62))) __PYX_ERR(0, 1545, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_62); __pyx_t_62 = 0;
    }
  } /* exit inner scope */
  __Pyx_DECREF_SET(__pyx_v__previous_water, ((PyObject*)__pyx_t_2));
  __pyx_t_2 = 0;
+1546:     _regolith = [[water[x][y].regolith.organic, water[x][y].regolith.rocks[0]] for y in range(size_y) for x in range(size_x)]
  { /* enter inner scope */
    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1546, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_17 = __pyx_v_size_y;
    __pyx_t_18 = __pyx_t_17;
    for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_8genexpr9__pyx_v_y = __pyx_t_19;
      __pyx_t_29 = __pyx_v_size_x;
      __pyx_t_28 = __pyx_t_29;
      for (__pyx_t_27 = 0; __pyx_t_27 < __pyx_t_28; __pyx_t_27+=1) {
        __pyx_8genexpr9__pyx_v_x = __pyx_t_27;
        __pyx_t_62 = PyFloat_FromDouble(((__pyx_v_water[__pyx_8genexpr9__pyx_v_x])[__pyx_8genexpr9__pyx_v_y]).regolith.organic); if (unlikely(!__pyx_t_62)) __PYX_ERR(0, 1546, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_62);
        __pyx_t_61 = PyFloat_FromDouble((((__pyx_v_water[__pyx_8genexpr9__pyx_v_x])[__pyx_8genexpr9__pyx_v_y]).regolith.rocks[0])); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1546, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_61);
        __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1546, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_GIVEREF(__pyx_t_62);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_62)) __PYX_ERR(0, 1546, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_61);
        if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 1, __pyx_t_61)) __PYX_ERR(0, 1546, __pyx_L1_error);
        __pyx_t_62 = 0;
        __pyx_t_61 = 0;
        if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_1))) __PYX_ERR(0, 1546, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      }
    }
  } /* exit inner scope */
  __Pyx_DECREF_SET(__pyx_v__regolith, ((PyObject*)__pyx_t_2));
  __pyx_t_2 = 0;
 1547: 
 1548:     # return a ctuple (or tuple? tbh nobody cares, it works) of Python lists by converting a memoryview into a numpy array and then converting that into a regular array
+1549:     return (np.array(heightmap).tolist(),
  __Pyx_XDECREF(__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_61, __pyx_n_s_np); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1549, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_62 = __Pyx_PyObject_GetAttrStr(__pyx_t_61, __pyx_n_s_array); if (unlikely(!__pyx_t_62)) __PYX_ERR(0, 1549, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_62);
  __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
  __pyx_t_61 = __pyx_memoryview_fromslice(__pyx_v_heightmap, 2, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1549, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_4 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_62))) {
    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_62);
    if (likely(__pyx_t_4)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_62);
      __Pyx_INCREF(__pyx_t_4);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_62, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_t_61};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_62, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1549, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_62); __pyx_t_62 = 0;
  }
  __pyx_t_62 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_tolist); if (unlikely(!__pyx_t_62)) __PYX_ERR(0, 1549, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_62);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_62))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_62);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_62);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_62, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_1, NULL};
    __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_62, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1549, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_62); __pyx_t_62 = 0;
  }
/* … */
  __pyx_t_66 = PyTuple_New(19); if (unlikely(!__pyx_t_66)) __PYX_ERR(0, 1549, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_66);
  __Pyx_GIVEREF(__pyx_t_2);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 0, __pyx_t_2)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_INCREF(__pyx_v__water);
  __Pyx_GIVEREF(__pyx_v__water);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 1, __pyx_v__water)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_INCREF(__pyx_v__previous_water);
  __Pyx_GIVEREF(__pyx_v__previous_water);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 2, __pyx_v__previous_water)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_INCREF(__pyx_v__sediment);
  __Pyx_GIVEREF(__pyx_v__sediment);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 3, __pyx_v__sediment)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_62);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 4, __pyx_t_62)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_INCREF(__pyx_v__regolith);
  __Pyx_GIVEREF(__pyx_v__regolith);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 5, __pyx_v__regolith)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_INCREF(__pyx_v__topsoil);
  __Pyx_GIVEREF(__pyx_v__topsoil);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 6, __pyx_v__topsoil)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_INCREF(__pyx_v__subsoil);
  __Pyx_GIVEREF(__pyx_v__subsoil);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 7, __pyx_v__subsoil)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_INCREF(__pyx_v__bedrock);
  __Pyx_GIVEREF(__pyx_v__bedrock);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 8, __pyx_v__bedrock)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_INCREF(__pyx_v__bedrock_types);
  __Pyx_GIVEREF(__pyx_v__bedrock_types);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 9, __pyx_v__bedrock_types)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_4);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 10, __pyx_t_4)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_5);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 11, __pyx_t_5)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_3);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 12, __pyx_t_3)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_63);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 13, __pyx_t_63)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_64);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 14, __pyx_t_64)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_69);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 15, __pyx_t_69)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_61);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 16, __pyx_t_61)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_1);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 17, __pyx_t_1)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_67);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_66, 18, __pyx_t_67)) __PYX_ERR(0, 1549, __pyx_L1_error);
  __pyx_t_2 = 0;
  __pyx_t_62 = 0;
  __pyx_t_4 = 0;
  __pyx_t_5 = 0;
  __pyx_t_3 = 0;
  __pyx_t_63 = 0;
  __pyx_t_64 = 0;
  __pyx_t_69 = 0;
  __pyx_t_61 = 0;
  __pyx_t_1 = 0;
  __pyx_t_67 = 0;
  __pyx_r = __pyx_t_66;
  __pyx_t_66 = 0;
  goto __pyx_L0;
 1550:     _water,
 1551:     _previous_water,
 1552:     _sediment,
+1553:     np.array(flow).tolist(),
  __Pyx_GetModuleGlobalName(__pyx_t_61, __pyx_n_s_np); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1553, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_61, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1553, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
  __pyx_t_61 = __pyx_memoryview_fromslice(__pyx_v_flow, 3, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1553, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_5 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_4))) {
    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
    if (likely(__pyx_t_5)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_4, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_t_61};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1553, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  }
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_tolist); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1553, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_4))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_4);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_4, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_1, NULL};
    __pyx_t_62 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_62)) __PYX_ERR(0, 1553, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_62);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  }
 1554:     _regolith,
 1555:     _topsoil,
 1556:     _subsoil,
 1557:     _bedrock,
 1558:     _bedrock_types,
+1559:     np.array(wet).tolist(),
  __Pyx_GetModuleGlobalName(__pyx_t_61, __pyx_n_s_np); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1559, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_61, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1559, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
  __pyx_t_61 = __pyx_memoryview_fromslice(__pyx_v_wet, 2, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1559, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_3 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_t_61};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1559, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_tolist); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1559, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_1, NULL};
    __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1559, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
+1560:     np.array(vegetation).tolist(),
  __Pyx_GetModuleGlobalName(__pyx_t_61, __pyx_n_s_np); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1560, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_61, __pyx_n_s_array); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1560, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
  __pyx_t_61 = __pyx_memoryview_fromslice(__pyx_v_vegetation, 2, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1560, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_63 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_63 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_63)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_63);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_63, __pyx_t_61};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_63); __pyx_t_63 = 0;
    __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1560, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  }
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_tolist); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1560, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_1, NULL};
    __pyx_t_5 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1560, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  }
+1561:     np.array(texture_type).tolist(),
  __Pyx_GetModuleGlobalName(__pyx_t_61, __pyx_n_s_np); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1561, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_63 = __Pyx_PyObject_GetAttrStr(__pyx_t_61, __pyx_n_s_array); if (unlikely(!__pyx_t_63)) __PYX_ERR(0, 1561, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_63);
  __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
  __pyx_t_61 = __pyx_memoryview_fromslice(__pyx_v_texture_type, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1561, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_64 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_63))) {
    __pyx_t_64 = PyMethod_GET_SELF(__pyx_t_63);
    if (likely(__pyx_t_64)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_63);
      __Pyx_INCREF(__pyx_t_64);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_63, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_64, __pyx_t_61};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_63, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_64); __pyx_t_64 = 0;
    __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1561, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_63); __pyx_t_63 = 0;
  }
  __pyx_t_63 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_tolist); if (unlikely(!__pyx_t_63)) __PYX_ERR(0, 1561, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_63);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_63))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_63);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_63);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_63, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_1, NULL};
    __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_63, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1561, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_63); __pyx_t_63 = 0;
  }
+1562:     np.array(texture_velocity).tolist(),
  __Pyx_GetModuleGlobalName(__pyx_t_61, __pyx_n_s_np); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1562, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_64 = __Pyx_PyObject_GetAttrStr(__pyx_t_61, __pyx_n_s_array); if (unlikely(!__pyx_t_64)) __PYX_ERR(0, 1562, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_64);
  __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
  __pyx_t_61 = __pyx_memoryview_fromslice(__pyx_v_texture_velocity, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1562, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_65 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_64))) {
    __pyx_t_65 = PyMethod_GET_SELF(__pyx_t_64);
    if (likely(__pyx_t_65)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_64);
      __Pyx_INCREF(__pyx_t_65);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_64, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_65, __pyx_t_61};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_64, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_65); __pyx_t_65 = 0;
    __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1562, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_64); __pyx_t_64 = 0;
  }
  __pyx_t_64 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_tolist); if (unlikely(!__pyx_t_64)) __PYX_ERR(0, 1562, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_64);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_64))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_64);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_64);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_64, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_1, NULL};
    __pyx_t_63 = __Pyx_PyObject_FastCall(__pyx_t_64, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_63)) __PYX_ERR(0, 1562, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_63);
    __Pyx_DECREF(__pyx_t_64); __pyx_t_64 = 0;
  }
+1563:     np.array(texture_organic).tolist(),
  __Pyx_GetModuleGlobalName(__pyx_t_61, __pyx_n_s_np); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1563, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_65 = __Pyx_PyObject_GetAttrStr(__pyx_t_61, __pyx_n_s_array); if (unlikely(!__pyx_t_65)) __PYX_ERR(0, 1563, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_65);
  __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
  __pyx_t_61 = __pyx_memoryview_fromslice(__pyx_v_texture_organic, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1563, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_66 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_65))) {
    __pyx_t_66 = PyMethod_GET_SELF(__pyx_t_65);
    if (likely(__pyx_t_66)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_65);
      __Pyx_INCREF(__pyx_t_66);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_65, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_66, __pyx_t_61};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_65, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_66); __pyx_t_66 = 0;
    __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1563, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_65); __pyx_t_65 = 0;
  }
  __pyx_t_65 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_tolist); if (unlikely(!__pyx_t_65)) __PYX_ERR(0, 1563, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_65);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_65))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_65);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_65);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_65, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_1, NULL};
    __pyx_t_64 = __Pyx_PyObject_FastCall(__pyx_t_65, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_64)) __PYX_ERR(0, 1563, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_64);
    __Pyx_DECREF(__pyx_t_65); __pyx_t_65 = 0;
  }
+1564:     (np.array(texture_rock0).tolist(), np.array(texture_rock1).tolist(), np.array(texture_rock2).tolist(), np.array(texture_rock3).tolist()),
  __Pyx_GetModuleGlobalName(__pyx_t_61, __pyx_n_s_np); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_66 = __Pyx_PyObject_GetAttrStr(__pyx_t_61, __pyx_n_s_array); if (unlikely(!__pyx_t_66)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_66);
  __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
  __pyx_t_61 = __pyx_memoryview_fromslice(__pyx_v_texture_rock0, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_67 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_66))) {
    __pyx_t_67 = PyMethod_GET_SELF(__pyx_t_66);
    if (likely(__pyx_t_67)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_66);
      __Pyx_INCREF(__pyx_t_67);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_66, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_67, __pyx_t_61};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_66, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_67); __pyx_t_67 = 0;
    __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1564, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_66); __pyx_t_66 = 0;
  }
  __pyx_t_66 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_tolist); if (unlikely(!__pyx_t_66)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_66);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_66))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_66);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_66);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_66, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_1, NULL};
    __pyx_t_65 = __Pyx_PyObject_FastCall(__pyx_t_66, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_65)) __PYX_ERR(0, 1564, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_65);
    __Pyx_DECREF(__pyx_t_66); __pyx_t_66 = 0;
  }
  __Pyx_GetModuleGlobalName(__pyx_t_61, __pyx_n_s_np); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_67 = __Pyx_PyObject_GetAttrStr(__pyx_t_61, __pyx_n_s_array); if (unlikely(!__pyx_t_67)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_67);
  __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
  __pyx_t_61 = __pyx_memoryview_fromslice(__pyx_v_texture_rock1, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_68 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_67))) {
    __pyx_t_68 = PyMethod_GET_SELF(__pyx_t_67);
    if (likely(__pyx_t_68)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_67);
      __Pyx_INCREF(__pyx_t_68);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_67, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_68, __pyx_t_61};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_67, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_68); __pyx_t_68 = 0;
    __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1564, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_67); __pyx_t_67 = 0;
  }
  __pyx_t_67 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_tolist); if (unlikely(!__pyx_t_67)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_67);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_67))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_67);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_67);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_67, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_1, NULL};
    __pyx_t_66 = __Pyx_PyObject_FastCall(__pyx_t_67, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_66)) __PYX_ERR(0, 1564, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_66);
    __Pyx_DECREF(__pyx_t_67); __pyx_t_67 = 0;
  }
  __Pyx_GetModuleGlobalName(__pyx_t_61, __pyx_n_s_np); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_68 = __Pyx_PyObject_GetAttrStr(__pyx_t_61, __pyx_n_s_array); if (unlikely(!__pyx_t_68)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_68);
  __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
  __pyx_t_61 = __pyx_memoryview_fromslice(__pyx_v_texture_rock2, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_69 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_68))) {
    __pyx_t_69 = PyMethod_GET_SELF(__pyx_t_68);
    if (likely(__pyx_t_69)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_68);
      __Pyx_INCREF(__pyx_t_69);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_68, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_69, __pyx_t_61};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_68, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_69); __pyx_t_69 = 0;
    __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1564, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_68); __pyx_t_68 = 0;
  }
  __pyx_t_68 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_tolist); if (unlikely(!__pyx_t_68)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_68);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_68))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_68);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_68);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_68, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_1, NULL};
    __pyx_t_67 = __Pyx_PyObject_FastCall(__pyx_t_68, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_67)) __PYX_ERR(0, 1564, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_67);
    __Pyx_DECREF(__pyx_t_68); __pyx_t_68 = 0;
  }
  __Pyx_GetModuleGlobalName(__pyx_t_61, __pyx_n_s_np); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_69 = __Pyx_PyObject_GetAttrStr(__pyx_t_61, __pyx_n_s_array); if (unlikely(!__pyx_t_69)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_69);
  __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
  __pyx_t_61 = __pyx_memoryview_fromslice(__pyx_v_texture_rock3, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __pyx_t_70 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_69))) {
    __pyx_t_70 = PyMethod_GET_SELF(__pyx_t_69);
    if (likely(__pyx_t_70)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_69);
      __Pyx_INCREF(__pyx_t_70);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_69, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_70, __pyx_t_61};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_69, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_70); __pyx_t_70 = 0;
    __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1564, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_69); __pyx_t_69 = 0;
  }
  __pyx_t_69 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_tolist); if (unlikely(!__pyx_t_69)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_69);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_69))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_69);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_69);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_69, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_1, NULL};
    __pyx_t_68 = __Pyx_PyObject_FastCall(__pyx_t_69, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_68)) __PYX_ERR(0, 1564, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_68);
    __Pyx_DECREF(__pyx_t_69); __pyx_t_69 = 0;
  }
  __pyx_t_69 = PyTuple_New(4); if (unlikely(!__pyx_t_69)) __PYX_ERR(0, 1564, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_69);
  __Pyx_GIVEREF(__pyx_t_65);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_69, 0, __pyx_t_65)) __PYX_ERR(0, 1564, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_66);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_69, 1, __pyx_t_66)) __PYX_ERR(0, 1564, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_67);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_69, 2, __pyx_t_67)) __PYX_ERR(0, 1564, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_68);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_69, 3, __pyx_t_68)) __PYX_ERR(0, 1564, __pyx_L1_error);
  __pyx_t_65 = 0;
  __pyx_t_66 = 0;
  __pyx_t_67 = 0;
  __pyx_t_68 = 0;
+1565:     (np.array(texture_bedrock0).tolist(), np.array(texture_bedrock1).tolist(), np.array(texture_bedrock2).tolist()),
  __Pyx_GetModuleGlobalName(__pyx_t_66, __pyx_n_s_np); if (unlikely(!__pyx_t_66)) __PYX_ERR(0, 1565, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_66);
  __pyx_t_65 = __Pyx_PyObject_GetAttrStr(__pyx_t_66, __pyx_n_s_array); if (unlikely(!__pyx_t_65)) __PYX_ERR(0, 1565, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_65);
  __Pyx_DECREF(__pyx_t_66); __pyx_t_66 = 0;
  __pyx_t_66 = __pyx_memoryview_fromslice(__pyx_v_texture_bedrock0, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_66)) __PYX_ERR(0, 1565, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_66);
  __pyx_t_1 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_65))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_65);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_65);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_65, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_t_66};
    __pyx_t_67 = __Pyx_PyObject_FastCall(__pyx_t_65, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_DECREF(__pyx_t_66); __pyx_t_66 = 0;
    if (unlikely(!__pyx_t_67)) __PYX_ERR(0, 1565, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_67);
    __Pyx_DECREF(__pyx_t_65); __pyx_t_65 = 0;
  }
  __pyx_t_65 = __Pyx_PyObject_GetAttrStr(__pyx_t_67, __pyx_n_s_tolist); if (unlikely(!__pyx_t_65)) __PYX_ERR(0, 1565, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_65);
  __Pyx_DECREF(__pyx_t_67); __pyx_t_67 = 0;
  __pyx_t_67 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_65))) {
    __pyx_t_67 = PyMethod_GET_SELF(__pyx_t_65);
    if (likely(__pyx_t_67)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_65);
      __Pyx_INCREF(__pyx_t_67);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_65, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_67, NULL};
    __pyx_t_68 = __Pyx_PyObject_FastCall(__pyx_t_65, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_67); __pyx_t_67 = 0;
    if (unlikely(!__pyx_t_68)) __PYX_ERR(0, 1565, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_68);
    __Pyx_DECREF(__pyx_t_65); __pyx_t_65 = 0;
  }
  __Pyx_GetModuleGlobalName(__pyx_t_66, __pyx_n_s_np); if (unlikely(!__pyx_t_66)) __PYX_ERR(0, 1565, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_66);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_66, __pyx_n_s_array); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1565, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_66); __pyx_t_66 = 0;
  __pyx_t_66 = __pyx_memoryview_fromslice(__pyx_v_texture_bedrock1, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_66)) __PYX_ERR(0, 1565, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_66);
  __pyx_t_61 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_1))) {
    __pyx_t_61 = PyMethod_GET_SELF(__pyx_t_1);
    if (likely(__pyx_t_61)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
      __Pyx_INCREF(__pyx_t_61);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_1, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_61, __pyx_t_66};
    __pyx_t_67 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_61); __pyx_t_61 = 0;
    __Pyx_DECREF(__pyx_t_66); __pyx_t_66 = 0;
    if (unlikely(!__pyx_t_67)) __PYX_ERR(0, 1565, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_67);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  }
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_67, __pyx_n_s_tolist); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1565, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_67); __pyx_t_67 = 0;
  __pyx_t_67 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_1))) {
    __pyx_t_67 = PyMethod_GET_SELF(__pyx_t_1);
    if (likely(__pyx_t_67)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
      __Pyx_INCREF(__pyx_t_67);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_1, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_67, NULL};
    __pyx_t_65 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_67); __pyx_t_67 = 0;
    if (unlikely(!__pyx_t_65)) __PYX_ERR(0, 1565, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_65);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  }
  __Pyx_GetModuleGlobalName(__pyx_t_66, __pyx_n_s_np); if (unlikely(!__pyx_t_66)) __PYX_ERR(0, 1565, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_66);
  __pyx_t_61 = __Pyx_PyObject_GetAttrStr(__pyx_t_66, __pyx_n_s_array); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1565, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __Pyx_DECREF(__pyx_t_66); __pyx_t_66 = 0;
  __pyx_t_66 = __pyx_memoryview_fromslice(__pyx_v_texture_bedrock2, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_66)) __PYX_ERR(0, 1565, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_66);
  __pyx_t_70 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_61))) {
    __pyx_t_70 = PyMethod_GET_SELF(__pyx_t_61);
    if (likely(__pyx_t_70)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_61);
      __Pyx_INCREF(__pyx_t_70);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_61, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_70, __pyx_t_66};
    __pyx_t_67 = __Pyx_PyObject_FastCall(__pyx_t_61, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_70); __pyx_t_70 = 0;
    __Pyx_DECREF(__pyx_t_66); __pyx_t_66 = 0;
    if (unlikely(!__pyx_t_67)) __PYX_ERR(0, 1565, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_67);
    __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
  }
  __pyx_t_61 = __Pyx_PyObject_GetAttrStr(__pyx_t_67, __pyx_n_s_tolist); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1565, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __Pyx_DECREF(__pyx_t_67); __pyx_t_67 = 0;
  __pyx_t_67 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_61))) {
    __pyx_t_67 = PyMethod_GET_SELF(__pyx_t_61);
    if (likely(__pyx_t_67)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_61);
      __Pyx_INCREF(__pyx_t_67);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_61, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_67, NULL};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_61, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_67); __pyx_t_67 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1565, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_61); __pyx_t_61 = 0;
  }
  __pyx_t_61 = PyTuple_New(3); if (unlikely(!__pyx_t_61)) __PYX_ERR(0, 1565, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_61);
  __Pyx_GIVEREF(__pyx_t_68);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_61, 0, __pyx_t_68)) __PYX_ERR(0, 1565, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_65);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_61, 1, __pyx_t_65)) __PYX_ERR(0, 1565, __pyx_L1_error);
  __Pyx_GIVEREF(__pyx_t_1);
  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_61, 2, __pyx_t_1)) __PYX_ERR(0, 1565, __pyx_L1_error);
  __pyx_t_68 = 0;
  __pyx_t_65 = 0;
  __pyx_t_1 = 0;
+1566:     np.array(texture_water).tolist(),
  __Pyx_GetModuleGlobalName(__pyx_t_68, __pyx_n_s_np); if (unlikely(!__pyx_t_68)) __PYX_ERR(0, 1566, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_68);
  __pyx_t_67 = __Pyx_PyObject_GetAttrStr(__pyx_t_68, __pyx_n_s_array); if (unlikely(!__pyx_t_67)) __PYX_ERR(0, 1566, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_67);
  __Pyx_DECREF(__pyx_t_68); __pyx_t_68 = 0;
  __pyx_t_68 = __pyx_memoryview_fromslice(__pyx_v_texture_water, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_68)) __PYX_ERR(0, 1566, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_68);
  __pyx_t_66 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_67))) {
    __pyx_t_66 = PyMethod_GET_SELF(__pyx_t_67);
    if (likely(__pyx_t_66)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_67);
      __Pyx_INCREF(__pyx_t_66);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_67, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_66, __pyx_t_68};
    __pyx_t_65 = __Pyx_PyObject_FastCall(__pyx_t_67, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_66); __pyx_t_66 = 0;
    __Pyx_DECREF(__pyx_t_68); __pyx_t_68 = 0;
    if (unlikely(!__pyx_t_65)) __PYX_ERR(0, 1566, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_65);
    __Pyx_DECREF(__pyx_t_67); __pyx_t_67 = 0;
  }
  __pyx_t_67 = __Pyx_PyObject_GetAttrStr(__pyx_t_65, __pyx_n_s_tolist); if (unlikely(!__pyx_t_67)) __PYX_ERR(0, 1566, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_67);
  __Pyx_DECREF(__pyx_t_65); __pyx_t_65 = 0;
  __pyx_t_65 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_67))) {
    __pyx_t_65 = PyMethod_GET_SELF(__pyx_t_67);
    if (likely(__pyx_t_65)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_67);
      __Pyx_INCREF(__pyx_t_65);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_67, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_65, NULL};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_67, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_65); __pyx_t_65 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1566, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_67); __pyx_t_67 = 0;
  }
+1567:     np.array(texture_vegetation).tolist())
  __Pyx_GetModuleGlobalName(__pyx_t_68, __pyx_n_s_np); if (unlikely(!__pyx_t_68)) __PYX_ERR(0, 1567, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_68);
  __pyx_t_66 = __Pyx_PyObject_GetAttrStr(__pyx_t_68, __pyx_n_s_array); if (unlikely(!__pyx_t_66)) __PYX_ERR(0, 1567, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_66);
  __Pyx_DECREF(__pyx_t_68); __pyx_t_68 = 0;
  __pyx_t_68 = __pyx_memoryview_fromslice(__pyx_v_texture_vegetation, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_68)) __PYX_ERR(0, 1567, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_68);
  __pyx_t_70 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_66))) {
    __pyx_t_70 = PyMethod_GET_SELF(__pyx_t_66);
    if (likely(__pyx_t_70)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_66);
      __Pyx_INCREF(__pyx_t_70);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_66, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_70, __pyx_t_68};
    __pyx_t_65 = __Pyx_PyObject_FastCall(__pyx_t_66, __pyx_callargs+1-__pyx_t_36, 1+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_70); __pyx_t_70 = 0;
    __Pyx_DECREF(__pyx_t_68); __pyx_t_68 = 0;
    if (unlikely(!__pyx_t_65)) __PYX_ERR(0, 1567, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_65);
    __Pyx_DECREF(__pyx_t_66); __pyx_t_66 = 0;
  }
  __pyx_t_66 = __Pyx_PyObject_GetAttrStr(__pyx_t_65, __pyx_n_s_tolist); if (unlikely(!__pyx_t_66)) __PYX_ERR(0, 1567, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_66);
  __Pyx_DECREF(__pyx_t_65); __pyx_t_65 = 0;
  __pyx_t_65 = NULL;
  __pyx_t_36 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_66))) {
    __pyx_t_65 = PyMethod_GET_SELF(__pyx_t_66);
    if (likely(__pyx_t_65)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_66);
      __Pyx_INCREF(__pyx_t_65);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_66, function);
      __pyx_t_36 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_65, NULL};
    __pyx_t_67 = __Pyx_PyObject_FastCall(__pyx_t_66, __pyx_callargs+1-__pyx_t_36, 0+__pyx_t_36);
    __Pyx_XDECREF(__pyx_t_65); __pyx_t_65 = 0;
    if (unlikely(!__pyx_t_67)) __PYX_ERR(0, 1567, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_67);
    __Pyx_DECREF(__pyx_t_66); __pyx_t_66 = 0;
  }