Problem on DirichletBC application

Hello everyone I have a problem I would like to apply the DirichletBC condition on the surface of my cylinder.
piezoboundary.PNG
I applied a tension on the upper surface and the lower surface is put on the ground
my code

from fenics import *
from mshr import *
import numpy as np
from math import *
from matplotlib import pyplot as plt
from dolfin import *
import matplotlib.cm as cm
import matplotlib.tri as tri
from mpl_toolkits.axes_grid1 import make_axes_locatable
# --------------------
# Parameters
# --------------------
c_11 = 1.19e11
c_12 = 0.84e11
c_13 = 0.83e11
c_33 = 1.17e11
c_44 = 0.21e11

eps_11 = 8.15e-9
eps_33 = 6.58e-9

e_15 = 12.09
e_13 = -6.03
e_33 = 15.49

alpha= 1.267e5
beta= 6.259e-10

rho_Piezo = Constant(7700.)

# Geometry of the domain
 voltage = 1 
Diameter = 0.01
Thickness = 0.001 
# Setup mesh
resolution = 30

geometry = Cylinder(Point(0, 0, 0), Point(0, 0, 0.001), 0.005, 0.005)


# Making Mesh (30 corresponds to the mesh density)
mesh = generate_mesh(geometry, resolution)
plot(mesh)
plt.show()
# --------------------
# Functions and classes
# --------------------

VV = VectorElement("CG", mesh.ufl_cell(), 2, dim=3)

WW = FiniteElement("CG", mesh.ufl_cell(), 1)

M = FunctionSpace(mesh, MixedElement([VV,VV, WW]))

# Get the needed boundaries: 
# 1. To apply a predefined stress on it We keep it simple: the top face sees the same stress vector. 
# 2. For zero Displacement we choose the bottom face of the disc
class TopBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and near(x[2], 0.001)

class BottomBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and near(x[2], 0.)
    
# Strain function   
def epsilon(u):
    strain_u=0.5*(grad(u)+grad(u).T)
    return strain_u
# rewrite a vector into a tensor using Voigt notation
def strain_voigt(u):
    strain_3_1=as_vector([u[i].dx(i) for i in range(2)] +[u[i].dx(j) + u[j].dx(i) for (i,j) in [(0,1)]])
    strain_6_1=as_vector([strain_3_1[0], strain_3_1[1], 0, 0, 0, strain_3_1[2]])
    return strain_6_1
# --------------------
# Boundary conditions
# --------------------
top_boundary  = TopBoundary()
bottom_boundary = BottomBoundary()

# Create the boundary condition for displacement
boundary = []
boundary.append(DirichletBC(M.sub(2), 0., bottom_boundary))
boundary.append(DirichletBC(M.sub(2), 1.0 , top_boundary))

# As the stress is defined over the outer surface we need to create a 
# integral over that surface
boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
boundaries.set_all(0)
top_boundary.mark(boundaries, 1)
bottom_boundary.mark(boundaries, 3)
ds = Measure("ds", subdomain_data=boundaries)

Please be more specific as to what issue you are currently having. Are you receiving an error message? Is your results not as you would expect?

note that you can expect your boundary markers with:

from fenics import *
from mshr import *

# Setup mesh
resolution = 30

geometry = Cylinder(Point(0, 0, 0), Point(0, 0, 0.001), 0.005, 0.005)


# Making Mesh (30 corresponds to the mesh density)
mesh = generate_mesh(geometry, resolution)

# Get the needed boundaries: 
# 1. To apply a predefined stress on it We keep it simple: the top face sees the same stress vector. 
# 2. For zero Displacement we choose the bottom face of the disc
class TopBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and near(x[2], 0.001)

class BottomBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and near(x[2], 0.)
    

top_boundary  = TopBoundary()
bottom_boundary = BottomBoundary()

mf =  MeshFunction("size_t", mesh, mesh.topology().dim()-1)
mf.set_all(0)
top_boundary.mark(mf, 1)
bottom_boundary.mark(mf, 2)
File("mf.pvd") << mf

thank you for your answer ,
in fact I apply a tension on the upper surface of my material and the lower part is zero I defined the form a and l of my equation see foto below but when I simulate it does not apply on all the surface of my material. that’s why I wonder if it is not the condiction of BCDiricelt which has a problem. The result
alsosame

As you have not supplied a code reproducing your error, I cannot help you much further.
This is how the mesh-tag I created looks like in paraview:

