Assemble only on the vertices

Hi,

I’m trying to assemble a variational form only over the vertices. I think that the integration measure dP could do the job, however, I recieve an error message when using it. Here is a minimal working example with the output of the code and the output I would like to have. Is there a way of doing that? or maybe a workaround?. I was also wondering if its possible to modify the Petsc Matrix assembled and insert this last line “manually”.

from fenics import *

N = 4

mesh = UnitIntervalMesh(N)
V = FiniteElement("CG", mesh.ufl_cell(), 1)
R = FiniteElement('R', mesh.ufl_cell(), 0)
W = FunctionSpace(mesh, MixedElement([V, R]))

u, c = TrialFunction(W)
v, d = TestFunctions(W)

w = Function(W)
u_w, c_w = split(w)

for i in range(N+2):
    w.vector()[i] = i+1

#a = d*u_w*u*dP + d*c_w*c*dP Doesn't work!
a = d*u_w*u*dx + d*c_w*c*dx

A = assemble(a)

print(A.array())

Output:

[[0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.        ]
 [0.16666667 0.5        0.75       1.         0.58333333 6.        ]]

What a would like:

[[0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.        ]
 [1.         2.         3.         4.         5.         6.        ]]

What do you mean by assemble only over the vertices? Do you mean that the assembly should be a point evaluation at each vertex?

I do not think this is supported with Real function spaces, as the error message states (Please attach that next time)

Traceback (most recent call last):
  File "/root/shared/mwe123.py", line 23, in <module>
    A = assemble(a)
  File "/usr/lib/python3/dist-packages/dolfin/fem/assembling.py", line 217, in assemble
    assembler.assemble(tensor, dolfin_form)
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 assemble form over vertices.
*** Reason:  Expecting test and trial spaces to only have dofs on vertices for point integrals.
*** Where:   This error was encountered inside Assembler.cpp.
*** Process: 0
*** 
*** DOLFIN version: 2019.2.0.dev0
*** Git changeset:  bd54183ed40f3597fe1187499c79c54eb4759f6d
*** -------------------------------------------------------------------------

You can see that it works with Lagrange 1 with:

from fenics import *

N = 4

mesh = UnitIntervalMesh(N)
V = FiniteElement("CG", mesh.ufl_cell(), 1)
W = FunctionSpace(mesh, V)

u = TrialFunction(W)
v = TestFunction(W)

w = Function(W)

for i in range(N+1):
    w.vector()[i] = i+1

dxP = dx(metadata={"quadrature_scheme":"vertex"}) 
a = w*u*v*dP

A = assemble(a)

print(A.array())

yielding

[[1. 0. 0. 0. 0.]
 [0. 2. 0. 0. 0.]
 [0. 0. 3. 0. 0.]
 [0. 0. 0. 4. 0.]
 [0. 0. 0. 0. 5.]]

while

from fenics import *

N = 4

mesh = UnitIntervalMesh(N)
V = FiniteElement("Real", mesh.ufl_cell(), 0)
W = FunctionSpace(mesh, V)

u = TrialFunction(W)
v = TestFunction(W)

w = Function(W)

for i in range(1):
    w.vector()[i] = i+1

dxP = dx(metadata={"quadrature_scheme":"vertex"}) 
a = w*u*v*dP

A = assemble(a)

print(A.array())

yields the error above.

Hi, @dokken. Thank you for your response!

The idea is to use the real space to solve an algebraic equation coupled to a differential equation. This algebraic equation is only a function of the vertices values. In this sense, I want the assemble to be a point evaluation at each vertex, as you mentioned.

As a workaround, I was trying to modify the Petsc Matrix. Since I’m not very familiar with it, I was not very successful.