"near" method is not recognized by DOLFIN

Dear all,
I’m trying to make a fenics code to solve the thermal problem of 2D two-phases material with periodicboundary condition. I want to make a boundary condition that the temperature T = 1 is applied on the top-side of REV, the others sides are zero temperature and I want to calculate the flux at macro. The code is given bellow:

from __future__ import print_function
from dolfin import *
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook

a = 1.         # unit cell width
b = sqrt(3)         # unit cell height

R = 0.2        # inclusion radius
vol = a*b      # unit cell volume
Ro1 = pi*R*R/vol
# we define the unit cell vertices coordinates for later use
vertices = np.array([[0, 0.],
                     [a, 0.],
                     [a, b],
                     [0, b]])
mesh = Mesh()
with XDMFFile("Mesh/t3.xdmf") as in_file:
    in_file.read(mesh)
    mvc_cells = MeshValueCollection("size_t", mesh, mesh.topology().dim())
    in_file.read(mvc_cells, "name_to_read")
subdomains = cpp.mesh.MeshFunctionSizet(mesh, mvc_cells)
plot(subdomains)
plt.show()
# class used to define the periodic boundary map
# class used to define the periodic boundary map
class PeriodicBoundary(SubDomain):
    def __init__(self, vertices, tolerance=DOLFIN_EPS):
        """ vertices stores the coordinates of the 4 unit cell corners"""
        SubDomain.__init__(self, tolerance)
        self.tol = tolerance
        self.vv = vertices
        self.a1 = self.vv[1,:]-self.vv[0,:] # first vector generating periodicity
        self.a2 = self.vv[3,:]-self.vv[0,:] # second vector generating periodicity
        # check if UC vertices form indeed a parallelogram
        assert np.linalg.norm(self.vv[2, :]-self.vv[3, :] - self.a1) <= self.tol
        assert np.linalg.norm(self.vv[2, :]-self.vv[1, :] - self.a2) <= self.tol

    def inside(self, x, on_boundary):
        # return True if on left or bottom boundary AND NOT on one of the
        # bottom-right or top-left vertices
        return bool((near(x[0], 0, self.tol) or
                     near(x[1], 0, self.tol)) and
                     (not ((near(x[0], a, self.tol) and near(x[1], 0, self.tol)) or
                     (near(x[0], 0, self.tol) and near(x[1], b, self.tol)))) and on_boundary)

    def map(self, x, y):
        if near(x[0], a, self.tol) and near(x[1], b, self.tol): # if on top-right corner
            y[0] = x[0] - a
            y[1] = x[1] - b
        elif near(x[0], a, self.tol): # if on right boundary
            y[0] = x[0] - a
            y[1] = x[1] 
        else:   # should be on top boundary
            y[0] = x[0] 
            y[1] = x[1] - b

km = 1
kr = 0.5

material_parameters = [km, kr]
nphases = len(material_parameters)

def Flux(u, i):
    k = material_parameters[i]
    return k*grad(u)

km = 1
kr = 0.5

material_parameters = [km, kr]
nphases = len(material_parameters)

def Flux(u, i):
    k = material_parameters[i]
    return k*grad(u)

# Define the boundary conditions
V = FunctionSpace(mesh, "P", 1, constrained_domain=PeriodicBoundary(vertices))
T = 1
bc_top = DirichletBC(V, T, PeriodicBoundary(vertices), "near(x[1], b, tol)")
bc_other = DirichletBC(V, 0, PeriodicBoundary(vertices), "on_boundary && !near(x[1], b, tol)")

# Define the variational problem
u = TrialFunction(V)
v = TestFunction(V)
f = Constant(0)
A = sum([inner(Flux(u, i), grad(v))*dx(i) for i in range(nphases)])
L = f*v*dx
# Apply the boundary conditions
bcs = [bc_top, bc_other]
# Solve the variational problem
u = Function(V)
solve(A == L, u, bcs)
flux = sum([Flux(u, i)*dx(i) for i in range(nphases)])
print(flux)

when I run this code, there is an error like that:

