Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added some features for params file and making non-hydrostatic model. #28

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
/.idea
/examples/xb-2D/

# Don't track pyc files
*.pyc
2 changes: 1 addition & 1 deletion docs/source/xbeach-setup-1D.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@
"\n",
"xb_setup.set_params({'Wavemodel':'surfbeat',\n",
" 'morphology':0,\n",
" 'befriccoef':0.01,\n",
" 'bedfriccoef':0.01,\n",
" 'tstop':3600,\n",
" 'zs0':0,\n",
" 'nglobalvar':['zb','zs','H'],\n",
Expand Down
2 changes: 1 addition & 1 deletion docs/source/xbeach-setup-2D.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@
"\n",
"xb_setup.set_params({'Wavemodel' : 'surfbeat',\n",
" 'morphology' : 0,\n",
" 'befriccoef' : 0.01,\n",
" 'bedfriccoef' : 0.01,\n",
" 'tstop' : 3600,\n",
" 'zs0' : 0,\n",
" 'nglobalvar' : ['zb', 'zs', 'H'],\n",
Expand Down
27 changes: 19 additions & 8 deletions examples/xbeach-setup-1D.ipynb

Large diffs are not rendered by default.

135 changes: 76 additions & 59 deletions examples/xbeach-setup-2D.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
license='GNU General Public License v3.0',
packages=['xbTools','xbTools.grid','xbTools.general'],
package_data={'': ['*.json']}, # always include .json files in the package contents
python_requires='>=3, <4',
python_requires='>=3.1, <4',
install_requires=['numpy','matplotlib>=3.5.0','netCDF4>=1.6.0','scipy>=1.10.0','datetime','geopandas>=0.13.0','shapely>=2.0.0','fiona>=1.9.4.post1','pytest'],
zip_safe=False)
42 changes: 42 additions & 0 deletions xbTools/general/dict_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# dict_utils.py

def check_keys_exist(dict1, dict2):
"""
Check if all keys from dict1 are present in dict2.

Parameters:
- dict1 (dict): Dictionary to check keys.
- dict2 (dict): Dictionary to check against.

Returns:
- bool: True if all keys from dict1 are in dict2, False otherwise.
"""
return all(key in dict2 for key in dict1)

def check_strings_in_dict(list_of_strings, dict_strings):
"""
Check if all strings in list_of_strings are present as values in dict_strings.

Parameters:
- list_of_strings (list): List of strings to check.
- dict_strings (dict): Dictionary with string values.

Returns:
- bool: True if all strings in list_of_strings are in dict_strings, False otherwise.
"""
dict_values = set(dict_strings.values())
return all(string in dict_values for string in list_of_strings)

# Other utility functions can go here if needed
# def other_utility_function():
# pass

# Test for the code
if __name__ == "__main__":
dict1 = {'a': 1, 'b': 2, 'c': 3}
dict2 = {'a': 10, 'b': 20, 'c': 30, 'd': 40}

print(check_keys_exist(dict1, dict2)) # Output: True

dict3 = {'a': 10, 'c': 30}
print(check_keys_exist(dict1, dict3)) # Output: False
98 changes: 94 additions & 4 deletions xbTools/general/executing_runs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# import python modules
import os
import numpy as np
import subprocess

from xbTools.xbeachtools import XBeachModelSetup

Expand All @@ -20,9 +21,9 @@ def xb_run_script_win(xb, N, maindir, xbeach_exe):
list with simulation paths or XBeachModelSetup class
N : int
Number of batch scripts.
maindir : TYPE
maindir : string
path where run script is created.
xbeach_exe : TYPE
xbeach_exe : string
path of XBeach executable.

Returns
Expand All @@ -44,6 +45,8 @@ def xb_run_script_win(xb, N, maindir, xbeach_exe):
path_sims = [xb.model_path]

## number of batch scripts
# TODO: This will cause an error if a string is passed into this function. This would return the length of the string divided by the N
# TODO: Don't think this makes any sense
Nmax = int(np.ceil(len(path_sims)/N))

## string
Expand All @@ -63,5 +66,92 @@ def xb_run_script_win(xb, N, maindir, xbeach_exe):
print(os.path.join(maindir,'run{}.bat'.format(run_number)))
with open(os.path.join(maindir,'run{}.bat'.format(run_number)), 'w') as f:
f.write(string)



def generate_batch_script(model_folder, exe_path, batch_file_name = "run_model.bat", include_cd = False, batch_file_folder = None):
"""
Generates an batch script inside of the model directory, linking to the exe_path

Parameters
----------
model_folder: string
Directory to the model that the batch script should be created for

exe_path: string
Directory to the executable that should be linked to in the batch file

batch_file_name: string (Optional)
Name of the batch script that should be generated. Defaults to "run_model.bat"

include_cd: Boolean (Optional)
Controls if a "cd {model directory}" statement is included in the batch file.

batch_file_folder: string (Optional)
Input a directory that should hold the batch file. This overrides including the file inside of the model folder
NOTE: This causes include_cd to be True
Returns
-------
None.

"""

if batch_file_folder is None:
# Make the batch file path
batch_script_path = os.path.join(model_folder, batch_file_name)

else:
# Make the include_cd statement true, because for the batch file to be saved in a different directory than the model it will have to cd into
# that directory
include_cd = True
batch_script_path = os.path.join(batch_file_folder)

# init empty string to possibly hold the change directory statement
cd_str = ""

if include_cd:
cd_str = "cd \"{}\"".format(model_folder)

