Skip to content

Commit a2819ae

Browse files
committedJan 15, 2022
Major cleanup
1 parent 9fad4df commit a2819ae

23 files changed

+2258
-2151
lines changed
 

‎.github/workflows/nix.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: "Nix tests"
2+
on:
3+
push:
4+
branches:
5+
- master
6+
pull_request:
7+
branches:
8+
- master
9+
jobs:
10+
tests:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v2.3.4
14+
- uses: cachix/install-nix-action@v13
15+
with:
16+
install_url: https://nixos-nix-install-tests.cachix.org/serve/i6laym9jw3wg9mw6ncyrk6gjx4l34vvx/install
17+
install_options: '--tarball-url-prefix https://nixos-nix-install-tests.cachix.org/serve'
18+
extra_nix_config: |
19+
experimental-features = nix-command flakes
20+
- run: nix flake check
21+
- run: nix build

‎.github/workflows/tox.yml

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: "Tox tests"
2+
on:
3+
push:
4+
pull_request:
5+
schedule:
6+
- cron: "0 8 * * *"
7+
jobs:
8+
test:
9+
name: tox test ${{ matrix.py }} - ${{ matrix.os }}
10+
runs-on: ${{ matrix.os }}-latest
11+
strategy:
12+
fail-fast: false
13+
matrix:
14+
os:
15+
- Ubuntu
16+
- Windows
17+
- MacOs
18+
py:
19+
- "3.10"
20+
- "3.9"
21+
steps:
22+
- name: Setup python for test ${{ matrix.py }}
23+
uses: actions/setup-python@v2
24+
with:
25+
python-version: ${{ matrix.py }}
26+
- uses: actions/checkout@v2
27+
- name: Install tox-gh
28+
run: python -m pip install tox-gh
29+
- name: Setup test suite
30+
run: tox4 r -vv --notest
31+
- name: Run test suite
32+
run: tox4 r --skip-pkg-install
33+
env:
34+
PYTEST_ADDOPTS: "-vv --durations=10"

‎.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,5 @@ _build
4646
*.png
4747

4848
result*
49+
50+
.ipynb_checkpoints

‎README.md

+2-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# pstd
22

3-
A Python implementation of the k-space pseudospectral time-domain method.
3+
A Python implementation of the $k$-space pseudospectral time-domain method.
44

55
This implementation was originally written to quantify the fluctuations in sound pressure due to atmospheric turbulence.
66

@@ -11,19 +11,8 @@ Currently there are no packages available.
1111

1212
The recommended method to install is to clone this repository
1313

14-
`git clone git@github.com:FRidh/pstd.git`
14+
pip install git+https://github.com/FRidh/seapy.git
1515

16-
and install this package in development mode
17-
18-
`python setup.py develop`
19-
20-
This way one can easily update to the latest version using
21-
22-
`git pull`
23-
24-
and running again
25-
26-
`python setup.py develop`
2716

2817
## Examples
2918

‎default.nix

+32-2
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,60 @@
11
{ buildPythonPackage
2+
3+
, flit-core
4+
25
, acoustics
36
, h5py
7+
, numba
48
, numpy
59
, scipy
610
, matplotlib
711
, numexpr
812
, pyyaml
13+
14+
, black
15+
, nbconvert
16+
, pylint
17+
, pytest
18+
, pytestCheckHook
919
}:
1020

1121
buildPythonPackage rec {
1222
pname = "pstd";
1323
version = "dev";
24+
format = "pyproject";
1425

1526
src = ./.;
1627

28+
nativeBuildInputs = [
29+
flit-core
30+
];
31+
1732
propagatedBuildInputs = [
1833
acoustics
1934
h5py
35+
numba
2036
numpy
2137
scipy
2238
matplotlib
2339
numexpr
2440
pyyaml
2541
];
2642

27-
# No tests
28-
doCheck = false;
43+
checkInputs = [
44+
black
45+
nbconvert
46+
pylint
47+
pytest
48+
pytestCheckHook
49+
];
50+
51+
preCheck = ''
52+
echo "Checking formatting with black..."
53+
black --check pstd tests docs/conf.py
54+
echo "Static analysis with pylint..."
55+
pylint -E pstd
56+
'';
57+
58+
passthru.allInputs = nativeBuildInputs ++ propagatedBuildInputs ++ checkInputs;
2959

3060
}

‎docs/conf.py

+93-86
Original file line numberDiff line numberDiff line change
@@ -18,225 +18,221 @@
1818
# If extensions (or modules to document with autodoc) are in another directory,
1919
# add these directories to sys.path here. If the directory is relative to the
2020
# documentation root, use os.path.abspath to make it absolute, like shown here.
21-
#sys.path.insert(0, os.path.abspath('.'))
21+
# sys.path.insert(0, os.path.abspath('.'))
2222

2323
# -- General configuration ------------------------------------------------
2424

2525
# If your documentation needs a minimal Sphinx version, state it here.
26-
#needs_sphinx = '1.0'
26+
# needs_sphinx = '1.0'
2727