RuntimeError                              Traceback (most recent call last)
<ipython-input-6-c7b32d48174a> in <module>
      2 V = FunctionSpace(mesh, "P", 1, constrained_domain=PeriodicBoundary(vertices))
      3 T = 1
----> 4 bc_top = DirichletBC(V, T, PeriodicBoundary(vertices), "near(x[1], b, tol)")
      5 bc_other = DirichletBC(V, 0, PeriodicBoundary(vertices), "on_boundary && !near(x[1], b, tol)")
      6 

/usr/local/lib/python3.6/dist-packages/dolfin/fem/dirichletbc.py in __init__(self, *args, **kwargs)
    129             raise RuntimeError("Invalid keyword arguments", kwargs)
    130 
--> 131         super().__init__(*args)

RuntimeError: 

*** -------------------------------------------------------------------------
*** DOLFIN encountered an error. If you are not able to resolve this issue
*** using the information listed below, you can ask for help at
***
***     fenics-support@googlegroups.com
***
*** Remember to include the error message listed below and, if possible,
*** include a *minimal* running example to reproduce the error.
***
*** -------------------------------------------------------------------------
*** Error:   Unable to create Dirichlet boundary condition.
*** Reason:  unknown method ("near(x[1], b, tol)").
*** Where:   This error was encountered inside DirichletBC.cpp.
*** Process: 0
*** 
*** DOLFIN version: 2019.1.0
*** Git changeset:  74d7efe1e84d65e9433fd96c50f1d278fa3e3f3f
*** -------------------------------------------------------------------------

Could you help me to solve this problem please. Thank you very much!

You are sending in markers in two arguments (PeriodicBoundary(vertices) and near(x[1], b, tol)).
The constructor only expects one subdomain description. The fourth argument should be the method, i.e.
one of: “topological”, “geometric”, “pointwise”

Thank you for your reply soon
I have modified the code as following:

from __future__ import print_function
from dolfin import *
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook

a = 1.         # unit cell width
b = sqrt(3)         # unit cell height

R = 0.2        # inclusion radius
vol = a*b      # unit cell volume
Ro1 = pi*R*R/vol
# we define the unit cell vertices coordinates for later use
vertices = np.array([[0, 0.],
                     [a, 0.],
                     [a, b],
                     [0, b]])
mesh = Mesh()
with XDMFFile("Mesh/t3.xdmf") as in_file:
    in_file.read(mesh)
    mvc_cells = MeshValueCollection("size_t", mesh, mesh.topology().dim())
    in_file.read(mvc_cells, "name_to_read")
subdomains = cpp.mesh.MeshFunctionSizet(mesh, mvc_cells)
plot(subdomains)
plt.show()
# class used to define the periodic boundary map
# class used to define the periodic boundary map
class PeriodicBoundary(SubDomain):
    def __init__(self, vertices, tolerance=DOLFIN_EPS):
        """ vertices stores the coordinates of the 4 unit cell corners"""
        SubDomain.__init__(self, tolerance)
        self.tol = tolerance
        self.vv = vertices
        self.a1 = self.vv[1,:]-self.vv[0,:] # first vector generating periodicity
        self.a2 = self.vv[3,:]-self.vv[0,:] # second vector generating periodicity
        # check if UC vertices form indeed a parallelogram
        assert np.linalg.norm(self.vv[2, :]-self.vv[3, :] - self.a1) <= self.tol
        assert np.linalg.norm(self.vv[2, :]-self.vv[1, :] - self.a2) <= self.tol

    def inside(self, x, on_boundary):
        # return True if on left or bottom boundary AND NOT on one of the
        # bottom-right or top-left vertices
        return bool((near(x[0], 0, self.tol) or
                     near(x[1], 0, self.tol)) and
                     (not ((near(x[0], a, self.tol) and near(x[1], 0, self.tol)) or
                     (near(x[0], 0, self.tol) and near(x[1], b, self.tol)))) and on_boundary)

    def map(self, x, y):
        if near(x[0], a, self.tol) and near(x[1], b, self.tol): # if on top-right corner
            y[0] = x[0] - a
            y[1] = x[1] - b
        elif near(x[0], a, self.tol): # if on right boundary
            y[0] = x[0] - a
            y[1] = x[1] 
        else:   # should be on top boundary
            y[0] = x[0] 
            y[1] = x[1] - b

