1

I started to try to solve PDEs in WM and I go gradually according to tutorial. Unfortunately, I couldn't get any solution other than that copied from the tutorial. So I ask someone more experienced to advise me where I made a mistake. Take, for example, Navier-Sotkes PDEs to solve fluid flow around a cylindrical obstacle (the first part is a stationary solution, the second part is a time-varying case).

My question is general: How to construct initial and boundary conditions for the same time-varying task (second part) so that the initial conditions are not constants but functions and that there is a solution and WM finds it?

My attempt: I tried to set the initial conditions so that at time t = 0, the functions of velocities u and v were equal to the stationary solution. And the boundary condition at one end the value of velocity in the x-direction increased (that is, a variation of the original solution, instead zero initial velocities is a stationary solution) all see the code. However, WM throws an error: "LinearSolve::nosol: Linear equation encountered that has no solution." Do you have any ideas what can be wrong and how to fix it?

CODE:

(*Stationary Navier–Stokes equation*)
ClearAll["Global`*"]
rules = {length -> 22/10, hight -> 41/100};
Ω = 
  RegionDifference[Rectangle[{0, 0}, {length, hight}], 
    Disk[{1/5, 1/5}, 1/20]] /. rules;
region = RegionPlot[Ω, AspectRatio -> Automatic]

op = {Inactive[
             Div][({{-μ, 0}, {0, -μ}}.Inactive[Grad][
                 u[x, y], {x, y}]), {x, 
             y}] + ρ {{u[x, y], v[x, y]}}.Inactive[Grad][
               u[x, y], {x, y}] + 

\!\(\*SuperscriptBox[\(p\), 
TagBox[
RowBox[{"(", 
RowBox[{"1", ",", "0"}], ")"}],
Derivative],
MultilineFunction->None]\)[x, y], 
       Inactive[
             Div][({{-μ, 0}, {0, -μ}}.Inactive[Grad][
                 v[x, y], {x, y}]), {x, 
             y}] + ρ {{u[x, y], v[x, y]}}.Inactive[Grad][
               v[x, y], {x, y}] + 

\!\(\*SuperscriptBox[\(p\), 
TagBox[
RowBox[{"(", 
RowBox[{"0", ",", "1"}], ")"}],
Derivative],
MultilineFunction->None]\)[x, y], 

\!\(\*SuperscriptBox[\(u\), 
TagBox[
RowBox[{"(", 
RowBox[{"1", ",", "0"}], ")"}],
Derivative],
MultilineFunction->None]\)[x, y] + 

\!\(\*SuperscriptBox[\(v\), 
TagBox[
RowBox[{"(", 
RowBox[{"0", ",", "1"}], ")"}],
Derivative],
MultilineFunction->None]\)[x, y]} /. {μ -> 10^-3, ρ -> 1}
pde = op == {0, 0, 0};

(*Boudnary conditions*)
bcs = {DirichletCondition[u[x, y] == 4*0.3*y*(hight - y)/hight^2, 
     x == 0], DirichletCondition[v[x, y] == 0, x == 0], 
    DirichletCondition[{u[x, y] == 0., v[x, y] == 0.}, 
     x > 0 && x < length], 
    DirichletCondition[p[x, y] == 0., x == length]} /. rules;
(*Create a refinement function based on the region of refinement, \
smaller mesh grid in this region - more precises*)
refinementRegion = 
  ImplicitRegion[
    a^4 (23 (y - 1/5))^2 + 
      b^2 (5/2 x - 2.05)^3 (2 a + (5/2 x - 2.05)) < 
     0, {{x, 0, length}, {y, 0, hight}}] /. 
   Flatten[{rules, a -> 1, b -> 5/2}];
Show[RegionPlot[Ω], RegionPlot[refinementRegion], 
 AspectRatio -> Automatic]
mrf = With[{rmf = RegionMember[refinementRegion]}, 
   Function[{vertices, area}, Block[{x, y}, {x, y} = Mean[vertices];
     If[rmf[{x, y}], area > 0.00025, area > 0.0025]]]];
