Skip to content

Commit 1f9e6da

Browse files
committed
Update demo_tnt-elements.py
According to https://github.com/mscroggs/symfem/blob/main/symfem/elements/tnt.py, we need to multiply by the primary bubble function, and take the laplacian. To this end tabulation which also generates the derivatives is used.
1 parent cee28f6 commit 1f9e6da

8 files changed

+281
-124
lines changed

python/demo/demo_axis.py

+38-32
Original file line numberDiff line numberDiff line change
@@ -458,23 +458,25 @@ def create_eps_mu(pml, rho, eps_bkg, mu_bkg):
458458

459459
model = MPI.COMM_WORLD.bcast(model, root=0)
460460
partitioner = dolfinx.cpp.mesh.create_cell_partitioner(dolfinx.mesh.GhostMode.shared_facet)
461-
msh, cell_tags, facet_tags = io.gmshio.model_to_mesh(
462-
model, MPI.COMM_WORLD, 0, gdim=2, partitioner=partitioner
463-
)
461+
mesh_data = io.gmshio.model_to_mesh(model, MPI.COMM_WORLD, 0, gdim=2, partitioner=partitioner)
462+
assert mesh_data.cell_tags is not None, "Cell tags are missing"
463+
assert mesh_data.facet_tags is not None, "Facet tags are missing"
464464

465465
gmsh.finalize()
466466
MPI.COMM_WORLD.barrier()
467467
# -
468468

469469
# Visually check of the mesh and of the subdomains using PyVista:
470470

471-
tdim = msh.topology.dim
471+
tdim = mesh_data.mesh.topology.dim
472472
if have_pyvista:
473-
topology, cell_types, geometry = plot.vtk_mesh(msh, 2)
473+
topology, cell_types, geometry = plot.vtk_mesh(mesh_data.mesh, 2)
474474
grid = pyvista.UnstructuredGrid(topology, cell_types, geometry)
475475
plotter = pyvista.Plotter()
476-
num_local_cells = msh.topology.index_map(tdim).size_local
477-
grid.cell_data["Marker"] = cell_tags.values[cell_tags.indices < num_local_cells]
476+
num_local_cells = mesh_data.mesh.topology.index_map(tdim).size_local
477+
grid.cell_data["Marker"] = mesh_data.cell_tags.values[
478+
mesh_data.cell_tags.indices < num_local_cells
479+
]
478480
grid.set_active_scalars("Marker")
479481
plotter.add_mesh(grid, show_edges=True)
480482
plotter.view_xy()
@@ -489,15 +491,17 @@ def create_eps_mu(pml, rho, eps_bkg, mu_bkg):
489491
# will use Lagrange elements:
490492

491493
degree = 3
492-
curl_el = element("N1curl", msh.basix_cell(), degree, dtype=real_type)
493-
lagr_el = element("Lagrange", msh.basix_cell(), degree, dtype=real_type)
494-
V = fem.functionspace(msh, mixed_element([curl_el, lagr_el]))
494+
curl_el = element("N1curl", mesh_data.mesh.basix_cell(), degree, dtype=real_type)
495+
lagr_el = element("Lagrange", mesh_data.mesh.basix_cell(), degree, dtype=real_type)
496+
V = fem.functionspace(mesh_data.mesh, mixed_element([curl_el, lagr_el]))
495497

496498
# The integration domains of our problem are the following:
497499

498500
# +
499501
# Measures for subdomains
500-
dx = ufl.Measure("dx", msh, subdomain_data=cell_tags, metadata={"quadrature_degree": 5})
502+
dx = ufl.Measure(
503+
"dx", mesh_data.mesh, subdomain_data=mesh_data.cell_tags, metadata={"quadrature_degree": 5}
504+
)
501505
dDom = dx((au_tag, bkg_tag))
502506
dPml = dx(pml_tag)
503507
# -
@@ -509,10 +513,10 @@ def create_eps_mu(pml, rho, eps_bkg, mu_bkg):
509513
eps_bkg = n_bkg**2 # Background relative permittivity
510514
eps_au = -1.0782 + 1j * 5.8089
511515

