feectools 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- feectools/__init__.py +0 -0
- feectools/accelerate/__init__.py +0 -0
- feectools/accelerate/accelerate.py +220 -0
- feectools/accelerate/compile_psydac.mk +52 -0
- feectools/api/__init__.py +0 -0
- feectools/api/essential_bc.py +122 -0
- feectools/api/fem_bilinear_form.py +2226 -0
- feectools/api/fem_common.py +286 -0
- feectools/api/fem_sum_form.py +123 -0
- feectools/api/settings.py +82 -0
- feectools/core/__init__.py +11 -0
- feectools/core/bsplines.py +1107 -0
- feectools/core/bsplines_kernels.py +1349 -0
- feectools/core/field_evaluation_kernels.py +5015 -0
- feectools/core/tests/__init__.py +0 -0
- feectools/core/tests/test_bsplines.py +263 -0
- feectools/core/tests/test_bsplines_kernel.py +40 -0
- feectools/core/tests/test_bsplines_pyccel.py +752 -0
- feectools/ddm/__init__.py +3 -0
- feectools/ddm/basic.py +78 -0
- feectools/ddm/blocking_data_exchanger.py +348 -0
- feectools/ddm/cart.py +1835 -0
- feectools/ddm/interface_data_exchanger.py +122 -0
- feectools/ddm/mpi.py +109 -0
- feectools/ddm/nonblocking_data_exchanger.py +331 -0
- feectools/ddm/partition.py +207 -0
- feectools/ddm/petsc.py +112 -0
- feectools/ddm/tests/__init__.py +0 -0
- feectools/ddm/tests/test_cart_1d.py +138 -0
- feectools/ddm/tests/test_cart_2d.py +164 -0
- feectools/ddm/tests/test_cart_3d.py +158 -0
- feectools/ddm/tests/test_multicart_2d.py +173 -0
- feectools/ddm/tests/test_partition.py +124 -0
- feectools/ddm/utilities.py +24 -0
- feectools/feec/__init__.py +0 -0
- feectools/feec/derivatives.py +780 -0
- feectools/feec/dof_kernels.py +210 -0
- feectools/feec/global_geometric_projectors.py +1073 -0
- feectools/feec/hodge.py +148 -0
- feectools/fem/__init__.py +0 -0
- feectools/fem/basic.py +465 -0
- feectools/fem/grid.py +181 -0
- feectools/fem/partitioning.py +344 -0
- feectools/fem/projectors.py +160 -0
- feectools/fem/splines.py +559 -0
- feectools/fem/tensor.py +1393 -0
- feectools/fem/tests/__init__.py +0 -0
- feectools/fem/tests/analytical_profiles_1d.py +100 -0
- feectools/fem/tests/analytical_profiles_base.py +34 -0
- feectools/fem/tests/splines_error_bounds.py +155 -0
- feectools/fem/tests/test_spline_histopolation.py +120 -0
- feectools/fem/tests/test_spline_interpolation.py +182 -0
- feectools/fem/tests/test_splines.py +184 -0
- feectools/fem/tests/test_splines_par.py +46 -0
- feectools/fem/tests/test_vector_spaces.py +150 -0
- feectools/fem/tests/utilities.py +47 -0
- feectools/fem/vector.py +729 -0
- feectools/linalg/__init__.py +0 -0
- feectools/linalg/basic.py +1386 -0
- feectools/linalg/block.py +1451 -0
- feectools/linalg/direct_solvers.py +201 -0
- feectools/linalg/fft.py +258 -0
- feectools/linalg/kernels/__init__.py +0 -0
- feectools/linalg/kernels/axpy_kernels.py +57 -0
- feectools/linalg/kernels/inner_kernels.py +100 -0
- feectools/linalg/kernels/matvec_kernels.py +206 -0
- feectools/linalg/kernels/stencil2IJV_kernels.py +227 -0
- feectools/linalg/kernels/stencil2coo_kernels.py +179 -0
- feectools/linalg/kernels/transpose_kernels.py +263 -0
- feectools/linalg/kron.py +911 -0
- feectools/linalg/solvers.py +1914 -0
- feectools/linalg/sparse.py +114 -0
- feectools/linalg/stencil.py +2923 -0
- feectools/linalg/stencil_dot_kernels.py +317 -0
- feectools/linalg/stencil_transpose_kernels.py +372 -0
- feectools/linalg/tests/__init__.py +0 -0
- feectools/linalg/tests/test_block.py +1588 -0
- feectools/linalg/tests/test_fft.py +106 -0
- feectools/linalg/tests/test_kron_stencil_matrix.py +114 -0
- feectools/linalg/tests/test_linalg.py +1065 -0
- feectools/linalg/tests/test_matrix_free.py +128 -0
- feectools/linalg/tests/test_solvers.py +213 -0
- feectools/linalg/tests/test_stencil_interface_matrix.py +379 -0
- feectools/linalg/tests/test_stencil_vector.py +1036 -0
- feectools/linalg/tests/test_stencil_vector_space.py +440 -0
- feectools/linalg/topetsc.py +522 -0
- feectools/linalg/utilities.py +200 -0
- feectools/utilities/__init__.py +0 -0
- feectools/utilities/quadratures.py +113 -0
- feectools/utilities/utils.py +166 -0
- feectools/version.py +1 -0
- feectools-0.1.0.dist-info/METADATA +66 -0
- feectools-0.1.0.dist-info/RECORD +98 -0
- feectools-0.1.0.dist-info/WHEEL +5 -0
- feectools-0.1.0.dist-info/entry_points.txt +3 -0
- feectools-0.1.0.dist-info/licenses/AUTHORS +22 -0
- feectools-0.1.0.dist-info/licenses/LICENSE +21 -0
- feectools-0.1.0.dist-info/top_level.txt +1 -0
feectools/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Based on https://gitlab.mpcdf.mpg.de/struphy/struphy/-/blob/devel/src/struphy/console/compile.py
|
|
2
|
+
import argparse
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
from shutil import which, rmtree
|
|
6
|
+
from subprocess import run as sub_run, PIPE, STDOUT # nosec B404
|
|
7
|
+
import subprocess
|
|
8
|
+
import sysconfig
|
|
9
|
+
|
|
10
|
+
import feectools
|
|
11
|
+
|
|
12
|
+
# Get the absolute path to the psydac directory
|
|
13
|
+
psydac_path = os.path.abspath(feectools.__path__[0])
|
|
14
|
+
libdir = sysconfig.get_config_var("LIBDIR")
|
|
15
|
+
psydac_makefile_dir = os.path.join(psydac_path, "accelerate")
|
|
16
|
+
|
|
17
|
+
def subp_run(cmd, cwd=None, check=True):
|
|
18
|
+
"""Call subprocess.run and print run command."""
|
|
19
|
+
|
|
20
|
+
if cwd is None:
|
|
21
|
+
cwd = psydac_path
|
|
22
|
+
|
|
23
|
+
print(f"\nRunning the following command as a subprocess:\n{' '.join(cmd)}")
|
|
24
|
+
print(f"Running in directory: {cwd}")
|
|
25
|
+
subprocess.run(cmd, cwd=cwd, check=check)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def psydac_compile(language, compiler_family, compiler_config, omp, delete, status, verbose, dependencies, yes):
|
|
29
|
+
"""
|
|
30
|
+
Compile Psydac kernels. All files that contain "kernels" are detected automatically and saved to state.yml.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
language : str
|
|
35
|
+
Either "c" (default) or "fortran".
|
|
36
|
+
|
|
37
|
+
compiler_family : str
|
|
38
|
+
Either "GNU" (default), "intel", "PGI", "nvidia", "LLVM"
|
|
39
|
+
|
|
40
|
+
compiler_config: str
|
|
41
|
+
Path to a JSON compiler file.
|
|
42
|
+
|
|
43
|
+
omp_pic : bool
|
|
44
|
+
Whether to compile PIC kernels with OpenMP (default=False).
|
|
45
|
+
|
|
46
|
+
omp_feec : bool
|
|
47
|
+
WHether to compile FEEC kernels with OpenMP (default=False).
|
|
48
|
+
|
|
49
|
+
delete : bool
|
|
50
|
+
If True, deletes generated Fortran/C files and .so files (default=False).
|
|
51
|
+
|
|
52
|
+
status : bool
|
|
53
|
+
If true, prints the current Psydac compilation status on screen.
|
|
54
|
+
|
|
55
|
+
verbose : bool
|
|
56
|
+
Call pyccel in verbose mode (default=False).
|
|
57
|
+
|
|
58
|
+
dependencies : bool
|
|
59
|
+
Whether to print Psydac kernels (to be compiled) and their dependencies on screen.
|
|
60
|
+
|
|
61
|
+
yes : bool
|
|
62
|
+
Whether to say yes to prompt when changing the language.
|
|
63
|
+
"""
|
|
64
|
+
if delete:
|
|
65
|
+
cleanup_files(psydac_path)
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
pyccel_path = which("pyccel")
|
|
69
|
+
if pyccel_path is None:
|
|
70
|
+
print(
|
|
71
|
+
"`pyccel` not found in PATH. Please ensure it is installed and accessible."
|
|
72
|
+
)
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
sources = []
|
|
76
|
+
# Cleanup if any files of the opposite language exist
|
|
77
|
+
cleanup = False
|
|
78
|
+
for root, _, files in os.walk(psydac_path):
|
|
79
|
+
for name in files:
|
|
80
|
+
if name.endswith("_kernels.py"):
|
|
81
|
+
file_path = os.path.join(root, name)
|
|
82
|
+
sources.append(file_path)
|
|
83
|
+
# Check if the corresponding pyccelized file already exists
|
|
84
|
+
subdir = "__pyccel__"
|
|
85
|
+
generated_file_fortran = os.path.join(root, subdir, name[:-3] + ".f90")
|
|
86
|
+
generated_file_c = os.path.join(root, subdir, name[:-3] + ".c")
|
|
87
|
+
if language == "fortran" and os.path.isfile(generated_file_c):
|
|
88
|
+
cleanup = True
|
|
89
|
+
elif language == "c" and os.path.isfile(generated_file_fortran):
|
|
90
|
+
cleanup = True
|
|
91
|
+
if cleanup:
|
|
92
|
+
if yes:
|
|
93
|
+
yesno = "Y"
|
|
94
|
+
else:
|
|
95
|
+
if language == "fortran":
|
|
96
|
+
compiled_in = "C"
|
|
97
|
+
else:
|
|
98
|
+
compiled_in = "fortran"
|
|
99
|
+
yesno = input(
|
|
100
|
+
f"Kernels compiled in language {compiled_in} exist, will be deleted, continue (Y/n)?"
|
|
101
|
+
)
|
|
102
|
+
if yesno in ("", "Y", "y", "yes"):
|
|
103
|
+
cleanup_files(psydac_path)
|
|
104
|
+
else:
|
|
105
|
+
return
|
|
106
|
+
|
|
107
|
+
# pyccel flags
|
|
108
|
+
# TODO: Compile psydac with OpenMP
|
|
109
|
+
flag_omp = ""
|
|
110
|
+
if omp:
|
|
111
|
+
flag_omp = "--openmp"
|
|
112
|
+
sources = " ".join(sources)
|
|
113
|
+
flags = "--language=" + language
|
|
114
|
+
|
|
115
|
+
if compiler_config:
|
|
116
|
+
flags += " --compiler-config=" + compiler_config
|
|
117
|
+
else:
|
|
118
|
+
flags += " --compiler-family=" + compiler_family
|
|
119
|
+
|
|
120
|
+
cmd = [
|
|
121
|
+
"make",
|
|
122
|
+
"-f",
|
|
123
|
+
"compile_psydac.mk",
|
|
124
|
+
"sources=" + sources,
|
|
125
|
+
"flags=" + flags,
|
|
126
|
+
"flags_openmp=" + flag_omp,
|
|
127
|
+
]
|
|
128
|
+
print(os.path.join(libdir, "accelerate"))
|
|
129
|
+
subp_run(cmd, cwd=psydac_makefile_dir),
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def cleanup_files(root_path: str):
|
|
133
|
+
"""
|
|
134
|
+
Remove unnecessary build artifacts, such as `__pyccel__` directories and `.lock_acquisition.lock` files.
|
|
135
|
+
"""
|
|
136
|
+
sources = []
|
|
137
|
+
for root, _, files in os.walk(root_path):
|
|
138
|
+
for filename in files:
|
|
139
|
+
if filename.endswith("_kernels.py"):
|
|
140
|
+
file_path = os.path.join(root, filename)
|
|
141
|
+
sources.append(file_path)
|
|
142
|
+
sources = " ".join(sources)
|
|
143
|
+
# Delete using the makefile
|
|
144
|
+
cmd = [
|
|
145
|
+
"make",
|
|
146
|
+
"clean",
|
|
147
|
+
"-f",
|
|
148
|
+
"compile_psydac.mk",
|
|
149
|
+
"sources=" + sources,
|
|
150
|
+
]
|
|
151
|
+
subp_run(cmd, cwd=psydac_makefile_dir)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def main():
|
|
155
|
+
parser = argparse.ArgumentParser(
|
|
156
|
+
description="Pyccelize Psydac kernel files and optionally clean up build artifacts.",
|
|
157
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
158
|
+
)
|
|
159
|
+
parser.add_argument(
|
|
160
|
+
"--language",
|
|
161
|
+
type=str,
|
|
162
|
+
default="c",
|
|
163
|
+
choices=["fortran", "c"],
|
|
164
|
+
help="Language used to pyccelize kernel files.",
|
|
165
|
+
)
|
|
166
|
+
parser.add_argument(
|
|
167
|
+
"--openmp",
|
|
168
|
+
action="store_true",
|
|
169
|
+
help="Use OpenMP multithreading in generated code.",
|
|
170
|
+
)
|
|
171
|
+
parser.add_argument(
|
|
172
|
+
"--cleanup",
|
|
173
|
+
action="store_true",
|
|
174
|
+
help="If True, deletes generated Fortran/C files and .so files (default=False).",
|
|
175
|
+
)
|
|
176
|
+
parser.add_argument(
|
|
177
|
+
"--compiler-family",
|
|
178
|
+
type=str,
|
|
179
|
+
default="GNU",
|
|
180
|
+
help='either "GNU" (default), "intel", "PGI", "nvidia" or the path to a JSON compiler file.',
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
parser.add_argument(
|
|
184
|
+
"--compiler-config",
|
|
185
|
+
type=str,
|
|
186
|
+
default=None,
|
|
187
|
+
help='Path to a JSON compiler file.',
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
parser.add_argument(
|
|
191
|
+
"--status", action="store_true", help="Show the status of pyccelization."
|
|
192
|
+
)
|
|
193
|
+
parser.add_argument("--verbose", action="store_true", help="Enable verbose output.")
|
|
194
|
+
parser.add_argument(
|
|
195
|
+
"--dependencies",
|
|
196
|
+
action="store_true",
|
|
197
|
+
help="Print Psydac kernels to be compiled (.py) and their dependencies (.so) on screen.",
|
|
198
|
+
)
|
|
199
|
+
parser.add_argument(
|
|
200
|
+
"--yes", action="store_true", help="Automatically answer 'yes' to prompts."
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
args = parser.parse_args()
|
|
204
|
+
|
|
205
|
+
# Assuming psydac_compile is a function defined elsewhere
|
|
206
|
+
psydac_compile(
|
|
207
|
+
language=args.language,
|
|
208
|
+
compiler_family=args.compiler_family,
|
|
209
|
+
compiler_config=args.compiler_config,
|
|
210
|
+
omp=args.openmp,
|
|
211
|
+
delete=args.cleanup,
|
|
212
|
+
status=args.status,
|
|
213
|
+
verbose=args.verbose,
|
|
214
|
+
dependencies=args.dependencies,
|
|
215
|
+
yes=args.yes,
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
if __name__ == "__main__":
|
|
220
|
+
main()
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Based on https://gitlab.mpcdf.mpg.de/struphy/struphy/-/blob/devel/src/struphy/compile_struphy.mk
|
|
2
|
+
#--------------------------------------
|
|
3
|
+
# CONFIGURATION
|
|
4
|
+
#--------------------------------------
|
|
5
|
+
|
|
6
|
+
PYTHON := python3
|
|
7
|
+
SO_EXT := $(shell $(PYTHON) -c "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))")
|
|
8
|
+
LIBDIR := $(shell $(PYTHON) -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))")
|
|
9
|
+
psydac_path := $(shell $(PYTHON) -c "import feectools as _; print(_.__path__[0])")
|
|
10
|
+
|
|
11
|
+
# Arguments to this script are:
|
|
12
|
+
PSYDAC_SOURCES := $(sources)
|
|
13
|
+
FLAGS := --libdir $(LIBDIR) $(flags)
|
|
14
|
+
FLAGS_openmp := $(flags_openmp)
|
|
15
|
+
|
|
16
|
+
#--------------------------------------
|
|
17
|
+
# SOURCE FILES
|
|
18
|
+
#--------------------------------------
|
|
19
|
+
|
|
20
|
+
SOURCES := $(PSYDAC_SOURCES)
|
|
21
|
+
|
|
22
|
+
OUTPUTS := $(SOURCES:.py=$(SO_EXT))
|
|
23
|
+
|
|
24
|
+
#--------------------------------------
|
|
25
|
+
# PYCCELIZE
|
|
26
|
+
#--------------------------------------
|
|
27
|
+
|
|
28
|
+
.PHONY: all
|
|
29
|
+
all: $(OUTPUTS)
|
|
30
|
+
|
|
31
|
+
# %$(SO_EXT) : %.py $$(shell $$(PYTHON)) $$(psydac_path)/dependencies.py $$@)
|
|
32
|
+
.SECONDEXPANSION:
|
|
33
|
+
%$(SO_EXT): %.py
|
|
34
|
+
|
|
35
|
+
@echo "Building $@"
|
|
36
|
+
@echo "from dependencies:"
|
|
37
|
+
@for dep in $^ ; do \
|
|
38
|
+
echo $$dep ; \
|
|
39
|
+
done
|
|
40
|
+
pyccel $(FLAGS)$(FLAGS_openmp) $<
|
|
41
|
+
@echo ""
|
|
42
|
+
|
|
43
|
+
#--------------------------------------
|
|
44
|
+
# CLEAN UP
|
|
45
|
+
#--------------------------------------
|
|
46
|
+
|
|
47
|
+
.PHONY: clean
|
|
48
|
+
clean:
|
|
49
|
+
rm -rf $(OUTPUTS)
|
|
50
|
+
find $(psydac_path)/ -type d -name '__pyccel__' -prune -exec rm -rf {} \;
|
|
51
|
+
find $(psydac_path)/ -type d -name '__pycache__' -prune -exec rm -rf {} \;
|
|
52
|
+
find $(psydac_path)/ -type f -name '*.lock' -delete
|
|
File without changes
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
from feectools.linalg.basic import ComposedLinearOperator
|
|
3
|
+
from feectools.linalg.stencil import StencilVector, StencilMatrix
|
|
4
|
+
from feectools.linalg.stencil import StencilInterfaceMatrix
|
|
5
|
+
from feectools.linalg.kron import KroneckerDenseMatrix
|
|
6
|
+
from feectools.linalg.block import BlockVector, BlockLinearOperator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
#==============================================================================
|
|
10
|
+
def apply_essential_bc_kronecker_dense_matrix(a, *, axis, ext, order, identity=False):
|
|
11
|
+
""" This function applies the homogeneous boundary condition to the Kronecker product matrix objects,
|
|
12
|
+
If the identity keyword argument is set to True, the boundary diagonal terms are set to 1.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
a : KroneckerDenseMatrix
|
|
17
|
+
The matrix to be modified.
|
|
18
|
+
|
|
19
|
+
axis : int
|
|
20
|
+
Axis of the boundary, i.e. the index of the coordinate which remains constant.
|
|
21
|
+
|
|
22
|
+
ext : int
|
|
23
|
+
Extremity of the boundary, it takes the value of -1 or 1.
|
|
24
|
+
|
|
25
|
+
order : int
|
|
26
|
+
All function derivatives up to `order` are set to zero
|
|
27
|
+
on the specified boundary. `order >= 0` is required.
|
|
28
|
+
|
|
29
|
+
identity : bool
|
|
30
|
+
If true, the diagonal terms corresponding to boundary coefficients are set to 1.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
mats = a.mats
|
|
34
|
+
p = a.codomain.pads[axis]
|
|
35
|
+
|
|
36
|
+
if ext == 1:
|
|
37
|
+
mats[axis][-p-1] = 0.
|
|
38
|
+
elif ext == -1:
|
|
39
|
+
mats[axis][p] = 0.
|
|
40
|
+
|
|
41
|
+
if identity and ext == 1:
|
|
42
|
+
mats[axis][-p-1,mats[axis].shape[0]-2*p-1] = 1
|
|
43
|
+
elif identity and ext == -1:
|
|
44
|
+
mats[axis][p][0] = 1
|
|
45
|
+
|
|
46
|
+
#==============================================================================
|
|
47
|
+
def apply_essential_bc_stencil(a, *, axis, ext, order, identity=False):
|
|
48
|
+
""" This function applies the homogeneous boundary condition to the Stencil objects,
|
|
49
|
+
by setting the boundary degrees of freedom to zero in the StencilVector,
|
|
50
|
+
and the corresponding rows in the StencilMatrix/StencilInterfaceMatrix to zeros.
|
|
51
|
+
If the identity keyword argument is set to True, the boundary diagonal terms are set to 1.
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
a : StencilVector, StencilMatrix or StencilInterfaceMatrix
|
|
56
|
+
The matrix or the Vector to be modified.
|
|
57
|
+
|
|
58
|
+
axis : int
|
|
59
|
+
Axis of the boundary, i.e. the index of the coordinate which remains constant.
|
|
60
|
+
|
|
61
|
+
ext : int
|
|
62
|
+
Extremity of the boundary, it takes the value of -1 or 1.
|
|
63
|
+
|
|
64
|
+
order : int
|
|
65
|
+
All function derivatives up to `order` are set to zero
|
|
66
|
+
on the specified boundary. `order >= 0` is required.
|
|
67
|
+
|
|
68
|
+
identity : bool
|
|
69
|
+
If True, the diagonal terms corresponding to boundary coefficients are set to 1.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
if isinstance(a, StencilVector):
|
|
73
|
+
V = a.space
|
|
74
|
+
n = V.ndim
|
|
75
|
+
elif isinstance(a, StencilMatrix):
|
|
76
|
+
V = a.codomain
|
|
77
|
+
n = V.ndim * 2
|
|
78
|
+
elif isinstance(a, StencilInterfaceMatrix):
|
|
79
|
+
V = a.codomain
|
|
80
|
+
n = V.ndim * 2
|
|
81
|
+
|
|
82
|
+
if axis == a.codomain_axis:
|
|
83
|
+
return
|
|
84
|
+
else:
|
|
85
|
+
raise TypeError('Cannot apply essential BC to object {} of type {}'\
|
|
86
|
+
.format(a, type(a)))
|
|
87
|
+
|
|
88
|
+
if V.parallel and V.cart.is_comm_null:
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
if axis not in range(V.ndim):
|
|
92
|
+
raise ValueError('Cannot apply essential BC along axis x{} in {}D'\
|
|
93
|
+
.format(axis + 1, V.ndim))
|
|
94
|
+
|
|
95
|
+
if ext not in (-1, 1):
|
|
96
|
+
raise ValueError("Argument 'ext' can only be -1 or 1, got {} instead"\
|
|
97
|
+
.format(ext))
|
|
98
|
+
|
|
99
|
+
if not isinstance(order, int) or order < 0:
|
|
100
|
+
raise ValueError("Argument 'order' must be a non-negative integer, got "
|
|
101
|
+
"{} instead".format(order))
|
|
102
|
+
|
|
103
|
+
if V.periods[axis]:
|
|
104
|
+
raise ValueError('Cannot apply essential BC along periodic direction '\
|
|
105
|
+
'x{}'.format(axis + 1))
|
|
106
|
+
|
|
107
|
+
if ext == -1 and V.starts[axis] == 0:
|
|
108
|
+
s = V.starts[axis]
|
|
109
|
+
index = [(s + order if j == axis else slice(None)) for j in range(n)]
|
|
110
|
+
a[tuple(index)] = 0.0
|
|
111
|
+
if isinstance(a, StencilMatrix) and identity:
|
|
112
|
+
a[tuple(index[:n//2])+(0,)*(n//2)] = 1.
|
|
113
|
+
|
|
114
|
+
elif ext == 1 and V.ends[axis] == V.npts[axis] - 1:
|
|
115
|
+
e = V.ends[axis]
|
|
116
|
+
index = [(e - order if j == axis else slice(None)) for j in range(n)]
|
|
117
|
+
a[tuple(index)] = 0.0
|
|
118
|
+
if isinstance(a, StencilMatrix) and identity:
|
|
119
|
+
a[tuple(index[:n//2])+(0,)*(n//2)] = 1.
|
|
120
|
+
else:
|
|
121
|
+
pass
|
|
122
|
+
|