5
$\begingroup$

I'm solving a linear elasticity problem and trying to plot a displacement/stress fields over the deformed mesh instead of the undeformed one. The deformed (red) and undeformed (black) meshes look like:

enter image description here

I tried the following:

Plot over undeformed mesh with

ContourPlot[vfun[x, y], {x, y} \[Element] mesh, 
 AspectRatio -> Automatic, PlotRange -> All, 
 ColorFunction -> ColorData["LightTemperatureMap"], Contours -> 50, 
 ContourLines -> False, ImageSize -> 200, PlotLegends -> Automatic]

and get

enter image description here

Plot over deformed mesh with

deformedMesh = ElementMeshDeformation[mesh, {ufun, vfun}];
ContourPlot[vfun[x, y], {x, y} \[Element] deformedMesh, 
 AspectRatio -> Automatic, PlotRange -> All, 
 ColorFunction -> ColorData["LightTemperatureMap"], Contours -> 50, 
 ContourLines -> False, ImageSize -> 200, PlotLegends -> Automatic]

and get

enter image description here

Since the domain of the deformed and undeformed meshes are differents, we are plot the interpolation function of the displacement over two different domains, hence the two contour plots are different. That is, the displacement values over the deformed mesh is not the one I want. I need keep displacement values unchanged but plotted over the deformed mesh.

This maybe a simple question. But I need help on this.

The minimum code is as follows.

ClearAll["Global`*"]

Needs["NDSolve`FEM`"]

op = {Inactive[
       Div][({{0, -((Y \[Nu])/((1 - 2 \[Nu]) (1 + \[Nu])))}, {-(Y/(
           2 (1 + \[Nu]))), 0}}.Inactive[Grad][v[x, y], {x, y}]), {x, 
       y}] + Inactive[
       Div][({{-((Y (1 - \[Nu]))/((1 - 2 \[Nu]) (1 + \[Nu]))), 
          0}, {0, -(Y/(2 (1 + \[Nu])))}}.Inactive[Grad][
         u[x, y], {x, y}]), {x, y}], 
    Inactive[
       Div][({{0, -(Y/(2 (1 + \[Nu])))}, {-((
           Y \[Nu])/((1 - 2 \[Nu]) (1 + \[Nu]))), 0}}.Inactive[Grad][
         u[x, y], {x, y}]), {x, y}] + 
     Inactive[
       Div][({{-(Y/(2 (1 + \[Nu]))), 
          0}, {0, -((
           Y (1 - \[Nu]))/((1 - 2 \[Nu]) (1 + \[Nu])))}}.Inactive[
          Grad][v[x, y], {x, y}]), {x, y}]} /. {Y -> 2.5, \[Nu] -> 
     1/4};(*note the negative sign in the expressions*)

Subscript[\[CapitalGamma], 
  D] = {DirichletCondition[{u[x, y] == 0.}, x == 0], 
   DirichletCondition[{v[x, y] == 0.}, y == 0]};

{ufun, vfun} = 
  NDSolveValue[{op == {0, -1}, Subscript[\[CapitalGamma], D]}, {u, 
    v}, {x, 0, 1}, {y, 0, 2}]; 
(*\[Del]\[CenterDot]\[Sigma]+Overscript[b, \[RightVector]]=0, given \
Overscript[b, \[RightVector]]={0,-1}*)

mesh = ufun["ElementMesh"];
Show[{
  mesh["Wireframe"[ "MeshElement" -> "BoundaryElements"]],
  ElementMeshDeformation[mesh, {ufun, vfun}][
   "Wireframe"[
    "ElementMeshDirective" -> Directive[EdgeForm[Red], FaceForm[]]]]}]
ContourPlot[vfun[x, y], {x, y} \[Element] mesh, 
 AspectRatio -> Automatic, PlotRange -> All, 
 ColorFunction -> ColorData["LightTemperatureMap"], Contours -> 50, 
 ContourLines -> False, ImageSize -> 200, PlotLegends -> Automatic]

deformedMesh = ElementMeshDeformation[mesh, {ufun, vfun}];

Show[{mesh["Wireframe"], 
  deformedMesh[
   "Wireframe"[
    "ElementMeshDirective" -> 
     Directive[EdgeForm[{Thin, Red}], FaceForm[]]]]}]
ContourPlot[vfun[x, y], {x, y} \[Element] deformedMesh, 
 AspectRatio -> Automatic, PlotRange -> All, 
 ColorFunction -> ColorData["LightTemperatureMap"], Contours -> 50, 
 ContourLines -> False, ImageSize -> 200, PlotLegends -> Automatic]
$\endgroup$

2 Answers 2

4
$\begingroup$

I am not sure that I understand what your question is, but if displacement values are the one in legend, you could try the following:

ContourPlot[vfun[x, y], {x, y} \[Element] mesh, 
  AspectRatio -> Automatic, PlotRange -> All, 
  ColorFunction -> ColorData["LightTemperatureMap"], Contours -> 50, 
  ContourLines -> False, ImageSize -> 200, 
  PlotLegends -> 
   Automatic] /. (g_Graphics :> ( 
    g /. {x_?NumericQ, y_?NumericQ} :> 
      Chop[(Through[{ufun, vfun}[x, y]] + {x, y})]))

enter image description here

$\endgroup$
4
  • $\begingroup$ Thank you, @halmir. That is what I want. Could you please explain a little bit of the command: (g_Graphics :> ( g /. {x_?NumericQ, y_?NumericQ} :> Chop[(Through[{ufun, vfun}[x, y]] + {x, y})])) $\endgroup$
    – Wilhelm
    Oct 26, 2017 at 18:00
  • 2
    $\begingroup$ basically, I did a coordinate translation of points inside graphics. g_Graphics :> find Graphics (it's mix of legend and graphics) and then {x_?NumericQ, y_?NumericQ} find numerical coordinates in Graphics, and Chop[(Through[{ufun, vfun}[x, y]] + {x, y})]) does transformation. $\endgroup$
    – halmir
    Oct 27, 2017 at 0:28
  • $\begingroup$ @halmir Is there a way to include the boundary of the deformed shape by a thick line in the above plot? $\endgroup$
    – KratosMath
    Feb 5, 2019 at 12:46
  • $\begingroup$ @MsenRezaee you could do Show[{res, deformedMesh[ "Wireframe"[{"MeshElement" -> "BoundaryElements", "MeshElementStyle" -> Thickness[.008]}]]}] where res is the contour plot from above $\endgroup$
    – halmir
    Feb 6, 2019 at 18:07
3
$\begingroup$

Another way to do it is to construct a new interpolating function over the deformed mesh with the original values like so:

deformedFun = 
 ElementMeshInterpolation[{deformedMesh}, vfun["ValuesOnGrid"]];

You can then proceed as in the undeformed case:

ContourPlot[deformedFun[x, y], {x, y} \[Element] deformedMesh, 
 AspectRatio -> Automatic, PlotRange -> All, 
 ColorFunction -> ColorData["LightTemperatureMap"], Contours -> 50, 
 ContourLines -> False, ImageSize -> 200, PlotLegends -> Automatic]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.