Skip to content
Open
Show file tree
Hide file tree
Changes from 101 commits
Commits
Show all changes
144 commits
Select commit Hold shift + click to select a range
c3c801d
poisson can run in parallel
Sep 16, 2025
ad8adad
reorganize
Sep 16, 2025
364d64c
only one geometry file is created
Sep 17, 2025
04b6e8c
minor changes
Sep 19, 2025
5012856
update names in examples/poisson_2d_mapping.py
Sep 24, 2025
51d0592
error in plot_2d_decomposition
Oct 13, 2025
63f9b65
merge 'devel' into polar_splines_alisa
Oct 14, 2025
7354e97
fix an error after merging
Oct 14, 2025
2c28462
error in plot_2d_decomposition
Oct 14, 2025
a86faf1
Use tight layout
yguclu Oct 14, 2025
6d1304f
Avoid string warnings
yguclu Oct 14, 2025
39d14f4
some changes to visualization
Oct 14, 2025
0ca428e
Merge branch 'polar_splines_alisa' of https://github.com/pyccel/psyda…
Oct 15, 2025
9d2a618
computing average in parallel
Oct 20, 2025
77cd4e4
fixed errors in parallel average
Oct 21, 2025
e6c8a1a
Merge branch 'devel' into polar_splines_alisa
Oct 21, 2025
dbdf3a1
update plot_2d_decomposition
Oct 21, 2025
8ce233f
Changes in disk domain
Oct 24, 2025
c4eab7c
Callable exact solution in logical coordinates for plotting
Oct 24, 2025
1026b3d
Fix right hand side
Oct 24, 2025
ad0a0db
Fix smoothing methods 'None', 'polar-std' and 'polar-spec'
Oct 24, 2025
fb2213b
Print info
Oct 24, 2025
529897b
remove trick
Oct 28, 2025
6feacff
fixed issue with polar-spec and polar-std (cause unknown)
Nov 4, 2025
6e74dd0
fix crash with analytical mapping
Nov 5, 2025
3682565
it now works with analytical mapping
Nov 5, 2025
0e7f56e
typo
Nov 7, 2025
573501c
Merge branch 'devel' into polar_splines_alisa
Nov 7, 2025
04e9c4b
initial commit for maxwell
Nov 10, 2025
bd3e1d5
fixed some errors
Nov 13, 2025
850100a
parallelization, fixed mapping
Nov 13, 2025
1a722f2
fixed an error with study_L2proj
Nov 18, 2025
5d3477f
fix plots at final time
Nov 20, 2025
cc500f8
Plotting only for root process
Nov 24, 2025
b048929
remove use_logical_solution
Nov 25, 2025
1e3e31c
fix error (exporting fields before projecting), remove comments
Nov 26, 2025
4687a24
create grid only with root process
Dec 1, 2025
516124e
tests for projection
Dec 10, 2025
25efc2e
fix P1 for C0
Dec 15, 2025
b50640e
fix P1 for C0
Dec 15, 2025
858078c
remove prints
Dec 15, 2025
e7ef374
fix a bug when use_spline_mapping is False
Dec 15, 2025
4051e64
small changes
Dec 16, 2025
baf1a32
C1 projections in serial
Dec 16, 2025
6894d32
added P0 C1
Dec 18, 2025
1262f66
Parallelize C1PolarProjection_V0
Dec 20, 2025
4508259
parallelized C1PolarProjection_V1
Dec 21, 2025
bedf25d
use only one allreduce
Dec 22, 2025
a37ef70
tosparse and unit test for C0 P0
Jan 20, 2026
6c7c072
fix a bug in test
Jan 20, 2026
d59232f
Merge branch 'devel' into polar_splines_alisa
Jan 20, 2026
3baed17
C0 projection P2 and unit tests
Jan 27, 2026
bf2b887
some unit tests for P1
Jan 27, 2026
463f009
tosparse for C0 P1 and hbc for tests
Jan 30, 2026
bda769b
add transposed to tests
Feb 10, 2026
fd7b300
fix bug in dot methods
Feb 12, 2026
6e97568
tosparse and unit test for C1 projection P0
Feb 13, 2026
8865845
refactor unit tests
Feb 17, 2026
f429390
get global vector for sparse operators
Feb 18, 2026
ccc485e
Merge branch 'devel' into polar_splines_alisa
Feb 18, 2026
758139b
add reference matrices to test the tosparse methods
Mar 3, 2026
d40e423
make some tests run correctly in parallel
Mar 4, 2026
2bf379f
tosparse methods for C1 P1
Mar 5, 2026
d5f180c
fixed deadlock in P1 C1
Mar 9, 2026
b37c41a
small fix
Mar 9, 2026
beaf3c9
Merge branch 'devel' into polar_splines_alisa
yguclu Mar 9, 2026
72864d6
merge polar_splines_alisa into polar_splines_alisa
Mar 10, 2026
ed9d75d
fix variable referenced before assignment
Mar 10, 2026
2a92569
small fix
Mar 10, 2026
4aa2591
changes in maxwell example
Mar 10, 2026
48b49e2
atol rtol in unit tests
Mar 12, 2026
4b19433
test checking entries of sparse matrices for P0
Mar 12, 2026
067ddf8
change allclose to isclose
Mar 13, 2026
054900f
test checking entries of sparse matrices for P2
Mar 13, 2026
099e586
test checking entries of sparse matrices for P1
Mar 16, 2026
f7555b4
change tosparse of C0 to distribution by row
Mar 18, 2026
e2a0a71
transpose for P2
Mar 18, 2026
3525acc
tosparse methods for C1 distributed by row
Mar 18, 2026
7d91955
fix failing test
Mar 19, 2026
7994262
revert changes in unrelated file
Mar 19, 2026
23525d0
remove unnecessary tests
Mar 19, 2026
88d82a1
Merge branch 'devel' into polar_splines_alisa
yguclu Mar 25, 2026
59b84c3
added conversion to coo matrix
Mar 29, 2026
551323c
changed atol and rtol to constants
Mar 29, 2026
b75b380
whitespaces
Mar 29, 2026
e91cbac
added verbose flag for unit tests
Apr 1, 2026
84d2848
utility function for gathering arrays of variable len
Apr 1, 2026
80a0fbd
specify datatype for cols and rows in tosparse
Apr 6, 2026
bdb796e
use Gatherv in the tests
Apr 6, 2026
7ae3507
added parameter mpi_root to utility function
Apr 13, 2026
2b8cb33
multiple numpy arrays can be passed to gather_vlen_arrays
Apr 13, 2026
85bcec6
clean up check_regular_ring_map
Apr 13, 2026
4be6872
remove unnecessary flag
Apr 13, 2026
99d935b
remove unused variable
Apr 13, 2026
8a048a7
change docstring
Apr 13, 2026
bf7dc69
remove some comments
Apr 13, 2026
487eda0
remove unused variables
Apr 15, 2026
a7bde8d
clean up debugging functions
Apr 15, 2026
ac3be5e
docstring for Laplacian class
Apr 15, 2026
514fb11
clean up Poisson example
Apr 16, 2026
501a18b
changed params dict in disk
Apr 16, 2026
36357d0
remove coordinates property
Apr 16, 2026
71788a6
testing my branch of sympde
May 5, 2026
be219a6
change mapping params to Rational
May 5, 2026
6ce62d3
Merge branch 'devel' into polar_splines_alisa
May 5, 2026
923fa53
change czarny mapping params to Rational
May 5, 2026
79f70cf
changed domain in Poisson2D to sympde domain
May 5, 2026
406e708
minor cleanup
May 5, 2026
edad37c
move plotting to a separate function
May 5, 2026
2a9b82a
add refine param to plotting
May 5, 2026
b7903ae
changes in mapping for plotting
May 5, 2026
9569239
codacy is complaining
May 5, 2026
b6184cf
codacy is complaining
May 5, 2026
ba6bca6
define a function compute_errors
May 8, 2026
47e1bac
moved add_colorbar to utils
May 8, 2026
7ba6f43
separated plotting objects creation
May 12, 2026
cde57db
remove some old comments
May 12, 2026
d456677
uncomment plot_fields_along_s
May 12, 2026
70ee0b3
remove some old todos
campospinto May 12, 2026
eaadbe5
Merge branch 'polar_splines_alisa' of https://github.com/pyccel/psyda…
May 15, 2026
f41754d
remove add_colorbar from Poisson
May 15, 2026
0659eb7
create space V only when use_spline_mapping
May 15, 2026
76c0bab
added docstring to Poisson
May 15, 2026
27dbf60
remove some unused variables
May 15, 2026
81cb257
remove some unused things
May 15, 2026
ab097db
rename phi, rho -> phi_log, rho_log in Poisson2D
May 15, 2026
2ad02db
rename domain -> domain_log
May 15, 2026
68516f4
some simplifications in Maxwell
May 19, 2026
880ef94
improvements in plotting logic
May 19, 2026
d53efb6
fix empty windows
May 19, 2026
26fc230
Fixed initial solution waveTE
May 21, 2026
7eabc4b
added utility function create_tensor_spline_space
May 21, 2026
3d9e4c7
removed basic_fix variable
May 21, 2026
f6687dc
fix error in L2 errors
May 21, 2026
f5df0fc
remove unused functions
Jun 3, 2026
5820abe
a few small changes in Poisson
Jun 9, 2026
21be4da
remove unused things from Maxwell
Jun 9, 2026
75e0474
docstring for run_study_L2_proj
Jun 9, 2026
ba35ee7
changed names of discrete derham spaces
Jun 9, 2026
b28334d
IdentityOperator
Jun 9, 2026
234203b
add backend
Jun 16, 2026
2dffb86
correct comments
Jun 16, 2026
801025f
write matrix vector mul in a better way
Jun 16, 2026
fb37885
add comment for BC
Jun 16, 2026
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
Empty file added psydac/feec/polar/__init__.py
Empty file.
1,245 changes: 1,245 additions & 0 deletions psydac/feec/polar/conga_projections.py

