I want to apply Periodic BC in all directions (2D). I followed the method given here.
This works well in serial, but not in parallel. Below is how it looks in parallel (2 procs).
Here is the MWE:
# Import Libraries
from mpi4py import MPI
from dolfinx import mesh, fem, io, log, default_real_type
import numpy as np
import ufl
from basix.ufl import element, mixed_element
from dolfinx.fem.petsc import NonlinearProblem
from dolfinx.nls.petsc import NewtonSolver
from petsc4py import PETSc
from pathlib import Path
from script import create_periodic_mesh
# Create mesh
domain = mesh.create_unit_square(MPI.COMM_WORLD, 100, 100, cell_type=mesh.CellType.triangle)
# Apply Periodic BCs
# Extract the dimension of the mesh
L_min = [domain.comm.allreduce(np.min(domain.geometry.x[:, i]), op=MPI.MIN) for i in range(3)]
L_max = [domain.comm.allreduce(np.max(domain.geometry.x[:, i]), op=MPI.MAX) for i in range(3)]
# Define the periodic boundary condition
def i_x(x):
return np.isclose(x[0], L_min[0])
def i_y(x):
return np.isclose(x[1], L_min[1])
def indicator(x):
return i_x(x) | i_y(x)
def mapping(x):
values = x.copy()
values[0] += i_x(x) * (L_max[0] - L_min[0])
values[1] += i_y(x) * (L_max[1] - L_min[1])
return values
# domain, replaced_vertices, replacement_map = create_periodic_mesh(domain, indicator, mapping)
fdim = domain.topology.dim - 1
domain.topology.create_entities(fdim)
domain, replaced_vertices, replacement_map = create_periodic_mesh(domain, indicator, mapping)
domain.topology.create_entities(fdim)
# Locate facets for boundary conditions and create meshtags
domain.topology.create_connectivity(fdim, fdim + 1)
# Create FunctionSpace
V = fem.functionspace(domain, ("Lagrange", 1))
# Define variational problem
# Define trial and test functions
u = fem.Function(V)
# Initial condition
u.x.array[:] = 0.0
rng = np.random.default_rng(2)
u.interpolate(lambda x: 0.63 + 0.1 * (0.5 - rng.random(x.shape[1])))
u.x.scatter_forward()
results_folder = Path("results")
results_folder.mkdir(exist_ok=True, parents=True)
filename = results_folder / "out_mwe.bp"
with io.VTXWriter(domain.comm, filename, [u], engine="BP4") as vtx:
vtx.write(0)