Access an array of expressions

Hello, I am working on a problem in linearized elasticity in curvilinear coordinates.
When I implement the weak formulation of the problem, some troubles occur when I insert tensors in the definition of the weak formulation.

I enclose a MWE here below.

File CS1_fenics.txt

(('0.0','0.0','1.0/(Re+x[2])'),
('0.0','0.0','0.0'),
('1.0/(Re+x[2])','0.0','0.0'))

File CS2_fenics.txt

(('0.0','0.0','0.0'),
('0.0','0.0','0.0'),
('0.0','0.0','0.0'))

File CS3_fenics.txt

(('-Re-x[2]','0.0','0.0'),
('0.0','0.0','0.0'),
('0.0','0.0','0.0'))

File a_fenics.txt

(('1.0/pow(Re+x[2],4.0)*(lambda_+mu*2.0)','lambda_*1.0/pow(Re+x[2],2.0)','lambda_*1.0/pow(Re+x[2],2.0)','0.0','0.0','0.0'),
('lambda_*1.0/pow(Re+x[2],2.0)','lambda_+mu*2.0','lambda_','0.0','0.0','0.0'),
('lambda_*1.0/pow(Re+x[2],2.0)','lambda_','lambda_+mu*2.0','0.0','0.0','0.0'),
('0.0','0.0','0.0','mu*2.0','0.0','0.0'),
('0.0','0.0','0.0','0.0','mu*1.0/pow(Re+x[2],2.0)*2.0','0.0'),
('0.0','0.0','0.0','0.0','0.0','mu*1.0/pow(Re+x[2],2.0)*2.0'))

and finally, the Python script:

from ast import Expression
from fenics import *
import math
import sympy as sym
import os

## 3D box mesh -----------------------------------

epsilon = 0.01
H=2 # height of the cylinder

#-----------------------
# 3D Geometry
#-----------------------

mesh3 = BoxMesh(Point(0, 0, -epsilon), Point(math.pi, H, epsilon), 50, 50, 20)

# #---------------------
# # Function spaces
# # --------------------
V = VectorFunctionSpace(mesh3, "CG", degree=1,dim=3)
W=FunctionSpace(mesh3, "CG",1)
u_tr = TrialFunction(V)
u_test = TestFunction(V)

mu, Re, lambda_ = 1.0, 1.0, 1.0

# First Christoffel symbol
with open('./CS1_fenics.txt') as file:
    expression = file.read()
CS1 = Expression(eval(expression), mu=mu, Re=Re, lambda_=lambda_, degree=3)

# Second Christoffel symbol
with open('./CS2_fenics.txt') as file:
    expression = file.read()
CS2 = Expression(eval(expression), mu=mu, Re=Re, lambda_=lambda_, degree=3)

# Third Christoffel symbol
with open('./CS3_fenics.txt') as file:
    expression = file.read()
CS3 = Expression(eval(expression), mu=mu, Re=Re, lambda_=lambda_, degree=3)

# Three-dimensional fourth order elasticity tensor (A)
with open('./a_fenics.txt') as a_fenics:
    expression = a_fenics.read()
A = Expression(eval(expression), mu=mu, Re=Re, lambda_=lambda_, degree=3)

def epsV(u):
    return Expression((
        ('Dx(u0,0)-CS1[0][0]*u0-CS2[0][0]*u1-CS3[0][0]*u2',
        'Dx(u1,1)-CS1[1][1]*u0-CS2[1][1]*u1-CS3[1][1]*u1',
        'Dx(u2,2)-CS1[2][2]*u0-CS2[2][2]*u1-CS3[2][2]*u2',
        'Dx(u1,2)-2.*CS1[1][2]*u0-2.*CS2[1][2]*u1-2.*CS3[1][2]*u2+Dx(u2,1)',
        'Dx(u0,2)-2.*CS1[0][2]*u0-2.*CS2[0][2]*u1-2.*CS3[0][2]*u2+Dx(u2,0)',
        'Dx(u0,1)-2.*CS1[0][1]*u0-2.*CS2[0][1]*u1-2.*CS3[0][1]*u2+Dx(u1,0)')
    ),u0=u[0],u1=u[1],u2=u[2],CS1=CS1,CS2=CS2,CS3=CS3,degree=2)


