FreeFEM Tutorial Shovkun
FreeFEM Tutorial Shovkun
Igor Shovkun
1 Introduction
Equilibrium equation:
−∇ · σ = f in Ω (1)
Linear elasticity:
σij = λδij ∇u + 2Gεij (3)
Definition of strain:
1 ∂ui ∂uj
εij = + (4)
2 ∂xj ∂xi
1
In the case of plane strain linear elasticity, the variational form look like this:
Z Z Z
[2Gεij (u)εij (v) + λεii (u)εjj (v)] dV + τ · n dS = f · v dV (6)
Ω ∂Ωn Ω
One problem of interest is to find stress component around a wellbore. Mathematically, this problem
implicates solving Eq. 1 in an infinite domain with a pressurized circular opening with radius R
and can be written as follows:
−∇σ = f
σxx (x = ±∞, y) = S1 (7)
σyy (x, y = ±∞) = S2
// Dimensions
real ySize = 1 0 . ; // y−s i z e o f t h e domain
real xSize = 1 0 . ; // x−s i z e o f t h e domain
r e a l R = 0 . 1 ; // w e l l b o r e r a d i u s
// E l a s t i c c o n s t a n t s
r e a l E = 1 e10 ; // young ’ s modulus
r e a l nu = 0 . 3 ; // p o i s s o n ’ s r a t i o
Then we calculate Lame constant and shear modulus that are used in the formulation:
r e a l G = E/(2∗(1+ nu ) ) ; // s h e a r modulus
2
r e a l lambda = E∗nu /((1+ nu )∗(1 −2∗ nu ) ) ; // Lame c o n s t a n t
// S t r e s s e s
r e a l Sx = 10 e6 ;
r e a l Sy = 10 e6 ;
r e a l Pwe l l = 0 . 0 ;
Next we proceed to the definition of the domain. We first define all the domain boundaries and
then create mesh:
// F i r s t d e f i n e b o u n d a r i e s
b o r d e r Right ( t=−y S i z e / 2 , y S i z e / 2 ) {x = x S i z e / 2 ; y = t ; }
b o r d e r Top ( t=x S i z e /2,− x S i z e / 2 ) {x = t ; y = y S i z e / 2 ; }
b o r d e r L e f t ( t=y S i z e /2,− y S i z e / 2 ) {x = −x S i z e / 2 ; y = t ; }
b o r d e r Bottom ( t=−x S i z e / 2 , x S i z e / 2 ) {x = t ; y = −y S i z e / 2 ; }
b o r d e r Well ( t = 0 , −2∗ p i ) {x = R∗ c o s ( t ) ; y = R∗ s i n ( t ) ; }
// Create mesh
int n = 2 0 ; // number o f mesh nodes on t h e o u t e r b o r d e r s
int n w e l l = 5 0 ; // number o f mesh nodes on w e l l o b r e
mesh Omega = buildmesh ( Right ( n)+Top ( n)+ L e f t ( n)+Bottom ( n)+Well ( n w e l l ) ) ;
The next step is to define Finite Element spaces. These object designate the type of shape functions
used to solve the problem. In this example we will be using “P1” elements for displacement:
continuous Galerkin polynomials of the first degree defined on triangles. To approximate stresses
we will use “P0” elements - piecewise constants.
// FE s p a c e s
f e s p a c e D i s p l a c e m e n t (Omega , P1 ) ; // l i n e a r s ha p e f u n c t i o n s
f e s p a c e S t r e s s (Omega , P0 ) ; // p i e c e w i s e c o n s t a n t s
Next, we will tell the interpreter to allocate several objects to store displacement components
(objects of type Displacement) and stresse components (objects of type Stress). u1 and u2 denote
3
x and y components of the displacement vector. v1 and v2 are the components of the virtual
displacement vector; we do not need those vectors per se, but we use these objects to code up
the system of equations. We also define objects sigmaxx, sigmaxy, and sigmayy to store stress
components. Note that we only need 3 components of the stress tensor because it is symmetric.
D i s p l a c e m e n t u1 , u2 , v1 , v2 ;
S t r e s s sigmaxx , sigmayy , sigmaxy ;
Next we define macros. Macros are special compiler instructions that are inserted into the part of
code where they are called during compilation (as opposed to runtime). In this code we use macros
in order to make the system of equation look neat later on. The following code defines two macros
for strain and stress “vectors”.
// d e f i n i t i o n o f 2 macros :
// macro f o r s t r a i n
macro e ( u1 , u2 )
[
dx ( u1 ) ,
( dy ( u1)+dx ( u2 ) ) / 2 ,
( dx ( u2)+dy ( u1 ) ) / 2 ,
dy ( u2 )
]
// e p s x x , e p s x y , e p s y x , e p s y y
// macro f o r s t r e s s
macro sigma ( u1 , u2 )
[
( lambda +2.∗G) ∗ e ( u1 , u2 ) [ 0 ] + lambda ∗ e ( u1 , u2 ) [ 3 ] ,
2 . ∗G∗ e ( u1 , u2 ) [ 1 ] ,
2 . ∗G∗ e ( u1 , u2 ) [ 2 ] ,
lambda ∗ e ( u1 , u2 ) [ 0 ] + ( lambda +2.∗G) ∗ e ( u1 , u2 ) [ 3 ]
] // s t r e s s sxx , sxy , syx , s y y
4
Now, we can finally define the system to be solved corresponding to the Formulation (ref).
// D e f i n e system o f e q u a t i o n s
problem E l a s t i c i t y ( [ u1 , u2 ] , [ v1 , v2 ] ) =
i n t 2 d (Omega) ( sigma ( u1 , u2 ) ’ ∗ e ( v1 , v2 ) )
// Boundary c o n d i t i o n s
+ i n t 1 d (Omega , Right ) ( Sx∗ v1 )
− i n t 1 d (Omega , L e f t ) ( Sx∗ v1 )
+ i n t 1 d (Omega , Top ) ( Sy∗ v2 )
− i n t 1 d (Omega , Bottom ) ( Sy∗ v2 )
+ i n t 1 d (Omega , Well ) ( P we ll ∗ (N. x∗ v1 + N. y∗ v2 ) )
;
// S o l v e system
Elasticity ;
// S t r e s s e s
sigmaxx = sigma ( u1 , u2 ) [ 0 ] ;
sigmayy = sigma ( u1 , u2 ) [ 3 ] ;
sigmaxy = sigma ( u1 , u2 ) [ 1 ] ; // we c o u l d use [ 2 ] as w e l l
The changes in the code are minor. Instead of a wellbore we need to define a fracture:
r e a l x f = 4 0 ; // f r a c t u r e h a l f −l e n g t h
r e a l fw = 0 . 1 ; // f r a c t u r e h a l f −w i d t h
5
b o r d e r Frac ( t = 0 , −2∗ p i ) {x = fw ∗ c o s ( t ) ; y = x f ∗ s i n ( t ) ; }
The bondary condition on the fracture boundary are also a little bit different:
// D e f i n e system o f e q u a t i o n s
problem E l a s t i c i t y ( [ u1 , u2 ] , [ v1 , v2 ] ) =
i n t 2 d (Omega) ( sigma ( u1 , u2 ) ’ ∗ e ( v1 , v2 ) )
// Boundary c o n d i t i o n s
+ i n t 1 d (Omega , Right ) ( Sx∗ v1 )
− i n t 1 d (Omega , L e f t ) ( Sx∗ v1 )
+ i n t 1 d (Omega , Top ) ( Sy∗ v2 )
− i n t 1 d (Omega , Bottom ) ( Sy∗ v2 )
// c o n d i t i o n o n l y on one component
+ i n t 1 d (Omega , Frac ) ( P f r a c ∗ (N. x∗ v1 ) )
;