# defining DirichletBC of a Tensor function space

I have defined a tensor function space as

VV = TensorFunctionS

VV_0, VV_1, VV_2, VV_3, VV_4, VV_5, VV_6, VV_7, VV_8= VV.split()

and I would like to define a Dirichlet boundary condition of the components, VV_2, VV_5. VV_6, VV_7,VV_8 which are equal to 0.0

How can I do that?

## Question information

- Language:
- English Edit question

- Status:
- Solved

- For:
- DOLFIN Edit question

- Assignee:
- No assignee Edit question

- Solved by:
- Veena P

- Solved:
- 2013-03-12

- Last query:
- 2013-03-12

- Last reply:
- 2013-03-12

## This question was reopened

- 2013-03-07 by Veena P

Jan Domurath (jan-domurath) said : | #1 |

Hello Veena,

does something like this work?

zero = Constant(0)

bc_2 = DirichletBC(

bc_5 = DirichletBC(

bc_6 = DirichletBC(

... and so on

Cheers,

Jan

Veena P (vp1110) said : | #2 |

Thank you Jan

I have tried to used that but it seems that I need the bc_2, bc_5, bc_6, bc_7 and bc_8 written in a tensor form - that one look like a vector form.

Actually, my problem is a mixed formulation. The vector function space represents displacements and the tensor function space is a strain tensor

V = VectorFunctionS

V_x, V_y, V_z= V.split()

VV = TensorFunctionS

VV_0, VV_1, VV_2, VV_3, VV_4, VV_5, VV_6, VV_7, VV_8= VV.split()

MX = MixedFunctionSp

(u, u_Strain) = TrialFunctions(MX)

(w, w_Strain) = TestFunctions(MX)

So, when I define the dirichlet boundary condition of displacements, V_z = 0.0 - it is OK

bc1=

But, when I do the same approach on the strains, VV_2, VV_5. VV_6, VV_7,VV_8

bc2=

bc3=

.... and so on

and the variational form I have, the VV variables are in a tensor form u_Strain [i,j]

F1 = StressT(

F2 = (StressTS(

When I run the code, It shows error which says;

ERROR: Unable to solve variational problem

REASON: Unable to extract boundary condition arguments

Jan Domurath (jan-domurath) said : | #3 |

Hi,

> I have tried to used that but it seems that I need the bc_2, bc_5, bc_6, bc_7

> and bc_8 written in a tensor form - that one look like a vector form.

I'm not sure what you mean here, but AFAIK the tensor is somewhat linearized in

a row-major style. So the tensor T

/ T_11 T_12 T_13 \

T = | T_21 T_22 T_23 |

\ T_31 T_32 T_33 /

is indexed as

T_linearized = [T_11 T_12 T_13 T_21 T_22 T_23 T_31 T_32 T_33]

this way you only need one index to access the elements of the tensor.

Maybe someone how knows can answer this better.

>

> Actually, my problem is a mixed formulation. The vector function space

> represents displacements and the tensor function space is a strain tensor

>

> ...

>

> MX = MixedFunctionSp

>

Maybe this is the problem(?)

In a mixed formulation you're supposed to apply the boundary conditions on the

mixed function space (see for example:

http://

somewhere in the middle of the section "5.2. Implementation").

So instead of

> bc1=[DirichletB

you should write

bc1=

and for the tensor

bc2=

bc3=

.... and so on

Also, maybe (I'm guessing here), if you split your function spaces in a mixed

form you might need to write something like this(??):

V_x, V_y, V_z= MX.sub(0).split()

VV_0, VV_1, VV_2, VV_3, VV_4, VV_5, VV_6, VV_7, VV_8= MX.sub(1).split()

Anyhow, I don't really understand why you do this? Sorry!

Cheers,

Jan

Veena P (vp1110) said : | #4 |

I am trying to do this

from dolfin import *

set_log_

#geometry is a 3D beam

xlength=100.0#[m]

ylength=1.0#[m]

zlength=1.0#[m]

mesh=Box(

coor = mesh.coordinates()

V = VectorFunctionS

VV = TensorFunctionS

MX = MixedFunctionSp

V_x, V_y, V_z= MX.sub(0).split() #u_x, u_y, u_z

VV_0, VV_1, VV_2, VV_3, VV_4, VV_5, VV_6, VV_7, VV_8= MX.sub(1).split() #e11 e12 e13, e21 e22 e23, e31 e32 e33

(u, u_Strain) = TrialFunctions(MX)

(w, w_Strain) = TestFunctions(MX)

#for integer marking of the surface(surface is one dimensionless than volume)

#from the domain V find the parts of the surface to clamp and tract

D = mesh.topology(

left = compile_

right = compile_

right.length = xlength

bottom = compile_

top = compile_

top.length = ylength

back =compile_

front = compile_

front.length = zlength

neumann_domains = MeshFunction(

#marking the parts of the surface

neumann_

right.mark(

# For the ds(1) symbols to work we must obviously connect them (or a and L)

# to the mesh function marking parts of the boundary. This is done by a

# certain keyword argument to the assemble function:

ds = Measure(

#loading in the surface normal direction, the traction vector in MPa

tr=Expression(

#Body Force, the gravity accerlation in m/s^2

bf=Expression(

#a zero for the left clamped in the wall

null=Constant(

#stating the boundary values,which will be set after the assembly

#bc=[DirichletB

bc1=[DirichletB

bc2=[DirichletB

bc3=[DirichletB

bc=[bc1, bc2, bc3]

#material coeff.s of a stainlesss tell

nu=0.3

Rho=10 #kg/m^3

E=210e6 #MPa

G=E/(2.0*(1.0+nu))

Lambda=

mu=G

#metric

delta=Identity(

#index notation

i,j,k,l,

#Strain tensor

def StrainT(u):

return as_tensor(

#Stress tensor

def StressT(u):

return as_tensor(

#Stress tensor based on Strain (from extra field, strain)

def StressTS(u_Strain):

return as_tensor(

#variational form

F1 = StressT(

F2 = (StressTS(

a=lhs(F)

L=rhs(F)

mx = Function(MX)

# Solving linear variational problem

solve(a == L, mx, bc)

u, u_Strain = mx.split()

I have used "bc1=[Dirichlet

and used "bc2=[Dirichlet

for u_y = 0 and u_z =0 but it is not working.

Jan Domurath (jan-domurath) said : | #5 |

Hi,

I think I spotted the problem.

> bc1=[DirichletB

> bc2=[DirichletB

> bc3=[DirichletB

> bc=[bc1, bc2, bc3]

with this code you're defining a list of lists (of DirichletBC's), meaning bc

looks like

bc = [[DirichletBC(

[

[

but solve expects a flat list of DirichletBC's.

Just remove the square brackets around the DirichletBC(MX...

like:

bc1=DirichletBC

bc2=DirichletBC

bc3=DirichletBC

bc=[bc1, bc2, bc3]

this way your code works for me. (I assumed F = F1 + F2)

I also tried a DirichletBC for the strain

bc4=DirichletBC

bc.append(bc4)

and it works too.

Cheers,

Jan

Jan Domurath (jan-domurath) said : | #6 |

the link in answer #3 is wrong

sorry!

Jan Domurath (jan-domurath) said : | #7 |

Just for completeness

you could also concatenate the lists of DirichletBC's to one flat list

bc1=[DirichletB

bc2=[DirichletB

bc3=[DirichletB

bc = bc1 + bc2 + bc3

Jan

Veena P (vp1110) said : | #8 |

Thank you so much Jan that solved my problem.

Veena P (vp1110) said : | #9 |

However, according to what you said that the tensor is somewhat linearized in a row-major style

/ T_11 T_12 T_13 \

T = | T_21 T_22 T_23 |

\ T_31 T_32 T_33 /

T is indexed as

T_linearized = [T_11 T_12 T_13 T_21 T_22 T_23 T_31 T_32 T_33]

this way I only need one index to access the elements of the tensor but the variational form I am using is in the form of T[i,j], (i and j are indices) is that represent the same thing, using two indices in the variational form and using one index in the function space?

and also when define the stress tensor StressT(u) [i,j] as

def StressT(u):

return as_tensor(

Is the StressT(u)[i,j] linearized as well?

#variational form

F1 = StressT(

F2 = (StressTS(

F=F1+F2

Do I have to use one index to access the elements of StressT(u)?

Jan Domurath (jan-domurath) said : | #10 |

Hi,

sorry for the late reply.

> However, according to what you said that the tensor is somewhat linearized

> in a row-major style

>

> / T_11 T_12 T_13 \

> T = | T_21 T_22 T_23 |

> \ T_31 T_32 T_33 /

>

> T is indexed as

> T_linearized = [T_11 T_12 T_13 T_21 T_22 T_23 T_31 T_32 T_33]

here I meant only the TensorFunctionS

> this way I only need one index to access the elements of the tensor but the

> variational form I am using is in the form of T[i,j], (i and j are indices)

> is that represent the same thing, using two indices in the variational form

> and using one index in the function space?

The function space and the form are not the same thing.

The function space basically defines properties of the solution, like how the

solution can vary over an element and some other properties, e.g. if the

derivative of the solution is continuous or not.

The form specifies what equation (the weak form) the solution should fulfill.

(For more please look in some book on finite elements. A good start, with

references to some books, may be

http://

> and also when define the stress tensor StressT(u) [i,j] as

>

> def StressT(u):

> return as_tensor(

>

> Is the StressT(u)[i,j] linearized as well?

>

> #variational form

> F1 = StressT(

> F2 = (StressTS(

> F=F1+F2

>

> Do I have to use one index to access the elements of StressT(u)?

No, in the form you must use two indices (StressT(u)[i,j]) for 2nd order

tensors, one index for vectors and no index for scalars. This is like in math

and like you did it. For indexing of the function space on the other hand you

must use one index. That is somewhat strange but the way it is and I cannot

tell you why, sorry.

I hope this helps you.

Jan

Veena P (vp1110) said : | #11 |

Yes, Thank you so much.