Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
9432ca7
Added Pyccelkernel class and use it for AccumulatorVector, Accumulato…
max-models Oct 1, 2025
45f3448
kernel = ... --> kernel = Pyccelkernel(...
max-models Oct 1, 2025
e34cd37
Pass Pyccelkernel directly
max-models Oct 1, 2025
8fd08ba
Formatting
max-models Oct 1, 2025
ee367da
Added missing imports
max-models Oct 1, 2025
39fc9fd
Fix try except case which doesn't cover the parent directory not exis…
max-models Oct 2, 2025
753433c
Simplified the dir creation
max-models Oct 2, 2025
0392cb0
Added Pyccelkernel around some pusher kernels
max-models Oct 2, 2025
644c3db
Added Pyccelkernel for Accumulatorvector argument
max-models Oct 2, 2025
10251e0
Added Pyccelkernel to more places
max-models Oct 2, 2025
3655a6e
Added Pyccelkernel
max-models Oct 2, 2025
f1ffc13
Added missing Pyccelkernel
max-models Oct 2, 2025
cfe431a
Wrap with Pyccelkernel in tutorial
max-models Oct 2, 2025
cf88d72
Restore src/struphy/post_processing/pproc_struphy.py to devel version
max-models Oct 2, 2025
57572ac
group=group
max-models Oct 2, 2025
ae71937
Merge branch 'devel' into 462-add-a-pyccelkernel-class-with-a-__call_…
max-models Oct 6, 2025
0103e67
Fixed src/struphy/pic/tests/test_pushers.py
max-models Oct 6, 2025
244f4ef
only grab models when inspecting model modules
spossann Oct 7, 2025
0ffc86b
formatting
spossann Oct 7, 2025
8522d23
Remove StepStaticEfield
dominikbell Oct 7, 2025
dac8de1
Merge branch 'remove-step-static-efield' into '462-add-a-pyccelkernel…
max-models Oct 7, 2025
cf18e34
Updated src/struphy/propagators/__init__.py
max-models Oct 7, 2025
d96173d
Use test_pproc_codes(group=mtype)
max-models Oct 8, 2025
40035e6
Added a simple xp.py
max-models Oct 8, 2025
4e6fae3
Added a temporary print
max-models Oct 8, 2025
f971a68
Update .gitlab-ci.yml file
max-models Oct 8, 2025
d71d82c
Update .gitlab-ci.yml file
max-models Oct 8, 2025
cbbb49a
Update .gitlab-ci.yml file
max-models Oct 8, 2025
e08372e
Commented out jobs
max-models Oct 8, 2025
45e9114
Run src/struphy/xp.py
max-models Oct 8, 2025
65cb598
Added src/struphy/test_xp.py
max-models Oct 8, 2025
3043957
Bugfix
max-models Oct 8, 2025
f397e7d
Updated prints
max-models Oct 8, 2025
5e5f871
Added ArrayBackend class
max-models Oct 8, 2025
fbc200e
Rewrite the class a bit to only import xp once in the init
max-models Oct 8, 2025
0c0ed2b
Formatting
max-models Oct 8, 2025
cd698c0
Bugfix
max-models Oct 8, 2025
d9fbee4
Added typing magic so that autocompletion works with xp
max-models Oct 8, 2025
0bc6867
xp --> arrays
max-models Oct 8, 2025
6abb8d4
Updated .gitlab-ci.yml
max-models Oct 8, 2025
c1ef5e2
Replaced import numpy as np with from struphy.arrays import xp as np
max-models Oct 9, 2025
b634b23
Fix in src/struphy/test_xp.py
max-models Oct 9, 2025
f8d4708
Merge branch '466-add-an-xp-module' of gitlab.mpcdf.mpg.de:struphy/st…
max-models Oct 9, 2025
c54bdc6
renamed test_xp.py
max-models Oct 9, 2025
947aa7f
Formatting
max-models Oct 10, 2025
cd820f9
Moved the printing into the class and fixed the literals wuth Backend…
max-models Oct 10, 2025
209c3d4
Formattign
max-models Oct 10, 2025
087e8f0
Moved test_cupy to test stage and uncommented the usual pipelines
max-models Oct 10, 2025
587ff25
Bugfix
max-models Oct 10, 2025
6e8b851
Fixed kernel, must import numpy
max-models Oct 10, 2025
d63132b
Fixed docstring
max-models Oct 10, 2025
f3f8c78
Moved arrays.py to utils/
max-models Oct 10, 2025
a1f52ad
Merge branch '466-add-an-xp-module' into struphy-with-cupy
max-models Oct 10, 2025
09d2a71
Fixes for running struphy with cupy arrays
max-models Oct 10, 2025
ccae087
Formatting
max-models Oct 14, 2025
3cd2942
Merge branch 'devel' into struphy-with-cupy
max-models Oct 14, 2025
c48eec4
fixed product of list
max-models Oct 15, 2025
9fa8c4e
Merge branch 'devel' into struphy-with-cupy
max-models Oct 20, 2025
c7f306a
Fixed round commands containing numpy numbers
max-models Oct 20, 2025
e6b9fea
TEMPORARY, import from cupy in pyccel kernel (only works with non-pyc…
max-models Oct 20, 2025
76ab894
Conditional import
max-models Oct 20, 2025
3e03606
Fix import
max-models Oct 20, 2025
37f34b8
Convert st to st_array
max-models Oct 20, 2025
f8d6afc
convert butcher to array
max-models Oct 20, 2025
388ac98
vtk with cpu arrays
max-models Oct 20, 2025
15d542f
Formatting
max-models Oct 20, 2025
6462d0e
Use datacontainer wit numpy arrays always
max-models Oct 20, 2025
a228d0e
bcount as numpy
max-models Oct 20, 2025
57ed6ad
Start fixing update_scalar
max-models Oct 20, 2025
77132e0
Ensure that value_array is a cupy array
max-models Oct 20, 2025
d3b5a34
Fixed update_scalar
max-models Oct 21, 2025
0775b23
Convert lists to arrays
max-models Oct 21, 2025
e094538
Merge branch '318-parameter-file-as-py' into struphy-with-cupy
max-models Oct 21, 2025
5f3160d
Merge branch '318-parameter-file-as-py' into struphy-with-cupy
max-models Oct 22, 2025
b5efe7b
Bufixes after merge
max-models Oct 22, 2025
2d7dc4c
bugfix
max-models Oct 22, 2025
08f8fbd
Converted list to xp array
max-models Oct 22, 2025
a2504fd
Replaced arrays.py with cunumpy
max-models Oct 22, 2025
d344353
Formatting
max-models Oct 22, 2025
be32dab
Fixed CI
max-models Oct 22, 2025
722d28d
Install cunumpy explicitly in test_cupy job
max-models Oct 22, 2025
15b469c
Merge branch 'use-cunumpy' into struphy-with-cupy
max-models Oct 22, 2025
c535ad4
Merge branch '318-parameter-file-as-py' into struphy-with-cupy
max-models Oct 22, 2025
704f319
Formatting
max-models Oct 22, 2025
5683c9f
Fixed cunumpy imports
max-models Oct 22, 2025
27e2557
Merge branch 'devel' into struphy-with-cupy
max-models Oct 24, 2025
12f1a80
Merge branch 'devel' into struphy-with-cupy
max-models Oct 28, 2025
e709c31
Use numpy for scalars
max-models Oct 28, 2025
0deb2d9
Merge branch 'devel' into struphy-with-cupy
max-models Oct 28, 2025
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
4 changes: 2 additions & 2 deletions src/struphy/bsplines/bsplines.py
Original file line number Diff line number Diff line change
Expand Up @@ -611,8 +611,8 @@ def make_knots(breaks, degree, periodic):

if periodic:
period = breaks[-1] - breaks[0]
T[0:p] = [xi - period for xi in breaks[-p - 1 : -1]]
T[-p:] = [xi + period for xi in breaks[1 : p + 1]]
T[0:p] = xp.asarray([xi - period for xi in breaks[-p - 1 : -1]])
T[-p:] = xp.asarray([xi + period for xi in breaks[1 : p + 1]])
else:
T[0:p] = breaks[0]
T[-p:] = breaks[-1]
Expand Down
2 changes: 1 addition & 1 deletion src/struphy/feec/basis_projection_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def __init__(self, derham, domain, verbose=True, **weights):

self._rank = derham.comm.Get_rank() if derham.comm is not None else 0

if xp.any([p == 1 and Nel > 1 for p, Nel in zip(derham.p, derham.Nel)]):
if xp.any(xp.array([p == 1 and Nel > 1 for p, Nel in zip(derham.p, derham.Nel)])):
if MPI.COMM_WORLD.Get_rank() == 0:
print(
f'\nWARNING: Class "BasisProjectionOperators" called with p={derham.p} (interpolation of piece-wise constants should be avoided).',
Expand Down
26 changes: 19 additions & 7 deletions src/struphy/feec/psydac_derham.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import importlib.metadata

import cunumpy as xp
import numpy as np
import psydac.core.bsplines as bsp
from psydac.ddm.cart import DomainDecomposition
from psydac.ddm.mpi import MockComm, MockMPI
Expand Down Expand Up @@ -117,7 +118,7 @@ def __init__(
if dirichlet_bc is not None:
assert len(dirichlet_bc) == 3
# make sure that boundary conditions are compatible with spline space
assert xp.all([bc == (False, False) for i, bc in enumerate(dirichlet_bc) if spl_kind[i]])
assert xp.all(xp.array([bc == (False, False) for i, bc in enumerate(dirichlet_bc) if spl_kind[i]]))

self._dirichlet_bc = dirichlet_bc

Expand Down Expand Up @@ -2789,12 +2790,17 @@ def get_pts_and_wts(space_1d, start, end, n_quad=None, polar_shift=False):
union_breaks = space_1d.breaks[:-1]

# Make union of Greville and break points
tmp = set(xp.round(space_1d.histopolation_grid, decimals=14)).union(
xp.round(union_breaks, decimals=14),
# tmp = set(xp.round(space_1d.histopolation_grid, decimals=14)).union(
# xp.round(union_breaks, decimals=14),
# )
# tmp = list(tmp)
# tmp.sort()
# tmp_a = xp.array(tmp)

tmp = set(xp.round(space_1d.histopolation_grid, decimals=14).tolist()).union(
xp.round(union_breaks, decimals=14).tolist()
)

tmp = list(tmp)
tmp.sort()
tmp = sorted(tmp)
tmp_a = xp.array(tmp)

x_grid = tmp_a[
Expand Down Expand Up @@ -2822,7 +2828,13 @@ def get_pts_and_wts(space_1d, start, end, n_quad=None, polar_shift=False):
# products of basis functions are integrated exactly
n_quad = space_1d.degree + 1

pts_loc, wts_loc = xp.polynomial.legendre.leggauss(n_quad)
pts_loc, wts_loc = np.polynomial.legendre.leggauss(n_quad)

if "cupy" in xp.__name__:
import cupy as cp

pts_loc = cp.array(pts_loc)
wts_loc = cp.array(wts_loc)

x, wts = bsp.quadrature_grid(x_grid, pts_loc, wts_loc)

Expand Down
8 changes: 5 additions & 3 deletions src/struphy/geometry/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from struphy.geometry import evaluation_kernels, transform_kernels
from struphy.kernel_arguments.pusher_args_kernels import DomainArguments
from struphy.linear_algebra import linalg_kron
from struphy.utils.pyccel import Pyccelkernel


class Domain(metaclass=ABCMeta):
Expand Down Expand Up @@ -769,8 +770,8 @@ def _evaluate_metric_coefficient(self, *etas, which=0, **kwargs):

# to keep C-ordering the (3, 3)-part is in the last indices
out = xp.empty((markers.shape[0], 3, 3), dtype=float)

n_inside = evaluation_kernels.kernel_evaluate_pic(
kernel = Pyccelkernel(evaluation_kernels.kernel_evaluate_pic)
n_inside = kernel(
markers,
which,
self.args_domain,
Expand Down Expand Up @@ -813,7 +814,8 @@ def _evaluate_metric_coefficient(self, *etas, which=0, **kwargs):
(E1.shape[0], E2.shape[1], E3.shape[2], 3, 3),
dtype=float,
)
evaluation_kernels.kernel_evaluate(
kernel = Pyccelkernel(evaluation_kernels.kernel_evaluate)
kernel(
E1,
E2,
E3,
Expand Down
2 changes: 1 addition & 1 deletion src/struphy/geometry/evaluation_kernels.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
corresponding to mappings (x, y, z) = F(eta_1, eta_2, eta_3).
"""

from numpy import empty, shape, zeros
from cupy import empty, shape, zeros
from pyccel.decorators import stack_array

import struphy.geometry.mappings_kernels as mappings_kernels
Expand Down
9 changes: 8 additions & 1 deletion src/struphy/geometry/transform_kernels.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,14 @@
- 2-form --> vector : (a_1, a_2, a_3) = (a^2_1, a^2_2, a^2_3) / |det(DF)|
"""

from numpy import empty, shape, sqrt, zeros
import cunumpy as np
from cunumpy.xp import array_backend

if array_backend.backend == "cupy":
from cupy import empty, shape, sqrt, zeros
else:
from numpy import empty, shape, sqrt, zeros

from pyccel.decorators import stack_array

import struphy.geometry.evaluation_kernels as evaluation_kernels
Expand Down
6 changes: 3 additions & 3 deletions src/struphy/io/output_handling.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import ctypes
import os

import cunumpy as xp
import h5py
import numpy as np


class DataContainer:
Expand Down Expand Up @@ -82,11 +82,11 @@ def add_data(self, data_dict):
Parameters
----------
data_dict : dict
Name-object pairs to save during time stepping, e.g. {key : val}. key must be a string and val must be a xp.array of fixed shape. Scalar values (floats) must therefore be passed as 1d arrays of size 1.
Name-object pairs to save during time stepping, e.g. {key : val}. key must be a string and val must be a np.array of fixed shape. Scalar values (floats) must therefore be passed as 1d arrays of size 1.
"""

for key, val in data_dict.items():
assert isinstance(val, xp.ndarray)
assert isinstance(val, np.ndarray)

# if dataset already exists, check for compatibility with given array
if key in self._dset_dict:
Expand Down
14 changes: 7 additions & 7 deletions src/struphy/kernel_arguments/pusher_args_kernels.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# from numpy import copy
from numpy import empty
import cunumpy as xp


class MarkerArguments:
Expand Down Expand Up @@ -99,12 +99,12 @@ def __init__(
self.tn3 = tn3
self.starts = starts

self.bn1 = empty(pn[0] + 1, dtype=float)
self.bn2 = empty(pn[1] + 1, dtype=float)
self.bn3 = empty(pn[2] + 1, dtype=float)
self.bd1 = empty(pn[0], dtype=float)
self.bd2 = empty(pn[1], dtype=float)
self.bd3 = empty(pn[2], dtype=float)
self.bn1 = xp.empty(int(pn[0] + 1), dtype=float)
self.bn2 = xp.empty(int(pn[1] + 1), dtype=float)
self.bn3 = xp.empty(int(pn[2] + 1), dtype=float)
self.bd1 = xp.empty(int(pn[0]), dtype=float)
self.bd2 = xp.empty(int(pn[1]), dtype=float)
self.bd3 = xp.empty(int(pn[2]), dtype=float)


class DomainArguments:
Expand Down
30 changes: 26 additions & 4 deletions src/struphy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,25 @@ def run(
absB0 = model.equil.absB0(*grids_log)
pointData["absB0"] = absB0

gridToVTK(os.path.join(path_out, "geometry"), *grids_phy, pointData=pointData)
from cunumpy.xp import array_backend

print("calling gridToVTK")
if array_backend.backend == "numpy":
gridToVTK(os.path.join(path_out, "geometry"), *grids_phy, pointData=pointData)
else:
# cupy
grids_phy_cpu = [g.get() if isinstance(g, xp.ndarray) else g for g in grids_phy]

# Convert pointData values to NumPy
pointData_cpu = {k: (v.get() if isinstance(v, xp.ndarray) else v) for k, v in pointData.items()}

# Now call gridToVTK safely
gridToVTK(os.path.join(path_out, "geometry"), *grids_phy_cpu, pointData=pointData_cpu)

# data object for saving (will either create new hdf5 files if restart==False or open existing files if restart==True)
# use MPI.COMM_WORLD as communicator when storing the outputs
data = DataContainer(path_out, comm=comm)

print("ccc")
# time quantities (current time value, value in seconds and index)
time_state = {}
time_state["value"] = xp.zeros(1, dtype=float)
Expand All @@ -270,8 +283,17 @@ def run(
for key, val in time_state.items():
key_time = "time/" + key
key_time_restart = "restart/time/" + key
data.add_data({key_time: val})
data.add_data({key_time_restart: val})
if array_backend.backend == "numpy":
data.add_data({key_time: val})
data.add_data({key_time_restart: val})
else:
val_cpu = val.get() # if isinstance(val, xp.ndarray) else val

# Then assign
print(f"{val_cpu = } {type(val_cpu) = }")
data.add_data({key_time: val_cpu})
# self._file[key][0] = val_cpu[0]
data.add_data({key_time_restart: val_cpu})

# retrieve time parameters
dt = time_opts.dt
Expand Down
21 changes: 13 additions & 8 deletions src/struphy/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from functools import reduce
from textwrap import indent

import numpy as np
import cunumpy as xp
import yaml
from line_profiler import profile
Expand Down Expand Up @@ -521,11 +522,12 @@ def update_scalar(self, name, value=None):

if summands is None:
# Ensure the value is a float if there are no summands
assert isinstance(value, float)

# Create a numpy array to hold the scalar value
value_array = xp.array([value], dtype=xp.float64)

if isinstance(value, float):
# Create a numpy array to hold the scalar value
value_array = np.array([value])
else:
value_array = np.asarray(value)
value_array = np.array(value_array)
# Perform MPI operations based on the compute flags
if "sum_world" in compute_operations and not isinstance(MPI, MockMPI):
MPI.COMM_WORLD.Allreduce(
Expand Down Expand Up @@ -562,11 +564,14 @@ def update_scalar(self, name, value=None):

if "divide_n_mks" in compute_operations:
# Initialize the total number of markers
n_mks_tot = xp.array([variable.particles.Np])
n_mks_tot = np.array([variable.particles.Np])
value_array /= n_mks_tot

# Update the scalar value
self._scalar_quantities[name]["value"][0] = value_array[0]
if value_array.ndim == 0:
self._scalar_quantities[name]["value"][0] = value_array.item()
else:
self._scalar_quantities[name]["value"][0] = value_array[0]

else:
# Sum the values of the summands
Expand Down Expand Up @@ -776,7 +781,7 @@ def update_distr_functions(self):
h2 = 1 / obj.boxes_per_dim[1]
h3 = 1 / obj.boxes_per_dim[2]

ndim = xp.count_nonzero([d > 1 for d in obj.boxes_per_dim])
ndim = xp.count_nonzero(xp.array([d > 1 for d in obj.boxes_per_dim]))
if ndim == 0:
kernel_type = "gaussian_3d"
else:
Expand Down
3 changes: 2 additions & 1 deletion src/struphy/models/toy.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import numpy as np
import cunumpy as xp
from psydac.ddm.mpi import mpi as MPI

Expand Down Expand Up @@ -157,7 +158,7 @@ def velocity_scale(self):
return "cyclotron"

def allocate_helpers(self):
self._tmp = xp.empty(1, dtype=float)
self._tmp = np.empty(1, dtype=float)

def update_scalar_quantities(self):
particles = self.kinetic_ions.var.particles
Expand Down
3 changes: 2 additions & 1 deletion src/struphy/ode/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ def __post_init__(self):
self._a = xp.tri(self.n_stages, k=-1)
for l, st in enumerate(a):
assert len(st) == l + 1
self._a[l + 1, : l + 1] = st

self._a[l + 1, : l + 1] = xp.array(st)

self._conv_rate = conv_rate

Expand Down
21 changes: 16 additions & 5 deletions src/struphy/pic/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ def __init__(
assert all([nboxes % nproc == 0 for nboxes, nproc in zip(self.boxes_per_dim, self.nprocs)]), (
f"Number of boxes {self.boxes_per_dim =} must be divisible by number of processes {self.nprocs =} in each direction."
)
n_boxes = xp.prod(self.boxes_per_dim, dtype=int) * self.num_clones
n_boxes = xp.prod(xp.array(self.boxes_per_dim), dtype=int) * self.num_clones

# if verbose:
# print(f"\n{self.mpi_rank = }, {n_boxes = }")
Expand Down Expand Up @@ -1095,7 +1095,7 @@ def _allocate_marker_array(self):
bufsize = self.bufsize + 1.0 / xp.sqrt(n_mks_load_loc)

# allocate markers array (3 x positions, vdim x velocities, weight, s0, w0, ..., ID) with buffer
self._n_rows = round(n_mks_load_loc * (1 + bufsize))
self._n_rows = round(float(n_mks_load_loc * (1 + bufsize)))
self._markers = xp.zeros((self.n_rows, self.n_cols), dtype=float)

# allocate auxiliary arrays
Expand Down Expand Up @@ -1917,7 +1917,7 @@ def binning(
The reconstructed delta-f distribution function.
"""

assert xp.count_nonzero(components) == len(bin_edges)
assert xp.count_nonzero(xp.array(components)) == len(bin_edges)

# volume of a bin
bin_vol = 1.0
Expand Down Expand Up @@ -2424,7 +2424,7 @@ def _set_boxes(self):
n_particles = self._markers_shape[0]
n_mkr = int(n_particles / n_box_in) + 1
n_cols = round(
n_mkr * (1 + 1 / xp.sqrt(n_mkr) + self._box_bufsize),
float(n_mkr) * (1 + 1 / float(xp.sqrt(n_mkr)) + self._box_bufsize),
)

# cartesian boxes
Expand Down Expand Up @@ -2643,7 +2643,17 @@ def check_and_assign_particles_to_boxes(self):
"""Check whether the box array has enough columns (detect load imbalance wrt to sorting boxes),
and then assigne the particles to boxes."""

bcount = xp.bincount(xp.int64(self.markers_wo_holes[:, -2]))
from cunumpy.xp import array_backend

if array_backend.backend == "numpy":
bcount = xp.bincount(xp.int64(self.markers_wo_holes[:, -2]))
else:
import cupy as cp

indices = self.markers_wo_holes[:, -2]
indices = indices.astype(cp.int64)
bcount = cp.bincount(indices)

max_in_box = xp.max(bcount)
if max_in_box > self._sorting_boxes.boxes.shape[1]:
warnings.warn(
Expand Down Expand Up @@ -4049,6 +4059,7 @@ def _gather_scalar_in_subcomm_array(self, scalar: int, out: xp.ndarray = None):
_tmp[self.mpi_rank] = scalar

if self.mpi_comm is not None:
print(f"{self.mpi_comm = }")
self.mpi_comm.Allgather(
_tmp[self.mpi_rank],
_tmp,
Expand Down
6 changes: 3 additions & 3 deletions src/struphy/propagators/propagators_markers.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def allocate(self):
import cunumpy as xp

butcher._a = xp.diag(butcher.a, k=-1)
butcher._a = xp.array(list(butcher.a) + [0.0])
butcher._a = xp.concatenate([xp.asarray(butcher.a), xp.array([0.0])])

args_kernel = (
butcher.a,
Expand Down Expand Up @@ -867,7 +867,7 @@ def allocate(self):
import cunumpy as xp

butcher._a = xp.diag(butcher.a, k=-1)
butcher._a = xp.array(list(butcher.a) + [0.0])
butcher._a = xp.concatenate([xp.asarray(butcher.a), xp.array([0.0])])

kernel = Pyccelkernel(pusher_kernels_gc.push_gc_bxEstar_explicit_multistage)

Expand Down Expand Up @@ -1315,7 +1315,7 @@ def allocate(self):
import cunumpy as xp

butcher._a = xp.diag(butcher.a, k=-1)
butcher._a = xp.array(list(butcher.a) + [0.0])
butcher._a = xp.concatenate([xp.asarray(butcher.a), xp.array([0.0])])

kernel = Pyccelkernel(pusher_kernels_gc.push_gc_Bstar_explicit_multistage)

Expand Down
Loading
Loading