(*Solution, u has to have higher order of of interpolation than p*)
{sxVel, syVel, spressure} = 
  NDSolveValue[{pde, bcs}, {u, v, p}, 
   Element[{x, y}, Ω], 
   Method -> {"FiniteElement", 
     "InterpolationOrder" -> {u -> 2, v -> 2, p -> 1}, 
     "MeshOptions" -> {"IncludePoints" -> {{0.15, 0.2}, {0.25, 0.2}}, 
       AccuracyGoal -> 5, PrecisionGoal -> 5, 
       MeshRefinementFunction -> mrf}}];
Show[ContourPlot[
  Sqrt[sxVel[x, y]^2 + syVel[x, y]^2], {x, 
    y} ∈ Ω, ColorFunction -> "TemperatureMap", 
  Contours -> 4], 
 ContourPlot[spressure[x, y] == #, {x, y} ∈ Ω, 
    ContourStyle -> Directive[Black, Thickness[0.002]]] & /@ {0.01, 
   0.02, 0.05, 0.08}, 
 VectorPlot[{sxVel[x, y], 
   syVel[x, y]}, {x, y} ∈ Ω, VectorPoints -> 9,
   VectorScale -> .05, VectorStyle -> {LightGray}], 
 AspectRatio -> Automatic, ImageSize -> Large]

(*Transient Navier–Stokes equation*)
ClearAll[ρ, μ]
op = {ρ*D[u[t, x, y], t] + 
     Inactive[
       Div][({{-μ, 0}, {0, -μ}}.Inactive[Grad][
         u[t, x, y], {x, y}]), {x, 
       y}] + ρ*{{u[t, x, y], v[t, x, y]}}.Inactive[Grad][
        u[t, x, y], {x, y}] + 
     D[p[t, x, y], x], ρ*D[v[t, x, y], t] + 
     Inactive[
       Div][({{-μ, 0}, {0, -μ}}.Inactive[Grad][
         v[t, x, y], {x, y}]), {x, 
       y}] + ρ*{{u[t, x, y], v[t, x, y]}}.Inactive[Grad][
        v[t, x, y], {x, y}] + D[p[t, x, y], y], 
    D[u[t, x, y], x] + D[v[t, x, y], y]} /. {μ -> 10^-3, ρ ->
      1};

(*ramp fucntion*)
rampFunction[min_, max_, c_, r_] := 
 Function[t, (min*Exp[c*r] + max*Exp[r*t])/(Exp[c*r] + Exp[r*t])]
sf = rampFunction[0, 1, 4, 5];
Plot[sf[t], {t, -1, 10}, PlotRange -> All]

(*boundary conditions*)
bcs = {DirichletCondition[
    u[t, x, y] == sf[t]*4*1.5*y*(hight - y)/hight^2, x == 0], 
   DirichletCondition[u[t, x, y] == 0., 0 < x < length], 
   DirichletCondition[v[t, x, y] == 0, 0 <= x < length], 
   DirichletCondition[p[t, x, y] == 0., x == length]} /. 
  rules;(*original bc*)
bcs = {DirichletCondition[u[t, x, y] == (sf[t] + 1) sxVel[x, y], 
    x == 0], DirichletCondition[u[t, x, y] == 0., 0 < x < length], 
   DirichletCondition[v[t, x, y] == 0, 0 <= x < length], 
   DirichletCondition[p[t, x, y] == 0., x == length]} /. 
  rules;(*my bc*)

(*initial conditions*)
ic = {u[0, x, y] == 0, v[0, x, y] == 0, p[0, x, y] == 0} /. 
  rules;(*original ic*)
ic = {u[0, x, y] == sxVel[x, y], v[0, x, y] == syVel[x, y], 
   p[0, x, y] == spressure[x, y]} /. rules;(*my ic*)

(*solution*)
Dynamic["time: " <> ToString[CForm[currentTime]]]
AbsoluteTiming[{xVel, yVel, pressure} = 
   NDSolveValue[{op == {0, 0, 0}, bcs, ic}, {u, v, 
     p}, {x, y} ∈ Ω, {t, 0, 10}, 
    Method -> {"TimeIntegration" -> {"IDA", 
        "MaxDifferenceOrder" -> 2}, 
      "PDEDiscretization" -> {"MethodOfLines", 
        "DifferentiateBoundaryConditions" -> True, 
        "SpatialDiscretization" -> {"FiniteElement", 
          "InterpolationOrder" -> {u -> 2, v -> 2, p -> 1}, 
          "MeshOptions" -> {"MaxCellMeasure" -> 0.0005}}}}, 
    EvaluationMonitor :> (currentTime = t;)];]