2828
# Add any Sphinx extension module names here, as strings. They can be
2929
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
3030
# ones.
31-
extensions = ['sphinx.ext.autodoc',
32-
'sphinx.ext.inheritance_diagram',
33-
'sphinx.ext.intersphinx',
34-
'sphinx.ext.pngmath',
35-
'sphinx.ext.viewcode',
36-
'sphinx.ext.autosummary']
31+
extensions = [
32+
"sphinx.ext.autodoc",
33+
"sphinx.ext.inheritance_diagram",
34+
"sphinx.ext.intersphinx",
35+
"sphinx.ext.pngmath",
36+
"sphinx.ext.viewcode",
37+
"sphinx.ext.autosummary",
38+
]
3739

3840
# Add any paths that contain templates here, relative to this directory.
39-
templates_path = ['_templates']
41+
templates_path = ["_templates"]
4042

4143
# The suffix of source filenames.
42-
source_suffix = '.rst'
44+
source_suffix = ".rst"
4345

4446
# The encoding of source files.
45-
#source_encoding = 'utf-8-sig'
47+
# source_encoding = 'utf-8-sig'
4648

4749
# The master toctree document.
48-
master_doc = 'index'
50+
master_doc = "index"
4951

5052
# General information about the project.
51-
project = u'pstd'
52-
copyright = u'2014, Frederik Rietdijk'
53+
project = u"pstd"
54+
copyright = u"2014, Frederik Rietdijk"
5355

5456
# The version info for the project you're documenting, acts as replacement for
5557
# |version| and |release|, also used in various other places throughout the
5658
# built documents.
5759
#
5860
# The short X.Y version.
59-
version = '0.0'
61+
version = "0.0"
6062
# The full version, including alpha/beta/rc tags.
61-
release = '0.0'
63+
release = "0.0"
6264

6365
# The language for content autogenerated by Sphinx. Refer to documentation
6466
# for a list of supported languages.
65-
#language = None
67+
# language = None
6668

6769
# There are two options for replacing |today|: either, you set today to some
6870
# non-false value, then it is used:
69-
#today = ''
71+
# today = ''
7072
# Else, today_fmt is used as the format for a strftime call.
71-
#today_fmt = '%B %d, %Y'
73+
# today_fmt = '%B %d, %Y'
7274

7375
# List of patterns, relative to source directory, that match files and
7476
# directories to ignore when looking for source files.
75-
exclude_patterns = ['_build']
77+
exclude_patterns = ["_build"]
7678

7779
# The reST default role (used for this markup: `text`) to use for all
7880
# documents.
79-
#default_role = None
81+
# default_role = None
8082

8183
# If true, '()' will be appended to :func: etc. cross-reference text.
82-
#add_function_parentheses = True
84+
# add_function_parentheses = True
8385

8486
# If true, the current module name will be prepended to all description
8587
# unit titles (such as .. function::).
86-
#add_module_names = True
88+
# add_module_names = True
8789

8890
# If true, sectionauthor and moduleauthor directives will be shown in the
8991
# output. They are ignored by default.
90-
#show_authors = False
92+
# show_authors = False
9193

9294
# The name of the Pygments (syntax highlighting) style to use.
93-
pygments_style = 'sphinx'
95+
pygments_style = "sphinx"
9496

9597
# A list of ignored prefixes for module index sorting.
96-
#modindex_common_prefix = []
98+
# modindex_common_prefix = []
9799

98100
# If true, keep warnings as "system message" paragraphs in the built documents.
99-
#keep_warnings = False
101+
# keep_warnings = False
100102

101103

102104
# -- Options for HTML output ----------------------------------------------
103105

104106
# The theme to use for HTML and HTML Help pages. See the documentation for
105107
# a list of builtin themes.
106-
html_theme = 'nature'
108+
html_theme = "nature"
107109

108110
# Theme options are theme-specific and customize the look and feel of a theme
109111
# further. For a list of options available for each theme, see the
110112
# documentation.
111-
#html_theme_options = {}
113+
# html_theme_options = {}
112114

113115
# Add any paths that contain custom themes here, relative to this directory.
114-
#html_theme_path = []
116+
# html_theme_path = []
115117

116118
# The name for this set of Sphinx documents. If None, it defaults to
117119
# "<project> v<release> documentation".
118-
#html_title = None
120+
# html_title = None
119121

120122
# A shorter title for the navigation bar. Default is the same as html_title.
121-
#html_short_title = None
123+
# html_short_title = None
122124

123125
# The name of an image file (relative to this directory) to place at the top
124126
# of the sidebar.
125-
#html_logo = None
127+
# html_logo = None
126128

127129
# The name of an image file (within the static path) to use as favicon of the
128130
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
129131
# pixels large.
130-
#html_favicon = None
132+
# html_favicon = None
131133

132134
# Add any paths that contain custom static files (such as style sheets) here,
133135
# relative to this directory. They are copied after the builtin static files,
134136
# so a file named "default.css" will overwrite the builtin "default.css".
135-
html_static_path = ['_static']
137+
html_static_path = ["_static"]
136138

