I am trying to calculate electric field and charge density from poisson equation using a projection function. The code gives NaN for meshes with scale =1E-6 (this is the actual scale of the problem), but works for scale =1. I am able to solve poission equation for both meshes, but projection does not seem to work.
from mpi4py import MPI
from dolfinx import mesh
import ufo
import numpy,gmsh
from dolfinx.io import gmshio, XDMFFile
from dolfinx import fem
from dolfinx.fem import functionspace
from dolfinx import default_scalar_type
from dolfinx.fem.petsc import LinearProblem
import pyvista
scale =1E-6
L = 600.0*scale #Length
W = 200.0*scale #Width
H=50*scale # Thickness
model_rank = 0
mesh_comm = MPI.COMM_WORLD
gdim=3
def simpleproject(e,V,bc=[]):
"""Simple Projection function"""
dx = ufl.dx(V.mesh)
# Define variational problem for projection
v = ufl.TrialFunction(V)
w = ufl.TestFunction(V)
sol=fem.Function(V)
a = ufl.dot(v, w) * dx
L = ufl.dot(ufl.grad(e), w) * dx
problem = LinearProblem(a,L,bc,petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
sol=problem.solve()
return sol
gmsh.initialize()
gmsh.model.add("Structure")
box=gmsh.model.occ.addBox(0,0,0,L,W,H,1)
gmsh.model.occ.synchronize()
gmsh.model.addPhysicalGroup(gdim,[3],tag=1)
boundaries = gmsh.model.getBoundary([(gdim,3)], oriented=False)
boundary_ids = [b[1] for b in boundaries]
gmsh.model.addPhysicalGroup(gdim-1,boundary_ids,tag=20)
gmsh.model.mesh.generate(gdim)
domain,_ ,_ = gmshio.model_to_mesh(gmsh.model, mesh_comm, model_rank, gdim=gdim)
gmsh.finalize()
tdim=domain.topology.dim
fdim=tdim-1
p=1
V = functionspace(domain, ("Lagrange", p))
V2= functionspace(domain, ("Lagrange", p,(tdim,)))
uD = fem.Function(V)
uD.interpolate(lambda x: 1 + x[0]**2 + 2 * x[1]**2)
Efield=simpleproject(-uD,V2)
Ez=Efield.sub(gdim-1).collapse()
from dolfinx import plot
u_topology, u_cell_types, u_geometry = plot.vtk_mesh(V)
u_grid = pyvista.UnstructuredGrid(u_topology, u_cell_types, u_geometry)
u_grid.point_data["u"] = Ez.x.array.realu_grid.set_active_scalars("u")
u_plotter = pyvista.Plotter()
u_plotter.add_mesh(u_grid, show_edges=True)
u_plotter.view_xy()
if not pyvista.OFF_SCREEN:
u_plotter.show()