512-
D = fem.functionspace(msh, ("DG", 0))
516+
D = fem.functionspace(mesh_data.mesh, ("DG", 0))
513517
eps = fem.Function(D)
514-
au_cells = cell_tags.find(au_tag)
515-
bkg_cells = cell_tags.find(bkg_tag)
518+
au_cells = mesh_data.cell_tags.find(au_tag)
519+
bkg_cells = mesh_data.cell_tags.find(bkg_tag)
516520
eps.x.array[au_cells] = np.full_like(au_cells, eps_au, dtype=eps.x.array.dtype)
517521
eps.x.array[bkg_cells] = np.full_like(bkg_cells, eps_bkg, dtype=eps.x.array.dtype)
518522
eps.x.scatter_forward()
@@ -556,7 +560,7 @@ def create_eps_mu(pml, rho, eps_bkg, mu_bkg):
556560
# We now now define `eps_pml` and `mu_pml`:
557561

558562
# +
559-
rho, z = ufl.SpatialCoordinate(msh)
563+
rho, z = ufl.SpatialCoordinate(mesh_data.mesh)
560564
alpha = 5
561565
r = ufl.sqrt(rho**2 + z**2)
562566

@@ -577,26 +581,28 @@ def create_eps_mu(pml, rho, eps_bkg, mu_bkg):
577581
Eh_m = fem.Function(V)
578582
Esh = fem.Function(V)
579583

580-
n = ufl.FacetNormal(msh)
584+
n = ufl.FacetNormal(mesh_data.mesh)
581585
n_3d = ufl.as_vector((n[0], n[1], 0))
582586

583587
# Geometrical cross section of the sphere, for efficiency calculation
584588
gcs = np.pi * radius_sph**2
585589

586590
# Marker functions for the scattering efficiency integral
587591
marker = fem.Function(D)
588-
scatt_facets = facet_tags.find(scatt_tag)
589-
incident_cells = mesh.compute_incident_entities(msh.topology, scatt_facets, tdim - 1, tdim)
590-
msh.topology.create_connectivity(tdim, tdim)
591-
midpoints = mesh.compute_midpoints(msh, tdim, incident_cells)
592+
scatt_facets = mesh_data.facet_tags.find(scatt_tag)
593+
incident_cells = mesh.compute_incident_entities(
594+
mesh_data.mesh.topology, scatt_facets, tdim - 1, tdim
595+
)
596+
mesh_data.mesh.topology.create_connectivity(tdim, tdim)
597+
midpoints = mesh.compute_midpoints(mesh_data.mesh, tdim, incident_cells)
592598
inner_cells = incident_cells[(midpoints[:, 0] ** 2 + midpoints[:, 1] ** 2) < (radius_scatt) ** 2]
593599
marker.x.array[inner_cells] = 1
594600

595601
# Define integration domain for the gold sphere
596602
dAu = dx(au_tag)
597603

598604
# Define integration facet for the scattering efficiency
599-
dS = ufl.Measure("dS", msh, subdomain_data=facet_tags)
605+
dS = ufl.Measure("dS", mesh_data.mesh, subdomain_data=mesh_data.facet_tags)
600606
# -
601607

602608
# We also specify a variable `phi`, corresponding to the $\phi$ angle of
@@ -620,7 +626,7 @@ def create_eps_mu(pml, rho, eps_bkg, mu_bkg):
620626
phi = np.pi / 4
621627

622628
# Initialize phase term
623-
phase = fem.Constant(msh, scalar_type(np.exp(1j * 0 * phi)))
629+
phase = fem.Constant(mesh_data.mesh, scalar_type(np.exp(1j * 0 * phi)))
624630
# -
625631