cylinder

which indicates that the boundaries are marked correctly.
Therefore it seems like your mistake is somewhere else in the code.

Please produce a minimal example that reproduces your error

thank you for your answer
In fact I have to solve a second order differential equation and I transformed it into first order to


facilitate its discretization and I put in the form a and l so here is implementation.

the code

from fenics import *
from mshr import *
import numpy as np
from math import *
from matplotlib import pyplot as plt
from dolfin import *
import matplotlib.cm as cm
import matplotlib.tri as tri
from mpl_toolkits.axes_grid1 import make_axes_locatable
# --------------------
# Parameters
# --------------------
c_11 = 1.19e11
c_12 = 0.84e11
c_13 = 0.83e11
c_33 = 1.17e11
c_44 = 0.21e11

eps_11 = 8.15e-9
eps_33 = 6.58e-9

e_15 = 12.09
e_13 = -6.03
e_33 = 15.49

alpha= 1.267e5
beta= 6.259e-10

rho_Piezo = Constant(7700.)

# Geometry of the domain
 voltage = 1 
Diameter = 0.01
Thickness = 0.001 
# Setup mesh
resolution = 30

geometry = Cylinder(Point(0, 0, 0), Point(0, 0, 0.001), 0.005, 0.005)


# Making Mesh (30 corresponds to the mesh density)
mesh = generate_mesh(geometry, resolution)
plot(mesh)
plt.show()
# --------------------
# Functions and classes
# --------------------

VV = VectorElement("CG", mesh.ufl_cell(), 2, dim=3)

WW = FiniteElement("CG", mesh.ufl_cell(), 1)

M = FunctionSpace(mesh, MixedElement([VV,VV, WW]))

# Get the needed boundaries: 
# 1. To apply a predefined stress on it We keep it simple: the top face sees the same stress vector. 
# 2. For zero Displacement we choose the bottom face of the disc
class TopBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and near(x[2], 0.001)

class BottomBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and near(x[2], 0.)
    
# Strain function   
def epsilon(u):
    strain_u=0.5*(grad(u)+grad(u).T)
    return strain_u
# rewrite a vector into a tensor using Voigt notation
def strain_voigt(u):
    strain_3_1=as_vector([u[i].dx(i) for i in range(2)] +[u[i].dx(j) + u[j].dx(i) for (i,j) in [(0,1)]])
    strain_6_1=as_vector([strain_3_1[0], strain_3_1[1], 0, 0, 0, strain_3_1[2]])
    return strain_6_1
# --------------------
# Boundary conditions
# --------------------
top_boundary  = TopBoundary()
bottom_boundary = BottomBoundary()

# Create the boundary condition for displacement
boundary = []
boundary.append(DirichletBC(M.sub(2), 0., bottom_boundary))
boundary.append(DirichletBC(M.sub(2), 1.0 , top_boundary))

# As the stress is defined over the outer surface we need to create a 
# integral over that surface
boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
boundaries.set_all(0)
top_boundary.mark(boundaries, 1)
bottom_boundary.mark(boundaries, 3)
ds = Measure("ds", subdomain_data=boundaries)
# the initial values
zero1d=Expression('0.0', degree=1)
zero3d=Expression(('0.0','0.0','0.0'), degree=1)
u0=interpolate(zero3d,M.sub(0).collapse())
z0=interpolate(zero3d,M.sub(1).collapse())
phi0=interpolate(zero1d,M.sub(2).collapse())
# --------------------
# Function spaces
# --------------------

#Defining the "Trial" functions
u1,z1,phi1=TrialFunctions(M)
#Defining the "Test" functions
u,z,phi=TestFunctions(M)
# --------------------
# Weak form
# --------------------

'''
a := ρ(z 1 , v)L 2 + Θ · dt((c E Bu1 + eT ∇φ1 ),Bv) L 2 + Θ · dt · α · ρ(z 1 , v)L 2
+Θ · dt · β(cE Bz 1 , Bv) L 2 + (eBu 1 − ε S ∇φ 1 , ∇w) L 2
+(u 1 , yi) L 2 − Θ · dt(z 1 , yi) L 2
'''

