Code for gully erosion developed (modified version) (8th Nov. 2005)

From GeoMod

Jump to: navigation, search

Code for class 'area' created for gully erosion

from visual import *
from random import *
from visual.graph import *

class area:
    '''This class will create a source area'''
    def __init__(self, nx, ny, dx, dy):
        self.nx=nx # Number of rows
        self.ny=ny # Number of columns
        self.dx=dx # Unit size in x direction
        self.dy=dy # Unit size in z direction
        self.xmin = 0 # The area starting from zero x cord
        self.ymax = nx*dx # The y cord is number of rows multiply by distance between teo cells being top left corner as start of area
        self.Elev=zeros((nx,ny), Float)
        self.ElevT=zeros((nx*ny), Float)
        self.ElevS=zeros((nx,ny), Float)

        self.land = []
        seed(100)
        for i in range(nx):
            for j in range(ny):
                self.land.append(box(length=dx, height=dy,
                                     width = (uniform(0.1,.5)),
                                     color = (uniform(0.7,1),0.8,0.4)))
                                     #up=(0,1.5,-0.26)))
                self.land[-1].pos.z = self.land[-1].width / 2.0
                self.land[-1].x=i*dx
                self.land[-1].y=j*dy
##                colval = (self.land[-1].width-0.1)/(4-0.1)
##                self.land[-1].color = (colval,colval,colval)
                self.Elev[i,j] = self.land[-1].width
               
        print 'the elevation', self.Elev
        scene.center = (self.dx * (self.nx/2), self.dy * (self.ny/2), 0)
        scene.forward = vector (1,0,0)
        scene.up = vector (0,0,1)
        scene.forward = vector(0,1,0)
        scene.up = vector(0,0,1)

  
    def draax (self):
         x_axis=cylinder(axis=(104,0,0), color=color.red, radius=2)
         y_axis=cylinder(axis=(0,104,0), color=color.green, radius=2)
         z_axis=cylinder(axis=(0,0,104), color=color.blue,radius=2)
    
    
    def slope(self, dxdz = 0, dydz = 0):
        k=0
        for i in self.land:
            de = dxdz * i.pos.x
            i.width = i.width + de
            de = dydz * i.pos.y
            i.width = i.width + de
            i.pos.z = i.width / 2.0
            self.ElevT[k] = i.width
            k=k+1
        p=0
        for i in range(self.nx):
            for j in range(self.ny):
                self.ElevS[i,j] = self.ElevT[p]
                p=p+1
            
        print 'The elevation after slope'
        print self.ElevS
##        print "local Elevation = "
##        print self.ElevS[1:4, 0:3]
        return self.ElevS

            
    def ij_number(self,r=0,c=0):
        Num = zeros((self.nx,self.ny))
        num = 0
        for i in range(self.nx):
            for j in range(self.ny):
                Num[i,j] = num
                num=num+1
##        print 'the no of land pieces', Num
##        print 'the number of r row and c col is', Num[r,c]
        return Num[r,c]
                
    def number_ij(self,number):
        T = number/self.nx
        print 'T', T
        if T <=1:
            i = 0
            j = number-1
        if (T > 1 and T <=2):
            i = 1
            j = number-self.nx-1
        if (T >2 and T<=3):
            i = 2
            j = number - 2*self.nx-1
        if (T >3 and T<=4):
            i=3
            j = number - 3*self.nx-1
        if (T >4 and T<=5):
            i = 4
            j = number -4*self.nx-1
        if (T>5 and T<=6):
            i=5
            j = number -5*self.nx-1
        if (T>6 and T<=7):
            i=6
            j = number -6*self.nx-1
        if (T>7 and T<=8):
            i=7
            j = number - 7*self.nx-1
        if (T>8 and T<=9):
            i=8
            j = number -8*self.nx-1
        if (T>9 and T<=10):
            i=9
            j = number - 9*self.nx-1
        print 'The i or Row is', i
        print 'The j or Column is', j

    def rc_xy(self,R,C):
        self.x=self.xmin+self.dx/2.0+((self.dx)*C)
        self.y=self.ymax-self.dx/2.0-((self.dx)*R)
##        print 'The x-cord for given Column, C is', C, self.x
##        print 'The y-cord for given Row, R is', R, self.y
        return self.x, self.y
        
        
    def LowRC(self): # This function give array of pixels around the given pixel and lowest value in that array
        Low = self.ElevS[self.PosR,self.PosC]
        self.PosRL = self.PosR
        self.PosCL = self.PosC
        temp =0
