Accessing basis functions

Hey guys, I am currently trying to evaluate the integral of the test functions over a line domain as you can see below

import numpy as np
import matplotlib
from ufl import FiniteElementBase
from fenics import *
from mshr import *


timesh = IntervalMesh(1,0.0,0.5)
Th = FunctionSpace(timesh, "Lagrange", 1)
vh = TestFunction(Th)

I1 = np.array(assemble(vh*dx))
print(I1)

It turns out that I1 returns a vector with the value of each Lagrange base function over the domain and then I simply sum the elements of the vector to get the integral of the sum. Now I am trying to get the value of the integral of the square of the sum, however when I do this

I1 = np.array(assemble(vh*vh*dx))

I get the error

Traceback (most recent call last):
(...)
  File "/usr/lib/python3/dist-packages/ufl/core/expr.py", line 390, in __len__
    raise NotImplementedError("Cannot take length of non-vector expression.")
NotImplementedError: Cannot take length of non-vector expression.

From what I could understand, the assemble function cannot read the size of the product of two forms. Is there a way to overcome this issue and get the integral of the products of all base functions? Is there a way to extract or access the entries of a TestFunction object?

Thanks in advance!!!

First, the wording of the text is a bit unclear, but, in mathematical notation, your first vector I1 is a vector whose i^\text{th} entry is

\int_\Omega\phi_i\,d\Omega\text{ ,}

where \phi_i is the i^\text{th} basis function of the space Th and \Omega is the interval (0,0.5). It looks like what you’re trying to compute next is a vector whose i^\text{th} entry is

\int_\Omega\phi_i^2\,d\Omega\text{ .}

This second vector is the diagonal of the matrix whose i,j entry is

\int_\Omega\phi_i\phi_j\,d\Omega\text{ ,}

which you can get from

import numpy as np
from fenics import *

timesh = IntervalMesh(1,0.0,0.5)
Th = FunctionSpace(timesh, "Lagrange", 1)
vh = TestFunction(Th)
uh = TrialFunction(Th)

A = assemble(uh*vh*dx)
diag_A = PETScVector(as_backend_type(A).mat().getDiagonal())
I1 = np.array(diag_A)
print(I1)

(There is some extra “wasted” computation of the off-diagonal entries, but it still scales linearly with the number of elements.)

1 Like

Sorry if I was not very clear. I am trying to compute \int_\Omega \phi_i\phi_j dx where the \phi_i's are the basis functions of the space Th. I think I got from your example an idea of what I needed. By what you did, The matrix A has entries a_{i,j} = \int_\Omega \phi_i\phi_j dx and that’s exactly what I need to compute the integrals. I don’t need only the diagonal of this matrix, but all of its entries.

How do I get a numpy matrix of A?

I got the answer. When the object is of type

dolfin.cpp.la.` `Matrix` ( **args* )

we just simply use the attribute .array() and the matrix object becomes a numpy type matrix.