626632
# We now solve the problem:
@@ -655,7 +661,7 @@ def create_eps_mu(pml, rho, eps_bkg, mu_bkg):
655661
elif sys.hasExternalPackage("superlu_dist"): # type: ignore
656662
mat_factor_backend = "superlu_dist"
657663
else:
658-
if msh.comm.size > 1:
664+
if mesh_data.mesh.comm.size > 1:
659665
raise RuntimeError("This demo requires a parallel linear algebra backend.")
660666
else:
661667
mat_factor_backend = "petsc"
@@ -705,26 +711,26 @@ def create_eps_mu(pml, rho, eps_bkg, mu_bkg):
705711
q_sca_fenics_proc = (
706712
fem.assemble_scalar(fem.form((P("+") + P("-")) * rho * dS(scatt_tag))) / gcs / I0
707713
).real
708-
q_abs_fenics = msh.comm.allreduce(q_abs_fenics_proc, op=MPI.SUM)
709-
q_sca_fenics = msh.comm.allreduce(q_sca_fenics_proc, op=MPI.SUM)
714+
q_abs_fenics = mesh_data.mesh.comm.allreduce(q_abs_fenics_proc, op=MPI.SUM)
715+
q_sca_fenics = mesh_data.mesh.comm.allreduce(q_sca_fenics_proc, op=MPI.SUM)
710716
elif m == m_list[0]: # initialize and add 2 factor
711717
P = 2 * np.pi * ufl.inner(-ufl.cross(Esh_m, ufl.conj(Hsh_m)), n_3d) * marker
712718
Q = 2 * np.pi * eps_au.imag * k0 * (ufl.inner(Eh_m, Eh_m)) / Z0 / n_bkg
713719
q_abs_fenics_proc = (fem.assemble_scalar(fem.form(Q * rho * dAu)) / gcs / I0).real
714720
q_sca_fenics_proc = (
715721
fem.assemble_scalar(fem.form((P("+") + P("-")) * rho * dS(scatt_tag))) / gcs / I0
716722
).real
717-
q_abs_fenics = msh.comm.allreduce(q_abs_fenics_proc, op=MPI.SUM)
718-
q_sca_fenics = msh.comm.allreduce(q_sca_fenics_proc, op=MPI.SUM)
723+
q_abs_fenics = mesh_data.mesh.comm.allreduce(q_abs_fenics_proc, op=MPI.SUM)
724+
q_sca_fenics = mesh_data.mesh.comm.allreduce(q_sca_fenics_proc, op=MPI.SUM)
719725
else: # do not initialize and add 2 factor
720726
P = 2 * np.pi * ufl.inner(-ufl.cross(Esh_m, ufl.conj(Hsh_m)), n_3d) * marker
721727
Q = 2 * np.pi * eps_au.imag * k0 * (ufl.inner(Eh_m, Eh_m)) / Z0 / n_bkg
722728
q_abs_fenics_proc = (fem.assemble_scalar(fem.form(Q * rho * dAu)) / gcs / I0).real
723729
q_sca_fenics_proc = (
724730
fem.assemble_scalar(fem.form((P("+") + P("-")) * rho * dS(scatt_tag))) / gcs / I0
725731
).real
726-
q_abs_fenics += msh.comm.allreduce(q_abs_fenics_proc, op=MPI.SUM)
727-
q_sca_fenics += msh.comm.allreduce(q_sca_fenics_proc, op=MPI.SUM)
732+
q_abs_fenics += mesh_data.mesh.comm.allreduce(q_abs_fenics_proc, op=MPI.SUM)
733+
q_sca_fenics += mesh_data.mesh.comm.allreduce(q_sca_fenics_proc, op=MPI.SUM)
728734

729735
q_ext_fenics = q_abs_fenics + q_sca_fenics
730736
# -
@@ -783,11 +789,11 @@ def create_eps_mu(pml, rho, eps_bkg, mu_bkg):
783789
# assert err_ext < 0.01
784790

