Prerequisites

Basic knowlegde on Linux and Python is required.

A Linux distribution (Ubuntu 14 to 18 suggested) with Python 2.7 and some basic python packages (e.g., numpy) are assumed to have been installed at the users' side, but no other third-party packages (e.g., boost, qt) need installing.

Basic Linux Commands

Only several commands the users should know are enough to set off running a program. A terminal (i.e., command window) is open by pressing a shortcut ‘CTRL+ALT+T’ or whatever other operations.

  • sudo apt-get install package[^2] install a package to the system with root permission.

  • pwd: show the current path.

  • cd directory: change the directory to directory. The directory can be a relative or absolute path. Two special notations ‘.’ and ‘..’ denote the current directory and the parent directory, respectively, which are useful to type a relative path. For example, ' cd ../sub' will change the directory to the subdirectory ‘sub’ of the parent directory of the current path. ‘cd /home/user’ will change the directory to the absolute path ‘/home/user’.

  • prog or ./path/prog: run an executable named prog. If prog is exposed to the terminal, i.e., prog is in the searching path of the system, then just type the name prog like the command ‘cd’ at the last item; otherwise, a path should be specified to locate prog.

  • ‘CTRL+C’: terminate a program at the terminal.

    $> sudo apt-get install python-numpy
    $> pwd
    $> cd /home/
    $> sudodem3d

Python 2.7

Python is sensitive to indent which is used to identify a script block. ‘#’ is used to comment a line which will not be executed. Here a piece of script is shown to explain the primitives of Python:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import math # import the module math which includes some basic math functions

# we have numbers
a = 2 # integer number
b = 5
c = 2.0 # float number
d = a/b # the value is an integer
e = c/b # float number
print a, d, e # print the values of a, d and e to the terminal

#we have strings
a = 'abc' # we can assign any type of values to any type of variables
b = "this is a 'Python' script."
print a, b

#we have list, tuple and dict to store and manage the above basic primitives
c = [1,2,3,'ss'] # a list
d = (1,2,3,'ss') # a tuple
c[0] = 5 # change the first item in the list c, and the index starts from 0.
d[0] = 5 # failed! a tuple is constant, which is the distinguishing property from a list
d={1:22,2:33,4:'ssss','w':123} #a dict: 1, 2, 4 and 'w' are keys of the dict, and 22, 33, 'ssss' and 123 are the corresponding values.
print d[1], d[4], d['w']

# we initialize two objects c and d for storing data at a for loop later
c = list() # an empty list
d = dict() # an empty dict
#test expression
if 1>2:
    print "1 is greater than 2, really?"
else:
    if 2 in [1, 2, 3]: # if 2 is in the list [1, 2, 3]
        #ok, let's start a for loop
        for i in range(5): # equal to for i in [0, 1, 2, 3, 4]
            print i # you can see what's going on in the for loop
            # we append some data to a list c and a dict d
            c.append(math.cos(i)*10 + 2.0**5) # we append the value of 10*cos(i) + 2.0^5 to the list c. We use the math function cos from the module math.
            if i not in d.keys(): # if i is not a key or index of the dict d. 
                d[i] = str(i)

#we can capsule our commands by a function
def GoodJob(input_number, keyword1 = 1, keyword2 = True):
    if keyword2: # that is if keyword2 == True
        print "the input number is", input
    input_number += keyword1 # i.e., the value of input_number is updated to input_number + keyword1
    return input_number # we can return the value
    
# call the function
a = GoodJob(2) # a = 3, with print info 'the input number is 3'
b = GoodJob(3, keyword1 = 5, keyword2 = False) # b = 8, without print info.

Ok, that is all you need to know prior to running a simulation. There are also other further techniques you might be interested in, e.g., how to open/read/write/close a file, and how to write a Python script with the object-oriented programming, which will be roughly introduced in the examples of this tutorial.

Package Setup

The project of SudoDEM is hosted on the website. Two ways to get the package installed are provided:

Binary Installation

Step 1: Get the package[^3]

Download the compiled package from the download page and unzip it to anywhere (e.g., /home/xxx/). If you just get a package of the main program which does not include the third-party libraries, then you need to download the package "3rdlibs.tar.xz" for the third-party libraries and extract it into the subfolder "lib". After that, make sure you get the following structure of folders:

::: {.forest} for tree= font=, grow'=0, child anchor=west, parent anchor=south, anchor=west, calign=first, inner xsep=7pt, edge path= (!u.south west) +(7.5pt,0) |- (.child anchor) pic folder ; , file/.style=edge path=(!u.south west) +(7.5pt,0) |- (.child anchor) ;, inner xsep=2pt,font= , before typesetting nodes= if n=1 insert before=[,phantom] , fit=band, before computing xy=l=15pt, [/home/xxx/SudoDEM/ [bin/ [sudodem3d] ] [lib/ [3rdlibs/] [sudodem/] ] [share/ ] ] :::