a = rho_Piezo*inner(z1,u)*dx
+ dot(theta,dt * inner(c * as_voigt_vector(epsilon(u1)) + et_piezo*grad(phi1), as_voigt_vector(grad(u)))) * dx
+ dot(theta,dot(dt, dot(alpha, rho_Piezo*inner(z1,u)))) * dx
+ dot(theta,dot(dt, beta*(inner(c * as_voigt_vector(epsilon(z1)), as_voigt_vector(epsilon(u)))))) * dx
+ inner(e_piezo*as_voigt_vector(epsilon(u1)) - eps_s*grad(phi1), grad(phi)) * dx
+ inner(u1,z)*dx
- dot(theta, dt*(inner(z1, z))) * dx
'''
l := −ρ(z 0 , v) L 2 + Θ · dt((cE Bu 0 + eT ∇φ 0 ), Bv) L 2 + Θ · dt · α · ρ(z 0 , v) L 2
+Θ · dt · β(c E Bz 0 , Bv) L 2 − (u 0 , y) L 2 − Θ · dt(z 0 , y) L 2 ,
'''
l = -rho_Piezo*inner(z0,u)*dx
+ dot(theta, dt * inner(c * as_voigt_vector(epsilon(u0)) + et_piezo*grad(phi0), as_voigt_vector(epsilon(u)))) * dx
+ dot(theta, dot(dt, dot(alpha, rho_Piezo*inner(z0,u)))) * dx
+ dot(theta, dot(dt, Beta*(inner(c * as_voigt_vector(epsilon(z0)), as_voigt_vector(grad(u0)))))) * dx
+ inner(u0, z)*dx
- dot(theta, dt*(inner(z0, z))) * dx
#assemble only  
A=assemble(a)
L=assemble(-l)
for bc in boundary:
    bc.apply(A,L)
tmps = Function(M)
solve(A,tmps.vector(),L)
u_result,z_result,phi_result=tmps.split()
FunctionAssigner([M.sub(0).collapse(),M.sub(1).collapse(),M.sub(2).collapse()],tmps.function_space())
assign(tmps.sub(0), u0)
assign(tmps.sub(1), z0)
assign(tmps.sub(2),phi0)
vtkfile = File('phi_result.pvd')

I do unfortunately not have time to go through this example. Hopefully someone with more experience with the equations you are handling can give you some feedback. I would strongly suggest you continue debugging your code. Check that all your boundary conditions are set correctly.
Try reducing the complexity of the problem by prescribing \phi(t), and check that you get your expected solution.

please one last question i have defined my ϕ(t) but when i apply it i have errors i don’t know if you can help me on this point .

from fenics import *
from mshr import *
import numpy as np
from math import *
from matplotlib import pyplot as plt
from dolfin import *
import matplotlib.cm as cm
import matplotlib.tri as tri
from mpl_toolkits.axes_grid1 import make_axes_locatable
# --------------------
# Parameters
# --------------------
c_11 = 1.19e11
c_12 = 0.84e11
c_13 = 0.83e11
c_33 = 1.17e11
c_44 = 0.21e11

eps_11 = 8.15e-9
eps_33 = 6.58e-9

e_15 = 12.09
e_13 = -6.03
e_33 = 15.49

alpha= 1.267e5
beta= 6.259e-10

rho_Piezo = Constant(7700.)

# Geometry of the domain
Diameter = 0.01
Thickness = 0.001 
# Setup mesh
resolution = 30

geometry = Cylinder(Point(0, 0, 0), Point(0, 0, 0.001), 0.005, 0.005)


# Making Mesh (30 corresponds to the mesh density)
mesh = generate_mesh(geometry, resolution)
plot(mesh)
plt.show()
# --------------------
# Functions and classes
# --------------------

VV = VectorElement("CG", mesh.ufl_cell(), 2, dim=3)

WW = FiniteElement("CG", mesh.ufl_cell(), 1)

M = FunctionSpace(mesh, MixedElement([VV,VV, WW]))

# Get the needed boundaries: 
# 1. To apply a predefined stress on it We keep it simple: the top face sees the same stress vector. 
# 2. For zero Displacement we choose the bottom face of the disc
class TopBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and near(x[2], 0.001)

class BottomBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and near(x[2], 0.)
    
# Strain function   
def epsilon(u):
    strain_u=0.5*(grad(u)+grad(u).T)
    return strain_u
# rewrite a vector into a tensor using Voigt notation
def strain_voigt(u):
    strain_3_1=as_vector([u[i].dx(i) for i in range(2)] +[u[i].dx(j) + u[j].dx(i) for (i,j) in [(0,1)]])
    strain_6_1=as_vector([strain_3_1[0], strain_3_1[1], 0, 0, 0, strain_3_1[2]])
    return strain_6_1