##        print 'The array of eight cell surronding the given cell'
##        print self.ElevS[self.PosR-1:self.PosR+2,self.PosC-1:self.PosC+2]
        for i in range(self.PosR-1,self.PosR+2):
            for j in range(self.PosC-1,self.PosC+2):
                if Low > self.ElevS[i,j]:
                     Low = self.ElevS[i,j]
                     self.PosRL = i
                     self.PosCL = j
                   
        return (self.PosRL, self.PosCL, Low)
        
    def LowTrace(self,r,c): # 
        self.PosR = r
        self.PosC = c
        
        (LowRow, LowCol, Low) = self.LowRC()

        self.cr_out[r,c] = self.ElevS[LowRow, LowCol]
        self.c_out[r,c] = LowCol
        self.r_out[r,c] = LowRow


    def catchment(self):

        self.c_out = zeros((self.ny,self.nx))
        self.r_out = zeros((self.nx,self.ny))
        self.cr_out = zeros((self.nx,self.ny), Float)
        for i in range(1,self.nx-1):
            for j in range(1,self.ny-1):
                self.LowTrace(i,j)

        print 'self.c_out', self.c_out
        print 'self.r_out', self.r_out
        print 'self.cr_out', self.cr_out

  
    def watershed(self):
        self.counter = ones((self.nx, self.ny))
        l_loop = 1
        while l_loop == 1:
            l_loop =0
            for i in range(1,self.nx-1):
                for j in range(1,self.ny-1):
                    temp = 1

                    for k in range(i-1,i+2):
                        for m in range(j-1,j+2):
                             if ((self.c_out[k,m] == j and self.r_out[k,m] == i) and not(k==i and m ==j)):
                                temp = temp +self.counter[k,m]
                    if temp <> self.counter[i,j]:
                        self.counter[i,j] = temp
                        l_loop = 1
##            print self.counter
            #rate(0.1)
                            
        print 'The catchment watershed area of area is',
        print self.counter

    def localSlope(self):
        self.Slope = zeros((self.nx,self.ny), Float)
        for i in range(1,self.nx-1):
            for j in range(1,self.ny-1):
                self.Slope[i,j] = abs((self.cr_out[i,j]- self.ElevS[i,j])/self.dx)
                        
        print 'the local slope is',
        print self.Slope

    def sediTrans(self):
####      '''The general sediment transport capacity is given as
####        Qs = (self.K* inv(self.ChiC)* self.ChiW* self.ChiT ^ self.P *
####              self.d ^ (1.5-self.P)* (1 - self.Tou* inv(self.ChiT) * (self.R*self.A)^ -self.MTou
####              * self.Slope^ -self.NTou) ^ self.P)* (self.R*self.A)^ -self.M * self.Slope^ -self.N'''
        
        self.Qs = zeros((self.nx, self.ny), Float)
        self.K = 20 # The calibration parameter
        self.g = 9.81 # Acceleration due to gravity
        self.P = 3 # Another calibration parameter
        self.D = 0.003 # dominant grain size
        self.TouCS = 0.045 # Dimensionless critical shear stress
        self.R = .035 # Runoff rate in mm/hr
        self.T = 1 # time for gully incision in hr
        self.s = 2.65 # quartz specific gravity
        self.RowW = 1000 # Specific gravity of water
        self.MTou = 0.6 # Exponent m
        self.NTou = 0.8125 # Exponent n
        self.M = 2.1 # Exponent M
        self.N = 2.25 # Exponent N
        Ks = 1.73
        Kn = 0.08
        C = 0.346
        Ngc = 0.025

##        print 'here in sedi'
        
        self.Qs = zeros((self.nx, self.ny), Float)
        
        self.ChiC = pow (self.RowW,self.P) * pow((self.g* (self.s -1)), (self.P -0.5))
        
        self.TouC = self.TouCS * (self.s-1) * self.D * self.RowW * self.g

        self.ChiW = Ks*pow(Kn,0.375)*pow(C,-0.25)
        
        self.ChiT = self.RowW*self.g*pow(C,0.75)*pow(Kn,-1.13)*pow(Ngc,1.5)

##        print "self.N", self.N
##        print "self.ElevS[3,8]", self.Slope[3,8]
##        print "pow ((self.ElevS[i,j]), self.N)", pow ((self.Slope[6,3]), self.N)
##        print "pow ((self.R * self. A),self.M)", pow ((self.R * self. counter[0,0]+1),self.M)
##        print "self.NTou", -self.NTou
##        print "pow (self.ElevS[i,j], -self.NTou", pow (self.Slope[6,3], -self.NTou)
##        print "pow ((self.R * self.A), -self.MTou)", pow ((self.R * self.counter[1,1]), -self.MTou)        
##        print "pow((1 - self.TouC*(1/self.ChiT)* pow ((self.R * self.A), -self.MTou) * pow (self.ElevS[i,j], -self.NTou)), self.P)) ",
##        print pow((1 - self.TouC*(1/self.ChiT)* pow ((self.R * self.counter[0,0]+1), -self.MTou) * pow (self.Slope[6,3], -self.NTou)), self.P)
        
        for i in range(1,self.nx-1):
            for j in range(1,self.ny-1):
                if ((self.counter[i,j] > 2) and (self.Slope[i,j] <> 0.0)):