137139
# Add any extra paths that contain custom files (such as robots.txt or
138140
# .htaccess) here, relative to this directory. These files are copied
139141
# directly to the root of the documentation.
140-
#html_extra_path = []
142+
# html_extra_path = []
141143

142144
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
143145
# using the given strftime format.
144-
#html_last_updated_fmt = '%b %d, %Y'
146+
# html_last_updated_fmt = '%b %d, %Y'
145147

146148
# If true, SmartyPants will be used to convert quotes and dashes to
147149
# typographically correct entities.
148-
#html_use_smartypants = True
150+
# html_use_smartypants = True
149151

150152
# Custom sidebar templates, maps document names to template names.
151-
#html_sidebars = {}
153+
# html_sidebars = {}
152154

153155
# Additional templates that should be rendered to pages, maps page names to
154156
# template names.
155-
#html_additional_pages = {}
157+
# html_additional_pages = {}
156158

157159
# If false, no module index is generated.
158-
#html_domain_indices = True
160+
# html_domain_indices = True
159161

160162
# If false, no index is generated.
161-
#html_use_index = True
163+
# html_use_index = True
162164

163165
# If true, the index is split into individual pages for each letter.
164-
#html_split_index = False
166+
# html_split_index = False
165167

166168
# If true, links to the reST sources are added to the pages.
167-
#html_show_sourcelink = True
169+
# html_show_sourcelink = True
168170

169171
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
170-
#html_show_sphinx = True
172+
# html_show_sphinx = True
171173

172174
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
173-
#html_show_copyright = True
175+
# html_show_copyright = True
174176

175177
# If true, an OpenSearch description file will be output, and all pages will
176178
# contain a <link> tag referring to it. The value of this option must be the
177179
# base URL from which the finished HTML is served.
178-
#html_use_opensearch = ''
180+
# html_use_opensearch = ''
179181

180182
# This is the file name suffix for HTML files (e.g. ".xhtml").
181-
#html_file_suffix = None
183+
# html_file_suffix = None
182184

183185
# Output file base name for HTML help builder.
184-
htmlhelp_basename = 'pstddoc'
186+
htmlhelp_basename = "pstddoc"
185187

186188

187189
# -- Options for LaTeX output ---------------------------------------------
188190

189191
latex_elements = {
190-
# The paper size ('letterpaper' or 'a4paper').
191-
#'papersize': 'letterpaper',
192-
193-
# The font size ('10pt', '11pt' or '12pt').
194-
#'pointsize': '10pt',
195-
196-
# Additional stuff for the LaTeX preamble.
197-
#'preamble': '',
192+
# The paper size ('letterpaper' or 'a4paper').
193+
#'papersize': 'letterpaper',
194+
# The font size ('10pt', '11pt' or '12pt').
195+
#'pointsize': '10pt',
196+
# Additional stuff for the LaTeX preamble.
197+
#'preamble': '',
198198
}
199199

200200
# Grouping the document tree into LaTeX files. List of tuples
201201
# (source start file, target name, title,
202202
# author, documentclass [howto, manual, or own class]).
203203
latex_documents = [
204-
('index', 'pstd.tex', u'pstd Documentation',
205-
u'Frederik Rietdijk', 'manual'),
204+
("index", "pstd.tex", u"pstd Documentation", u"Frederik Rietdijk", "manual"),
206205
]
207206

208207
# The name of an image file (relative to this directory) to place at the top of
209208
# the title page.
210-
#latex_logo = None
209+
# latex_logo = None
211210

212211
# For "manual" documents, if this is true, then toplevel headings are parts,
213212
# not chapters.
214-
#latex_use_parts = False
213+
# latex_use_parts = False
215214

216215
# If true, show page references after internal links.
217-
#latex_show_pagerefs = False
216+
# latex_show_pagerefs = False
218217

219218
# If true, show URL addresses after external links.
220-
#latex_show_urls = False
219+
# latex_show_urls = False
221220

222221
# Documents to append as an appendix to all manuals.
223-
#latex_appendices = []
222+
# latex_appendices = []
224223

225224
# If false, no module index is generated.
226-
#latex_domain_indices = True
225+
# latex_domain_indices = True
227226

228227

229228
# -- Options for manual page output ---------------------------------------
230229

231230
# One entry per manual page. List of tuples
232231
# (source start file, name, description, authors, manual section).
233-
man_pages = [
234-
('index', 'pstd', u'pstd Documentation',
235-
[u'Frederik Rietdijk'], 1)
236-
]
232+
man_pages = [("index", "pstd", u"pstd Documentation", [u"Frederik Rietdijk"], 1)]
237233

238234
# If true, show URL addresses after external links.
239-
#man_show_urls = False
235+
# man_show_urls = False
240236

241237

