Edit
Thanks for the responses. I now agree with xzczd and Bill Watts who kindly gave answers and user21 who wrote useful comments. Both my cases below are correct. On reflection I think I made an elementary mistake. I noted the need to give a Dirichlet Condition for the u-direction to provide a reference for displacements. I should have just tied down one point using the condition
DirichletCondition[u[x, y] == 0, x == 0 && y == 0]
Instead I wrote
DirichletCondition[u[x, y] == 0, x == 0]
This latter condition fixes the entire edge y == 0
. Fixing this edge introduces asymmetry. I apologise if I have caused pointless concerns. I have also added the single point DirichletCondition as Case 3 below. This gives the same result as Case 1 but fixes a starting point. Thanks to all that helped.
Original Question
If a DirichletCondition
is not specified in NDSolve
then a warning is given. However, if I specify a condition then I seem to get the wrong answer. Below I have Case 1 where I get the warning and then Case 2 where I don't but I think the answer is wrong. Here is a minimum working example involving a stress computation. We need the following code
Needs["NDSolve`FEM`"]
ClearAll[planeStress];
planeStress[
Y_, ν_] := {Inactive[
Div][{{-(Y/(1 - ν^2)),
0}, {0, -((Y*(1 - ν))/(2*(1 - ν^2)))}} .
Inactive[Grad][u[x, y], {x, y}], {x, y}] +
Inactive[
Div][{{0, -((Y*ν)/(1 - ν^2))}, {-((Y*(1 - ν))/(2*(1 \
- ν^2))), 0}} . Inactive[Grad][v[x, y], {x, y}], {x, y}],
Inactive[
Div][{{0, -((Y*(1 - ν))/(2*(1 - ν^2)))}, {-((Y*ν)/(1 \
- ν^2)), 0}} . Inactive[Grad][u[x, y], {x, y}], {x, y}] +
Inactive[
Div][{{-((Y*(1 - ν))/(2*(1 - ν^2))),
0}, {0, -(Y/(1 - ν^2))}} .
Inactive[Grad][v[x, y], {x, y}], {x, y}]}
Case 1. I make a rectangular grid and apply a force to part of the top surface. The bottom is prevented from moving vertically and is free horizontally. There are no other horizontal forces or constraints.
L = 1; (* Length *)
h = 0.2; (* Height *)
Y = 20 10^10;(* Modulus of elasticity *)
ν = 33/100 ;(* Poission ratio *)
stress = 100;
mesh = ToElementMesh[Rectangle[{0, 0}, {L, h}]];
mesh["Wireframe"]
Now the solver
{uif, vif} = NDSolveValue[{
planeStress[Y, ν] == {0,
NeumannValue[-stress, L/4 <= x <= 3 L/4 && y == h]},
DirichletCondition[v[x, y] == 0, 0 <= x <= L && y == 0]
},
{u, v}, Element[{x, y}, mesh]];
I get the message
NDSolveValue::femibcnd: No DirichletCondition or Robin-type NeumannValue was specified for {u}; the result may not be unique.
The results are good if I Plot
the horizontal displacement along the bottom edge I get
Plot[uif[x, 0], {x, 0, L}]
This has an arbitrary starting point but appears good and retains the symmetry of the problem. To test further I check the derivative (which I need to calculate the stress) and see if the left and right side are similar
du = Head@D[uif[x, y], x];
Plot[du[x, 0], {x, 0, L}]
Plot[du[x, 0] - du[L - x, 0], {x, 0, L/2}]
So far so good. I have a symmetric solution which is very good with the left and right sides differing only by numerical noise. However, I do have an arbitrary starting point for the horizontal displacement.
Case2. Now I try and fix the starting point for horizontal displacements by giving an additional DirichletCondition
at one end of the mesh.
{uif, vif} = NDSolveValue[{
planeStress[Y, ν] == {0,
NeumannValue[-stress, L/4 <= x <= 3 L/4 && y == h]},
DirichletCondition[v[x, y] == 0, 0 <= x <= L && y == 0],
DirichletCondition[u[x, y] == 0, x == 0]
},
{u, v}, Element[{x, y}, mesh]];
This is where everything begins to go wrong. Plotting the displacement along the bottom edge gives
Plot[uif[x, 0], {x, 0, L}]
This starts from zero. Checking the derivative again I see problems
du = Head@D[uif[x, y], x];
Plot[du[x, 0], {x, 0, L}]
Plot[du[x, 0] - du[L - x, 0], {x, 0, L/2}]
Now there is a clear distortion and the left and right hand sides are not symmetric. What has gone wrong? Is there a workaround so that I can fix the location of the start of the displacements? Thanks
Edit
In the comments user21 suggests that in the second case the Dirichlet condition is applied to just one side so that this is an asymmetric case automatically. However, on physical grounds I think the symmetry should still be there particularly in the derivatives (the stresses).
Only vertical forces are applied. There are horizontal displacements due to the Poisson Ratio effect. This will cause the horizontal length of the block to increase. When considering stresses this effect will be symmetric. All this is confirmed in Case 1. When we come to Case 2 then when the Poisson Ratio expansion occurs the expansion to the left is prevented by the stop there. However, there are no other horizontal constraints so the block should push against the stop and all the expansion should be to the right. Thus in Case 2 the displacements should be the same as in Case 1 except for everything moving to the right. The derivatives on the left and right (the stresses) should just be the same. This is an argument from the physical stress analysis viewpoint. From the numerical viewpoint I think a constant should be added to the displacements. I suspect a gradient is being added to the displacements. I am surprised that in the first case there is a solution at all since there is nothing to tie down the system. I hope that adds some more background.
Edit 2 User xzczd has asked for the boundary condition in math notation. What I want is to define the stress on the upper surface. Thus
$$ 100 = \sigma_{yy} = \frac{E}{1 - \nu^2} (\frac{\partial v(x, y)}{\partial y} + \nu \frac{\partial u(x, y)}{\partial x})$$
for $ 1/4 < x < 3/4 $ and $ y = 0.2$.
Here $\sigma_{yy}$ is the stress in the vertical direction. I have the stress going downwards so this may be -σyy depending on the sign convention for the boundary. Also modulus of elasticity $E$ and Poisson Ratio $ν$ are E = 20 *10^10
and ν =0.33
** Edit and Case 3**
One point at x = 0 and y = 0 fixed.
{uif, vif} = NDSolveValue[{
planeStress[Y, ν] == {0,
NeumannValue[-stress, L/4 <= x <= 3 L/4 && y == h]},
DirichletCondition[v[x, y] == 0, 0 <= x <= L && y == 0],
DirichletCondition[u[x, y] == 0, x == 0 && y == 0]
},
{u, v},
Element[{x, y}, mesh]
];
The same checks as above
Plot[uif[x, 0], {x, 0, L}]
du = Head@D[uif[x, y], x];
Plot[du[x, 0], {x, 0, L}]
Plot[du[x, 0] - du[L - x, 0], {x, 0, L/2}]
No warning message and a symmetric result as expected.
NeumannValue
you refer to. In any case zero valuedNeumannValues
are eliminated at parser level. The never go into any equation. Also careful withActivate
in these equations as sub matrices A12, etc have asymmetric off diagonal components which are hard maintain in active form (see: Formal Partial Differential Equations) I have not checked is your usage ofActivate
is affecting the equation in that way. $\endgroup$NeumannValue[0, whatever]
does not contribute anything ever. It is taken out at parser level. Now, let's assume you haveNeumannValue[something, whatever]
andDirichletCondition[u==someting, whatever]
then theDirichletCondition
will trump theNeumannValue
. For coupled systems the uDirichletCondition
will overwrite the first NeumannValue that is part of the the first equation and the a v DirichletCondition will overwrite the second NeumannValue which is part of the second equation. $\endgroup$