MFEM  v4.3.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
navier_shear.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 //
12 // Navier double shear layer example
13 //
14 // Solve the double shear problem in the following configuration.
15 //
16 // +-------------------+
17 // | |
18 // | u0 = ua |
19 // | |
20 // -------------------------------- y = 0.5
21 // | |
22 // | u0 = ub |
23 // | |
24 // +-------------------+
25 //
26 // The initial condition u0 is chosen to be a varying velocity in the y
27 // direction. It includes a perturbation at x = 0.5 which leads to an
28 // instability and the dynamics of the flow. The boundary conditions are fully
29 // periodic.
30 
31 #include "navier_solver.hpp"
32 #include <fstream>
33 
34 using namespace mfem;
35 using namespace navier;
36 
37 struct s_NavierContext
38 {
39  int order = 6;
40  double kinvis = 1.0 / 100000.0;
41  double t_final = 10 * 1e-3;
42  double dt = 1e-3;
43 } ctx;
44 
45 void vel_shear_ic(const Vector &x, double t, Vector &u)
46 {
47  double xi = x(0);
48  double yi = x(1);
49 
50  double rho = 30.0;
51  double delta = 0.05;
52 
53  if (yi <= 0.5)
54  {
55  u(0) = tanh(rho * (yi - 0.25));
56  }
57  else
58  {
59  u(0) = tanh(rho * (0.75 - yi));
60  }
61 
62  u(1) = delta * sin(2.0 * M_PI * xi);
63 }
64 
65 int main(int argc, char *argv[])
66 {
67  MPI_Session mpi(argc, argv);
68 
69  int serial_refinements = 2;
70 
71  Mesh *mesh = new Mesh("../../data/periodic-square.mesh");
72  mesh->EnsureNodes();
73  GridFunction *nodes = mesh->GetNodes();
74  *nodes -= -1.0;
75  *nodes /= 2.0;
76 
77  for (int i = 0; i < serial_refinements; ++i)
78  {
79  mesh->UniformRefinement();
80  }
81 
82  if (mpi.Root())
83  {
84  std::cout << "Number of elements: " << mesh->GetNE() << std::endl;
85  }
86 
87  auto *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
88  delete mesh;
89 
90  // Create the flow solver.
91  NavierSolver flowsolver(pmesh, ctx.order, ctx.kinvis);
92  flowsolver.EnablePA(true);
93 
94  // Set the initial condition.
95  ParGridFunction *u_ic = flowsolver.GetCurrentVelocity();
96  VectorFunctionCoefficient u_excoeff(pmesh->Dimension(), vel_shear_ic);
97  u_ic->ProjectCoefficient(u_excoeff);
98 
99  double t = 0.0;
100  double dt = ctx.dt;
101  double t_final = ctx.t_final;
102  bool last_step = false;
103 
104  flowsolver.Setup(dt);
105 
106  ParGridFunction *u_gf = flowsolver.GetCurrentVelocity();
107  ParGridFunction *p_gf = flowsolver.GetCurrentPressure();
108 
109  ParGridFunction w_gf(*u_gf);
110  flowsolver.ComputeCurl2D(*u_gf, w_gf);
111 
112  ParaViewDataCollection pvdc("shear_output", pmesh);
114  pvdc.SetHighOrderOutput(true);
115  pvdc.SetLevelsOfDetail(ctx.order);
116  pvdc.SetCycle(0);
117  pvdc.SetTime(t);
118  pvdc.RegisterField("velocity", u_gf);
119  pvdc.RegisterField("pressure", p_gf);
120  pvdc.RegisterField("vorticity", &w_gf);
121  pvdc.Save();
122 
123  for (int step = 0; !last_step; ++step)
124  {
125  if (t + dt >= t_final - dt / 2)
126  {
127  last_step = true;
128  }
129 
130  flowsolver.Step(t, dt, step);
131 
132  if (step % 10 == 0)
133  {
134  flowsolver.ComputeCurl2D(*u_gf, w_gf);
135  pvdc.SetCycle(step);
136  pvdc.SetTime(t);
137  pvdc.Save();
138  }
139 
140  if (mpi.Root())
141  {
142  printf("%11s %11s\n", "Time", "dt");
143  printf("%.5E %.5E\n", t, dt);
144  fflush(stdout);
145  }
146  }
147 
148  flowsolver.PrintTimingData();
149 
150  delete pmesh;
151 
152  return 0;
153 }
void PrintTimingData()
Print timing summary of the solving routine.
Class for grid function - Vector with associated FE space.
Definition: gridfunc.hpp:30
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetDataFormat(VTKFormat fmt)
Helper class for ParaView visualization data.
int GetNE() const
Returns number of elements.
Definition: mesh.hpp:846
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Definition: pgridfunc.cpp:493
void Setup(double dt)
Initialize forms, solvers and preconditioners.
A simple convenience class that calls MPI_Init() at construction and MPI_Finalize() at destruction...
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Definition: mesh.cpp:9143
ParGridFunction * GetCurrentPressure()
Return a pointer to the current pressure ParGridFunction.
double delta
Definition: lissajous.cpp:43
bool Root() const
Return true if WorldRank() == 0.
void EnablePA(bool pa)
Enable partial assembly for every operator.
void SetHighOrderOutput(bool high_order_output_)
void ComputeCurl2D(ParGridFunction &u, ParGridFunction &cu, bool assume_scalar=false)
Compute for .
void SetTime(double t)
Set physical time (for time-dependent simulations)
A general vector function coefficient.
ParGridFunction * GetCurrentVelocity()
Return a pointer to the current velocity ParGridFunction.
RefCoord t[3]
void SetLevelsOfDetail(int levels_of_detail_)
Vector data type.
Definition: vector.hpp:60
void GetNodes(Vector &node_coord) const
Definition: mesh.cpp:7343
void Step(double &time, double dt, int cur_step, bool provisional=false)
Compute solution at the next time step t+dt.
virtual void Save() override
double u(const Vector &xvec)
Definition: lor_mms.hpp:24
Class for parallel grid function.
Definition: pgridfunc.hpp:32
Class for parallel meshes.
Definition: pmesh.hpp:32
Transient incompressible Navier Stokes solver in a split scheme formulation.
int main()
void EnsureNodes()
Definition: mesh.cpp:4849