242238
# -- Options for Texinfo output -------------------------------------------
@@ -245,47 +241,58 @@
245241
# (source start file, target name, title, author,
246242
# dir menu entry, description, category)
247243
texinfo_documents = [
248-
('index', 'pstd', u'pstd Documentation',
249-
u'Frederik Rietdijk', 'pstd', 'One line description of project.',
250-
'Miscellaneous'),
244+
(
245+
"index",
246+
"pstd",
247+
u"pstd Documentation",
248+
u"Frederik Rietdijk",
249+
"pstd",
250+
"One line description of project.",
251+
"Miscellaneous",
252+
),
251253
]
252254

253255
# Documents to append as an appendix to all manuals.
254-
#texinfo_appendices = []
256+
# texinfo_appendices = []
255257

256258
# If false, no module index is generated.
257-
#texinfo_domain_indices = True
259+
# texinfo_domain_indices = True
258260

259261
# How to display URL addresses: 'footnote', 'no', or 'inline'.
260-
#texinfo_show_urls = 'footnote'
262+
# texinfo_show_urls = 'footnote'
261263

262264
# If true, do not generate a @detailmenu in the "Top" node's menu.
263-
#texinfo_no_detailmenu = False
265+
# texinfo_no_detailmenu = False
264266

265267

266268
# Example configuration for intersphinx: refer to the Python standard library.
267-
intersphinx_mapping = {'http://docs.python.org/': None}
269+
intersphinx_mapping = {"http://docs.python.org/": None}
270+
271+
intersphinx_mapping = {
272+
"python": ("http://docs.python.org/3", None),
273+
"numpy": ("http://docs.scipy.org/doc/numpy/", None),
274+
"np": ("http://docs.scipy.org/doc/numpy/", None),
275+
"scipy": ("http://docs.scipy.org/doc/scipy/reference/", None),
276+
"matplotlib": ("http://matplotlib.sourceforge.net/", None),
277+
}
268278

269-
intersphinx_mapping = {'python': ('http://docs.python.org/3', None),
270-
'numpy': ('http://docs.scipy.org/doc/numpy/', None),
271-
'np': ('http://docs.scipy.org/doc/numpy/', None),
272-
'scipy': ('http://docs.scipy.org/doc/scipy/reference/', None),
273-
'matplotlib': ('http://matplotlib.sourceforge.net/', None)}
279+
autodoc_default_flags = ["members", "show-inheritance"]
274280

275-
autodoc_default_flags = ['members', 'show-inheritance']
276281

277282
def skip(app, what, name, obj, skip, options):
278283
if name == "__init__":
279284
return False
280285
return skip
281286

287+
282288
def setup(app):
283289
app.connect("autodoc-skip-member", skip)
284-
285-
290+
291+
286292
# -----------------------------------------------------------------------------
287293
# Autosummary
288294
# -----------------------------------------------------------------------------
289295

290296
import glob
297+
291298
autosummary_generate = glob.glob("reference/*.rst")

‎examples/basic_example.ipynb

+2-2
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@
327327
],
328328
"metadata": {
329329
"kernelspec": {
330-
"display_name": "Python 3",
330+
"display_name": "Python 3 (ipykernel)",
331331
"language": "python",
332332
"name": "python3"
333333
},
@@ -341,7 +341,7 @@
341341
"name": "python",
342342
"nbconvert_exporter": "python",
343343
"pygments_lexer": "ipython3",
344-
"version": "3.8.5"
344+
"version": "3.9.9"
345345
}
346346
},
347347
"nbformat": 4,

‎examples/turbulence_example.ipynb

+44-173
Large diffs are not rendered by default.

‎flake.lock

+23-24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎flake.nix

+38-27
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,45 @@
11
{
2-
description = "PSTD";
2+
description = "K-space PSTD for Python.";
33

4-
inputs.nixpkgs.url = "github:nixos/nixpkgs?ref=nixpkgs-unstable";
5-
inputs.flake-utils.url = "github:numtide/flake-utils";
4+
inputs.nixpkgs.url = "nixpkgs/nixpkgs-unstable";
5+
inputs.utils.url = "github:numtide/flake-utils";
66

7-
outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: let
8-
pkgs = nixpkgs.legacyPackages.${system};
9-
in rec {
10-
11-
packages = rec {
7+
outputs = { self, nixpkgs, utils }: {
8+
overlay = final: prev: {
9+
pythonPackagesOverrides = (prev.pythonPackagesOverrides or []) ++ [
10+
(self: super: {
11+
pstd = self.callPackage ./. {};
12+
})
13+
];
14+
# Remove when https://github.com/NixOS/nixpkgs/pull/91850 is fixed.
1215
python3 = let
13-
python = pkgs.python3;
14-
in python.override {
15-
packageOverrides = final: prev: {
16-
pstd = final.callPackage ./default.nix {};
16+
composeOverlays = nixpkgs.lib.foldl' nixpkgs.lib.composeExtensions (self: super: {});
17+
self = prev.python3.override {
18+
inherit self;
19+
packageOverrides = composeOverlays final.pythonPackagesOverrides;
1720
};
18-
self = python;
19-
};
20-
21-
pstd = python3.pkgs.pstd;
21+
in self;
2222
};
23+
} // (utils.lib.eachSystem [ "x86_64-linux" ] (system: let
24+
pkgs = (import nixpkgs {
25+
inherit system;
26+
overlays = [ self.overlay ];
27+
});
28+
python = pkgs.python3;
29+
pstd = python.pkgs.pstd;
30+
devEnv = python.withPackages(ps: with ps.pstd; nativeBuildInputs ++ propagatedBuildInputs);
31+
in {
32+
# Our own overlay does not get applied to nixpkgs because that would lead to
33+
# an infinite recursion. Therefore, we need to import nixpkgs and apply it ourselves.
34+
defaultPackage = pstd;
2335

24-
defaultPackage = packages.pstd;
25-
26-
# devShell = (pkgs.mkShell {
27-
# nativeBuildInputs = with packages.python3.pkgs; [ notebook ] ++ pstd.propagatedBuildInputs;
28-
29-
# });
30-
devShell = (packages.python3.withPackages(ps: with ps; [
31-
notebook
32-
] ++ pstd.propagatedBuildInputs)).env;
33-
});
34-
}
36+
devShell = pkgs.mkShell {
37+
nativeBuildInputs = [
38+
devEnv
39+
];
40+
shellHook = ''
41+
export PYTHONPATH=$(readlink -f $(find . -maxdepth 1 -type d ) | tr '\n' ':'):$PYTHONPATH
42+
'';
43+
};
44+
}));
45+
}

