Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions psydac/api/discretization.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,12 @@ def discretize(a, *args, **kwargs):

if isinstance(a, sym_BasicForm):
if isinstance(a, (sym_Norm, sym_SemiNorm)):
if hasattr(a._space, 'codomain_type') and a._space.codomain_type == 'complex':
print('WARNING (56436574):',
'discretization of norms is not correctly tested yet for complex fields: see https://github.com/campospinto/psydac_dev/issues/12.')
if isinstance(a, sym_SemiNorm):
print('WARNING (87676545):',
'discretization of semi-norms is not correctly tested yet: see https://github.com/campospinto/psydac_dev/issues/12.')
kernel_expr = TerminalExpr(a, domain)
if not mapping is None:
kernel_expr = tuple(LogicalExpr(i, domain) for i in kernel_expr)
Expand Down
166 changes: 107 additions & 59 deletions psydac/api/tests/test_2d_complex.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# -*- coding: UTF-8 -*-
import os

from collections import OrderedDict

from mpi4py import MPI
import pytest
import numpy as np
from sympy import pi, cos, sin, symbols, conjugate, exp
from sympy import Tuple, Matrix
from sympy import lambdify

from sympde.calculus import grad, dot, cross, curl
from sympde.calculus import minus, plus
Expand Down Expand Up @@ -224,7 +227,7 @@ def run_helmholtz_2d(solution, kappa, e_w_0, dx_e_w_0, domain, ncells=None, degr
equation = find(u, forall=v, lhs=a(u,v), rhs=l(v))

l2norm = Norm(error, domain, kind='l2')
h1norm = SemiNorm(error, domain, kind='h1')
h1norm = SemiNorm(error, domain, kind='h1') # [MCP 19.07.2024] This is probably wrong: see https://github.com/campospinto/psydac_dev/issues/12

#+++++++++++++++++++++++++++++++
# 2. Discretization
Expand All @@ -244,7 +247,7 @@ def run_helmholtz_2d(solution, kappa, e_w_0, dx_e_w_0, domain, ncells=None, degr
l2_error = l2norm_h.assemble(u=uh)
h1_error = h1norm_h.assemble(u=uh)

return l2_error, h1_error
return l2_error, h1_error, uh

#==============================================================================
def run_maxwell_2d(uex, f, alpha, domain, *, ncells=None, degree=None, filename=None, comm=None):
Expand Down Expand Up @@ -400,7 +403,7 @@ def test_complex_poisson_2d_multipatch_mapping():
assert abs(h1_error - expected_h1_error) < 1e-7


def test_complex_helmholtz_2d():
def test_complex_helmholtz_2d(plot_sol=False):
# This test solves the homogeneous Helmhotz equation with impedance BC.
# In particular, we impose an incoming wave from the left and absorbing boundary conditions at the right.
# Along y, periodic boundary conditions are considered.
Expand All @@ -412,13 +415,50 @@ def test_complex_helmholtz_2d():
e_w_0 = sin(kappa * y) # value of incoming wave at x=0, forall y
dx_e_w_0 = 1j*kappa*sin(kappa * y) # derivative wrt. x of incoming wave at x=0, forall y

l2_error, h1_error = run_helmholtz_2d(solution, kappa, e_w_0, dx_e_w_0, domain, ncells=[2**2,2**2], degree=[2,2])
l2_error, h1_error, uh = run_helmholtz_2d(solution, kappa, e_w_0, dx_e_w_0, domain, ncells=[2**2,2**2], degree=[2,2])

expected_l2_error = 0.01540947560953227
expected_h1_error = 0.19040207344639598
# commented because semi-norms of complex-fields are not working properly for now: see https://github.com/campospinto/psydac_dev/issues/12
expected_h1_error = 'NOT IMPLEMENTED' #

print(f'errors: l2 = {l2_error}, h1 = {h1_error} (THIS IS PROBABLY WRONG)')
print(f'expected errors: l2 = {expected_l2_error}, h1 = {expected_h1_error}')

if plot_sol:
from psydac.feec.multipatch.plotting_utilities import get_plotting_grid, get_grid_vals
from psydac.feec.multipatch.plotting_utilities import get_patch_knots_gridlines, my_small_plot
from psydac.feec.pull_push import pull_2d_h1

Id_mapping = IdentityMapping('M', 2)
mappings = OrderedDict([(domain, Id_mapping)])
mappings_list = [m for m in mappings.values()]
call_mappings_list = [m.get_callable_mapping() for m in mappings_list]

uh = [uh] # single-patch cast as multi-patch solution

u = lambdify(domain.coordinates, solution)
u_log = [pull_2d_h1(u, f) for f in call_mappings_list]

etas, xx, yy = get_plotting_grid(mappings, N=20)
grid_vals_h1 = lambda v: get_grid_vals(v, etas, mappings_list, space_kind='h1')

uh_vals = grid_vals_h1(uh)
u_vals = grid_vals_h1(u_log)

u_err = [(u1 - u2) for u1, u2 in zip(u_vals, uh_vals)]

my_small_plot(
title=r'approximation of solution $u$',
vals=[u_vals, uh_vals, u_err],
titles=[r'$u^{ex}(x,y)$', r'$u^h(x,y)$', r'$|(u^{ex}-u^h)(x,y)|$'],
xx=xx,
yy=yy,
gridlines_x1=None,
gridlines_x2=None,
)

assert( abs(l2_error - expected_l2_error) < 1.e-7)
assert( abs(h1_error - expected_h1_error) < 1.e-7)
# assert( abs(h1_error - expected_h1_error) < 1.e-7)

def test_maxwell_2d_2_patch_dirichlet_2():
# This test solve the maxwell problem with non-homogeneous dirichlet condition with penalization on the border of the exact solution
Expand Down Expand Up @@ -487,59 +527,67 @@ def teardown_function():

if __name__ == '__main__':

from collections import OrderedDict

from sympy import lambdify

from psydac.feec.multipatch.plotting_utilities import get_plotting_grid, get_grid_vals
from psydac.feec.multipatch.plotting_utilities import get_patch_knots_gridlines, my_small_plot
from psydac.api.tests.build_domain import build_pretzel
from psydac.feec.pull_push import pull_2d_hcurl
# we do some visual verifications...

domain = build_pretzel()
x,y = domain.coordinates
verify = 'helmholtz'

omega = 1.5
alpha = -omega**2
Eex = Tuple(sin(pi*y), sin(pi*x)*cos(pi*y))
f = Tuple(alpha*sin(pi*y) - pi**2*sin(pi*y)*cos(pi*x) + pi**2*sin(pi*y),
alpha*sin(pi*x)*cos(pi*y) + pi**2*sin(pi*x)*cos(pi*y))
if verify == 'helmholtz':
test_complex_helmholtz_2d(plot_sol=True)

l2_error, Eh = run_maxwell_2d(Eex, f, alpha, domain, ncells=[2**2, 2**2], degree=[2,2])

mappings = OrderedDict([(P.logical_domain, P.mapping) for P in domain.interior])
mappings_list = list(mappings.values())
mappings_list = [mapping.get_callable_mapping() for mapping in mappings_list]

Eex_x = lambdify(domain.coordinates, Eex[0])
Eex_y = lambdify(domain.coordinates, Eex[1])
Eex_log = [pull_2d_hcurl([Eex_x,Eex_y], f) for f in mappings_list]

etas, xx, yy = get_plotting_grid(mappings, N=20)
grid_vals_hcurl = lambda v: get_grid_vals(v, etas, mappings_list, space_kind='hcurl')

Eh_x_vals, Eh_y_vals = grid_vals_hcurl(Eh)
E_x_vals, E_y_vals = grid_vals_hcurl(Eex_log)

E_x_err = [(u1 - u2) for u1, u2 in zip(E_x_vals, Eh_x_vals)]
E_y_err = [(u1 - u2) for u1, u2 in zip(E_y_vals, Eh_y_vals)]

my_small_plot(
title=r'approximation of solution $u$, $x$ component',
vals=[E_x_vals, Eh_x_vals, E_x_err],
titles=[r'$u^{ex}_x(x,y)$', r'$u^h_x(x,y)$', r'$|(u^{ex}-u^h)_x(x,y)|$'],
xx=xx,
yy=yy,
gridlines_x1=None,
gridlines_x2=None,
)

my_small_plot(
title=r'approximation of solution $u$, $y$ component',
vals=[E_y_vals, Eh_y_vals, E_y_err],
titles=[r'$u^{ex}_y(x,y)$', r'$u^h_y(x,y)$', r'$|(u^{ex}-u^h)_y(x,y)|$'],
xx=xx,
yy=yy,
gridlines_x1=None,
gridlines_x2=None,
)
else:
from collections import OrderedDict

from sympy import lambdify

from psydac.feec.multipatch.plotting_utilities import get_plotting_grid, get_grid_vals
from psydac.feec.multipatch.plotting_utilities import get_patch_knots_gridlines, my_small_plot
from psydac.api.tests.build_domain import build_pretzel
from psydac.feec.pull_push import pull_2d_hcurl

domain = build_pretzel()
x,y = domain.coordinates

omega = 1.5
alpha = -omega**2
Eex = Tuple(sin(pi*y), sin(pi*x)*cos(pi*y))
f = Tuple(alpha*sin(pi*y) - pi**2*sin(pi*y)*cos(pi*x) + pi**2*sin(pi*y),
alpha*sin(pi*x)*cos(pi*y) + pi**2*sin(pi*x)*cos(pi*y))

l2_error, Eh = run_maxwell_2d(Eex, f, alpha, domain, ncells=[2**2, 2**2], degree=[2,2])

mappings = OrderedDict([(P.logical_domain, P.mapping) for P in domain.interior])
mappings_list = list(mappings.values())
call_mappings_list = [m.get_callable_mapping() for m in mappings_list]

Eex_x = lambdify(domain.coordinates, Eex[0])
Eex_y = lambdify(domain.coordinates, Eex[1])
Eex_log = [pull_2d_hcurl([Eex_x,Eex_y], f) for f in call_mappings_list]

etas, xx, yy = get_plotting_grid(mappings, N=20)
grid_vals_hcurl = lambda v: get_grid_vals(v, etas, mappings_list, space_kind='hcurl')

Eh_x_vals, Eh_y_vals = grid_vals_hcurl(Eh)
E_x_vals, E_y_vals = grid_vals_hcurl(Eex_log)

E_x_err = [(u1 - u2) for u1, u2 in zip(E_x_vals, Eh_x_vals)]
E_y_err = [(u1 - u2) for u1, u2 in zip(E_y_vals, Eh_y_vals)]

my_small_plot(
title=r'approximation of solution $u$, $x$ component',
vals=[E_x_vals, Eh_x_vals, E_x_err],
titles=[r'$u^{ex}_x(x,y)$', r'$u^h_x(x,y)$', r'$|(u^{ex}-u^h)_x(x,y)|$'],
xx=xx,
yy=yy,
gridlines_x1=None,
gridlines_x2=None,
)

my_small_plot(
title=r'approximation of solution $u$, $y$ component',
vals=[E_y_vals, Eh_y_vals, E_y_err],
titles=[r'$u^{ex}_y(x,y)$', r'$u^h_y(x,y)$', r'$|(u^{ex}-u^h)_y(x,y)|$'],
xx=xx,
yy=yy,
gridlines_x1=None,
gridlines_x2=None,
)
Loading