# define the potential
dt = 0.01
t        = np.arange(0, 10.0, dt);

# Amplitude of the sine wave is sine of a variable like time
potential   = np.sinc(3*np.pi*(t-(20.0/2)))

# --------------------
# Boundary conditions
# --------------------
top_boundary  = TopBoundary()
bottom_boundary = BottomBoundary()

# Create the boundary condition for displacement
boundary = []
boundary.append(DirichletBC(M.sub(2), 0., bottom_boundary))
boundary.append(DirichletBC(M.sub(2), potential , top_boundary))

# As the stress is defined over the outer surface we need to create a 
# integral over that surface
boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
boundaries.set_all(0)
top_boundary.mark(boundaries, 1)
bottom_boundary.mark(boundaries, 3)
ds = Measure("ds", subdomain_data=boundaries)

RuntimeError Traceback (most recent call last)
in
8 boundary = []
9 boundary.append(DirichletBC(M.sub(2), 0., bottom_boundary))
—> 10 boundary.append(DirichletBC(M.sub(2), potential , top_boundary))
11
12 # As the stress is defined over the outer surface we need to create a

~/anaconda3/envs/fenicsfix2/lib/python3.8/site-packages/dolfin/fem/dirichletbc.py in init(self, *args, **kwargs)
129 raise RuntimeError(“Invalid keyword arguments”, kwargs)
130
→ 131 super().init(*args)

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 create Dirichlet boundary condition.
*** Reason: Expecting a scalar boundary value but given function is vector-valued.
*** Where: This error was encountered inside DirichletBC.cpp.
*** Process: 0


*** DOLFIN version: 2019.1.0
*** Git changeset: 77c758717da1cb8017bf95109363bb1a91a4f8e5
*** -------------------------------------------------------------------------
It would be a great help if you could help me out on this point

As t as an array, potential is a vector. I suppose you would like to use the $i$th entry of the array at the $i$th time step?

# define the potential
dt = 0.01
t = np.arange(0, 10.0, dt)

# Amplitude of the sine wave is sine of a variable like time
potential = np.sinc(3*np.pi*(t-(20.0/2)))
phi = Expression("t", degree=0, t=potential[0])

# --------------------
# Boundary conditions
# --------------------
top_boundary = TopBoundary()
bottom_boundary = BottomBoundary()

# Create the boundary condition for displacement
boundary = []
boundary.append(DirichletBC(M.sub(2), 0., bottom_boundary))
boundary.append(DirichletBC(M.sub(2), phi, top_boundary))

for i in range(len(t)):
    phi.t = t[i]
    print(assemble(phi*dx(domain=mesh)))

hello,
first of all thank you for your help last time i still need your help i am trying to do a dot operation but i keep getting errors could you help me on this point.

from fenics import *
from mshr import *
import numpy as np
from math import *
from matplotlib import pyplot as plt
from dolfin import *
import matplotlib.cm as cm
import matplotlib.tri as tri
from mpl_toolkits.axes_grid1 import make_axes_locatable

# --------------------
# Parameters
# --------------------
c_11 = 1.19e11
c_12 = 0.84e11
c_13 = 0.83e11
c_33 = 1.17e11
c_44 = 0.21e11
dt= 0.001  # time step
theta  = 0.5 
# Elasticity tensor c^E
c = as_matrix([[c_11, c_12, c_13, 0., 0., 0.], 
               [c_12, c_11, c_13, 0., 0., 0.],
               [c_13, c_13, c_33, 0., 0., 0.],
               [0., 0., 0., c_44, 0., 0],
               [0., 0., 0., 0., c_44, 0.],
               [0., 0., 0., 0., 0., (c_11-c_12)/2]])


# piezoelectric coupling tensor e
e_piezo = as_matrix([[0. , 0. , 0., 0. , e_15, 0.],
                   [0., 0., 0., e_15, 0., 0.],
                   [e_13, e_13, e_33, 0., 0., 0.]])


# transpose form of piezo tensor
et_piezo = as_matrix([[0., 0., e_13],
                    [0., 0., e_13],
                    [0., 0., e_33],
                    [0., e_15, 0.],
                    [e_15, 0., 0.],
                    [0., 0., 0.]])