‎pstd/__init__.py

+15-13
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1+
"""
2+
k-space
3+
=======
4+
"""
5+
6+
__version__ = "0.0.0"
17

28
from .model import *
39

4-
#try:
5-
#from .pstd_using_numba import PSTD
6-
#except ImportError:
7-
#from .pstd import PSTD
10+
# try:
11+
# from .pstd_using_numba import PSTD
12+
# except ImportError:
13+
# from .pstd import PSTD
814

915
from .pstd import PSTD
1016

11-
#try:
12-
#from .pstd_using_numba import PSTD_using_numba
13-
#except ImportError:
14-
#raise ImportWarning("Cannot import numba. pstd_using_numba is not available")
15-
#from pstd_using_cuda import PSTD_using_cuda
16-
17-
18-
19-
17+
# try:
18+
# from .pstd_using_numba import PSTD_using_numba
19+
# except ImportError:
20+
# raise ImportWarning("Cannot import numba. pstd_using_numba is not available")
21+
# from pstd_using_cuda import PSTD_using_cuda

‎pstd/model.py

+1,136-969
Large diffs are not rendered by default.

‎pstd/pstd.py

+272-186
Large diffs are not rendered by default.

‎pstd/pstd_using_cuda.py

+319-321
Large diffs are not rendered by default.

‎pstd/pstd_using_numba.py

+25-26
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,31 @@
55
import numba
66
from . import pstd
77

8-
kappa = numba.autojit(pstd.kappa)
9-
#abs_exp = numba.autojit(pstd.abs_exp)
10-
pressure_abs_exp = numba.autojit(pstd.pressure_abs_exp)
11-
velocity_abs_exp = numba.autojit(pstd.velocity_abs_exp)
12-
pressure_with_pml = numba.autojit(pstd.pressure_with_pml)
13-
velocity_with_pml = numba.autojit(pstd.pressure_with_pml)
14-
to_pressure_gradient = numba.autojit(pstd.to_pressure_gradient)
15-
to_velocity_gradient = numba.autojit(pstd.to_velocity_gradient)
16-
update = numba.autojit(pstd.update)
8+
kappa = numba.jit(pstd.kappa)
9+
# abs_exp = numba.jit(pstd.abs_exp)
10+
pressure_abs_exp = numba.jit(pstd.pressure_abs_exp)
11+
velocity_abs_exp = numba.jit(pstd.velocity_abs_exp)
12+
pressure_with_pml = numba.jit(pstd.pressure_with_pml)
13+
velocity_with_pml = numba.jit(pstd.pressure_with_pml)
14+
to_pressure_gradient = numba.jit(pstd.to_pressure_gradient)
15+
to_velocity_gradient = numba.jit(pstd.to_velocity_gradient)
16+
update = numba.jit(pstd.update)
17+
1718

1819
class PSTD(pstd.PSTD):
19-
20+
2021
_update = staticmethod(update)
21-
22-
#_record = numba.autojit(pstd.PSTD._record)
23-
24-
#kappa = staticmethod(numba.autojit(PSTD.kappa))
25-
#abs_exp = staticmethod(numba.autojit(PSTD.abs_exp))
26-
#pressure_with_pml = staticmethod(numba.autojit(PSTD.pressure_with_pml))
27-
#velocity_with_pml = staticmethod(numba.autojit(PSTD.velocity_with_pml))
28-
#pressure_gradient = staticmethod(numba.autojit(PSTD.to_pressure_gradient))
29-
#velocity_gradient = staticmethod(numba.autojit(PSTD.to_velocity_gradient))
30-
#update = classmethod(numba.autojit(PSTD.update))
31-
32-
#pre_run = numba.autojit(PSTD.pre_run)
33-
34-
#run = numba.autojit(Model.run)
35-
36-
22+
23+
# _record = numba.jit(pstd.PSTD._record)
24+
25+
# kappa = staticmethod(numba.jit(PSTD.kappa))
26+
# abs_exp = staticmethod(numba.jit(PSTD.abs_exp))
27+
# pressure_with_pml = staticmethod(numba.jit(PSTD.pressure_with_pml))
28+
# velocity_with_pml = staticmethod(numba.jit(PSTD.velocity_with_pml))
29+
# pressure_gradient = staticmethod(numba.jit(PSTD.to_pressure_gradient))
30+
# velocity_gradient = staticmethod(numba.jit(PSTD.to_velocity_gradient))
31+
# update = classmethod(numba.jit(PSTD.update))
32+
33+
# pre_run = numba.jit(PSTD.pre_run)
34+
35+
# run = numba.jit(Model.run)