(*visualization*)
{minX, maxX} = MinMax[xVel["ValuesOnGrid"]]
mesh = xVel["ElementMesh"]
AbsoluteTiming[
 frames = Table[
    Rasterize[
     ContourPlot[xVel[t, x, y], {x, y} ∈ mesh, 
      PlotRange -> All, AspectRatio -> Automatic, 
      ColorFunction -> "TemperatureMap", 
      Contours -> Range[minX, maxX, (maxX - minX)/7], Axes -> False, 
      Frame -> None], RasterSize -> 2*{360, 68}, 
     ImageSize -> {360, 68}], {t, 0, 10, 1/12}];]
Vrbic
  • 75
  • 7
  • Do you want to solve this problem or just to test code? – Alex Trounev Apr 19 '20 at 20:23
  • @Alex Trounev, thank you for a response! If I'm right you are bigwig in programming in WM. I would like to solve different problem which I posted previously ( https://mathematica.stackexchange.com/questions/219583/problem-with-a-solution-of-pde-with-initial-and-boundary-conditions?noredirect=1#comment559288_219583 ), but nobody could help. The problem is probably too much complicated to ask at the forum. So I decided to go step by step and learn it from tutorial. My idea is to adjust already working code or learn from that. – Vrbic Apr 20 '20 at 04:01
  • bigwig in programming in WM I assumed you meant beginning there. Normally when one is starting to learn new language/environment, they pick very small and simple problems first. You seem to jump to the most complex problems right away, and then ask how to solve them using Mathematica when you say yourself you are just a beginner in it. This for me does not sound like a logical way to learn new language. If you want to learn FEM in Mathematica, it is better to start with simpler examples. Just my 2 cents ofcourse as you are free to do what you wish. – Nasser Apr 20 '20 at 04:29
  • @Nasser. Thank you. I didn't mean beginner generally but in a PDE solution. I have been working with WM for a couple of years, but mostly I dealt with ODE, (thesis, etc.). I know where you're pointing, but I read many tutorials, and I haven't moved much because I was mostly unable to change any tutorial example. Most of the changes I tried to make in learning led to a mistake that I couldn't solve. And I did not find the tutorial one level down. I understand and accept your comment, and if you have any idea, text or anything, let me know. – Vrbic Apr 20 '20 at 04:51
  • 1
    @Nasser I think "bigwig" was meant as a compliment to Alex ;) – Henrik Schumacher Apr 20 '20 at 08:19
  • @HenrikSchumacher opps, I am not good at modern linguistics terms and read it all wrong then. – Nasser Apr 20 '20 at 08:25
  • @Henrik Schumacher and Nasser. It was a compliment! I read many forums and WM guiding material and I saw the name Alex Toroune many times. So I wanted to mention it is an honour, that HE reacted on my post :-) – Vrbic Apr 20 '20 at 08:29
  • @Vrbic Thank you for compliment, and let look my answer. – Alex Trounev Apr 20 '20 at 11:09

1 Answers1

3

New nonlinear FEM solver is very good, and I tested it on some complicated problems. But in this case it is not working. Therefore we could try another approach like my solver for NSE in 2D and 3D based on a semi-implicit Oseen discretization in time and linear FEM:

Solver for unsteady flow with the use of the Navier-Stokes and Mathematica FEM

Transition to turbulence

https://community.wolfram.com/groups/-/m/t/1433064

