diff --git a/examples/block_hill_with_dike.txt b/examples/block_hill_with_dike.txt new file mode 100644 index 0000000..61f711c --- /dev/null +++ b/examples/block_hill_with_dike.txt @@ -0,0 +1,27 @@ +# GrainHill input file: +# +# block_hill_with_dike: "block hill" model that includes a cell state to +# represent boulders. Here boulders form a vertical dike in the center of the +# domain. Similar to Figure 18d in Tucker et al. (2018). +# +model_type: 'blockhill' +number_of_node_rows: 61 +number_of_node_columns: 101 +cell_width: 0.1 +grav_accel: 9.8 +friction_coef: 1.0 +run_duration: 10000.0 +uplift_interval: 200.0 +disturbance_rate: 0.01 +weathering_rate: 0.0005 +rock_state_for_uplift: 7 +block_layer_dip_angle: 90.0 +block_layer_thickness: 10.0 +layer_left_x: 39.0 +opt_rock_collapse: 1 +save_plots: True +plot_filename: 'block_hill_with_dike' +plot_filetype: '.png' +plot_interval: 1000.0 +output_interval: 1.0e20 +report_interval: 5.0 diff --git a/examples/block_hill_with_hogback30deg.txt b/examples/block_hill_with_hogback30deg.txt new file mode 100644 index 0000000..2ffcaa8 --- /dev/null +++ b/examples/block_hill_with_hogback30deg.txt @@ -0,0 +1,28 @@ +# GrainHill input file: +# +# block_hill_with_hogback30deg: "block hill" model that includes a cell state to +# represent boulders. Here boulders form a 30-degree dipping layer that creates +# a hogback. Similar to Figure 18b in Tucker et al. (2018). +# +model_type: 'blockhill' +number_of_node_rows: 61 +number_of_node_columns: 101 +cell_width: 0.1 +grav_accel: 9.8 +friction_coef: 1.0 +run_duration: 15000.0 +uplift_interval: 200.0 +uplift_duration: 10000.0 +disturbance_rate: 0.01 +weathering_rate: 0.0005 +rock_state_for_uplift: 7 +block_layer_dip_angle: 30.0 +block_layer_thickness: 10.0 +y0_top: -50.0 +opt_rock_collapse: 1 +save_plots: True +plot_filename: 'block_hill_with_hogback30deg' +plot_filetype: '.png' +plot_interval: 1500.0 +output_interval: 1.0e20 +report_interval: 5.0 diff --git a/examples/block_hill_with_hogback60deg.txt b/examples/block_hill_with_hogback60deg.txt new file mode 100644 index 0000000..21227f2 --- /dev/null +++ b/examples/block_hill_with_hogback60deg.txt @@ -0,0 +1,28 @@ +# GrainHill input file: +# +# block_hill_with_hogback60deg: "block hill" model that includes a cell state to +# represent boulders. Here boulders form a 60-degree dipping layer that creates +# a hogback. Similar to Figure 18c in Tucker et al. (2018). +# +model_type: 'blockhill' +number_of_node_rows: 61 +number_of_node_columns: 101 +cell_width: 0.1 +grav_accel: 9.8 +friction_coef: 1.0 +run_duration: 15000.0 +uplift_interval: 200.0 +uplift_duration: 10000.0 +disturbance_rate: 0.01 +weathering_rate: 0.0005 +rock_state_for_uplift: 7 +block_layer_dip_angle: 60.0 +block_layer_thickness: 10.0 +y0_top: -150.0 +opt_rock_collapse: 1 +save_plots: True +plot_filename: 'block_hill_with_hogback60deg' +plot_filetype: '.png' +plot_interval: 1500.0 +output_interval: 1.0e20 +report_interval: 5.0 diff --git a/examples/regolith_hill_d1.txt b/examples/regolith_hill_d1.txt deleted file mode 100644 index b1993f1..0000000 --- a/examples/regolith_hill_d1.txt +++ /dev/null @@ -1,19 +0,0 @@ -# GrainHill input file for generating frames used in animations. -number_of_node_rows: 79 -number_of_node_columns: 184 -cell_size: 0.1 -grav_accel: 9.8 -friction_coef: 1.0 -run_duration: 15000.0 -output_name: 'regolith_hill_d1' -uplift_interval: 100.0 -disturbance_rate: 0.01 -weathering_rate: 0.001 -rock_state_for_uplift: 7 -opt_rock_collapse: 0 -opt_track_grains: False -show_plots: False -plot_to_file: True -plot_interval: 150.0 -output_interval: 1.0e20 -report_interval: 60.0 diff --git a/examples/regolith_hill_dp1.txt b/examples/regolith_hill_dp1.txt new file mode 100644 index 0000000..80cba0e --- /dev/null +++ b/examples/regolith_hill_dp1.txt @@ -0,0 +1,26 @@ +# GrainHill input file: +# +# regolith_hill_dp1: symmetric, all-regolith hillslope with d = 0.01 1/yr, +# tau = 100 yr, and d' = d tau = 1. +# Run is similar to the top center panel of Figure 8 of Tucker et al. (2018), +# but with a shorter hill (~18 m wide instead of ~58 m). +# +model_type: 'grainhill' +number_of_node_rows: 79 +number_of_node_columns: 184 +cell_width: 0.1 +grav_accel: 9.8 +friction_coef: 1.0 +run_duration: 15000.0 +uplift_interval: 100.0 +disturbance_rate: 0.01 +weathering_rate: 0.001 +rock_state_for_uplift: 7 +opt_rock_collapse: 0 +opt_track_grains: False +save_plots: True +plot_filename: 'regolith_hill_dp1' +plot_filetype: '.png' +plot_interval: 3000.0 +output_interval: 1.0e20 +report_interval: 5.0 diff --git a/examples/regolith_hill_dp10.txt b/examples/regolith_hill_dp10.txt new file mode 100644 index 0000000..95b9ad4 --- /dev/null +++ b/examples/regolith_hill_dp10.txt @@ -0,0 +1,26 @@ +# GrainHill input file: +# +# regolith_hill_dp10: symmetric, all-regolith hillslope with d = 0.1 1/yr, +# tau = 100 yr, and d' = d tau = 10. +# Run is similar to the top right panel of Figure 8 of Tucker et al. (2018), +# but with a shorter hill (~18 m wide instead of ~58 m). +# +model_type: 'grainhill' +number_of_node_rows: 79 +number_of_node_columns: 184 +cell_width: 0.1 +grav_accel: 9.8 +friction_coef: 1.0 +run_duration: 15000.0 +uplift_interval: 100.0 +disturbance_rate: 0.1 +weathering_rate: 0.001 +rock_state_for_uplift: 7 +opt_rock_collapse: 0 +opt_track_grains: False +save_plots: True +plot_filename: 'regolith_hill_dp10' +plot_filetype: '.png' +plot_interval: 3000.0 +output_interval: 1.0e20 +report_interval: 5.0 diff --git a/examples/rock_hill_dp10wp0p4.txt b/examples/rock_hill_dp10wp0p4.txt new file mode 100644 index 0000000..0341d97 --- /dev/null +++ b/examples/rock_hill_dp10wp0p4.txt @@ -0,0 +1,27 @@ +# GrainHill input file: +# +# rock_hill_dp10wp0p4: symmetric, rock-based hillslope with relatively +# inefficient weathering, and efficient disturbance. +# Run is similar to the bottom middle panel of Figure 11 of +# Tucker et al. (2018), but with a slightly shorter hill (~18 m wide instead +# of ~26 m). +# +model_type: 'grainhill' +number_of_node_rows: 158 +number_of_node_columns: 184 +cell_width: 0.1 +grav_accel: 9.8 +friction_coef: 1.0 +run_duration: 100000.0 +uplift_interval: 1000.0 +disturbance_rate: 0.01 +weathering_rate: 0.0004 +rock_state_for_uplift: 8 +opt_rock_collapse: 0 +opt_track_grains: False +save_plots: True +plot_filename: 'rock_hill_dp10wp0p4' +plot_filetype: '.png' +plot_interval: 10000.0 +output_interval: 1.0e20 +report_interval: 5.0 diff --git a/examples/rock_hill_dp10wp40.txt b/examples/rock_hill_dp10wp40.txt new file mode 100644 index 0000000..7bc26bb --- /dev/null +++ b/examples/rock_hill_dp10wp40.txt @@ -0,0 +1,26 @@ +# GrainHill input file: +# +# rock_hill_dp10wp40: symmetric, rock-based hillslope with relatively +# efficient weathering and disturbance. +# Run is similar to the top middle panel of Figure 11 of Tucker et al. (2018), +# but with a slightly shorter hill (~18 m wide instead of ~26 m). +# +model_type: 'grainhill' +number_of_node_rows: 158 +number_of_node_columns: 184 +cell_width: 0.1 +grav_accel: 9.8 +friction_coef: 1.0 +run_duration: 100000.0 +uplift_interval: 1000.0 +disturbance_rate: 0.01 +weathering_rate: 0.04 +rock_state_for_uplift: 8 +opt_rock_collapse: 0 +opt_track_grains: False +save_plots: True +plot_filename: 'rock_hill_dp10wp40' +plot_filetype: '.png' +plot_interval: 10000.0 +output_interval: 1.0e20 +report_interval: 5.0 diff --git a/grainhill/block_hill.py b/grainhill/block_hill.py index 15317bc..841356d 100644 --- a/grainhill/block_hill.py +++ b/grainhill/block_hill.py @@ -25,21 +25,25 @@ class BlockHill(GrainHill): def __init__(self, grid_size, cell_width=1.0, grav_accel=9.8, report_interval=1.0e8, run_duration=1.0, output_interval=1.0e99, disturbance_rate=1.0, - weathering_rate=1.0, uplift_interval=1.0, plot_interval=1.0e99, + weathering_rate=1.0, uplift_interval=1.0, uplift_duration=None, + plot_interval=1.0e99, save_plots=False, + plot_filename='blockhill', plot_filetype='.png', friction_coef=0.3, rock_state_for_uplift=7, opt_rock_collapse=False, block_layer_dip_angle=0.0, block_layer_thickness=1.0, layer_left_x=0.0, y0_top=0.0): """Call the initialize() method.""" self.bh_initialize(grid_size, cell_width, grav_accel, report_interval, run_duration,output_interval, disturbance_rate, - weathering_rate, uplift_interval, plot_interval, - friction_coef, rock_state_for_uplift, - opt_rock_collapse, block_layer_dip_angle, - block_layer_thickness, layer_left_x, y0_top) + weathering_rate, uplift_interval, uplift_duration, + plot_interval, save_plots, plot_filename, plot_filetype, + friction_coef, rock_state_for_uplift, opt_rock_collapse, + block_layer_dip_angle, block_layer_thickness, + layer_left_x, y0_top) def bh_initialize(self, grid_size, cell_width, grav_accel, report_interval, run_duration, output_interval, disturbance_rate, - weathering_rate, uplift_interval, plot_interval, + weathering_rate, uplift_interval, uplift_duration, + plot_interval, save_plots, plot_filename, plot_filetype, friction_coef, rock_state_for_uplift, opt_rock_collapse, block_layer_dip_angle, block_layer_thickness, layer_left_x, y0_top): @@ -61,10 +65,14 @@ def bh_initialize(self, grid_size, cell_width, grav_accel, report_interval, disturbance_rate=disturbance_rate, weathering_rate=weathering_rate, uplift_interval=uplift_interval, + uplift_duration=uplift_duration, plot_interval=plot_interval, friction_coef=friction_coef, rock_state_for_uplift=rock_state_for_uplift, - opt_rock_collapse=opt_rock_collapse) + opt_rock_collapse=opt_rock_collapse, + save_plots=save_plots, + plot_filename=plot_filename, + plot_filetype=plot_filetype) self.uplifter = LatticeUplifter(self.grid, self.grid.at_node['node_state'], diff --git a/grainhill/grain_hill.py b/grainhill/grain_hill.py index d5ad665..74b34e4 100644 --- a/grainhill/grain_hill.py +++ b/grainhill/grain_hill.py @@ -88,6 +88,7 @@ def __init__( weathering_rate=1.0, dissolution_rate=0.0, uplift_interval=1.0, + uplift_duration=None, plot_interval=1.0e99, friction_coef=0.3, rock_state_for_uplift=7, @@ -114,6 +115,7 @@ def __init__( weathering_rate, dissolution_rate, uplift_interval, + uplift_duration, plot_interval, friction_coef, rock_state_for_uplift, @@ -141,6 +143,7 @@ def initialize( weathering_rate, dissolution_rate, uplift_interval, + uplift_duration, plot_interval, friction_coef, rock_state_for_uplift, @@ -161,6 +164,10 @@ def initialize( self.weathering_rate = weathering_rate self.dissolution_rate = dissolution_rate self.uplift_interval = uplift_interval + if uplift_duration is not None: + self.uplift_duration = uplift_duration + else: + self.uplift_duration = run_duration self.plot_interval = plot_interval self.friction_coef = friction_coef self.rock_state = rock_state_for_uplift # 7 (resting sed) or 8 (rock) @@ -473,6 +480,8 @@ def run(self, to=None): self.ca, self.current_time, rock_state=self.rock_state ) self.next_uplift += self.uplift_interval + if self.current_time >= self.uplift_duration: + self.next_uplift = self.run_duration + 1.0 # no more uplift def get_profile_and_soil_thickness(self, grid, data): """Calculate and return profiles of elevation and soil thickness. diff --git a/tools/make_gif_animation.py b/tools/make_gif_animation.py new file mode 100644 index 0000000..06d63cc --- /dev/null +++ b/tools/make_gif_animation.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +""" +Make a gif animation from a set of .png files. + +Assumes the files have the same base name, followed by a number, +followed by .png. Designed to create movies from a sequence of +output images from the GrainHill model. + +Created on Tue May 15 14:05:15 2018 + +@author: gtucker +""" + +import imageio +import sys +import os + + +def main(basename): + + images = [] + + for this_name in sorted(os.listdir('.')): + print('appending ' + this_name) + if this_name[-3:] == 'png': + images.append(imageio.imread(this_name)) + imageio.mimsave(basename + '_movie.gif', images) + + +if __name__ == '__main__': + + try: + basename = sys.argv[1] + except: + print('Usage: ' + sys.argv[0] + ' ') + raise + + main(basename)