I am trying to calculate the pressure required to flatten a bowed wafer. The simple model I am using for the study has a bottom layer (the bowed wafer) pushed against a harder flat surface as shown in Fig. 1.
Using the plane stress operator from the FEM tutorial I get a solution where the upper surface of the wafer protrudes from the bottom surface of the harder layer (when the pressure is high enough to overcome the gap). Fig. 2, where I combined the starting mesh boundary, in black, and the deformed one, in red, shows what I mean.
I am not a structural engineer, so I do not fully appreciate the subtleties of setting up a model for this case. Perhaps additional boundary conditions on the gap between the layers are needed. I could envision a condition involving inequalities (such as the difference between the top and the bottom deformation be less than the gap distance), but I am not sure how it could be accomplished in Mathematica's FEM framework. I am wondering how a solution that does not have this issue could be obtained using Mathematica FEM framework?
Here is the Mathematica code used for this example.
Needs["NDSolve`FEM`"];
pi = 3.1415926535897932384626433832795028845;
(* linear units *)
mm = N[1];
um = N[10^-3];
psi2GPa = 6.894757313303502*10^(-6);
(* structure geometry *)
h1 = 0.2 mm;
h2 = h1 + 1 mm;
s = 10 um;
w = 30 mm;
bmesh = ToBoundaryMesh[
ImplicitRegion[(y >= -s/2 (1 + Cos[(2 pi)/w x]) &&
y <= h1 - s/2 (1 + Cos[(2 pi)/w x])) || (y > h1 &&
y <= h2), {{x, -w/2, w/2}, y}]];
mesh = ToElementMesh[bmesh, MaxCellMeasure -> 1*10^-3];
(* uncomment section below to visualize the mesh *)
(*
bmesh["Wireframe"[ImageSize\[Rule]"Large"]]
Show[bmesh["Wireframe"[ImageSize\[Rule]400,AspectRatio\[Rule]0.2]],\
PlotRange\[Rule]{All,{0-s-2 um,h1+5 um}}]
bmesh["Wireframe"["MeshElement"\[Rule]"BoundaryElements",\
"MeshElementMarkerStyle"\[Rule]Blue,ImageSize\[Rule]500,AspectRatio\
\[Rule]0.2]]
Show[bmesh["Wireframe"["MeshElement"\[Rule]"BoundaryElements",\
"MeshElementMarkerStyle"\[Rule]Blue,ImageSize\[Rule]500]],PlotRange\
\[Rule]{All,{h1-s-1 um,h1+5 um}},AspectRatio\[Rule]0.2]
Show[mesh["Wireframe"],ImageSize\[Rule]"Large",PlotRange\[Rule]{{-100 \
um,100 um},{h1-50 um,h1+50 um}}]
*)
(* Material parameters *)
Y1 = 64;
nu1 = 0.2;
Y2 = 345;
nu2 = 0.29;
With[{h1 = h1, h2 = h2,
Y1 = Y1, Y2 = Y2,
nu1 = nu1, nu2 = nu2},
Y = If[y <= h1, Y1, Y2];
nu = If[y < h1, nu1, nu2];
];
(* Boundary Conditions *)
Subscript[\[CapitalGamma], D] =
DirichletCondition[{u[x, y] == 0, v[x, y] == 0}, y == h2];
psi = 0.015; (* applied pressure in psi *)
p = psi*psi2GPa;
Subscript[\[CapitalGamma], N] = {0,
NeumannValue[p,
ElementMarker ==
4]}; (* ElementMarker 4 is the bottom surface *)
(* plane stress operator *)
pde = {Inactive[
Div][({{0, -((Y nu)/(1 -
nu^2))}, {-((Y (1 - nu))/(2 (1 - nu^2))), 0}} .
Inactive[Grad][v[x, y], {x, y}]), {x, y}] +
Inactive[
Div][({{-(Y/(1 - nu^2)),
0}, {0, -((Y (1 - nu))/(2 (1 - nu^2)))}} .
Inactive[Grad][u[x, y], {x, y}]), {x, y}],
Inactive[Div][({{0, -((Y (1 - nu))/(2 (1 - nu^2)))}, {-((Y nu)/(1 -
nu^2)), 0}} . Inactive[Grad][u[x, y], {x, y}]), {x, y}] +
Inactive[
Div][({{-((Y (1 - nu))/(2 (1 - nu^2))),
0}, {0, -(Y/(1 - nu^2))}} .
Inactive[Grad][v[x, y], {x, y}]), {x, y}]};
(* Solve *)
{ufun, vfun} =
NDSolveValue[{pde == Subscript[\[CapitalGamma], N],
Subscript[\[CapitalGamma], D]}, {u, v}, {x, y} \[Element] mesh];
(* show the undeformed and deformed mesh boundary near the gap *)
Show[{mesh["Wireframe"["MeshElement" -> "BoundaryElements"]],
ElementMeshDeformation[mesh, {ufun, vfun}, "ScalingFactor" -> 1][
"Wireframe"["MeshElement" -> "BoundaryElements",
"MeshElementStyle" -> Red]]}, ImageSize -> 500,
AspectRatio -> 0.5, PlotRange -> {All, {h1 - s - 2 um, h1 + 5 um}}]
Update: Given that this problem seems to involve internal boundary conditions, I am starting to think that it would be too difficult to solve using the current Mathematica finite element framework (I would love to be proven wrong). Although that remains my problem at hand, for the sake of making some progress, I made it simpler by eliminating the top (harder) layer (as also suggested by Oleksii's comment). The new geometry is shown in Fig. 3 (it is the same thin wafer, but in the graph the aspect ratio was modified to make the bow more evident).
There are only two points of contact and a Dirichlet condition can only be defined for those two points. To account for the presence of the hard constrain in between these two points, we can define a fictitious external pressure that changes from zero to a large value as soon as the displacement gets close to the gap value. This can be done by defining a non-linear Neumann value. The transition from zero to a large pressure value can be implemented using a smoothed step function. The attached code is the implementation of this idea. Figg. 4 and 5 show the solution without and with the fictitious pressure. Unfortunately I get a warning message ("The line search decreased the step size to within tolerance specified by AccuracyGoal..."), so I was wondering if anybody could help fix this numerical issue.
Needs["NDSolve`FEM`"];
SmoothedStepFunction[fmin_, fmax_, ts_, m_] :=
Function[t, (fmin*Exp[ts*m] + fmax*Exp[m*t])/(Exp[ts*m] + Exp[m*t])]
steepnessFactor = 20000;
\[Theta] = SmoothedStepFunction[1, 0, 0, steepnessFactor];
pi = 3.1415926535897932384626433832795028845;
(* linear units *)
mm = N[1];
um = N[10^-3];
psi2GPa = 6.894757313303502*10^(-6);
(* structure geometry *)
h1 = 0.2 mm;
s = 10 um;
w = 30 mm;
bmesh1 = ToBoundaryMesh[
ImplicitRegion[(y >= -s/2 (1 + Cos[(2 pi)/w x]) &&
y <= h1 - s/2 (1 + Cos[(2 pi)/w x])), {{x, -w/2, w/2}, y}]];
mesh1 = ToElementMesh[bmesh1, MaxCellMeasure -> 1*10^-3];
(* uncomment section below to visualize the mesh *)
(*
bmesh1["Wireframe"[ImageSize\[Rule]"Large"]]
Show[bmesh1["Wireframe"[ImageSize\[Rule]"Large",AspectRatio\[Rule]0.2]\
]]
bmesh1["Wireframe"["MeshElement"\[Rule]"BoundaryElements",\
"MeshElementMarkerStyle"\[Rule]Blue,ImageSize\[Rule]500,AspectRatio\
\[Rule]0.2]]
Show[mesh1["Wireframe"],ImageSize\[Rule]"Large"]
*)
(* Material parameters *)
Y1 = 64;
nu1 = 0.2;
Y2 = 345;
nu2 = 0.29;
With[{h1 = h1, h2 = h2,
Y1 = Y1, Y2 = Y2,
nu1 = nu1, nu2 = nu2},
Y = If[y <= h1, Y1, Y2];
nu = If[y < h1, nu1, nu2];
];
(* Boundary Conditions *)
Subscript[\[CapitalGamma], D] =
DirichletCondition[{u[x, y] == 0, v[x, y] == 0},
y == h1(*&&(x\[Equal]-w/2||x\[Equal]w/2)*)];
psi = 0.1; (* applied pressure in psi *)
p = psi*psi2GPa;
Subscript[\[CapitalGamma], N1] = {0,
NeumannValue[p,
ElementMarker ==
1]}; (* ElementMarker 1 is the bottom surface *)Subscript[\
\[CapitalGamma], N2] = {0,
NeumannValue[-100 (1 - \[Theta][
v[x, y] - s/2 (1 + Cos[(2 pi)/w x])]), (-w/2 < x < w/2) &&
y == h1 - s/2 (1 + Cos[(2 pi)/w x])]};
(* plane stress operator *)
pde = {Inactive[
Div][({{0, -((Y nu)/(1 -
nu^2))}, {-((Y (1 - nu))/(2 (1 - nu^2))), 0}} .
Inactive[Grad][v[x, y], {x, y}]), {x, y}] +
Inactive[
Div][({{-(Y/(1 - nu^2)),
0}, {0, -((Y (1 - nu))/(2 (1 - nu^2)))}} .
Inactive[Grad][u[x, y], {x, y}]), {x, y}],
Inactive[
Div][({{0, -((Y (1 - nu))/(2 (1 - nu^2)))}, {-((Y nu)/(1 -
nu^2)), 0}} . Inactive[Grad][u[x, y], {x, y}]), {x,
y}] + Inactive[
Div][({{-((Y (1 - nu))/(2 (1 - nu^2))),
0}, {0, -(Y/(1 - nu^2))}} .
Inactive[Grad][v[x, y], {x, y}]), {x, y}]};
(* Solve without the fictitious pressure*)
{u0, v0} =
NDSolveValue[{pde == Subscript[\[CapitalGamma], N1],
Subscript[\[CapitalGamma], D]}, {u, v}, {x, y} \[Element] mesh1];
(* show the undeformed and deformed mesh boundary *)
Print["Deformation without the fictitious pressure"];
Show[{mesh1["Wireframe"["MeshElement" -> "BoundaryElements"]],
ElementMeshDeformation[mesh1, {u0, v0}, "ScalingFactor" -> 1][
"Wireframe"["MeshElement" -> "BoundaryElements",
"MeshElementStyle" -> Red]]}, ImageSize -> 500, AspectRatio -> 0.3]
(* Solve with the fictitious pressure*)
{u1, v1} =
NDSolveValue[{pde ==
Subscript[\[CapitalGamma], N1] + Subscript[\[CapitalGamma], N2],
Subscript[\[CapitalGamma], D]}, {u, v}, {x, y} \[Element] mesh1,
Method -> {"PDEDiscretization" -> {"FiniteElement",
"PDESolveOptions" -> {"FindRootOptions" -> {Method -> \
{"Newton"}}}}}];
Print["Deformation with the fictitious pressure"];
Show[{mesh1["Wireframe"["MeshElement" -> "BoundaryElements"]],
ElementMeshDeformation[mesh1, {u1, v1}, "ScalingFactor" -> 1][
"Wireframe"["MeshElement" -> "BoundaryElements",
"MeshElementStyle" -> Red]]}, ImageSize -> 500,
AspectRatio -> 0.3]
Second Update: Looking at the user21 result, I also thought that the issue was the inability of the top surface to move in the x direction due to the Dirichlet condition u[x,y]==0 when y==h1. I think that, due to the symmetry, an appropriate replacement is u[x,y]==0 when (y<0 && x==0). Here are the modifications to the code.
delta = w/500; (* a small fraction of w *)
(* Boundary Conditions *)
dbc = {DirichletCondition[v[x, y] == 0, y == h1],
DirichletCondition[u[x, y] == 0,
y <= 0 && -delta/2 <= x <= delta/2]};
nbc1 = {0, NeumannValue[p, y <= 0]}; nbc2 = {0,
NeumannValue[
If[(y + v[x, y]) < h1, 0, 1/10^4*(0 - v[x, y])], (-w/2 < x < w/2) &&
y >= h1 - s/2 (1 + Cos[(2 Pi)/w x])]};
{u1, v1} =
NDSolveValue[{pde == nbc1 + nbc2, dbc, Sequence[]}, {u,
v}, {x, y} \[Element] mesh1, Method -> {"PDEDiscretization" ->
{"FiniteElement",
"PDESolveOptions" -> {"FindRootOptions" -> {Method -> {"Newton"}}}}
}];
Even though now the top surface can slide in the x direction, as shown in the plot detailing the top left corner, the solution still penetrates into the constraining surface. The FindRoot::lstol error message is generated during the computation. If the "Newton" method is not specified, then FindRoot fails.
Another interesting thing is that if I use the user21's code, i.e. with the problematic Dirichlet condition, and specify "Newton" in the FindRootOptions, then the solution is very similar to Fig. 7 (except for the top corners), i.e. the dip in the middle is below the blue line (a FindRoot::lstol error message is issued even in this case). The fact that we are getting two solutions (with different error messages) depending on the method used does not give me confidence that we are getting closer to the correct solution.