# Make the string that will be written to the file
batch_str = cd_str + "call \"{}\"".format(exe_path)

# Create the file and open it in write mode
with open(batch_script_path, "w") as f:
# write the string to the batch file
f.write(batch_str)

def run_batch_script(batch_script_path, flag_print_Blog = False):
"""
Run a batch script given a path

Parameters
----------
batch_script_path : string
The path to a batch script that the user wants to run. This will cause the script to be run inside of the python script

Returns
-------
None.

'''
"""

# Set the working directory to where the batch file is located
working_directory = os.path.dirname(batch_script_path)

try:
# Execute the batch file, capturing both stdout and stderr
result = subprocess.run(batch_script_path, check=True, shell=True, cwd=working_directory, capture_output=True, text=True)

# Print success message and output
print(f"Batch file '{batch_script_path}' executed successfully.")

if flag_print_Blog:
print("Output:")
print(result.stdout)
except subprocess.CalledProcessError as e:
# Print error message and captured stderr
print(f"An error occurred while executing the batch file: {e}")
print("Error output:")
print(e.stderr)

if __name__ == "__main__":
pass
62 changes: 62 additions & 0 deletions xbTools/general/file_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""
Functions that help you output or work with files
"""

# Standard imports
import json
import os

def write_2d_arr_2_file(arr, file_path, decimal_digits=3):
"""
Writes a 2d array into a file with each row of the 2d array written as a row in the file.

Inputs:
file_path : Name of the file that the data should be written to.
arr : 2d array that should be written to the file.
decimal_digits : Number of decimal digits to format the elements in the array (default is 2).
"""

# Create a format string based on the number of decimal digits
format_str = f"{{:.{decimal_digits}f}}"

# Open the file in write mode
with open(file_path, 'w') as file:
# Write each row of the array to the file
for row in arr:
formatted_row = ' '.join(format_str.format(value) for value in row)
file.write(formatted_row + '\n')

def format_header_line(text):
"""
Used to format the header line the in params.txt file

inputs:
text: string
The text should be put in the header
"""
return f"%%% {text.ljust(71)} %%%"

def format_subsection_header(text, length = 78):
"""
Format the subsection headers in the text file
"""
string = f"%%% {text}"

num_perc_signs = length - len(string)

perc_signs = "%" * num_perc_signs
return f"{string} {perc_signs}"

def get_json(folder_path, file_name):
"""
Reads a json and returns it as a dict
NOTE: Can be used to look at the json in script so you can see the inputs
"""

## Open the json file
json_file = open(os.path.join(folder_path, file_name),'r')

# Read the json file and store it as a python dict
json_dict = json.loads(json_file.read())

return json_dict
1 change: 0 additions & 1 deletion xbTools/general/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ def rotate(x, y, theta, origin = [0,0]):

return xrot.reshape(ny, nx)+x0, yrot.reshape(ny, nx)+y0


def rotate_grid(xgr, ygr, theta):
'''
Rotate_grid(xgr,ygr,theta)
Expand Down
3 changes: 1 addition & 2 deletions xbTools/general/wave_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

def dispersion(w, d, max_error=0.00001,g=9.81):
'''
Computes the wave number given a radial frequeny and water depth
Computes the wave number given a radial frequency and water depth

Parameters
----------
Expand Down Expand Up @@ -46,7 +46,6 @@ def dispersion(w, d, max_error=0.00001,g=9.81):
print ('Warning: no convergence')
return k


def wavecelerity(Tp, d, g=9.81):
'''
Computes the group velocity and wave celerity ratio based on the wave period and water depth.
Expand Down
25 changes: 18 additions & 7 deletions xbTools/grid/creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@ def xgrid(x,z,
xgr = xgr-xgr[-1]+xend
return xgr, zgr


def ygrid(y,
dymin = 5,
dymax = 20,
Expand Down Expand Up @@ -283,15 +282,27 @@ def ygrid(y,
return ygr

def grid_transition(cell1, cell2, distance):

"""
function for grid_transition from one cell to the other
Function for grid transition from one cell to the other.

Parameters:
cell1 (float): Size of cell 1.
cell2 (float): Size of cell 2.
distance (float): Distance to transition over.

Returns:
ff, nf, gridf, error

#todo improve docstring and syntax of code
"""
tuple: Tuple containing:
ff (np.ndarray): Array of scaling factors.
nf (int): Number of grid points.
gridf (list): List of grid points.
error (float): Error in transition.

Notes:
- This function calculates the transition grid between two cells.
- Adjusts the grid transition based on distance.

# TODO: Improve the syntax of this function and the docstring
"""

precision = 1e-10
maxloop = 1e2
Expand Down
5 changes: 4 additions & 1 deletion xbTools/grid/grid_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

def diff(A,direc = 0):
'''
NOTE: There's a built in numpy function to do this: np.diff( "vector or matrix")
Link: https://numpy.org/doc/stable/reference/generated/numpy.diff.html

Computes the difference in subsequent items
A is either a vector or a 2D matrix
if A is a matrix,
Expand Down Expand Up @@ -69,7 +72,7 @@ def smoothness(x, y, outputloc = ''):
'''
Perform grid checks based on D3D-quickin procedure for
smoothness in m and n-direction and stores figures
note that it is advisable to use local coordinate system!
NOTE: It is advisable to use local coordinate system!
Author: Cas van Bemmelen
Date: 26-06-2023

Expand Down
Loading