#!/usr/bin/env python3 # -*- coding: utf-8 -*- #--------------------------------------------------------------------------------# # This file is part of the PALM model system. # # PALM is free software: you can redistribute it and/or modify it under the terms # of the GNU General Public License as published by the Free Software Foundation, # either version 3 of the License, or (at your option) any later version. # # PALM is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # PALM. If not, see . # # Copyright 1997-2018 Leibniz Universitaet Hannover #--------------------------------------------------------------------------------# # # Current revisions: # ----------------- # Bugfix: missing conversion to integer # # # Former revisions: # ----------------- # $Id: palm_csd_tools.py 3773 2019-03-01 08:56:57Z maronga $ # Unspecified changes # # 3726 2019-02-07 18:22:49Z maronga # Index bound bugfix # # 3668 2019-01-14 12:49:24Z maronga # Minor changes # # 3567 2018-11-27 13:59:21Z maronga # Initial revisions # # # Description: # ------------ # Support routines for palm_csd # # @Author Bjoern Maronga (maronga@muk.uni-hannover.de) # #------------------------------------------------------------------------------# import numpy as np from scipy.interpolate import interp2d def blend_array_2d(array1,array2,radius): # Blend over the parent and child terrain height within a radius of 50 px gradient_matrix = np.copy(array1) gradient_matrix[:,:] = 1.0 gradient_px = 50 for i in range(0,gradient_px): gradient_matrix[:,i] = float(i)/float(gradient_px) for i in range(len(gradient_matrix[0,:])-gradient_px,len(gradient_matrix[0,:])): gradient_matrix[:,i] = float(len(gradient_matrix[0,:])-i)/float(gradient_px) for j in range(0,gradient_px): for i in range(0,len(gradient_matrix[0,:])): if gradient_matrix[j,i] == 1.0: gradient_matrix[j,i] = float(j)/float(gradient_px) else: gradient_matrix[j,i] = (gradient_matrix[j,i] + float(j)/float(gradient_px))/2.0 for j in range(len(gradient_matrix[:,0])-gradient_px,len(gradient_matrix[:,0])): for i in range(0,len(gradient_matrix[0,:])): if gradient_matrix[j,i] == 1.0: gradient_matrix[j,i] = (len(gradient_matrix[:,0])-j)/float(gradient_px) else: gradient_matrix[j,i] = (gradient_matrix[j,i] + (len(gradient_matrix[:,0])-j)/float(gradient_px))/2.0 array_blended = array1 * gradient_matrix + (1.0 - gradient_matrix ) * array2 return array_blended def interpolate_2d(array,x1,y1,x2,y2): tmp_int2d = interp2d(x1,y1,array,kind='linear') array_ip = tmp_int2d(x2.astype(float), y2.astype(float)) return array_ip def bring_to_palm_grid(array,x,y,dz): # Bring the parent terrain height to the child grid k_tmp = np.arange(0,max(array.flatten())+dz*2,dz) k_tmp[1:] = k_tmp[1:] - dz * 0.5 for l in range(0,len(x)): for m in range(0,len(y)): for k in range(1,len(k_tmp+1)): if k_tmp[k] > array[m,l]: array[m,l] = k_tmp[k-1] + dz * 0.5 break return array def make_3d_from_2d(array_2d,x,y,dz): k_tmp = np.arange(0,max(array_2d.flatten())+dz*2,dz) k_tmp[1:] = k_tmp[1:] - dz * 0.5 array_3d = np.ones((len(k_tmp),len(y),len(x))) for l in range(0,len(x)): for m in range(0,len(y)): for k in range(0,len(k_tmp)): if k_tmp[k] > array_2d[m,l]: array_3d[k,m,l] = 0 return array_3d.astype(np.byte), k_tmp def make_3d_from_bridges_2d(array_3d,array_2d,x,y,dz,width,fill): for l in range(0,len(x)-1): for m in range(0,len(y)-1): if array_2d[m,l] != fill: k_min = max( int((array_2d[m,l] - width)/dz), 0 ) k_max = int(round(array_2d[m,l]/dz)) array_3d[k_min:k_max+1,m,l] = 1 return array_3d.astype(np.byte) def check_arrays_2(array1,array2,fill1,fill2): missing1 = np.where(array1 == fill1,1,0) missing2 = np.where(array2 == fill2,1,0) result = np.array_equal(missing1,missing2) return result def check_consistency_3(array1,array2,array3,fill1,fill2,fill3): tmp_array = np.where(array1 != fill1,1,0) + np.where(array2 != fill2,1,0) + np.where(array3 != fill3,-1,0) test = np.any(tmp_array.flatten() != 0) if test: print("soil_type array is not consistent!") print("max: " + str(max(tmp_array.flatten())) + ", min: " + str(min(tmp_array.flatten()))) else: print("soil_type array is consistent!") return tmp_array, test def check_consistency_4(array1,array2,array3,array4,fill1,fill2,fill3,fill4): tmp_array = np.where(array1 != fill1,1,0) + np.where(array2 != fill2,1,0) + np.where(array3 != fill3,1,0) + np.where(array4 != fill4,1,0) test = np.any(tmp_array.flatten() != 1) if test: print("*_type arrays are not consistent!") print("max: " + str(max(tmp_array.flatten())) + ", min: " + str(min(tmp_array.flatten()))) else: print("*_type arrays are consistent!") return tmp_array, test