‎pstd/pstd_using_numexpr.py

-95
This file was deleted.

‎pyproject.toml

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
[build-system]
2+
requires = ["flit_core >=2,<4"]
3+
build-backend = "flit_core.buildapi"
4+
5+
[tool.flit.metadata]
6+
module = "pstd"
7+
author = "Frederik Rietdijk"
8+
requires = [
9+
"acoustics",
10+
"numpy",
11+
"scipy",
12+
"matplotlib",
13+
"numexpr",
14+
"pyyaml",
15+
]
16+
[tool.tox]
17+
legacy_tox_ini = """
18+
[tox]
19+
envlist = py39, py310
20+
21+
[gh-actions]
22+
python =
23+
3.9: py39
24+
3.10: py310
25+
26+
[testenv]
27+
deps =
28+
nbconvert
29+
pytest
30+
commands = pytest -k "not test_notebook" {posargs}
31+
"""

‎setup.py

-42
This file was deleted.

‎tests/test_model.py

+12-13
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,35 @@
22
import numpy as np
33
from pstd import Model, PSTD, Medium
44

5-
class TestModel():
5+
6+
class TestModel:
67
"""
78
Test Model.
89
"""
9-
10-
10+
1111
def test_init_abstract_class(self):
1212
"""
1313
__init__
1414
"""
1515
f_max = 100.0
16-
with pytest.raises(TypeError):
16+
with pytest.raises(RuntimeError):
1717
model = Model(f_max)
18-
1918

20-
class TestMedium():
21-
"""Test Medium.
22-
"""
23-
19+
20+
class TestMedium:
21+
"""Test Medium."""
22+
2423
def test_init_default(self):
2524
medium = Medium()
26-
25+
2726
def test_soundspeed_for_calculation(self):
2827
"""Test when not used in a model."""
29-
28+
3029
# Single value. Can return
3130
medium = Medium()
3231
medium.soundspeed_for_calculation
33-
32+
3433
# Grid. Needs to know Model grid/pml.
35-
medium = Medium(np.ones((10,10)))
34+
medium = Medium(np.ones((10, 10)))
3635
with pytest.raises(ValueError):
3736
medium.soundspeed_for_calculation

‎tests/test_notebooks.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import pathlib
2+
import pytest
3+
4+
import nbformat
5+
import nbconvert.preprocessors
6+
7+
8+
NOTEBOOKS = list((pathlib.Path(__file__).parent.parent / "examples").glob("*.ipynb"))
9+
10+
11+
@pytest.mark.parametrize("notebook", NOTEBOOKS)
12+
def test_notebook(notebook):
13+
14+
executor = nbconvert.preprocessors.ExecutePreprocessor(timeout=60)
15+
16+
with open(notebook) as fin:
17+
contents = nbformat.read(fin, as_version=4)
18+
executor.preprocess(contents)

‎tests/test_pstd.py

+62-76
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,46 @@
44

55
model_parameters = [
66
{
7-
'maximum_frequency' : 1000.0,
8-
'cfl' : 0.05,
9-
'size' : (15, 15),
10-
},
7+
"maximum_frequency": 1000.0,
8+
"cfl": 0.05,
9+
"size": (15, 15),
10+
},
1111
{
12-
'maximum_frequency' : 1000.0,
13-
'cfl' : 0.10,
14-
'size' : (20, 20),
15-
},
16-
]
12+
"maximum_frequency": 1000.0,
13+
"cfl": 0.10,
14+
"size": (20, 20),
15+
},
16+
]
1717

1818