# #----------------------
# # 3D applied body force
# #----------------------
f = Constant((0, 0, -1))

# vtkfile3 = File('./box_mesh.pvd')
# vtkfile3<<mesh3

# # --------------------
# # Weak form
# # --------------------
a = inner(epsV(u_tr), A*epsV(u_test))*dx
l = dot(f, u_test)*dx

When I run the code, it seems that Fenics cannot access the matrices of expressions CS1, CS2 and CS3.

Would anyone know how to solve this issue without having to declare the matrices entries one by one?
Apart from having a correct code, I would like to avoid having to expand all the sums in the matrix-vector products.

Thanks in advance.

I have not tried running your code, but the following line seems fishy

The ast module is totally unrelated to fenics, which means that the Expressions you create are not fenics objects. Try removing this line. If it does not help, please post the entire error that your code produces.

1 Like

Hi, thank you for checking. I tried to remove that line as you suggested.
However, the code does not work yet.

Here is the error message:

------------------- Start compiler output ------------------------
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp: In member function ‘virtual void dolfin::dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1::eval(Eigen::Ref<Eigen::Matrix<double, -1, 1> >, Eigen::Ref<const Eigen::Matrix<double, -1, 1> >) const’:
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:73:26: error: ‘u0’ was not declared in this scope; did you mean ‘y0’?
   73 |           values[0] = Dx(u0,0)-CS1[0][0]*u0-CS2[0][0]*u1-CS3[0][0]*u2;
      |                          ^~
      |                          y0
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:73:23: error: ‘Dx’ was not declared in this scope; did you mean ‘x’?
   73 |           values[0] = Dx(u0,0)-CS1[0][0]*u0-CS2[0][0]*u1-CS3[0][0]*u2;
      |                       ^~
      |                       x
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:73:40: error: invalid types ‘double[int]’ for array subscript
   73 |           values[0] = Dx(u0,0)-CS1[0][0]*u0-CS2[0][0]*u1-CS3[0][0]*u2;
      |                                        ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:73:53: error: invalid types ‘double[int]’ for array subscript
   73 |           values[0] = Dx(u0,0)-CS1[0][0]*u0-CS2[0][0]*u1-CS3[0][0]*u2;
      |                                                     ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:73:55: error: ‘u1’ was not declared in this scope; did you mean ‘y1’?
   73 |           values[0] = Dx(u0,0)-CS1[0][0]*u0-CS2[0][0]*u1-CS3[0][0]*u2;
      |                                                       ^~
      |                                                       y1
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:73:66: error: invalid types ‘double[int]’ for array subscript
   73 |           values[0] = Dx(u0,0)-CS1[0][0]*u0-CS2[0][0]*u1-CS3[0][0]*u2;
      |                                                                  ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:73:68: error: ‘u2’ was not declared in this scope
   73 |           values[0] = Dx(u0,0)-CS1[0][0]*u0-CS2[0][0]*u1-CS3[0][0]*u2;
      |                                                                    ^~
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:74:40: error: invalid types ‘double[int]’ for array subscript
   74 |           values[1] = Dx(u1,1)-CS1[1][1]*u0-CS2[1][1]*u1-CS3[1][1]*u1;
      |                                        ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:74:53: error: invalid types ‘double[int]’ for array subscript
   74 |           values[1] = Dx(u1,1)-CS1[1][1]*u0-CS2[1][1]*u1-CS3[1][1]*u1;
      |                                                     ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:74:66: error: invalid types ‘double[int]’ for array subscript
   74 |           values[1] = Dx(u1,1)-CS1[1][1]*u0-CS2[1][1]*u1-CS3[1][1]*u1;
      |                                                                  ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:75:40: error: invalid types ‘double[int]’ for array subscript
   75 |           values[2] = Dx(u2,2)-CS1[2][2]*u0-CS2[2][2]*u1-CS3[2][2]*u2;
      |                                        ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:75:53: error: invalid types ‘double[int]’ for array subscript
   75 |           values[2] = Dx(u2,2)-CS1[2][2]*u0-CS2[2][2]*u1-CS3[2][2]*u2;
      |                                                     ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:75:66: error: invalid types ‘double[int]’ for array subscript
   75 |           values[2] = Dx(u2,2)-CS1[2][2]*u0-CS2[2][2]*u1-CS3[2][2]*u2;
      |                                                                  ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:76:43: error: invalid types ‘double[int]’ for array subscript
   76 |           values[3] = Dx(u1,2)-2.*CS1[1][2]*u0-2.*CS2[1][2]*u1-2.*CS3[1][2]*u2+Dx(u2,1);
      |                                           ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:76:59: error: invalid types ‘double[int]’ for array subscript
   76 |           values[3] = Dx(u1,2)-2.*CS1[1][2]*u0-2.*CS2[1][2]*u1-2.*CS3[1][2]*u2+Dx(u2,1);
      |                                                           ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:76:75: error: invalid types ‘double[int]’ for array subscript
   76 |           values[3] = Dx(u1,2)-2.*CS1[1][2]*u0-2.*CS2[1][2]*u1-2.*CS3[1][2]*u2+Dx(u2,1);
      |                                                                           ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:77:43: error: invalid types ‘double[int]’ for array subscript
   77 |           values[4] = Dx(u0,2)-2.*CS1[0][2]*u0-2.*CS2[0][2]*u1-2.*CS3[0][2]*u2+Dx(u2,0);
      |                                           ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:77:59: error: invalid types ‘double[int]’ for array subscript
   77 |           values[4] = Dx(u0,2)-2.*CS1[0][2]*u0-2.*CS2[0][2]*u1-2.*CS3[0][2]*u2+Dx(u2,0);
      |                                                           ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:77:75: error: invalid types ‘double[int]’ for array subscript
   77 |           values[4] = Dx(u0,2)-2.*CS1[0][2]*u0-2.*CS2[0][2]*u1-2.*CS3[0][2]*u2+Dx(u2,0);
      |                                                                           ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:78:43: error: invalid types ‘double[int]’ for array subscript
   78 |           values[5] = Dx(u0,1)-2.*CS1[0][1]*u0-2.*CS2[0][1]*u1-2.*CS3[0][1]*u2+Dx(u1,0);
      |                                           ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:78:59: error: invalid types ‘double[int]’ for array subscript
   78 |           values[5] = Dx(u0,1)-2.*CS1[0][1]*u0-2.*CS2[0][1]*u1-2.*CS3[0][1]*u2+Dx(u1,0);
      |                                                           ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:78:75: error: invalid types ‘double[int]’ for array subscript
   78 |           values[5] = Dx(u0,1)-2.*CS1[0][1]*u0-2.*CS2[0][1]*u1-2.*CS3[0][1]*u2+Dx(u1,0);
      |                                                                           ^
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp: In member function ‘virtual std::shared_ptr<dolfin::GenericFunction> dolfin::dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1::get_generic_function(std::string) const’:
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:103:11: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
  103 |           if (name == "CS1") return generic_function_CS1;          if (name == "CS2") return generic_function_CS2;          if (name == "CS3") return generic_function_CS3;
      |           ^~