Step 2: Set the environmental variable PATH

Append the path of the executable sudodem3d, i.e., ‘/home/xxx/SudoDEM/bin’ to the environmental variable PATH by adding the following line to the config file ‘/home/xxx/.bashrc’:

PATH=${PATH}:/home/xxx/SudoDEM/bin

Non-root Compilation

Here is a video that may guide you to compile SudoDEM. You can copy the command lines directly from this video.

(1) Directory trees

After unzipping the source package, you have the following directory tree:

./home/xxx/SudoDEM

  • [SudoDEM2D]
  • [SudoDEM3D]
  • [scripts]
  • [INSTALL]
  • [LICENSE]
  • [Readme.md]

::: {.forest} for tree= font=, grow'=0, child anchor=west, parent anchor=south, anchor=west, calign=first, inner xsep=7pt, edge path= (!u.south west) +(7.5pt,0) |- (.child anchor) pic folder ; , file/.style=edge path=(!u.south west) +(7.5pt,0) |- (.child anchor) ;, inner xsep=2pt,font= , before typesetting nodes= if n=1 insert before=[,phantom] , fit=band, before computing xy=l=15pt, [/home/xxx/SudoDEM [SudoDEM2D ] [SudoDEM3D ] [scripts] [INSTALL,file ] [LICENSE,file ] [Readme.md,file ] ] :::

You may add subfolders, e.g.,‘3rdlib’, ‘build2d’, ‘build3d’, and ‘sudodeminstall’, inside the parent folder ‘SudoDEM’. Thus, the directory tree looks like

::: {.forest} for tree= font=, grow'=0, child anchor=west, parent anchor=south, anchor=west, calign=first, inner xsep=7pt, edge path= (!u.south west) +(7.5pt,0) |- (.child anchor) pic folder ; , file/.style=edge path=(!u.south west) +(7.5pt,0) |- (.child anchor) ;, inner xsep=2pt,font= , before typesetting nodes= if n=1 insert before=[,phantom] , fit=band, before computing xy=l=15pt, [/home/xxx/SudoDEM [SudoDEM2D ] [SudoDEM3D ] [3rdlib] [build2d] [build3d] [sudodeminstall] [scripts] [INSTALL,file ] [LICENSE,file ] [Readme.md,file ] ] :::

The subfolder ‘3rdlib’ is for the third-party libraries. Note that the subfolder ‘3rdlib’ hosts the header files and the compiled dynamic libraries, while for launching SudoDEM you need to copy all dynamic libraries ‘*.so.*’ files into the install directory, e.g., ‘lib/3rdlibs/’. The compilation of the 2D and 3D versions will be done within the subfolders ‘build2d’ and ‘build3d’, respectively. The compiled outputs (binary and library) will be installed in the subfolder ‘sudodeminstall’.

(2) Compilation of third-party libraries

::: {.forest} for tree= font=, grow'=0, child anchor=west, parent anchor=south, anchor=west, calign=first, inner xsep=7pt, edge path= (!u.south west) +(7.5pt,0) |- (.child anchor) pic folder ; , file/.style=edge path=(!u.south west) +(7.5pt,0) |- (.child anchor) ;, inner xsep=2pt,font= , before typesetting nodes= if n=1 insert before=[,phantom] , fit=band, before computing xy=l=15pt, [/home/xxx/SudoDEM/3rdlib [boost-1_6_7] [eigen3.3.5] [libQGLViewer-2.6.3] [minieigen] ] :::