19-
20-
class TestPSTD():
19+
class TestPSTD:
2120
"""
2221
Test Model.
2322
"""
24-
25-
#@pytest.fixture(params=[0.05, 0.10])
26-
#def cfl(self, request):
27-
#return request.param
28-
29-
23+
24+
# @pytest.fixture(params=[0.05, 0.10])
25+
# def cfl(self, request):
26+
# return request.param
27+
3028
@pytest.fixture(params=model_parameters)
3129
def model(self, request):
3230
kwargs = request.param
33-
kwargs['pml'] = PML(depth=10.0)
31+
kwargs["pml"] = PML(depth=10.0)
3432
model = PSTD(**kwargs)
3533
return model
36-
37-
38-
@pytest.fixture(params=[0, 10])
34+
35+
@pytest.fixture(params=[10])
3936
def steps(self, request):
4037
return request.param
41-
42-
@pytest.fixture(params=[0.0, 0.001])
38+
39+
@pytest.fixture(params=[0.001])
4340
def seconds(self, request):
4441
return request.param
45-
42+
4643
def test_init(self, model):
4744
"""Initialization of model.
48-
49-
If this passes, then the models returned by the fixture
45+
46+
If this passes, then the models returned by the fixture
5047
were initialized successfully.
5148
"""
5249
pass
@@ -59,88 +56,77 @@ def test_init_no_size(self):
5956
with pytest.raises(RuntimeError):
6057
model = PSTD(maximum_frequency=f_max)
6158

62-
6359
def test_overview(self, model):
6460
model.overview()
6561

6662
def test_properties(self, model):
67-
68-
properties = ['cfl', 'constant_field', 'ndim',
69-
'timestep', 'sample_frequency'
70-
]
63+
64+
properties = ["cfl", "constant_field", "timestep"]
7165

7266
for prop in properties:
7367
getattr(model, prop)
7468

75-
7669
def test_run_steps(self, model, steps):
7770
model.run(steps=steps)
7871

7972
def test_run_seconds(self, model, seconds):
8073
model.run(seconds=seconds)
81-
82-
class TestPML():
74+
75+
76+
class TestPML:
8377
"""Test PML.
84-
78+
8579
Should use Mock!
8680
"""
87-
81+
8882
def setup_method(self, method):
8983
time = 1.0
9084
f_max = 100.0
9185
size = (100.0, 50.0)
9286
self.model = PSTD(maximum_frequency=f_max, size=size)
93-
94-
87+
9588
def test_init_default(self):
9689
pass
97-
98-
90+
9991
def test_init_custom(self):
100-
absorption_coefficient = (100.0,100.0)
92+
absorption_coefficient = (100.0, 100.0)
10193
depth = 5.0
10294
pml = PML(absorption_coefficient, depth)
103-
95+
10496
def test_depth(self):
105-
106-
assert(self.model.pml.depth == 0.0)
107-
97+
98+
assert self.model.pml.depth == 0.0
99+
108100
self.model.pml.depth_target = 1.0
109-
assert(self.model.pml.depth != 0.0)
110-
101+
assert self.model.pml.depth != 0.0
102+
111103
def test_nodes(self):
112-
113-
assert(self.model.pml.nodes == 0)
114-
104+
105+
assert self.model.pml.nodes == 0
106+
115107
self.model.pml.depth_target = 1.0
116-
assert(self.model.pml.nodes != 0.0)
117-
108+
assert self.model.pml.nodes != 0.0
109+
118110
def is_used(self):
119-
120-
assert(self.model.is_used)
121-
122-
self.model.settings['pml']['use'] = False
123-
assert(not self.model.is_used)
124-
111+
112+
assert self.model.is_used
113+
114+
self.model.settings["pml"]["use"] = False
115+
assert not self.model.is_used
116+
125117
def generate_grid(self):
126-
127-
with pytest.raises(ValueError): # Zero size, cannot generate a PML.
118+
119+
with pytest.raises(ValueError): # Zero size, cannot generate a PML.
128120
self.model.pml.generate_grid()
129-
121+
130122
self.model.pml.depth_target = 1.0
131123
pml = self.model.pml.generate_grid()
132-
133-
assert(isinstance(pml, collections.MutableMapping))
134-
assert(isinstance(pml, dict))
135-
136-
137-
138-
139-
#class TestCalculation():
140-
141-
142-
#def test_
143-
144-
145-
146-
124+
125+
assert isinstance(pml, collections.MutableMapping)
126+
assert isinstance(pml, dict)
127+
128+
129+
# class TestCalculation():
130+
131+
132+
# def test_

‎tests/test_td.py

+52-62
Original file line numberDiff line numberDiff line change
@@ -5,73 +5,63 @@
55

66
from numpy.testing import assert_array_almost_equal
77

8-
#import acoustics.td.pstd
9-
#import acoustics.td.pstd_using_cuda
8+
# import acoustics.td.pstd
9+
# import acoustics.td.pstd_using_cuda
1010

11-
#class PSTD(unittest.TestCase):
12-
13-
#def test_pressure_with_pml(self):
14-
#pass
15-
16-
#def test_velocity_with_pml(self):
17-
#pass
11+
# class PSTD(unittest.TestCase):
1812

13+
# def test_pressure_with_pml(self):
14+
# pass
1915

16+
# def test_velocity_with_pml(self):
17+
# pass
2018

2119

20+
##class Validate_PSTD(unittest.TestCase):
21+
##"""
22+
##PSTD related tests.
23+
##"""
2224

25+
##def test_amplitude_and_phase(self):
26+
##"""
27+
##Validate the response in the frequency domain.
28+
##"""
2329