785791
if has_vtx:
786-
v_dg_el = element("DG", msh.basix_cell(), degree, shape=(3,), dtype=real_type)
787-
W = fem.functionspace(msh, v_dg_el)
792+
v_dg_el = element("DG", mesh_data.mesh.basix_cell(), degree, shape=(3,), dtype=real_type)
793+
W = fem.functionspace(mesh_data.mesh, v_dg_el)
788794
Es_dg = fem.Function(W)
789795
Es_expr = fem.Expression(Esh, W.element.interpolation_points)
790796
Es_dg.interpolate(Es_expr)
791-
with VTXWriter(msh.comm, "sols/Es.bp", Es_dg) as f:
797+
with VTXWriter(mesh_data.mesh.comm, "sols/Es.bp", Es_dg) as f:
792798
f.write(0.0)
793799
# -

python/demo/demo_gmsh.py

+39-13
Original file line numberDiff line numberDiff line change
@@ -161,19 +161,45 @@ def create_mesh(comm: MPI.Comm, model: gmsh.model, name: str, filename: str, mod
161161
filename: XDMF filename.
162162
mode: XDMF file mode. "w" (write) or "a" (append).
163163
"""
164-
msh, ct, ft = gmshio.model_to_mesh(model, comm, rank=0)
165-
msh.name = name
166-
ct.name = f"{msh.name}_cells"
167-
ft.name = f"{msh.name}_facets"
168-
with XDMFFile(msh.comm, filename, mode) as file:
169-
msh.topology.create_connectivity(2, 3)
170-
file.write_mesh(msh)
171-
file.write_meshtags(
172-
ct, msh.geometry, geometry_xpath=f"/Xdmf/Domain/Grid[@Name='{msh.name}']/Geometry"
173-
)
174-
file.write_meshtags(
175-
ft, msh.geometry, geometry_xpath=f"/Xdmf/Domain/Grid[@Name='{msh.name}']/Geometry"
176-
)
164+
mesh_data = gmshio.model_to_mesh(model, comm, rank=0)
165+
mesh_data.mesh.name = name
166+
if mesh_data.cell_tags is not None:
167+
mesh_data.cell_tags.name = f"{name}_cells"
168+
if mesh_data.facet_tags is not None:
169+
mesh_data.facet_tags.name = f"{name}_facets"
170+
if mesh_data.edge_tags is not None:
171+
mesh_data.edge_tags.name = f"{name}_edges"
172+
if mesh_data.vertex_tags is not None:
173+
mesh_data.vertex_tags.name = f"{name}_vertices"
174+
with XDMFFile(mesh_data.mesh.comm, filename, mode) as file:
175+
mesh_data.mesh.topology.create_connectivity(2, 3)
176+
mesh_data.mesh.topology.create_connectivity(1, 3)
177+
mesh_data.mesh.topology.create_connectivity(0, 3)
178+
file.write_mesh(mesh_data.mesh)
179+
if mesh_data.cell_tags is not None:
180+
file.write_meshtags(
181+
mesh_data.cell_tags,
182+
mesh_data.mesh.geometry,
183+
geometry_xpath=f"/Xdmf/Domain/Grid[@Name='{name}']/Geometry",
184+
)
185+
if mesh_data.facet_tags is not None:
186+
file.write_meshtags(
187+
mesh_data.facet_tags,
188+
mesh_data.mesh.geometry,
189+
geometry_xpath=f"/Xdmf/Domain/Grid[@Name='{name}']/Geometry",
190+
)
191+
if mesh_data.edge_tags is not None:
192+
file.write_meshtags(
193+
mesh_data.edge_tags,
194+
mesh_data.mesh.geometry,
195+
geometry_xpath=f"/Xdmf/Domain/Grid[@Name='{name}']/Geometry",
196+
)
197+
if mesh_data.vertex_tags is not None:
198+
file.write_meshtags(
199+
mesh_data.vertex_tags,
200+
mesh_data.mesh.geometry,
201+
geometry_xpath=f"/Xdmf/Domain/Grid[@Name='{name}']/Geometry",
202+
)
177203

178204

179205
# -

0 commit comments

Comments
 (0)