km = 1
kr = 0.5

material_parameters = [km, kr]
nphases = len(material_parameters)

def Flux(u, i):
    k = material_parameters[i]
    return k*grad(u)

km = 1
kr = 0.5

material_parameters = [km, kr]
nphases = len(material_parameters)

def Flux(u, i):
    k = material_parameters[i]
    return k*grad(u)

# Define the boundary conditions
V = FunctionSpace(mesh, "P", 1, constrained_domain=PeriodicBoundary(vertices))
u = TrialFunction(V)
v = TestFunction(V)
T = 1
def lateral_sides(x, on_boundary):
    return (near(x[0], 0) or near(x[0], a)) and on_boundary
def bottom(x, on_boundary):
    return near(x[1], 0) and on_boundary
def top(x, on_boundary):
    return near(x[1], b) and on_boundary

bcT = [DirichletBC(V, Constant(0.), bottom),
       DirichletBC(V, Constant(T), top),
       DirichletBC(V, Constant(0.), lateral_sides)]

# Define the variational problem

f = Constant(0.0)
A = sum([inner(Flux(u, i), grad(v))*dx(i) for i in range(nphases)])
L = f*v*dx

# Solve the variational problem
u = Function(V)
solve(A == L, u, bcT)
flux = sum([Flux(u, i)*dx(i) for i in range(nphases)])
print(flux)

When I run, there is an error bellow:

RuntimeError                              Traceback (most recent call last)
<ipython-input-2-d8be57cc5483> in <module>
    101 # Solve the variational problem
    102 u = Function(V)
--> 103 solve(A == L, u, bcT)
    104 flux = sum([Flux(u, i)*dx(i) for i in range(nphases)])
    105 print(flux)

/usr/local/lib/python3.6/dist-packages/dolfin/fem/solving.py in solve(*args, **kwargs)
    218     # tolerance)
    219     elif isinstance(args[0], ufl.classes.Equation):
--> 220         _solve_varproblem(*args, **kwargs)
    221 
    222     # Default case, just call the wrapped C++ solve function

/usr/local/lib/python3.6/dist-packages/dolfin/fem/solving.py in _solve_varproblem(*args, **kwargs)
    245         solver = LinearVariationalSolver(problem)
    246         solver.parameters.update(solver_parameters)
--> 247         solver.solve()
    248 
    249     # Solve nonlinear variational problem

RuntimeError: 

*** -------------------------------------------------------------------------
*** DOLFIN encountered an error. If you are not able to resolve this issue
*** using the information listed below, you can ask for help at
***
***     fenics-support@googlegroups.com
***
*** Remember to include the error message listed below and, if possible,
*** include a *minimal* running example to reproduce the error.
***
*** -------------------------------------------------------------------------
*** Error:   Unable to set given (local) rows to identity matrix.
*** Reason:  some diagonal elements not preallocated (try assembler option keep_diagonal).
*** Where:   This error was encountered inside PETScMatrix.cpp.
*** Process: 0
*** 
*** DOLFIN version: 2019.1.0
*** Git changeset:  74d7efe1e84d65e9433fd96c50f1d278fa3e3f3f
*** -------------------------------------------------------------------------