Large diffs are not rendered by default.

Empty file.
300 changes: 300 additions & 0 deletions psydac/feec/polar/examples/analyticalTE.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @alisa-kirkinskaia, I've started reviewing your PR and will leave some comments throughout the next days. Regarding this particular file: What is its purpose? Are you testing different plotting options?
I've also noticed that the variable variables is not used in the __init__ of CircularCavitySolution (What is CircularCavitySolution?). And in the main function you first mention that the physical domain is a rectangle, and later that the physical domain is also a disk? Also, the domain variable is not used and could be removed.

Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
from sympde.topology import Square
from sympde.topology.analytical_mapping import PolarMapping
from psydac.feec.pull_push import push_2d_hcurl, push_2d_l2
from numpy import pi
import numpy as np
import matplotlib.pyplot as plt


def add_colorbar(im, ax, **kwargs):
from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size=0.2, pad=0.3)
cbar = ax.get_figure().colorbar(im, cax=cax, **kwargs)
return cbar


class CircularCavitySolution:
"""
Time-harmonic solution of Maxwell's equations in a disk-like domain with
perfectly conducting walls. This is a "transverse electric" solution, with
E = (Ex, Ey) and B = Bz. Domain is [0, R] x [0, 2pi].

Parameters
----------
R : float
domain radius

c: float
Speed of light in arbitrary units

(m, n): int
Mode number. Warning: m > 0, n >= 0

D: float
shift of logical center (in "Target" mapping with c0=D*R2, c1=0, k=0, D=D)

scale: float
Rescaling the values by a real factor. Default = 1

"""