# Permittivitatstensor  epsilon^S
eps_s = as_matrix([[eps_11, 0., 0.],
                    [0., eps_11, 0.],
                    [0., 0., eps_33]])
# Strain function   
def epsilon(u):
    strain_u=0.5*(grad(u)+grad(u).T)
    return strain_u
# --------------------
# Function spaces
# --------------------

#Defining the "Trial" functions
u,z,phi=TrialFunctions(M)

#Defining the "Test" functions
u1,z1,phi1=TestFunctions(M)

a=theta*dt *inner(dot(c,epsilon(u1)) + dot(et_piezo,grad(phi1)), grad(u)) * dx

the error
Dimension mismatch in dot product.


UFLException Traceback (most recent call last)
in
----> 1 a=theta*dt *inner(dot(c,epsilon(u1)) + dot(et_piezo,grad(phi1)), grad(u)) * dx

~/anaconda3/envs/fenicsfix2/lib/python3.8/site-packages/ufl/operators.py in dot(a, b)
185 if a.ufl_shape == () and b.ufl_shape == ():
186 return a * b
→ 187 return Dot(a, b)
188
189

~/anaconda3/envs/fenicsfix2/lib/python3.8/site-packages/ufl/tensoralgebra.py in new(cls, a, b)
206 “got arguments with ranks %d and %d.” % (ar, br))
207 if not (scalar or ash[-1] == bsh[0]):
→ 208 error(“Dimension mismatch in dot product.”)
209
210 # Simplification

~/anaconda3/envs/fenicsfix2/lib/python3.8/site-packages/ufl/log.py in error(self, *message)
170 “Write error message and raise an exception.”
171 self._log.error(*message)
→ 172 raise self._exception_type(self._format_raw(*message))
173
174 def begin(self, *message):

UFLException: Dimension mismatch in dot product.

Please make sure that the code is actually executable. You are currently missing several definitions of variables.

Your issue is here, as:

In [11]: grad(u1).ufl_shape                                                                                                                                                   
Out[11]: (3, 2)

Thus you cannot add grad(u1) to grad(u1).T as they are not of the same shape.

Please think carefully about your example before adding another post to this thread.

sorry it’s true I’m posting the whole code

from fenics import *
from mshr import *
import numpy as np
from math import *
from matplotlib import pyplot as plt
from dolfin import *
import matplotlib.cm as cm
import matplotlib.tri as tri
from mpl_toolkits.axes_grid1 import make_axes_locatable
import ufl
# --------------------
# Parameters
# --------------------
c_11 = 1.19e11
c_12 = 0.84e11
c_13 = 0.83e11
c_33 = 1.17e11
c_44 = 0.21e11

eps_11 = 8.15e-9
eps_33 = 6.58e-9

e_15 = 12.09
e_13 = -6.03
e_33 = 15.49

alpha= 1.267e5
beta= 6.259e-10

rho_Piezo = Constant(7700.)

# Geometry of the domain

Diameter = 0.01
Thickness = 0.001 

#Rayleigh damping
alpha = 1.267e5
Beta = 6.259e-10
dt= 0.001  # time step
theta  = 0.5 
# Elasticity tensor c^E
c = as_matrix([[c_11, c_12, c_13, 0., 0., 0.], 
               [c_12, c_11, c_13, 0., 0., 0.],
               [c_13, c_13, c_33, 0., 0., 0.],
               [0., 0., 0., c_44, 0., 0],
               [0., 0., 0., 0., c_44, 0.],
               [0., 0., 0., 0., 0., (c_11-c_12)/2]])


# piezoelectric coupling tensor e
e_piezo = as_matrix([[0. , 0. , 0., 0. , e_15, 0.],
                   [0., 0., 0., e_15, 0., 0.],
                   [e_13, e_13, e_33, 0., 0., 0.]])


# transpose form of piezo tensor
et_piezo = as_matrix([[0., 0., e_13],
                    [0., 0., e_13],
                    [0., 0., e_33],
                    [0., e_15, 0.],
                    [e_15, 0., 0.],
                    [0., 0., 0.]])


# Permittivitatstensor  epsilon^S
eps_s = as_matrix([[eps_11, 0., 0.],
                    [0., eps_11, 0.],
                    [0., 0., eps_33]])
# Setup mesh
resolution = 30

geometry = Cylinder(Point(0, 0, 0), Point(0, 0, 0.001), 0.005, 0.005)