##                    print 'i,j', i, j
                    self.A = self.counter[i,j]
                    self.Qs[i,j] = (self.K * (1/self.ChiC) * self.ChiW * pow(self.ChiT,self.P) * pow ( self.D, (1.5-self.P)) * pow((1 - self.TouC*(1/self.ChiT)* pow ((self.R * self.A), -self.MTou) * pow (self.Slope[i,j], -self.NTou)), self.P)) * pow ((self.R * self. A),self.M) * pow ((self.Slope[i,j]), self.N)
                    self.land[self.ij_number(i,j)].color = color.red
        print 'The sediment capacity of different cells are',
        print self.Qs

    def eroht1(self):
        AreaC = self.dx * self.dy
        self.eroht = zeros((self.nx, self.ny), Float)
        for i in range(self.nx):
            for j in range(self.ny):
                self.eroht[i,j] = (self.Qs[i,j]/AreaC)*self.T
        print 'erosion height of all cells', self.eroht
        #return self.eroht
                
    def chgele(self):
        self.ChgElv = zeros((self.nx, self.ny), Float)
        for i in range(1,self.nx-1):
            for j in range(1,self.ny-1):
##                if (self.counter[i,j] > 3):
##                    self.ChgElv[i,j] = self.ElevS[i,j]+self.eroht[i,j]
##                else:
                if self.eroht[i,j] > self.ElevS[i,j]:
##                    print 'the eroht > elevs', self.eroht[i,j], self.ElevS[i,j]
                    self.eroht[i,j] = self.ElevS[i,j]
                    self.ChgElv[i,j] = self.ElevS[i,j]-self.eroht[i,j]
##                    print 'erosion ht ', self.eroht[6,3], self.eroht[i,j], self.ElevS[i,j] 
##                    print 'chg elve after equating', self.ChgElv[i,j]
                    
                else:
##                    print 'eroht not greater'
##                    print self.eroht[i,j], self.ElevS[i,j]
                    self.ChgElv[i,j] = self.ElevS[i,j]-self.eroht[i,j]
               
        print 'change elevation', self.ChgElv
        for i in range(1,self.nx-1):
            for j in range(1,self.ny-1):
                self.ElevS[i,j] = self.ChgElv[i,j]
        print 'final elev.',
        print self.ElevS
        
    def newdisp(self,t=1):
        dispa = display ( x =0, y = 0, width= 640,height = 480)
        for i in range(self.nx):
            for j in range(self.ny):
                self.land.append(box(length=self.dx, height=self.dy,
                                     width = (uniform(0.1,.5))))
                                     #color = (uniform(0.7,1),0.8,0.4)))
                
                self.land[-1].x=i*self.dx
                self.land[-1].y=j*self.dy
                self.land[-1].width = self.ElevS[i,j]
                self.land[-1].pos.z = self.land[-1].width / 2.0

        dispa.center = (self.dx * (self.nx/2), self.dy * (self.ny/2), 0)    
        dispa.forward = vector (1,0,0)
        dispa.up = vector (0,0,1)
        
        dispa.forward = vector(0,1,0)
        dispa.up = vector(0,0,1)
    ##    self.land[self.ij_number(i,j)].color = color.green




Code for main function calling this class is

from visual import *
from random import *
from SAREA_3 import *
from visual.graph import *
import math

# Define parameters
nx = 10
lx = 10.0
ny = 10
ly = 10.0

dx = lx/nx
dy = ly/ny
##print 'dx', dx
##print 'dy', dy

# creating land area as per the parameters defined
sourceArea = area (nx, ny, dx, dy)

# Translating the land to the center
#sourceArea.trans ( (nx-1)*lx/2, 0, (nz-1)*lz/2)

# drawing the axis
#sourceArea.draax()

sourceArea.slope(dydz=0.5)

# To get the land number from row and column
#sourceArea.ij_number(1,2)


# To get the value of i,j if the land number given
##sourceArea.number_ij(95.0) # Specify number as float quantity

#To get the contributing area of each pixel by noting the number of counter

tt = 15
while tt<>0:
   
    sourceArea.catchment()

    sourceArea.watershed()

    sourceArea.localSlope()
    
    sourceArea.sediTrans()

    sourceArea.eroht1()

    sourceArea.chgele()

    if tt == 1:
        sourceArea.newdisp(1)

    tt= tt-1

--Ekta2 16:26, 6 Nov 2005 (CST)

Personal tools