​```
what does it mean and how to solve this problem
thank you in advance for your help

I would suggest you try to simplify your problem, i.e., replace solve with assemble(A), does that still produce the error? If so, remove everything related to bcs (as they are not used in the matrix assembly).

I modify my code as following:


from __future__ import print_function
from dolfin import *
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook

a = 1.         # unit cell width
b = sqrt(3)         # unit cell height

R = 0.2        # inclusion radius
vol = a*b      # unit cell volume
Ro1 = pi*R*R/vol
# we define the unit cell vertices coordinates for later use
vertices = np.array([[0, 0.],
                     [a, 0.],
                     [a, b],
                     [0, b]])
mesh = Mesh()
with XDMFFile("Mesh/t3.xdmf") as in_file:
    in_file.read(mesh)
    mvc_cells = MeshValueCollection("size_t", mesh, mesh.topology().dim())
    in_file.read(mvc_cells, "name_to_read")
subdomains = cpp.mesh.MeshFunctionSizet(mesh, mvc_cells)
plot(subdomains)
plt.show()

# class used to define the periodic boundary map
# class used to define the periodic boundary map
class PeriodicBoundary(SubDomain):
    def __init__(self, vertices, tolerance=DOLFIN_EPS):
        """ vertices stores the coordinates of the 4 unit cell corners"""
        SubDomain.__init__(self, tolerance)
        self.tol = tolerance
        self.vv = vertices
        self.a1 = self.vv[1,:]-self.vv[0,:] # first vector generating periodicity
        self.a2 = self.vv[3,:]-self.vv[0,:] # second vector generating periodicity
        # check if UC vertices form indeed a parallelogram
        assert np.linalg.norm(self.vv[2, :]-self.vv[3, :] - self.a1) <= self.tol
        assert np.linalg.norm(self.vv[2, :]-self.vv[1, :] - self.a2) <= self.tol

    def inside(self, x, on_boundary):
        # return True if on left or bottom boundary AND NOT on one of the
        # bottom-right or top-left vertices
        return bool((near(x[0], 0, self.tol) or
                     near(x[1], 0, self.tol)) and
                     (not ((near(x[0], a, self.tol) and near(x[1], 0, self.tol)) or
                     (near(x[0], 0, self.tol) and near(x[1], b, self.tol)))) and on_boundary)

    def map(self, x, y):
        if near(x[0], a, self.tol) and near(x[1], b, self.tol): # if on top-right corner
            y[0] = x[0] - a
            y[1] = x[1] - b
        elif near(x[0], a, self.tol): # if on right boundary
            y[0] = x[0] - a
            y[1] = x[1] 
        else:   # should be on top boundary
            y[0] = x[0] 
            y[1] = x[1] - b

km = 1
kr = 0.5

material_parameters = [km, kr]
nphases = len(material_parameters)

def Flux(u, i):
    k = material_parameters[i]
    return k*grad(u)

# Define the boundary conditions
V = FunctionSpace(mesh, "P", 1, constrained_domain=PeriodicBoundary(vertices))
u = TrialFunction(V)
v = TestFunction(V)
u = Function(V)
dx = Measure('dx')(subdomain_data=subdomains)
# Define the variational problem

f = Constant(0.0)
A = sum([inner(Flux(u, i), grad(v))*dx(i) for i in range(nphases)])
L = f*v*dx

def macro_temp(i):
    """returns the macroscopic strain for the 2 elementary load cases"""
    T_Voigt = np.zeros((2,))
    T_Voigt[i] = 1
    return as_vector([T_Voigt[0], T_Voigt[1]])

def Flux2Voigt(s):
    return as_vector([s[0], s[1]])
T = Constant((0, 0))

for (j, case) in enumerate(["Txx", "Tyy"]):
    print("Solving {} case...".format(case))
    T.assign(Constant(macro_temp(j)))
    solve(a == L, u, [])
    #(v, lamb) = split(w)
    
    Flux = np.zeros((2,))
    for k in range(2):
        Flux[k] = assemble(sum([Flux2Voigt(Flux(u, i))[k]*dx(i) for i in range(nphases)]))/vol

print(Flux)




there is an error like that


Solving Txx case...
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-c5b12c10efe3> in <module>
     98     Flux = np.zeros((2,))
     99     for k in range(2):
--> 100         Flux[k] = assemble(sum([Flux2Voigt(Flux(u, i))[k]*dx(i) for i in range(nphases)]))/vol
    101 
    102 print(Flux)

<ipython-input-11-c5b12c10efe3> in <listcomp>(.0)
     98     Flux = np.zeros((2,))
     99     for k in range(2):
--> 100         Flux[k] = assemble(sum([Flux2Voigt(Flux(u, i))[k]*dx(i) for i in range(nphases)]))/vol
    101 
    102 print(Flux)

TypeError: 'numpy.ndarray' object is not callable

What is the problem and how to fix my code, please help me

You are redefining the Flux class as a numpy array here, thus

throws the error you are describing. Please spend some time looking at your error message and debug your code (for instance with from IPython import embed;embed() inside your code, to inspect variables and classes.

thank you for your comment
Now I modified my code as following:


from __future__ import print_function
from dolfin import *
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook

a = 1.         # unit cell width
b = sqrt(3)         # unit cell height

R = 0.2        # inclusion radius
vol = a*b      # unit cell volume
Ro1 = pi*R*R/vol
# we define the unit cell vertices coordinates for later use
vertices = np.array([[0, 0.],
                     [a, 0.],
                     [a, b],
                     [0, b]])
mesh = Mesh()
with XDMFFile("Mesh/t3.xdmf") as in_file:
    in_file.read(mesh)
    mvc_cells = MeshValueCollection("size_t", mesh, mesh.topology().dim())
    in_file.read(mvc_cells, "name_to_read")
subdomains = cpp.mesh.MeshFunctionSizet(mesh, mvc_cells)

# class used to define the periodic boundary map
# class used to define the periodic boundary map
class PeriodicBoundary(SubDomain):
    def __init__(self, vertices, tolerance=DOLFIN_EPS):
        """ vertices stores the coordinates of the 4 unit cell corners"""
        SubDomain.__init__(self, tolerance)
        self.tol = tolerance
        self.vv = vertices
        self.a1 = self.vv[1,:]-self.vv[0,:] # first vector generating periodicity
        self.a2 = self.vv[3,:]-self.vv[0,:] # second vector generating periodicity
        # check if UC vertices form indeed a parallelogram
        assert np.linalg.norm(self.vv[2, :]-self.vv[3, :] - self.a1) <= self.tol
        assert np.linalg.norm(self.vv[2, :]-self.vv[1, :] - self.a2) <= self.tol

    def inside(self, x, on_boundary):
        # return True if on left or bottom boundary AND NOT on one of the
        # bottom-right or top-left vertices
        return bool((near(x[0], 0, self.tol) or
                     near(x[1], 0, self.tol)) and
                     (not ((near(x[0], a, self.tol) and near(x[1], 0, self.tol)) or
                     (near(x[0], 0, self.tol) and near(x[1], b, self.tol)))) and on_boundary)

    def map(self, x, y):
        if near(x[0], a, self.tol) and near(x[1], b, self.tol): # if on top-right corner
            y[0] = x[0] - a
            y[1] = x[1] - b
        elif near(x[0], a, self.tol): # if on right boundary
            y[0] = x[0] - a
            y[1] = x[1] 
        else:   # should be on top boundary
            y[0] = x[0] 
            y[1] = x[1] - b

Cm = 1 #thermal conductivity of matrice
Cr = 0.5 #thermal conductivity of inclusion
#delta_T = 1 #macro temperature
material_parameters = [Cm, Cr]
nphases = len(material_parameters)

def get_flux(t, i):
    C = material_parameters[i]
    return C*grad(t)



Ve = FiniteElement("CG", mesh.ufl_cell(), 2)
W = FunctionSpace(mesh, Ve)

T = TrialFunction(W)
v = TestFunction(W)

dx = Measure('dx')(subdomain_data=subdomains)
#F = Cm*inner(grad(T), grad(v))*dx(0) + Cr*inner(grad(T), grad(v))*dx(1) - dot(v, Constant((0, 0))*dx
F = inner(Cm*grad(T), grad(v))*dx(0) + inner(Cr*grad(T), grad(v))*dx(1) + dot(v, Constant(0))*dx
a, L = lhs(F), rhs(F)

# Giải phương trình
t = Function(W)

def macro_temp(i):
    """returns the macroscopic strain for the 2 elementary load cases"""
    delta_T_Voigt = np.zeros((2,))
    delta_T_Voigt[i] = 1
    return as_vector([delta_T_Voigt[0], delta_T_Voigt[1]])

def Flux2Voigt(s):
    return as_vector([s[0], s[1]])
#grad_T = Constant((0, 0))
Chom = np.zeros((2,2))
for (j, case) in enumerate(["Txx", "Tyy"]):
    print("Solving {} case...".format(case))
    grad_T = Constant(macro_temp(j))
    solve(a == L, t, [])
    
    flux_values = np.zeros((2,))
    for k in range(2):
        flux_values[k] = assemble(sum([Flux2Voigt(get_flux(t, i))[k]*dx(i) for i in range(nphases)]))/vol
        #print(flux_values)
    Chom[j, :] = flux_values

        
print(np.array_str(Chom, precision=2))
Ceff = Chom[0, 0]
print(Ceff)

However, the program give the zero value for the effective thermal conductivity. I couldn’t found the reason for this problem. Could you help me please!


Solving Txx case...
Solving Tyy case...
[[0. 0.]
 [0. 0.]]
0.0

I cannot help you any further, as you have not supplied the mesh you are working on.
Again, I would like to re-iterate

as you should be able to reproduce a similar result on a unit-cube or unit square, and you still have alot of commented out code here.

Thank you for your comment, I spent many time to find out the problem in my program but I couldn’t find it.
for the mesh, firstly, I used fenicsx to creat gmesh by following code and then write to “t3.msh” file:


import gmsh
import sys
import numpy as np
import matplotlib.pyplot as plt

from mpi4py import MPI
from petsc4py import PETSc

from dolfinx.cpp.mesh import to_type, cell_entity_type
from dolfinx.fem import (Constant, Function, FunctionSpace, 
                         assemble_scalar, dirichletbc, form, locate_dofs_topological, set_bc)
from dolfinx.fem.petsc import (apply_lifting, assemble_matrix, assemble_vector, 
                               create_vector, create_matrix, set_bc)
from dolfinx.graph import create_adjacencylist
from dolfinx.geometry import BoundingBoxTree, compute_collisions, compute_colliding_cells
from dolfinx.io import (VTXWriter, distribute_entity_data, gmshio)
from dolfinx.mesh import create_mesh, meshtags_from_entities

from ufl import (FacetNormal, FiniteElement, Identity, Measure, TestFunction, TrialFunction, VectorElement,
                 as_vector, div, dot, ds, dx, inner, lhs, grad, nabla_grad, rhs, sym)
gmsh.initialize()
# rectangle points:
from math import sqrt
a = 1.
b = sqrt(3.)
R = 0.2
lc = 0.02
p1 = gmsh.model.geo.add_point(0., 0., 0., lc)
p2 = gmsh.model.geo.add_point(a, 0., 0., lc)
p3 = gmsh.model.geo.add_point(a, b, 0., lc)
p4 = gmsh.model.geo.add_point(0., b, 0., lc)
p5 = gmsh.model.geo.add_point(a/2, b/2, 0., lc)
p6 = gmsh.model.geo.add_point(R, 0., 0., lc)
p7 = gmsh.model.geo.add_point(a-R, 0., 0., lc)
p8 = gmsh.model.geo.add_point(a, R, 0., lc)
p9 = gmsh.model.geo.add_point(a, b-R, 0., lc)
p10 = gmsh.model.geo.add_point(a-R, b, 0., lc)
p11 = gmsh.model.geo.add_point(R, b, 0., lc)
p12 = gmsh.model.geo.add_point(0., b-R, 0., lc)
p13 = gmsh.model.geo.add_point(0., R, 0., lc)
p14 = gmsh.model.geo.add_point(a/2+R, b/2, 0., lc)
p15 = gmsh.model.geo.add_point(a/2, b/2+R, 0., lc)
p16 = gmsh.model.geo.add_point(a/2-R, b/2, 0., lc)
p17 = gmsh.model.geo.add_point(a/2, b/2-R, 0., lc)
# Edge of rectangle:
l1 = gmsh.model.geo.add_line(p1, p6)
l2 = gmsh.model.geo.add_line(p6, p7)
l3 = gmsh.model.geo.add_line(p7, p2)
l4 = gmsh.model.geo.add_line(p2, p8)
l5 = gmsh.model.geo.add_line(p8, p9)
l6 = gmsh.model.geo.add_line(p9, p3)
l7 = gmsh.model.geo.add_line(p3, p10)
l8 = gmsh.model.geo.add_line(p10, p11)
l9 = gmsh.model.geo.add_line(p11, p4)
l10 = gmsh.model.geo.add_line(p4, p12)
l11 = gmsh.model.geo.add_line(p12, p13)
l12 = gmsh.model.geo.add_line(p13, p1)
# Arc lines:

c13 = gmsh.model.geo.addCircleArc(p6, p1, p13)
c14 = gmsh.model.geo.addCircleArc(p8, p2, p7)
c15 = gmsh.model.geo.addCircleArc(p10, p3, p9)
c16 = gmsh.model.geo.addCircleArc(p12, p4, p11)
c17 = gmsh.model.geo.addCircleArc(p14, p5, p15)
c18 = gmsh.model.geo.addCircleArc(p15, p5, p16)
c19 = gmsh.model.geo.addCircleArc(p16, p5, p17)
c20 = gmsh.model.geo.addCircleArc(p17, p5, p14)

# Creat loops of faces:
face1 = gmsh.model.geo.add_curve_loop([l1, c13, l12])
face2 = gmsh.model.geo.add_curve_loop([l3, l4, c14])
face3 = gmsh.model.geo.add_curve_loop([l7, c15, l6])
face4 = gmsh.model.geo.add_curve_loop([l10, c16, l9])
face5 = gmsh.model.geo.add_curve_loop([c19, c20, c17, c18])
face6 = gmsh.model.geo.add_curve_loop([l11, -c13, l2, -c14, l5, -c15, l8, -c16])
# creat surfaces:
plsf1 = gmsh.model.geo.add_plane_surface([face1])
plsf2 = gmsh.model.geo.add_plane_surface([face2])
plsf3 = gmsh.model.geo.add_plane_surface([face3])
plsf4 = gmsh.model.geo.add_plane_surface([face4])
plsf5 = gmsh.model.geo.add_plane_surface([face5])
plsf6 = gmsh.model.geo.add_plane_surface([face5, face6])
gmsh.model.geo.synchronize()

gmsh.model.addPhysicalGroup(1, [l1, l2, l3])
gmsh.model.addPhysicalGroup(1, [l4, l5, l6])
gmsh.model.addPhysicalGroup(1, [l7, l8, l9])
gmsh.model.addPhysicalGroup(1, [l10, l11, l12])
gmsh.model.addPhysicalGroup(2, [plsf1, plsf2, plsf3, plsf4, plsf5], 1)
gmsh.model.addPhysicalGroup(2, [plsf6], 0)

trsf1 = [1,0,0,a,  0,1,0,0,  0,0,1,0,  0,0,0,1]
gmsh.model.mesh.setPeriodic(1, [l4, l5, l6], [l12, l11, l10], trsf1)
trsf2 = [1,0,0,0,  0,1,0,b,  0,0,1,0,  0,0,0,1]
gmsh.model.mesh.setPeriodic(1, [l9, l8, l7], [l1, l2, l3], trsf2)

gmsh.model.mesh.generate(2)
gmsh.write("t3.msh")
mesh, cell_tags, facet_tags = gmshio.model_to_mesh(gmsh.model, MPI.COMM_WORLD, 0,gdim=2)
gmsh.finalize()

Then it was convert into .xdmf file to use in the principal code (this mesh was successfully used in the mechanical problem)

Please help me!
Best regards!

Could you help me please to find out the problem of my code?
waiting for your response!
best regards!

Please help me so solve the problem