Introduction
Introduction Statistics Contact Development Disclaimer Help
tFirst commit - werner - cellular automata simulation of wind-driven sand trans…
git clone git://src.adamsgaard.dk/werner
Log
Files
Refs
LICENSE
---
commit d238e187ed68520db7a7d73e1fb9b011ec1d8c53
Author: Anders Damsgaard Christensen <[email protected]>
Date: Sun, 21 Apr 2013 11:08:31 +0200
First commit
Diffstat:
A Makefile | 35 +++++++++++++++++++++++++++++…
A README.rst | 31 +++++++++++++++++++++++++++++…
A initrnd.c | 29 +++++++++++++++++++++++++++++
A iterate.c | 35 +++++++++++++++++++++++++++++…
A out/plotmatrix.gp | 20 ++++++++++++++++++++
A printmat.c | 26 ++++++++++++++++++++++++++
A werner.c | 318 +++++++++++++++++++++++++++++…
A werner.h | 23 +++++++++++++++++++++++
A wernerparams.h | 11 +++++++++++
9 files changed, 528 insertions(+), 0 deletions(-)
---
diff --git a/Makefile b/Makefile
t@@ -0,0 +1,35 @@
+CFLAGS=-g -Wall -O3 -std=gnu11 -pg
+LDLIBS=`pkg-config --libs gsl`
+LDFLAGS=-pg
+
+default: plots
+
+initrnd: initrnd.o werner.o *.h
+
+iterate: iterate.o werner.o *.h
+
+printmat: printmat.o werner.o *.h
+
+display: matrix.png
+ display $<
+
+matrixes: initrnd iterate printmat Makefile
+ ./initrnd > tmp.mat
+ for i in {001..400}; do cat tmp.mat | ./iterate 1 > tmp_new.mat && cat…
+
+plots: matrixes
+ cd out && for f in *.txt; do gnuplot -e "matrixfile='$$f'" plotmatrix.…
+
+view: plots
+ feh out/*.png
+
+profile-iter: initrnd iterate
+ ./initrnd > tmp.mat
+ ./iterate 10 > tmp_new.mat
+
+clean:
+ $(RM) initrnd iterate printmat
+ $(RM) *.o
+ $(RM) tmp.mat
+ $(RM) out/*.txt
+ $(RM) out/*.png
diff --git a/README.rst b/README.rst
t@@ -0,0 +1,31 @@
+Werner
+======
+
+Discrete simulation of wind driven (
+`aeolian <https://en.wikipedia.org/wiki/Aeolian_processes>`_) erosion, transpo…
+deposition and avalanching of sand, based on `B.T. Werner's algorithm
+<http://geology.geoscienceworld.org/content/23/12/1107>`_.
+
+The software is licensed under the GNU General Public License, v.3. See
+`license.txt` for more information. These programs are created by Anders
+Damsgaard, `<[email protected]>`_.
+
+Requirements
+------------
+The requirements are:
+ * A C compiler toolkit, e.g. the `GNU Compiler Collection
+ <http://gcc.gnu.org/>`_ (GCC)
+ * `GNU Make <https://www.gnu.org/software/make/>`_
+ * `Gnuplot <http://www.gnuplot.info/>`_
+ * `GSL - GNU Scientific Library <http://www.gnuplot.info/>`_
+
+Build and run instructions
+--------------------------
+From the root directory, execute the following command::
+ make
+
+This will build the program, and run an example simulation. Output images are
+placed in the `out/` folder.
+Simulation parameters are changed in `wernerparams.h`. After changing this fil…
+run ``make`` again.
+
diff --git a/initrnd.c b/initrnd.c
t@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+// see https://www.gnu.org/software/gsl/manual/html_node/Matrices.html
+#include <gsl/gsl_matrix.h>
+
+#include "wernerparams.h"
+#include "werner.h"
+
+
+int main(int argc, char** argv)
+{
+
+ // Allocate matrix Z: number of sand slabs
+ gsl_matrix* Z = gsl_matrix_alloc(rows, cols);
+
+ // Initialize with random values
+ init_rnd_matrix(Z, 1.0, 10.0);
+
+ // Add 100 sand slabs to each cell
+ //gsl_matrix_add_constant(Z, 100.0);
+
+ // Write matrix to stdout
+ gsl_matrix_fprintf(stdout, Z, "%f");
+
+ // End program
+ gsl_matrix_free(Z);
+ return 0;
+}
diff --git a/iterate.c b/iterate.c
t@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+// see https://www.gnu.org/software/gsl/manual/html_node/Matrices.html
+#include <gsl/gsl_matrix.h>
+
+#include "wernerparams.h"
+#include "werner.h"
+
+
+int main(int argc, char** argv)
+{
+ // check if the user specified the number of times to iterate
+ int N_c = 1; // Number of cycles, default value
+ if (argc > 1)
+ N_c = atoi(argv[1]);
+
+ // Allocate matrix Z: number of sand slabs
+ gsl_matrix* Z = gsl_matrix_alloc(rows, cols);
+
+ // Read matrix from stdin
+ FILE* fp = fopen("tmp.mat", "r");
+ gsl_matrix_fscanf(fp, Z);
+ //gsl_matrix_fscanf(stdin, Z);
+
+ // Run N_c Werner iterations
+ werner_loop(Z, N_c, d_l, p_ns, p_s);
+
+ // Print result to stdout
+ gsl_matrix_fprintf(stdout, Z, "%f");
+
+ // End program
+ gsl_matrix_free(Z);
+ return 0;
+}
diff --git a/out/plotmatrix.gp b/out/plotmatrix.gp
t@@ -0,0 +1,20 @@
+#!/usr/env gnuplot
+
+# plot matrix file. Invoke with:
+# $ gnuplot -e "matrixfile='file.txt'" plotmatrix.gp
+
+set terminal pngcairo
+set output matrixfile.".png"
+
+set size ratio -1
+
+set title "Werner model for aeolian transport and deposition"
+set xlabel "x"
+set ylabel "y"
+set cblabel "sand slabs"
+
+# With interpolation
+set pm3d map interpolate 0,0
+set palette gray
+splot matrixfile matrix
+
diff --git a/printmat.c b/printmat.c
t@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+// see https://www.gnu.org/software/gsl/manual/html_node/Matrices.html
+#include <gsl/gsl_matrix.h>
+
+#include "wernerparams.h"
+#include "werner.h"
+
+
+int main(int argc, char** argv)
+{
+
+ // Allocate matrix Z: number of sand slabs
+ gsl_matrix* Z = gsl_matrix_alloc(rows, cols);
+
+ // Read matrix from stdin
+ gsl_matrix_fscanf(stdin, Z);
+
+ // Print formatted result to stdout
+ print_matrix(Z);
+
+ // End program
+ gsl_matrix_free(Z);
+ return 0;
+}
diff --git a/werner.c b/werner.c
t@@ -0,0 +1,318 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <gsl/gsl_matrix.h>
+
+// Return a random number in [0;1[
+double rnd(void)
+{
+ return (double)rand()/RAND_MAX;
+}
+
+// Initialize matrix M with random ints from low to high
+void init_rnd_matrix(gsl_matrix* M, double low, double high)
+{
+ int row, col;
+ for (row = 0; row < M->size1; row++)
+ for (col = 0; col < M->size2; col++)
+ gsl_matrix_set(M, row, col,
+ (int)(rnd() * (high-low) + low));
+}
+
+// Write matrix to stdout
+void print_matrix(gsl_matrix* M)
+{
+ int row, col;
+ double val;
+ for (row = 0; row < M->size1; row++) {
+ for (col = 0; col < M->size2; col++) {
+ val = gsl_matrix_get(M, row, col);
+ printf("%f\t", val);
+ }
+ puts(""); // newline
+ }
+}
+
+// Add a slab of sand from the target cell
+void deposit(gsl_matrix* Z, int row, int col)
+{
+ gsl_matrix_set(Z, row, col, gsl_matrix_get(Z, row, col) + 1.0);
+}
+
+// Remove a slab of sand from the target cell
+void erode(gsl_matrix* Z, int row, int col)
+{
+ gsl_matrix_set(Z, row, col, gsl_matrix_get(Z, row, col) - 1.0);
+}
+
+// Find out if cell is in shade (1) or not (0)
+int inshade(
+ gsl_matrix* Z, // matrix with sand slabs
+ int row, // row idx of interest
+ int col) // col idx of interest
+{
+ int js;
+ int i = 1;
+ int shade = 0;
+ int nx = Z->size2;
+
+ while ((i <= nx/4) && (shade == 0)) {
+ js = col - i;
+ if (js < 0) // periodic boundary
+ js += nx;
+ if (gsl_matrix_get(Z, row, js) >= gsl_matrix_get(Z, row, col) + i)
+ shade = 1;
+ i++;
+ }
+ return shade;
+}
+
+void find_max_slope_neighbor_ero(
+ gsl_matrix* Z, // sand slab values
+ int row, // target row
+ int col, // target col
+ int* row_max, // max slope neighbor row
+ int* col_max, // max slope neighbor col
+ double* dh_max) // max slope
+{
+
+ int n; // 1d neighbor idx
+ int i, j; // 2d neighbor idx
+ double dh; // slope
+
+ // relative neighbor coordinates and distances
+ int drow[] = {1, 1, 1, 0, -1, -1, -1, 0};
+ int dcol[] = {-1, 0, 1, 1, 1, 0, -1, -1};
+ double dx[] = {1.4142, 1.0, 1.4142, 1.0, 1.4142, 1.0, 1.4142, 1.0};
+
+ // matrix dimensions
+ int nrows = Z->size1;
+ int ncols = Z->size2;
+
+ // check the 8 surrounding neighbor cells
+ for (n = 0; n<8; n++) {
+
+ // absolute neighbor cell idx
+ i = row + drow[n];
+ j = col + dcol[n];
+
+ // correct for periodic boundaries
+ if (i < 0)
+ i += nrows;
+ if (i >= nrows)
+ i -= nrows;
+ if (j < 0)
+ j += ncols;
+ if (j >= ncols)
+ j -= ncols;
+
+ // find slope
+ dh = (gsl_matrix_get(Z, i, j) - gsl_matrix_get(Z, row, col)) / dx[n];
+
+ // save position if it is the highest slope so far
+ if (dh > *dh_max) {
+ *dh_max = dh;
+ *row_max = i;
+ *col_max = j;
+ }
+ }
+}
+
+void find_max_slope_neighbor_depo(
+ gsl_matrix* Z, // sand slab values
+ int row, // target row
+ int col, // target col
+ int* row_max, // max slope neighbor row
+ int* col_max, // max slope neighbor col
+ double* dh_max) // max slope
+{
+
+ int n; // 1d neighbor idx
+ int i, j; // 2d neighbor idx
+ double dh; // slope
+
+ // relative neighbor coordinates and distances
+ int drow[] = {1, 1, 1, 0, -1, -1, -1, 0};
+ int dcol[] = {-1, 0, 1, 1, 1, 0, -1, -1};
+ double dx[] = {1.4142, 1.0, 1.4142, 1.0, 1.4142, 1.0, 1.4142, 1.0};
+
+ // matrix dimensions
+ int nrows = Z->size1;
+ int ncols = Z->size2;
+
+ // check the 8 surrounding neighbor cells
+ for (n = 0; n<8; n++) {
+
+ // absolute neighbor cell idx
+ i = row + drow[n];
+ j = col + dcol[n];
+
+ // correct for periodic boundaries
+ if (i < 0)
+ i += nrows;
+ if (i >= nrows)
+ i -= nrows;
+ if (j < 0)
+ j += ncols;
+ if (j >= ncols)
+ j -= ncols;
+
+ // find slope
+ dh = (gsl_matrix_get(Z, row, col) - gsl_matrix_get(Z, i, j)) / dx[n];
+
+ // save position if it is the highest slope so far
+ if (dh > *dh_max) {
+ *dh_max = dh;
+ *row_max = i;
+ *col_max = j;
+ }
+ }
+
+}
+
+
+// Check and perform avalanche into cell if slope exceeds limit
+void avalanche_erosion(
+ gsl_matrix* Z, // sand slab values
+ int row, // target row
+ int col) // target col
+{
+ // find the neighbor with the max. height difference and the slope value
+ double dh_max = 0.0; // max slope
+ int row_max, col_max;
+ find_max_slope_neighbor_ero(Z, row, col, &row_max, &col_max, &dh_max);
+
+ // Perform avalanche along max slope neighbor
+ double threshold = 2.0; // avalanche threshold
+ if (dh_max > threshold) {
+ deposit(Z, row, col); // put sand in target cell
+ erode(Z, row_max, col_max); // remove sand from max slope neighbor cell
+
+ // Recursion
+ avalanche_erosion(Z, row, col);
+ }
+}
+
+// Check and perform avalanche away from cell if slope exceeds limit
+void avalanche_deposition(
+ gsl_matrix* Z, // sand slab values
+ int row, // target row
+ int col) // target col
+{
+ // find the neighbor with the max. height difference and the slope value
+ double dh_max = 0.0; // max slope
+ int row_max, col_max;
+ find_max_slope_neighbor_depo(Z, row, col, &row_max, &col_max, &dh_max);
+
+ // Perform avalanche along max slope neighbor
+ double threshold = 2.0; // avalanche threshold
+ if (dh_max > threshold) {
+ erode(Z, row, col);
+ deposit(Z, row_max, col_max);
+
+ // Recursion
+ avalanche_deposition(Z, row, col);
+ }
+}
+
+// Move a sand unit and deposit it where it fits
+void move_and_deposit(
+ gsl_matrix* Z, // matrix with sand slabs
+ double p_ns, // likelihood of deposition in no-sand cell
+ double p_s, // likelihood of deposition in sand cell
+ double d_l, // transport distance in no. of cells
+ int* row, // current cell row
+ int* col, // current cell col
+ int* deposited) // deposited? 1=yes, 0=no
+{
+ // move sand slab in wind direction
+ *col += d_l;
+ int ncols = Z->size1;
+ if (*col >= ncols)
+ *col -= ncols;
+
+ // is the target in the shade?
+ // 1=yes, 0=no
+ int shade = 0;
+ shade = inshade(Z, *row, *col);
+ if (shade > 0) {
+ deposit(Z, *row, *col);
+ avalanche_deposition(Z, *row, *col); // check for avalanches
+ *deposited = 1; // sand deposited, stop moving it
+ }
+
+ // if not in the shade, check against deposition probabilities
+ else {
+
+ // sand in cell
+ if (gsl_matrix_get(Z, *row, *col) > 0.) {
+ if (rnd() <= p_s) { // deposit in cell with sand
+ deposit(Z, *row, *col);
+ avalanche_deposition(Z, *row, *col); // check for avalanches
+ *deposited = 1; // sand deposited, stop moving it
+ }
+ } else { // no sand in cell
+ if (rnd() <= p_ns) { // deposit in cell without sand
+ deposit(Z, *row, *col);
+ avalanche_deposition(Z, *row, *col); // check for avalanches
+ *deposited = 1; // sand deposited, stop moving it
+ }
+ }
+ }
+}
+
+// Perform a single Werner iteration
+void werner_iter(
+ gsl_matrix* Z, // matrix with sand slabs
+ int d_l, // wind transport distance
+ double p_ns, // likelihood of deposition in sand-free cell
+ double p_s) // likelihood of deposition in sand-covered cell
+{
+ // Evaluate N=nx*ny cells in random order
+ int row, col, deposited;
+ int nrows = Z->size1; // row major
+ int ncols = Z->size2;
+ long int n;
+ long int N = nrows*ncols;
+ double cellval;
+
+
+ // Perform cycle
+ for (n=0; n<N; n++) {
+
+ // random cell idx
+ row = rand()%nrows;
+ col = rand()%ncols;
+
+ // If the cell has sand in it (val>0), and is not in the shadow zone
+ cellval = gsl_matrix_get(Z, row, col);
+ if ((cellval > 0.) && (inshade(Z, row, col) == 0)) {
+
+ // erode
+ erode(Z, row, col);
+
+ // check for avalanche
+ avalanche_erosion(Z, row, col);
+
+ // move eroded sand and deposit where it fits
+ deposited = 0;
+ while (deposited == 0)
+ move_and_deposit(Z, p_ns, p_s, d_l, &row, &col, &deposited);
+
+ }
+ }
+}
+
+// Loop system through time
+void werner_loop(
+ gsl_matrix* Z, // matrix with sand slabs
+ long int N_c, // number of iterations
+ int d_l, // wind transport distance
+ double p_ns, // likelihood of deposition in sand-free cell
+ double p_s) // likelihood of deposition in sand-covered cell
+{
+ long int t;
+ for (t = 0; t<N_c; t++)
+ werner_iter(Z, d_l, p_ns, p_s);
+}
+
+
diff --git a/werner.h b/werner.h
t@@ -0,0 +1,23 @@
+#ifndef WERNER_H_
+#define WERNER_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <gsl/gsl_matrix.h>
+
+void init_rnd_matrix(gsl_matrix* M, double low, double high);
+void print_matrix(gsl_matrix* M);
+void werner_iter(
+ gsl_matrix* Z, // matrix with sand slabs
+ int d_l, // wind transport distance
+ double p_ns, // likelihood of deposition in sand-free cell
+ double p_s); // likelihood of deposition in sand-covered cell
+void werner_loop(
+ gsl_matrix* Z, // matrix with sand slabs
+ long int N_c, // number of iterations
+ int d_l, // wind transport distance
+ double p_ns, // likelihood of deposition in sand-free cell
+ double p_s); // likelihood of deposition in sand-covered cell
+
+
+#endif
diff --git a/wernerparams.h b/wernerparams.h
t@@ -0,0 +1,11 @@
+#ifndef WERNERPARAMS_H_
+#define WERNERPARAMS_H_
+
+// set simulation parameters
+const int rows = 400;
+const int cols = 400;
+const int d_l = 5; // wind transport distance (left to right)
+const double p_ns = 0.4; // likelihood of deposition in sand free cells
+const double p_s = 0.6; // likelihood of deposition in sand covered cells
+
+#endif
You are viewing proxied material from mx1.adamsgaard.dk. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.