/tmp/tmpe6kxw0lr/dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1.cpp:103:68: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
  103 |           if (name == "CS1") return generic_function_CS1;          if (name == "CS2") return generic_function_CS2;          if (name == "CS3") return generic_function_CS3;
      |                                                                    ^~

-------------------  End compiler output  ------------------------
Compilation failed! Sources, command, and errors have been written to: /home/paolo/Documents/Xiaoqin - Numerical Koiter 2D 3D/3D numerical experiments/flexural shells/Cylindrical shell/time-dependent case/ver1/MWE/jitfailure-dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1
Traceback (most recent call last):
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/jit/jit.py", line 168, in compile_class
    module, signature = dijitso_jit(cpp_data, module_name, params,
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/jit/jit.py", line 50, in mpi_jit
    return local_jit(*args, **kwargs)
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/jit/jit.py", line 106, in dijitso_jit
    return dijitso.jit(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/dijitso/jit.py", line 216, in jit
    raise DijitsoError("Dijitso JIT compilation failed, see '%s' for details"
dijitso.jit.DijitsoError: Dijitso JIT compilation failed, see '/home/paolo/Documents/Xiaoqin - Numerical Koiter 2D 3D/3D numerical experiments/flexural shells/Cylindrical shell/time-dependent case/ver1/MWE/jitfailure-dolfin_expression_f97999d2dc7f4c8cbed83149ac139fc1' for details

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "MWE.py", line 77, in <module>
    a = inner(epsV(u_tr), epsV(u_test))*dx
  File "MWE.py", line 56, in epsV
    return Expression((
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/function/expression.py", line 400, in __init__
    self._cpp_object = jit.compile_expression(cpp_code, params)
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/function/jit.py", line 158, in compile_expression
    expression = compile_class(cpp_data, mpi_comm=mpi_comm)
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/jit/jit.py", line 173, in compile_class
    raise RuntimeError("Unable to compile C++ code with dijitso")
RuntimeError: Unable to compile C++ code with dijitso

My strategy is to transform each entry of the tensors CS1, CS2 and CS3 into finite element functions via the interpolate command and access these functions using the standard matrix notation of python, but I have not found anything on the Internet in this regard.

You’re trying to mix a ufl.TrialFunction and C++ code in the dolfin.Expression.

u_tr = TrialFunction(V)
...
def epsV(u):
    return Expression((
    ...
    ),u0=u[0],u1=u[1],u2=u[2],CS1=CS1,CS2=CS2,CS3=CS3,degree=2)
...
a = inner(epsV(u_tr), A*epsV(u_test))*dx

It doesn’t make sense. It looks like your problem is nonlinear, and should be formulated as such. Consider the nonlinear Poisson demo.

It is highly possible that what I wrote does not make sense :slight_smile: but, for sure, the problem is linear.
The functions in CS1, CS2 and CS3 are given in terms of the parametrization of the mesh and they are continuous. The only unknown is the displacement field u.

I would suggest using

x = SpatialCoordinate(mesh)
CS1 = as_matrix(eval(expression)))

and similarly for the following expressions.

1 Like

It indeed looks linear, my mistake. A ufl object typically does not belong in a dolfinx.Expression's C++ code. @dokken’s proposal will evaluate your code as a ufl formulation.

Thanks for the suggestion. I tried to modify as you suggested but there are still problems.
This is the error message I receive:

Traceback (most recent call last):
  File "dynamic_cylinder.py", line 74, in <module>
    CS1 = as_matrix(eval(expression))
  File "/usr/lib/python3/dist-packages/ufl/tensors.py", line 289, in as_matrix
    return as_tensor(expressions, indices)
  File "/usr/lib/python3/dist-packages/ufl/tensors.py", line 243, in as_tensor
    return _as_list_tensor(expressions)
  File "/usr/lib/python3/dist-packages/ufl/tensors.py", line 191, in _as_list_tensor
    expressions = [_as_list_tensor(e) for e in expressions]
  File "/usr/lib/python3/dist-packages/ufl/tensors.py", line 191, in <listcomp>
    expressions = [_as_list_tensor(e) for e in expressions]
  File "/usr/lib/python3/dist-packages/ufl/tensors.py", line 191, in _as_list_tensor
    expressions = [_as_list_tensor(e) for e in expressions]
  File "/usr/lib/python3/dist-packages/ufl/tensors.py", line 191, in <listcomp>
    expressions = [_as_list_tensor(e) for e in expressions]
  File "/usr/lib/python3/dist-packages/ufl/tensors.py", line 194, in _as_list_tensor
    return as_ufl(expressions)
  File "/usr/lib/python3/dist-packages/ufl/constantvalue.py", line 437, in as_ufl
    raise UFLValueError("Invalid type conversion: %s can not be converted"
ufl.log.UFLValueError: Invalid type conversion: 0.0 can not be converted to any UFL type.

I also enclose the code after the suggested modification.

from pyclbr import Function
from fenics import *
import math
import sympy as sym
import os

## 3D box mesh -----------------------------------

epsilon = 0.01
H=2 # height of the cylinder

#-----------------------
# 3D Geometry
#-----------------------

mesh3 = BoxMesh(Point(0, 0, -epsilon), Point(math.pi, H, epsilon), 50, 50, 20)

#---------------------
# Function spaces
# --------------------
V = VectorFunctionSpace(mesh3, "CG", degree=1,dim=3)
u_tr = TrialFunction(V)
u_test = TestFunction(V)

mu, Re, lambda_ = 1.0, 1.0, 1.0

x = SpatialCoordinate(mesh3)

# First Christoffel symbol
with open('./CS1_fenics.txt') as file:
    expression = file.read()
CS1 = as_matrix(eval(expression))

# Second Christoffel symbol
with open('./CS2_fenics.txt') as file:
    expression = file.read()
CS2 = as_matrix(eval(expression))

# Third Christoffel symbol
with open('./CS3_fenics.txt') as file:
    expression = file.read()
CS3 = as_matrix(eval(expression))

# Three-dimensional fourth order elasticity tensor (A)
with open('./a_fenics.txt') as a_fenics:
    expression = a_fenics.read()
A = as_matrix(eval(expression))

def epsV(u):
    return as_vector(
        [
        Dx(u[0],0)-CS1[0][0]*u[0]-CS2[0][0]*u[1]-CS3[0][0]*u[2],
        Dx(u[1],1)-CS1[1][1]*u[0]-CS2[1][1]*u[1]-CS3[1][1]*u[1],
        Dx(u[2],2)-CS1[2][2]*u[0]-CS2[2][2]*u[1]-CS3[2][2]*u[2],
        Dx(u[1],2)-2.*CS1[1][2]*u[0]-2.*CS2[1][2]*u[1]-2.*CS3[1][2]*u[2]+Dx(u[2],1),
        Dx(u[0],2)-2.*CS1[0][2]*u[0]-2.*CS2[0][2]*u[1]-2.*CS3[0][2]*u[2]+Dx(u[2],0),
        Dx(u[0],1)-2.*CS1[0][1]*u[0]-2.*CS2[0][1]*u[1]-2.*CS3[0][1]*u[2]+Dx(u[1],0)
        ]
    )


# #----------------------
# # 3D applied body force
# #----------------------
f = Constant((0, 0, -1))

# vtkfile3 = File('./box_mesh.pvd')
# vtkfile3<<mesh3

# # --------------------
# # Weak form
# # --------------------
a = inner(epsV(u_tr), A*epsV(u_test))*dx
l = dot(f, u_test)*dx

You need to define the arrays in CS1_fenics.txt, CS2_fenics.txt, etc. such that the arrays contain numeric or ufl types, not strings, i.e. by removing the single quotes around all the terms. E.g. for CS1_fenics.txt:

((0.0          , 0.0, 1.0/(Re+x[2])),
 (0.0          , 0.0, 0.0          ),
 (1.0/(Re+x[2]), 0.0, 0.0          ))

As an aside, it looks like there might be a typo in epsV:

def epsV(u):
    return as_vector(
        [
        Dx(u[0],0)-CS1[0][0]*u[0]-CS2[0][0]*u[1]-CS3[0][0]*u[2],
        Dx(u[1],1)-CS1[1][1]*u[0]-CS2[1][1]*u[1]-CS3[1][1]*u[1],
        #                                                    ^
        #                                                    should be u[2]
        Dx(u[2],2)-CS1[2][2]*u[0]-CS2[2][2]*u[1]-CS3[2][2]*u[2],
        Dx(u[1],2)-2.*CS1[1][2]*u[0]-2.*CS2[1][2]*u[1]-2.*CS3[1][2]*u[2]+Dx(u[2],1),
        Dx(u[0],2)-2.*CS1[0][2]*u[0]-2.*CS2[0][2]*u[1]-2.*CS3[0][2]*u[2]+Dx(u[2],0),
        Dx(u[0],1)-2.*CS1[0][1]*u[0]-2.*CS2[0][1]*u[1]-2.*CS3[0][1]*u[2]+Dx(u[1],0)
        ]
    )

As a further aside, it appears that you could implement epsV in a more concise form, by combining CS1_fenics.txt, CS2_fenics.txt, and CS3_fenics.txt into a third-order tensor:

# CS_fenics.txt
(
    ((0.0          , 0.0, 1.0/(Re+x[2])),
     (0.0          , 0.0, 0.0          ),
     (1.0/(Re+x[2]), 0.0, 0.0          )),
    
    ((0.0, 0.0, 0.0),
     (0.0, 0.0, 0.0),
     (0.0, 0.0, 0.0)),
    
    ((-Re-x[2], 0.0, 0.0),
     ( 0.0    , 0.0, 0.0),
     ( 0.0    , 0.0, 0.0))
)

and using ufl.indices to implement the tensor product using Einstein summation notation:

from fenics import *
import ufl
import math

## 3D box mesh -----------------------------------

epsilon = 0.01
H=2 # height of the cylinder

#-----------------------
# 3D Geometry
#-----------------------

mesh3 = BoxMesh(Point(0, 0, -epsilon), Point(math.pi, H, epsilon), 50, 50, 20)

#---------------------
# Function spaces
# --------------------
V = VectorFunctionSpace(mesh3, "CG", degree=1,dim=3)
u_tr = TrialFunction(V)
u_test = TestFunction(V)

mu, Re, lambda_ = 1.0, 1.0, 1.0

x = SpatialCoordinate(mesh3)

# First Christoffel symbol
with open('./CS_fenics.txt') as file:
    expression = file.read()
CS = as_matrix(eval(expression))

# Three-dimensional fourth order elasticity tensor (A)
with open('./a_fenics.txt') as a_fenics:
    expression = a_fenics.read()
A = as_matrix(eval(expression))

def epsV(u):
    i = ufl.indices(1)
    eps = sym(grad(u)) - CS[i,:,:]*u[i]
    return as_vector(
        [
            eps[0, 0],
            eps[1, 1],
            eps[2, 2],
            2*eps[1, 2],
            2*eps[0, 2],
            2*eps[0, 1]
        ]
    )

# #----------------------
# # 3D applied body force
# #----------------------
f = Constant((0, 0, -1))

# vtkfile3 = File('./box_mesh.pvd')
# vtkfile3<<mesh3

# # --------------------
# # Weak form
# # --------------------
a = inner(epsV(u_tr), dot(A, epsV(u_test)))*dx
l = dot(f, u_test)*dx
1 Like

Thank you very much for your help.
I will definitely keep in mind the possibility to implement the Einstein summation in Fenics.

Yes, there was a typo in the definition of epsV, thanks for catching it.

I tried to remove the apostrophes as you suggested but I keep up receiving an error message, which I enclose here below:

python3 dynamic_cylinder.py
Component and shape length don't match.
Traceback (most recent call last):
  File "dynamic_cylinder.py", line 132, in <module>
    a = inner(epsV(u_tr), epsV(u_test))*dx
  File "dynamic_cylinder.py", line 102, in epsV
    [Dx(u[0],0)-CS1[0][0]*u[0]-CS2[0][0]*u[1]-CS3[0][0]*u[2],
  File "/usr/lib/python3/dist-packages/ufl/exproperators.py", line 438, in _getitem
    all_indices, slice_indices, repeated_indices = create_slice_indices(component, shape, self.ufl_free_indices)
  File "/usr/lib/python3/dist-packages/ufl/index_combination_utils.py", line 170, in create_slice_indices
    error("Component and shape length don't match.")
  File "/usr/lib/python3/dist-packages/ufl/log.py", line 158, in error
    raise self._exception_type(self._format_raw(*message))
ufl.log.UFLException: Component and shape length don't match.

My mistake. I forgot mention that you also need to amend the syntax used to define epsV. You need to use CS1[0, 0] instead of CS1[0][0] throughout, i.e.:

def epsV(u):
    return as_vector(
        [
        Dx(u[0],0)-CS1[0, 0]*u[0]-CS2[0, 0]*u[1]-CS3[0, 0]*u[2],
        Dx(u[1],1)-CS1[1, 1]*u[0]-CS2[1, 1]*u[1]-CS3[1, 1]*u[2],
        Dx(u[2],2)-CS1[2, 2]*u[0]-CS2[2, 2]*u[1]-CS3[2, 2]*u[2],
        Dx(u[1],2)-2.*CS1[1, 2]*u[0]-2.*CS2[1, 2]*u[1]-2.*CS3[1, 2]*u[2]+Dx(u[2],1),
        Dx(u[0],2)-2.*CS1[0, 2]*u[0]-2.*CS2[0, 2]*u[1]-2.*CS3[0, 2]*u[2]+Dx(u[2],0),
        Dx(u[0],1)-2.*CS1[0, 1]*u[0]-2.*CS2[0, 1]*u[1]-2.*CS3[0, 1]*u[2]+Dx(u[1],0)
        ]
    )
1 Like

Thank you! THis last amendment solves the problem and the code correctly compiles.
Thank you very much to everyone for the help!

1 Like