# Making Mesh (30 corresponds to the mesh density)
mesh = generate_mesh(geometry, resolution)
plot(mesh)
File("mesh.pvd") << mesh
plt.show()
# --------------------
# Functions and classes
# --------------------

V = VectorElement("CG", mesh.ufl_cell(), 2, dim=3)

W = FiniteElement("CG", mesh.ufl_cell(), 1)

M = FunctionSpace(mesh, MixedElement([V,V, W]))

# Get the needed boundaries: 
# 1. To apply a predefined stress on it We keep it simple: the top face sees the same stress vector. 
# 2. For zero Displacement we choose the bottom face of the disc
class TopBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and near(x[2], 0.001)

class BottomBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and near(x[2], 0.)

    
# Strain function   
def epsilon(u):
    strain_u=0.5*(grad(u)+grad(u).T)
    return strain_u
# define the potential
dt = 0.01
t = np.arange(0, 10.0, dt)

# Amplitude of the sine wave is sine of a variable like time
potential = np.sin(3*np.pi*(t-(20.0/2)))
phi = Expression("t", degree=0, t=potential[0])

# --------------------
# Boundary conditions
# --------------------
top_boundary = TopBoundary()
bottom_boundary = BottomBoundary()

# Create the boundary condition for displacement
boundary = []
boundary.append(DirichletBC(M.sub(2), 0., bottom_boundary))
boundary.append(DirichletBC(M.sub(2), phi, top_boundary))

for i in range(len(t)):
    phi.t = t[i]
    print(assemble(phi*dx(domain=mesh)))
# As the stress is defined over the outer surface we need to create a 
# integral over that surface
boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
boundaries.set_all(0)
top_boundary.mark(boundaries, 1)
bottom_boundary.mark(boundaries, 3)

dx = Measure("dx", domain=mesh, subdomain_data=boundaries)
ds = Measure("ds", subdomain_data=boundaries)
mf =  MeshFunction("size_t", mesh, mesh.topology().dim()-1)
mf.set_all(0)
top_boundary.mark(mf, 1)
bottom_boundary.mark(mf, 2)
# the initial values
zero1d=Expression('0.0', degree=1)
zero3d=Expression(('0.0','0.0','0.0'), degree=1)

u0=interpolate(zero3d,M.sub(0).collapse())
z0=interpolate(zero3d,M.sub(1).collapse())
phi0=interpolate(zero1d,M.sub(2).collapse())
# --------------------
# Function spaces
# --------------------

#Defining the "Trial" functions
u,z,phi=TrialFunctions(M)

#Defining the "Test" functions
u1,z1,phi1=TestFunctions(M)
# --------------------
# Weak form
# --------------------
a=rho_Piezo*inner(z1,u)*dx+theta*dt *inner(dot(c,epsilon(u1)) + dot(et_piezo,grad(phi1)), grad(u)) * dx

l = -rho_Piezo*inner(z0,u)*dx
+ theta*dt * inner(dot(c,epsilon(u0)) + dot(et_piezo,grad(phi0)),epsilon(u)) * dx

Dimension mismatch in dot product.


UFLException Traceback (most recent call last)
in
----> 1 a=rho_Piezo*inner(z1,u)dx+thetadt inner(dot(c,epsilon(u1)) + dot(et_piezo,grad(phi1)), grad(u)) * dx
2
3 l = -rho_Piezo
inner(z0,u)dx
4 + theta
dt * inner(dot(c,epsilon(u0)) + dot(et_piezo,grad(phi0)),epsilon(u)) * dx

~/anaconda3/envs/fenicsfix2/lib/python3.8/site-packages/ufl/operators.py in dot(a, b)
185 if a.ufl_shape == () and b.ufl_shape == ():
186 return a * b
→ 187 return Dot(a, b)
188
189

~/anaconda3/envs/fenicsfix2/lib/python3.8/site-packages/ufl/tensoralgebra.py in new(cls, a, b)
206 “got arguments with ranks %d and %d.” % (ar, br))
207 if not (scalar or ash[-1] == bsh[0]):
→ 208 error(“Dimension mismatch in dot product.”)
209
210 # Simplification

~/anaconda3/envs/fenicsfix2/lib/python3.8/site-packages/ufl/log.py in error(self, *message)
170 “Write error message and raise an exception.”
171 self._log.error(*message)
→ 172 raise self._exception_type(self._format_raw(*message))
173
174 def begin(self, *message):