Implementation.

  1. This part we take from demonstration page

    ClearAll["Global`*"]
    rules = {length -> 22/10, hight -> 41/100}; 
    Ω = RegionDifference[Rectangle[{0, 0}, {length, hight}], 
         Disk[{1/5, 1/5}, 1/20]] /. rules; 
    region = RegionPlot[Ω, AspectRatio -> Automatic]
    op = {Inactive[Div][{{-μ, 0}, {0, -μ}} . Inactive[Grad][
                 u[x, y], {x, y}], {x, y}] + 
           ρ*{{u[x, y], v[x, y]}} . 
       Inactive[Grad][u[x, y], {x, y}] + 
           Derivative[1, 0][p][x, y], 
         Inactive[Div][{{-μ, 0}, {0, -μ}} . 
       Inactive[Grad][v[x, y], 
                 {x, y}], {x, y}] + ρ*{{u[x, y], v[x, y]}} . 
               Inactive[Grad][v[x, y], {x, y}] + 
     Derivative[0, 1][p][x, 
             y], Derivative[1, 0][u][x, y] + Derivative[0, 1][v][x, 
             y]} /. {μ -> 10^(-2), ρ -> 1}; 
    pde = op == {0, 0, 0}; 
    bcs = {DirichletCondition[u[x, y] == 3*y*((hight - y)/hight^2), 
           x == 0], DirichletCondition[v[x, y] == 0, x == 0], 
         DirichletCondition[{u[x, y] == 0., v[x, y] == 0.}, 
           x > 0 && x < length], DirichletCondition[p[x, y] == 0., 
           x == length]} /. rules; 
    refinementRegion = ImplicitRegion[a^4*(23*(y - 1/5))^2 + 
             b^2*((5/2)*x - 2.05)^3*(2*a + ((5/2)*x - 2.05)) < 0, 
         {{x, 0, length}, {y, 0, hight}}] /. 
       Flatten[{rules, a -> 1, b -> 5/2}]; 
    Show[RegionPlot[Ω], RegionPlot[refinementRegion], 
       AspectRatio -> Automatic]
    mrf = With[{rmf = RegionMember[refinementRegion]}, 
       Function[{vertices, area}, Block[{x, y}, 
           {x, y} = Mean[vertices]; If[rmf[{x, y}], area > 0.00025, 
              area > 0.0025]]]]; 
    {sxVel, syVel, spressure} = NDSolveValue[{pde, bcs}, {u, v, p}, 
       Element[{x, y}, Ω], Method -> {"FiniteElement", 
           "InterpolationOrder" -> {u -> 2, v -> 2, p -> 1}, 
           "MeshOptions" -> {"IncludePoints" -> {{0.15, 0.2}, 
                   {0.25, 0.2}}, AccuracyGoal -> 5, 
       PrecisionGoal -> 5, 
               MeshRefinementFunction -> mrf}}]; 
    Show[DensityPlot[Sqrt[sxVel[x, y]^2 + syVel[x, y]^2], 
     Element[{x, y}, Ω], ColorFunction -> "Rainbow", 
     PlotPoints -> 50], VectorPlot[{sxVel[x, y], syVel[x, y]}, 
     Element[{x, y}, Ω], VectorPoints -> 9, 
      VectorScale -> 0.05, 
     VectorStyle -> {LightGray}], AspectRatio -> Automatic, 
       ImageSize -> Large]
    
  2. Second part we take from here but using ramp function:

    rampFunction[min_, max_, c_, r_] := 
       Function[t, (min*Exp[c*r] + max*Exp[r*t])/(Exp[c*r] + Exp[r*t])]
    sf = rampFunction[0, 1, 4, 5]; Plot[sf[10*t], {t, -0.1, 1}] 
    

Main code

UX[0][x_, y_] := sxVel[x, y]; VY[0][x_, y_] := syVel[x, y]; 
ν = 10^(-3); t0 = 0.02; H = 0.41; L = 2.2; 
  {x0, y0, r0} = {1/5, 1/5, 1/20}; 
