Mission
Consider a plane (a*b
rectangular). On the left side, the edge is attached to a wall but can move freely along a vertical axis. On the right side, a pressure p
is applied that stretches the plate.
A sketch:
Attempt at solution
So I took a look at a couple of examples and I came up with the following code relevant to the problem definition:
varf elas([u1,u2],[v1,v2]) =
int2d(Th)(
lam*div(u1,u2)*div(v1,v2)
+2.*mu*( epsilon(u1,u2)'*epsilon(v1,v2) )
)
+ on(4, u1 = 0)
;
varf l([u1,u2],[v1,v2]) = int1d(Th, 2)(p * v1);
matrix A = elas(Nh, Nh); // Stiffness matrix.
real[int] b = l(0, Nh); // External forces.
real[int] U(A.n);
U = A^-1*b;
So displacement in x
direction on the left side is fixed to 0 and pressure is applied to the right side. I did not fix the displacement along the y
axis.
However, this does not produce correct results, as
real[int] U1(A.n/2),U2(A.n/2);
for(int i=0; i<A.n/2; i++){
U1(i) = U(2*i);
U2(i) = U(2*i+1);
}
cout << "max x: " << U1.max << endl;
cout << "max y: " << U2.max << endl;
prints out
//max x: 0.00247184
//max y: 0.00852047
while my reference (Abaqus) solution results in
//max x: 2.774e-3
//max y: 2.735e-4
Question
I checked the code several times but I can not find any mistakes. I don’t know what is wrong, but I am quite sure the results are NOT ok. Please help.
I am guessing this boundary condition
varf l([u1,u2],[v1,v2]) = int1d(Th, 2)(p * v1);
is not correctly written, but I am not sure how to fix it.
Entire code
load "medit"
// Generate mesh.
real x0 = 0;
real x1 = 1;
real y0 = 0;
real y1 = 0.5;
int n = 20;
real m = 10;
mesh Th = square(n, m, [x0+(x1-x0)*x, y0+(y1-y0)*y]);
plot(Th, wait=1, cmm="Mesh");
// **********
// Variables.
// **********
real sqrt2 = sqrt(2.);
real p = 2e8;
// Material properties.
real youngModul = 72.1e9; // Elasticity (Young) modulus.
real poisson = 0.33; // Poisson ratio.
// Print constants.
if (1) {
cout << "=========================" << endl;
cout << "E = " << youngModul << endl;
cout << "poissonRatio = " << poisson << endl;
cout << "=========================" << endl;
}
// Lame parameters
real mu = youngModul / 2. / (1. + poisson);
real lam = youngModul * poisson / (1. - 2. * poisson) / (1. + poisson);
real G = youngModul / 2. / (1. + poisson);
// Print derived constants.
if (1) {
cout << "=========================" << endl;
cout << "mu = " << mu << endl;
cout << "lam = " << lam << endl;
cout << "G = " << G << endl;
cout << "=========================" << endl;
}
// *********************
// Finite element space.
// *********************
// The finite element space defined over mesh
fespace Vh(Th, P1);
fespace Nh(Th, [P1, P1]);
// FEM variables.
Vh v;
Nh [u1,u2], [v1,v2];
// *******
// Macros.
// *******
macro grad(u) [dx(u), dy(u)] //EOM
macro div(u1, u2) (dx(u1) + dy(u2)) // EOM
macro epsilon(u1, u2) [dx(u1), dy(u2), (dy(u1) + dx(u2)) / sqrt2] // EOM
macro e(u1, u2) [dx(u1), dy(u2), dz(u3), dy(u1) + dx(u2)] // EOM
macro matE [[(lam + 2. * mu), lam, 0.],
[lam, (lam + 2. * mu), 0.],
[0., 0., mu]] // EOM
// ***********************
// Variational definition.
// ***********************
varf elas([u1,u2],[v1,v2]) =
int2d(Th)(
lam*div(u1,u2)*div(v1,v2)
+2.*mu*( epsilon(u1,u2)'*epsilon(v1,v2) )
)
+ on(4, u1 = 0)
;
varf l([u1,u2],[v1,v2]) = int1d(Th, 2)(p * v1);
matrix A = elas(Nh, Nh); // Stiffness matrix.
real[int] b = l(0, Nh); // External forces.
real[int] U(A.n);
U = A^-1*b;
real[int] U1(A.n/2),U2(A.n/2);
for(int i=0; i<A.n/2; i++){
U1(i) = U(2*i);
U2(i) = U(2*i+1);
}
cout << "max x: " << U1.max << endl;
cout << "max y: " << U2.max << endl;