UFLException: Dimension mismatch in dot product.

Good evening drokken,
please I would like to know if you can give me some indications how to solve this problem because I think I have solved all the errors and the code runs without error but the output does not receive any voltage although I have applied a value of -0.00098462 Volt on the upper side but the result is unchanged.

from fenics import *
from mshr import *
import numpy as np
from math import *
from matplotlib import pyplot as plt
from dolfin import *
import matplotlib.cm as cm
import matplotlib.tri as tri
from mpl_toolkits.axes_grid1 import make_axes_locatable
import ufl

c_11 = 1.19e11
c_12 = 0.84e11
c_13 = 0.83e11
c_33 = 1.17e11
c_44 = 0.21e11

eps_11 = 8.15e-9
eps_33 = 6.58e-9

e_15 = 12.09
e_13 = -6.03
e_33 = 15.49

alpha = 1.267e5
beta = 6.259e-10
theta = 0.5
rho_Piezo = Constant(7700.0)
# different tensor of  material

# Elasticity tensor c^E
C = as_tensor(
    [
        [c_11, c_12, c_13, 0.0, 0.0, 0.0],
        [c_12, c_11, c_13, 0.0, 0.0, 0.0],
        [c_13, c_13, c_33, 0.0, 0.0, 0.0],
        [0.0, 0.0, 0.0, c_44, 0.0, 0],
        [0.0, 0.0, 0.0, 0.0, c_44, 0.0],
        [0.0, 0.0, 0.0, 0.0, 0.0, (c_11 - c_12) / 2],
    ]
)


#  coupling tensor e
E_piezo = as_tensor(
    [
        [0.0, 0.0, 0.0, 0.0, e_15, 0.0],
        [0.0, 0.0, 0.0, e_15, 0.0, 0.0],
        [e_13, e_13, e_33, 0.0, 0.0, 0.0],
    ]
)


# transpose form  tensor
E_t_piezo = as_tensor(
    [
        [0.0, 0.0, e_13],
        [0.0, 0.0, e_13],
        [0.0, 0.0, e_33],
        [0.0, e_15, 0.0],
        [e_15, 0.0, 0.0],
        [0.0, 0.0, 0.0],
    ]
)

# Permittivitatstensor  epsilon^S
Eps_s = as_tensor([[eps_11, 0.0, 0.0], [0.0, eps_11, 0.0], [0.0, 0.0, eps_33]])
# Setup mesh
resolution = 10

geometry = Cylinder(Point(0, 0, 0), Point(0, 0, 0.001), 0.005, 0.005)

# Making Mesh (30 corresponds to the mesh density)
mesh = generate_mesh(geometry, resolution)
# --------------------
# Functions and classes
# --------------------

V = VectorElement("CG", mesh.ufl_cell(), 2, dim=3)

W = FiniteElement("CG", mesh.ufl_cell(), 1)

M = FunctionSpace(mesh, MixedElement([V, V, W]))


# Get the needed boundaries:
# 1. To apply a predefined stress on it We keep it simple: the top face sees the same stress vector.
# 2. For zero Displacement we choose the bottom face of the disc
class TopBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and near(x[2], 0.001)


class BottomBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and near(x[2], 0.0)


# first define the function for the strain tensor in fenics notation
# definition of the different components of my Stress tensor equation (sigma=C^E:Bu-e_transpose.E)

# rewrite the tensor into a vector using Voigt notation
def strain3voigt(ten):
    # FEniCS does not know anything about Voigt notation,
    # so one need to access the components directly as eps[0, 0] etc.
    return as_vector(
        [ten[0, 0], ten[1, 1], ten[2, 2], 2 * ten[1, 2], 2 * ten[0, 2], 2 * ten[0, 1]]
    )


# rewrite a vector into a tensor using Voigt notation
def voigt3stress(vec):
    # FEniCS does not know anything about Voigt notation,
    # so one need to rewrite the vector by hand into a tensor.
    return as_tensor(
        [[vec[0], vec[5], vec[4]], [vec[5], vec[1], vec[3]], [vec[4], vec[3], vec[2]]]
    )


# first define the function for the strain tensor in fenics notation
def B(u):
    # note that it would be shorter to use sym(grad(u)) but the way used now
    # represents the formula
    return 1.0 / 2.0 * (grad(u) + (grad(u).T))


