Define random values through expression

Dear Fenics users,

I want to define some random values in each nodes through expression. Here is my code but it didn’t work:

import numpy as np
from dolfin import *
from fenics import *

#Define mesh
N=2;
mesh = BoxMesh(Point(0, 0, 0), Point(1, 1, 1), N, N, N)

#Define mixed space
P2 = VectorElement(“Lagrange”, mesh.ufl_cell(), 1)
P1 = FiniteElement(“Lagrange”, mesh.ufl_cell(), 1)
TH = P2 * P1
W = FunctionSpace(mesh, TH)
gdim = mesh.geometry().dim()
I = Identity(W.mesh().geometry().dim())
Z = FunctionSpace(mesh, ‘CG’, 1)
w = Function(W)
(u, p) = split(w)
#Determine number of nodes and denoting them
dof2vt = dof_to_vertex_map(Z)
coords = mesh.coordinates()
coords = coords[dof2vt]
length_of_nodes = coords.shape[0]

mu = 0.5 # a constant
#Generating random values in each nodes
ran_mu = np.random.rand(1,length_of_nodes)
print(“random mu :”, ran_mu)

#Defining the constant value in expression
mu_expr=Expression(“mu”,mu=mu, degree=1)
mu_in_vert=interpolate(mu_expr, Z)
print("mu in each nodes : ", mu_in_vert.vector().get_local())

#Now I want to define the random values (ran_mu) through expression
ran_mu_expr=Expression(“ran_mu”,ran_mu=ran_mu, degree=4)
ran_mu_in_vert=interpolate(ran_mu_expr, Z)

Many thanks in advance for your help.

Regards,
Mehedi

Hi, f=Expression(“g”, g=g, degree=1) should be thought of as defining f such that f(x)=g(x). In ran_mu_expr=Expression(“ran_mu”,ran_mu=ran_mu, degree=4) you seem to make an assumption that Expression will do the lookup in ran_mu array to assign the coefficient value appropriately. That is not the case. Consider instead

from dolfin import *
import numpy as np


class RandomScalar(UserExpression):
    def eval(self, value, x):
        value[:] = np.random.rand()
    def value_shape(self, ):
        return ()

    
def fill_random0(f):
    f.assign(interpolate(RandomScalar(degree=1), f.function_space()))
    return f


def fill_random1(f):
    f.vector().set_local(np.random.rand(f.vector().local_size()))
    return f
# To illustrate speed difference
for n in (64, 128, 256):
    mesh = UnitSquareMesh(n, n)
    V = FunctionSpace(mesh, 'CG', 1)
    f = Function(V)
    print('n=%d' % n)
    for fill in (fill_random0, fill_random1):
        t = Timer()
        fill(f)
        print('\t', t.stop())

# Expression using function
mesh = UnitSquareMesh(n, n)
V = FunctionSpace(mesh, 'CG', 1)

f = Function(V)
# Randomize
f = fill_random1(f)

f_expr = Expression('f', f=f, degree=1)
print(sqrt(abs(assemble(inner(f-f_expr, f-f_expr)*dx))))

Thank you for your reply. Now, it is working.