def __init__(self, R, c, m, n, D=0, scale=1, variables='log'):
from numpy import pi
from scipy.special import jnp_zeros
pnm = jnp_zeros(n, m)[-1]
kc = pnm / R
omega = c * kc

phase = pi / 4

self.c = c
self.scale = scale
self.n = n
self.kc = kc
self.omega = omega
self.phase = phase
self._R = R
assert 0 <= D < .5
self._D = D
# assert variables in ['log', 'phys']
# self._logical = (variables == 'log')

# Exact solutions for electric and magnetic field with polar parametrization of disk domain
def Es_ex(self, t, s, theta):
from numpy import sin # , cos, sqrt, arctan2
from scipy.special import jv

scale = self.scale
n = self.n
kc = self.kc
omega = self.omega
phase = self.phase
c = self.c

return - scale * c * n / (s * kc + 1e-10) * sin(n * theta) * jv(n, kc * s) * sin(omega * t + phase)

def Et_ex(self, t, s, theta, s_factor=True):
"""
if s_factor: multiply by s (as in logical field)
"""
from numpy import sin, cos
from scipy.special import jvp

scale = self.scale
n = self.n
kc = self.kc
omega = self.omega
phase = self.phase
c = self.c

val = - scale * c * cos(n * theta) * jvp(n, kc * s) * sin(omega * t + phase)
if s_factor:
val *= s
return val