Four major libraries:

  • Boost-1.67
    Download the source from its official page (https://www.boost.org/users/history/version_1_67_0.html) or the github repo (https://github.com/SwaySZ/boost-1_6_7).

    cd boost-1\_6\_7
        ./bootstrap.sh --prefix=$PWD/../boost167 --with-libraries=python,thread,filesystem,iostreams,regex,serialization,system,date_time link=shared runtime-link=shared --without-icu
        ./b2 -j3
        ./b2 install
    
  • Eigen-3.3.5: no need to compile but all head files will be included. You may download the source from the repo (https://github.com/SwaySZ/Eigen-3.3.5).

  • MiniEigen
    Download the source from the repo (https://github.com/SwaySZ/minieigen). Set the directory of your compiled boost in the file ‘CMakeLists.txt’:

    set(BOOST_ROOT "/home/swayzhao/software/DEM/3rdlib/boost167")
    

    Then,

    mkdir build
    cd build
    cmake ../
    make
    

    After compilation, you will get the shared library ‘minieigen.so’. Copy it to the folder ‘lib/3rdlibs/py’.

  • LibQGLViewer-2.6.3
    Download the source from the repo (https://github.com/SwaySZ/libQGLViewer-2.6.3)

    cd QGLViewer
    qmake
    make
    

Tools and dependencies:

  • biuld-essential, cmake

  • freeglut3-dev

  • zlib1g-dev (boost)

  • python-dev (boost)

  • pyqt4-dev-tools

  • qt4-default

  • python-numpy python-tk

  • libbz2-dev

  • python-xlib python-qt4

  • ipython3.0 python-matplotlib

  • libxi-dev

  • libglib2.0-dev

  • libxmu-dev

(3) Compilation of SudoDEM main programs

Here we show the example to compile SudoDEM3D as follows. In the folder ‘SudoDEM3D’, you have the directory tree:

::: {.forest} for tree= font=, grow'=0, child anchor=west, parent anchor=south, anchor=west, calign=first, inner xsep=7pt, edge path= (!u.south west) +(7.5pt,0) |- (.child anchor) pic folder ; , file/.style=edge path=(!u.south west) +(7.5pt,0) |- (.child anchor) ;, inner xsep=2pt,font= , before typesetting nodes= if n=1 insert before=[,phantom] , fit=band, before computing xy=l=15pt, [/home/xxx/SudoDEM/SudoDEM3D [cMake] [CMakeLists.txt, file] [core] [doc] [gui] [lib] [pkg] [py] ] :::

Prior to compiling, you may need to edit the file ‘CMakeLists.txt’, in which you may change the installation directory, paths of library header files, etc.

(a) The installation path is set by

SET(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/../sudodeminstall/SudoDEM3D")

(b) The root directory of BOOST library is set by

  set(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../3rdlib/boost167")

(c) For the QGLViewer, the paths for both header files and library are set by the following two lines:

set(QGLVIEWER_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../3rdlib/libQGLViewer-2.6.3/")
set(QGLVIEWER_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/../3rdlib/libQGLViewer-2.6.3/QGLViewer/libQGLViewer.so")

(d) Copy your system-installed numpy and pyqt4 to the path ‘./lib/3rdlibs/py’. You may also change the search path of numpy in the file FindNumPy.cmake under the folder ‘cMake’:

set(DPDIR "${CMAKE_CURRENT_SOURCE_DIR}/../dem2dinstall/SudoDEM/lib/3rdlibs/py/")

Compile and install SudoDEM3D:

cd build3d
cmake ../SudoDEM3D
make -j3
make install

The binary ‘sudodem3d’ will be installed in the path ‘/home/xxx/SudoDEM/sudodeminstall/SudoDEM3D/bin/’. Append the path to the environmental variable PATH by adding the following line to the config file ‘/home/xxx/.bashrc’:

PATH=${PATH}:/home/xxx/SudoDEM/sudodeminstall/SudoDEM3D/bin

You are expected to get the following directory tree after installation:

::: {.forest} for tree= font=, grow'=0, child anchor=west, parent anchor=south, anchor=west, calign=first, inner xsep=7pt, edge path= (!u.south west) +(7.5pt,0) |- (.child anchor) pic folder ; , file/.style=edge path=(!u.south west) +(7.5pt,0) |- (.child anchor) ;, inner xsep=2pt,font= , before typesetting nodes= if n=1 insert before=[,phantom] , fit=band, before computing xy=l=15pt, [/home/xxx/SudoDEM/sudodeminstall [bin ] [lib [3rdlibs [*.so,file] [py [minieigen.so,file] [numpy] [PyQt4] [other Python modules,file] ] ] [sudodem] ] [share] ] :::

Note: the installation procedure of SudoDEM will overwrite the above directories except ‘3rdlibs’. You need to copy all the 3rd-party libraries compiled above (boost, libQGLViewer, minieigen) to ‘3rdlibs’. If you encounter any problems about the 3rd-libraries, you may check the directory tree for the binary package of SudoDEM.

IMPORTANT: Add rpath to all 3rd-party libraries under ‘3rdlibs’ by executing the script ‘changerpath.sh’ in the folder ‘scripts’.

cd 3rdlibs
cp /home/xxx/SudoDEM/scripts/changerpath.sh .
chmod +x changerpath.sh
./changerpath.sh

Note: ‘changerpath.sh’ will add rpath ‘$ORIGIN’ to all dynamic libraries under ‘3rdlibs’ and rpath ‘$ORIGIN/../../’ to all dynamic libraries under ‘3rdlibs/py/PyQt4’. An rpath would make a dynamic library to search its dependencies (other dynamic libraries) from the rpath-specified path in the first place, which helps to avoid invoking other versions of dependencies in the system path.