U0[y_, t_] := (sf[10*t] + 1)*3.*y*((H - y)/H^2); 
P0[0][x_, y_] := spressure[x, y]; 
Do[{UX[i], VY[i], P0[i]} = NDSolveValue[
         {{Inactive[Div][{{-μ, 0}, {0, -μ}} . Inactive[Grad][
                         u[x, y], {x, y}], {x, y}] + 
         Derivative[1, 0][p][x, 
                     y] + (u[x, y] - UX[i - 1][x, y])/t0 + UX[i - 1][x, y]*D[u[x, y], x] + VY[i - 1][x, y]*D[u[x, y], y], 
        Inactive[Div][{{-μ, 0}, {0, -μ}} . 
                       Inactive[Grad][v[x, y], {x, y}], {x, y}] + 

         Derivative[0, 1][p][x, y] + (v[x, y] - VY[i - 1][x, y])/
                     t0 + UX[i - 1][x, y]*D[v[x, y], x] + 
         VY[i - 1][x, y]*
                     D[v[x, y], y], Derivative[1, 0][u][x, y] + 
                   Derivative[0, 1][v][x, y]} == {0, 0, 0} /. 
             μ -> 10^(-3), {DirichletCondition[
               {u[x, y] == U0[y, i*t0], v[x, y] == 0}, x == 0.], 
             DirichletCondition[{u[x, y] == 0., v[x, y] == 0.}, 
               (0 <= x <= L && y == 0) || y == H], DirichletCondition[
               {u[x, y] == 0, v[x, y] == 0}, (x - x0)^2 + (y - y0)^2 == 
                 r0^2], DirichletCondition[p[x, y] == P0[i - 1][x, y], 
               x == L]}}, {u, v, p}, Element[{x, y}, Ω], 
         Method -> {"FiniteElement", "InterpolationOrder" -> 
               {u -> 2, v -> 2, p -> 1}, "MeshOptions" -> 
               {"MaxCellMeasure" -> 0.001}}], {i, 1, 50}];

Now we can compare initial and last steps:

    {ContourPlot[UX[0][x, y], {x, y} ∈ Ω, 
   AspectRatio -> Automatic, ColorFunction -> "BlueGreenYellow", 
   FrameLabel -> {x, y}, PlotLegends -> Automatic, Contours -> 20, 
   PlotPoints -> 25, PlotLabel -> u, MaxRecursion -> 2], 
  ContourPlot[VY[0][x, y], {x, y} ∈ Ω, 
   AspectRatio -> Automatic, ColorFunction -> "BlueGreenYellow", 
   FrameLabel -> {x, y}, PlotLegends -> Automatic, Contours -> 20, 
   PlotPoints -> 25, PlotLabel -> v, MaxRecursion -> 2, 
   PlotRange -> All]} // Quiet
{ContourPlot[UX[50][x, y], {x, y} ∈ Ω, 
   AspectRatio -> Automatic, ColorFunction -> "BlueGreenYellow", 
   FrameLabel -> {x, y}, PlotLegends -> Automatic, Contours -> 20, 
   PlotPoints -> 25, PlotLabel -> u, MaxRecursion -> 2], 
  ContourPlot[VY[50][x, y], {x, y} ∈ Ω, 
   AspectRatio -> Automatic, ColorFunction -> "BlueGreenYellow", 
   FrameLabel -> {x, y}, PlotLegends -> Automatic, Contours -> 20, 
   PlotPoints -> 25, PlotLabel -> v, MaxRecursion -> 2, 
   PlotRange -> All]} // Quiet

Figure 1

xzczd
  • 65,995
  • 9
  • 163
  • 468
Alex Trounev
  • 44,369
  • 3
  • 48
  • 106
  • Thank you! I think I understand it and I'm going to play with it :) Could I ask another question about my main problem https://mathematica.stackexchange.com/questions/219583/problem-with-a-solution-of-pde-with-initial-and-boundary-conditions ? If you look at these equations and the initial and boundary conditions. Do you think this can be solved by the same (or similar) approach in WM? If you see immediately, it is impossible (or very difficult for a guy like me), please let me know. If you suggested or give a link to a similar solution I could start from, it would help me a lot. Thanks again! – Vrbic Apr 20 '20 at 12:26
  • @Vrbic Ok! The system of equation describing collapse, it is not standard. Could you give me a link to this book where your got this? – Alex Trounev Apr 21 '20 at 10:21
  • Thank you for your interest. I have this paper https://www.dropbox.com/s/8wkoc7uaz0pw2ot/may_white.pdf?dl=0 – Vrbic Apr 21 '20 at 16:07
  • @Vrbic Ok! See my answer on https://mathematica.stackexchange.com/questions/219583/problem-with-a-solution-of-pde-with-initial-and-boundary-conditions – Alex Trounev Apr 21 '20 at 23:53