def B_ex(self, t, s, theta, s_factor=True):
"""
if s_factor: multiply by s (as in logical field)
"""
from numpy import cos
from scipy.special import jv

scale = self.scale
n = self.n
kc = self.kc
omega = self.omega
phase = self.phase

val = scale * cos(n * theta) * jv(n, kc * s) * cos(omega * t + phase)
if s_factor:
val *= s
return val
# The magnitude of B is approximately equal to scale / 3

def Bt_ex(self, t, s, theta):
'''
= dB/dt
todo: change the name
'''
from numpy import cos, sin
from scipy.special import jv

scale = self.scale
n = self.n
kc = self.kc
omega = self.omega
phase = self.phase

return scale * omega * s * cos(n * theta) * jv(n, kc * s) * sin(omega * t + phase)

# physical field

def get_radius_angle(self, x, y):
from numpy import sqrt, arctan2 # , sin, cos
r = sqrt(x * x + y * y)
alpha = arctan2(y, x)
# print(f'r*np.cos(alpha) - x = {r*np.cos(alpha) - x}')
# print(f'r*np.sin(alpha) - y = {r*np.sin(alpha) - y}')
return r, alpha

def Ex_ex(self, t, x, y):
from numpy import cos, sin

r, alpha = self.get_radius_angle(x, y)
return cos(alpha) * self.Es_ex(t, r, alpha) - sin(alpha) * self.Et_ex(t, r, alpha, s_factor=False)

def Ey_ex(self, t, x, y):
from numpy import cos, sin

r, alpha = self.get_radius_angle(x, y)
return sin(alpha) * self.Es_ex(t, r, alpha) + cos(alpha) * self.Et_ex(t, r, alpha, s_factor=False)

def Bz_ex(self, t, x, y):

r, alpha = self.get_radius_angle(x, y)
return self.B_ex(t, r, alpha, s_factor=False)


def main():
# TODO: update with D_shift

# Physical domain is rectangle [0, R] x [0, 2pi]
R = 2.0

# Speed of light equal c and scaling of the fields by a scale factor
c = 1
scale = 1

# Mode number
# (m, n) = (1, 0)
# (m, n) = (2, 1)
(m, n) = (2, 3)

# Exact solution
exact_solution = CircularCavitySolution(R=R, c=c, m=m, n=n, scale=scale)

# Exact fields, as callable functions of (t, s, theta)
Es_ex = exact_solution.Es_ex
Et_ex = exact_solution.Et_ex
B_ex = exact_solution.B_ex
Bt_ex = exact_solution.Bt_ex

# Logical domain: [0, R] x [0, 2pi]
logical_domain = Square('Omega', bounds1=[0, R], bounds2=[0, 2 * pi])

# Physical domain: disk of radius R obtained as image of the logical_domain
# with the analytical mapping of a circle
mapping = PolarMapping('F', c1=0, c2=0, rmin=0, rmax=1)
domain = mapping(logical_domain)
F = mapping.get_callable_mapping()

# Set time
t = 0

Es = lambda x, y: Es_ex(t, x, y)
Et = lambda x, y: Et_ex(t, x, y)
B = lambda x, y: B_ex(t, x, y)
Bt = lambda x, y: Bt_ex(t, x, y)

# Plot of fields
N = 100

rho = np.linspace(1e-20, R, N)
theta = np.linspace(0, 2 * pi, N)
rho, theta = np.meshgrid(rho, theta, indexing='ij')
x, y = F(rho, theta)

Ex_values = np.empty_like(rho)
Ey_values = np.empty_like(rho)
B_values = np.empty_like(rho)