# define the electric field vector
def E_field_val_vector(Ei):
    return as_vector([Ei[0], Ei[1], Ei[2]])


# define the electric field in relation to potential
def elect_field_E(phi):
    return -grad(phi)


# sigma for coupled linear elasicity and electrostatics
def sigma(u, phi):

    return voigt3stress(
        dot(C, strain3voigt(B(u))) + dot(E_t_piezo , E_field_val_vector(elect_field_E(phi)))
    )


# the electric displacements vector
def disp_D(Di):

    return as_vector([Di[0], Di[1], Di[2]])


# definition of the different components of my electric displacements equation (D=e^s:Bu+eps^S.E)
# elect_disp_D for coupled linear elasicity and electrostatics
def elect_disp_D(u, phi):

    elect_disp = dot(E_piezo ,strain3voigt(B(u))) - dot(Eps_s , elect_field_E(phi))

    return disp_D(elect_disp)

# define the potential
dt = 0.01
t = np.arange( -0.00098462, 20.0, dt)

# Amplitude of the sine wave is sine of a variable like time
potential = np.sin(3 * np.pi * (t - (20.0 / 2)))
phi = Expression("t", degree=0, t=potential[0])

# --------------------
# Boundary conditions
# --------------------
top_boundary = TopBoundary()
bottom_boundary = BottomBoundary()

# Create the boundary condition for displacement
boundary = []
boundary.append(DirichletBC(M.sub(2), 0.0, bottom_boundary))
boundary.append(DirichletBC(M.sub(2), phi, top_boundary))

for i in range(len(t)):
    phi.t = t[i]
    print(assemble(phi * dx(domain=mesh)))
# As the stress is defined over the outer surface we need to create a
# integral over that surface
boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
boundaries.set_all(0)
top_boundary.mark(boundaries, 1)
bottom_boundary.mark(boundaries, 2)

dx = Measure("dx", domain=mesh)
ds = Measure("ds", subdomain_data=boundaries)
mf = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
mf.set_all(0)
top_boundary.mark(mf, 1)
bottom_boundary.mark(mf, 2)
# the initial values
zero1d = Expression("0.0", degree=1)
zero3d = Expression(("0.0", "0.0", "0.0"), degree=1)

u0 = interpolate(zero3d, M.sub(0).collapse())
z0 = interpolate(zero3d, M.sub(1).collapse())
phi0 = interpolate(zero1d, M.sub(2).collapse())
# --------------------
# Function spaces
# --------------------

# Defining the "Trial" functions
u1, z1, phi1 = TrialFunctions(M)

# Defining the "Test" functions
v, y, w = TestFunctions(M)
# --------------------
# Weak form
# --------------------
tmps = Function(M)


a = (
    rho_Piezo * inner(z1, v) * dx
    + theta * dt * inner(sigma(u1, phi1), B(v)) * dx
    + theta * dt * alpha * rho_Piezo * inner(z1, v) * dx
    + theta * dt * beta * inner(dot(C, strain3voigt(B(z1))), strain3voigt(B(v))) * dx
    + inner(elect_disp_D(u1, phi1), grad(w)) * dx
    + inner(u1, y) * dx
    - theta * dt * (inner(z1, y)) * dx
)


l = (
    -rho_Piezo * inner(z0, v) * dx
    + theta * dt * inner(sigma(u0, phi0), B(v)) * dx
    + theta * dt * alpha * rho_Piezo * inner(z0, v) * dx
    + theta * dt * beta * inner(dot(C, strain3voigt(B(z0))), strain3voigt(B(v))) * dx
    - inner(u0, y) * dx
    - theta * dt * (inner(z0, y)) * dx
)
# assemble only A and L
A = assemble(a)
L = assemble(-l)
# apply A and L
for bc in boundary:
    bc.apply(A, L)
# solve the weak equation

solve(A, tmps.vector(), L)

u_result, z_result, phi_result = tmps.split()
FunctionAssigner(
    [M.sub(0).collapse(), M.sub(1).collapse(), M.sub(2).collapse()],
    tmps.function_space(),
)
assign(tmps.sub(0), u0)
assign(tmps.sub(1), z0)
assign(tmps.sub(2), phi0)
vtkfile = File("phi_result.pvd")
vtkfile << phi_result

the result I’d like to have.
willget

As I am not familiar with the PDE you are trying to solve, and your code is far from a minimal example, I cannot offer much assistance as to indicate what is not working.