24-
##class Validate_PSTD(unittest.TestCase):
25-
##"""
26-
##PSTD related tests.
27-
##"""
28-
29-
##def test_amplitude_and_phase(self):
30-
##"""
31-
##Validate the response in the frequency domain.
32-
##"""
33-
34-
##x, y = 40.0, 40.0
35-
36-
##c = 343.2
37-
38-
##source = Source(Position2D(x/2.0, 5.0), pressure=0.1)
39-
##receiver = Receiver(Position2D(x/2.0, 35.0), quantities=['p'])
40-
##medium = Medium(soundspeed=c, density=1.296)
41-
42-
##time = y / c
43-
44-
##pml = PML((10.0, 10.0), depth=5.0)
45-
46-
##model = PSTD(time=time, f_max=200.0, pml=pml, medium=medium, cfl=0.3, size=[x, y])
47-
48-
##model.sources.append(source)
49-
##model.receivers.append(receiver)
50-
51-
##print model.timesteps
52-
53-
##import logging
54-
##logger = logging.getLogger('acoustics.td') # Module name
55-
##logger.setLevel(logging.INFO) # Logging level
56-
57-
58-
##model.run()
59-
60-
61-
##p_pstd = np.fft.fft(receiver.data['p'])
62-
63-
##print p_pstd
64-
65-
##r = receiver.position[1] - source.position[1]
66-
67-
##p_freq = A / r * np.exp(1j*k*r)
68-
69-
70-
71-
72-
73-
74-
75-
76-
if __name__ == '__main__':
30+
##x, y = 40.0, 40.0
31+
32+
##c = 343.2
33+
34+
##source = Source(Position2D(x/2.0, 5.0), pressure=0.1)
35+
##receiver = Receiver(Position2D(x/2.0, 35.0), quantities=['p'])
36+
##medium = Medium(soundspeed=c, density=1.296)
37+
38+
##time = y / c
39+
40+
##pml = PML((10.0, 10.0), depth=5.0)
41+
42+
##model = PSTD(time=time, f_max=200.0, pml=pml, medium=medium, cfl=0.3, size=[x, y])
43+
44+
##model.sources.append(source)
45+
##model.receivers.append(receiver)
46+
47+
##print model.timesteps
48+
49+
##import logging
50+
##logger = logging.getLogger('acoustics.td') # Module name
51+
##logger.setLevel(logging.INFO) # Logging level
52+
53+
54+
##model.run()
55+
56+
57+
##p_pstd = np.fft.fft(receiver.data['p'])
58+
59+
##print p_pstd
60+
61+
##r = receiver.position[1] - source.position[1]
62+
63+
##p_freq = A / r * np.exp(1j*k*r)
64+
65+
66+
if __name__ == "__main__":
7767
unittest.main()

‎tests/test_td_cuda.py

+25-21
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,36 @@
1-
try:
2-
import numbapro
3-
except ImportError:
4-
ImportWarning("numbapro not available. Cannot run tests.")
1+
import sys
2+
import pytest
53

64
try:
7-
from acoustics.td.pstd_using_cuda import exp, add
8-
except numbapro.cudadrv.error.CudaSupportError:
5+
from pstd.pstd_using_cuda import exp, add
6+
except ImportError:
97
pass
108

11-
class Cuda(unittest.TestCase):
9+
10+
@pytest.mark.skipif("cupy" not in sys.modules, reason="requires cuda")
11+
class TestCuda:
1212
"""
1313
Cuda related tests.
1414
"""
15-
15+
1616
def test_add(self):
17-
18-
a = np.random.randn(100).astype('complex64') + 1j*np.random.randn(100).astype('complex64')
19-
b = np.random.randn(100).astype('complex64') + 1j*np.random.randn(100).astype('complex64')
20-
21-
assert_array_almost_equal(a+b, add(a,b))
22-
17+
18+
a = np.random.randn(100).astype("complex64") + 1j * np.random.randn(100).astype(
19+
"complex64"
20+
)
21+
b = np.random.randn(100).astype("complex64") + 1j * np.random.randn(100).astype(
22+
"complex64"
23+
)
24+
25+
assert_array_almost_equal(a + b, add(a, b))
26+
2327
def test_exp(self):
24-
25-
theta = np.linspace(0.0, 2.0*np.pi, 100).astype('complex64')
26-
assert_array_almost_equal(np.exp(1j*theta), exp(1j*theta))
27-
28-
a = (np.random.randn(100) + 1j * np.random.randn(100)).astype('complex64')
28+
29+
theta = np.linspace(0.0, 2.0 * np.pi, 100).astype("complex64")
30+
assert_array_almost_equal(np.exp(1j * theta), exp(1j * theta))
31+
32+
a = (np.random.randn(100) + 1j * np.random.randn(100)).astype("complex64")
2933
assert_array_almost_equal(np.log(np.exp(a)), np.log(exp(a)))
30-
31-
x = np.arange(50).astype('complex64')
34+
35+
x = np.arange(50).astype("complex64")
3236
assert_array_almost_equal(np.log(np.exp(x)), np.log(exp(x)))

0 commit comments

Comments
 (0)
Please sign in to comment.