valerr = 0
for i, x1i in enumerate(rho[:, 0]):
for j, x2j in enumerate(theta[0, :]):
Ex_values[i, j], Ey_values[i, j] = \
push_2d_hcurl(Es, Et, x1i, x2j, F)

B_values[i, j] = push_2d_l2(B, x1i, x2j, F)

fig, axs = plt.subplots(2, 2, figsize=(12, 12))
im0 = axs[0, 0].contourf(x, y, Ex_values, 50)
im1 = axs[0, 1].contourf(x, y, Ey_values, 50)
im2 = axs[1, 0].contourf(x, y, np.sqrt(Ex_values ** 2 + Ey_values ** 2), 50)
im3 = axs[1, 1].contourf(x, y, B_values, 50)
axs[0, 0].set_title(r'$E_x$')
axs[0, 1].set_title(r'$E_y$')
axs[1, 0].set_title(r'$||\mathbf{E}||$')
axs[1, 1].set_title('$B$')
add_colorbar(im0, axs[0, 0])
add_colorbar(im1, axs[0, 1])
add_colorbar(im2, axs[1, 0])
add_colorbar(im3, axs[1, 1])

# Test: curl E = - d_t B_z with finite Differences
# on a tensor grid in the square inscribed the disk
N = 160
l = R / np.sqrt(2) # edge length

x, dx = np.linspace(-l, l, N, retstep=True)
y, dy = np.linspace(-l, l, N, retstep=True)
x, y = np.meshgrid(x, y, indexing='ij')
rho = np.sqrt(x ** 2 + y ** 2)
theta = np.arctan2(y, x) % (2 * pi)

Ex_values = np.empty_like(rho)
Ey_values = np.empty_like(rho)
Bt_values = np.empty_like(rho)

ni, nj = rho.shape
for i in range(ni):
for j in range(nj):
x1_ij = rho[i, j]
x2_ij = theta[i, j]
Ex_values[i, j], Ey_values[i, j] = \
push_2d_hcurl(Es, Et, x1_ij, x2_ij, F)

Bt_values[i, j] = push_2d_l2(Bt, x1_ij, x2_ij, F)

fig, axs = plt.subplots(2, 3, figsize=(15, 15))
im1 = axs[0, 0].contourf(x, y, np.sqrt(Ex_values ** 2 + Ey_values ** 2))
im2 = axs[0, 1].contourf(x, y, -Bt_values)
axs[0, 0].set_title(r'$||\mathbf{E}||$')
axs[0, 1].set_title(r'$-\partial_t B$')
for axi in axs.flat:
axi.set_aspect('equal')
add_colorbar(im1, axs[0, 0])
add_colorbar(im2, axs[0, 1])

curlE_values = np.zeros_like(rho)
valerr = 0
for i in range(1, ni - 1):
for j in range(1, nj - 1):
curlE_values[i, j] = (Ey_values[i + 1, j] - Ey_values[i - 1, j]) / (2 * dx) \
- (Ex_values[i, j + 1] - Ex_values[i, j - 1]) / (2 * dy)

d = np.abs(Bt_values[i, j] + curlE_values[i, j])

if valerr < d:
valerr = d

skip = (slice(None, None, int(N / 20)), slice(None, None, int(N / 20)))
im3 = axs[1, 0].contourf(x, y, curlE_values)
axs[1, 0].quiver(x[skip], y[skip], Ex_values[skip], Ey_values[skip])
add_colorbar(im3, axs[1, 0])
axs[1, 0].set_title(r'curl $\mathbf{E}$')
im4 = axs[1, 1].contourf(x, y, -Bt_values)
axs[1, 1].quiver(x[skip], y[skip], Ex_values[skip], Ey_values[skip])
add_colorbar(im4, axs[1, 1])
im5 = axs[0, 2].contourf(x, y, Ex_values)
im6 = axs[1, 2].contourf(x, y, Ey_values)
add_colorbar(im5, axs[0, 2])
add_colorbar(im6, axs[1, 2])
print('|curlE + d_t B| <= ', valerr)


if __name__ == "__main__":
main()
plt.show()


Loading