Hello,
I have a question about external volume source.
The weak formulation of my problem looks like this
where the highlighted term represents the volume source, which I have available in the form of raw data like this
# x y z source_x source_y source_z
0.0525 0.0375 0 -0.955421 223.385 0
0 0.0375 0 -1541.5 1497.81 0
0.0525 0 0 0 0 0
0 0 0 -1177.21 531.919 0
0.0525 0.075 0 1.06877 297.886 0
0 0.075 0 -494.927 2098.87 0
.
.
.
This data was obtained on the same mesh as is used in fenics.
Here is part of my code implementing this
# mesh
msh, gmsh_cell_tags, gmsh_facet_tags = io.gmshio.read_from_msh("mesh.msh", MPI.COMM_WORLD, gdim=2)
# finite element space
FE_source = basix.ufl.element("Lagrange", msh.basix_cell(), degree=1, shape=(msh.geometry.dim,))
V_source = fem.functionspace(msh, FE_source)
source = fem.Function(V_source)
FE = basix.ufl.element("Lagrange", msh.basix_cell(), degree=FE_SPACE_DEGREE)
V = fem.functionspace(msh, FE)
(u, v) = ufl.TrialFunction(V), ufl.TestFunction(V)
uh = fem.Function(V)
# constants
c = PETSc.ScalarType(343)
dt = 1e-4
t = fem.Constant(msh, 0.0)
T = 0.1
# central scheme
u_nn = fem.Function(V)
u_n = fem.Function(V)
dudtdt = (u - 2 * u_n + u_nn) / dt**2
dudt = (u - u_nn) /(2*dt)
du = (u + u_nn) / 2
# variational problem
F = 1/c**2 * ufl.inner(dudtdt, v) * ufl.dx \
+ 1/c * ufl.inner(dudt, v) * ds(1) \
+ ufl.inner(ufl.grad(du), ufl.grad(v)) * ufl.dx \
+ ufl.dot(source, ufl.grad(v)) * ufl.dx
a, L = ufl.system(F)
# applying volume source
ids = msh.geometry.input_global_indices
dim = msh.topology.dim
data = np.loadtxt("source.raw")
source.x.array[:] = data[ids, 3:3+dim].flatten()
# solving problem
petsc_options = {"ksp_type": "preonly",
"pc_type": "lu",
"pc_factor_mat_solver_type": "mumps"}
problem = dolfinx.fem.petsc.LinearProblem(a, L, u=uh, bcs=[], petsc_options=petsc_options)
vtx_u = io.VTXWriter(msh.comm, "results.bp", u_n, engine="BP4")
while t.value < T:
problem.solve()
u_nn.x.array[:] = u_n.x.array
u_n.x.array[:] = uh.x.array
vtx_u.write(t.value)
t.value += dt
(I have left out a few lines of codes for the sake of clarity and I am aware that the volume source is the same for all the time steps)
I visually checked if the mapping of the volume source is done right in the domain using pyvista and all seems good. But I still wonder if this approach is correct, because I am getting unexpected results and I want to be sure this is implemented correctly, before I go to look for problem elsewhere.