MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
navier_shear.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, 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
34using namespace mfem;
35using namespace navier;
36
37struct s_NavierContext
38{
39 int order = 6;
40 real_t kinvis = 1.0 / 100000.0;
41 real_t t_final = 10 * 1e-3;
42 real_t dt = 1e-3;
44
46{
47 real_t xi = x(0);
48 real_t yi = x(1);
49
50 real_t rho = 30.0;
51 real_t 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
65int main(int argc, char *argv[])
66{
67 Mpi::Init(argc, argv);
69
70 int serial_refinements = 2;
71
72 Mesh *mesh = new Mesh("../../data/periodic-square.mesh");
73 mesh->EnsureNodes();
74 GridFunction *nodes = mesh->GetNodes();
75 *nodes -= -1.0;
76 *nodes /= 2.0;
77
78 for (int i = 0; i < serial_refinements; ++i)
79 {
80 mesh->UniformRefinement();
81 }
82
83 if (Mpi::Root())
84 {
85 std::cout << "Number of elements: " << mesh->GetNE() << std::endl;
86 }
87
88 auto *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
89 delete mesh;
90
91 // Create the flow solver.
92 NavierSolver flowsolver(pmesh, ctx.order, ctx.kinvis);
93 flowsolver.EnablePA(true);
94
95 // Set the initial condition.
96 ParGridFunction *u_ic = flowsolver.GetCurrentVelocity();
97 VectorFunctionCoefficient u_excoeff(pmesh->Dimension(), vel_shear_ic);
98 u_ic->ProjectCoefficient(u_excoeff);
99
100 real_t t = 0.0;
101 real_t dt = ctx.dt;
102 real_t t_final = ctx.t_final;
103 bool last_step = false;
104
105 flowsolver.Setup(dt);
106
107 ParGridFunction *u_gf = flowsolver.GetCurrentVelocity();
108 ParGridFunction *p_gf = flowsolver.GetCurrentPressure();
109
110 ParGridFunction w_gf(*u_gf);
111 flowsolver.ComputeCurl2D(*u_gf, w_gf);
112
113 ParaViewDataCollection pvdc("shear_output", pmesh);
114 pvdc.SetDataFormat(VTKFormat::BINARY32);
115 pvdc.SetHighOrderOutput(true);
116 pvdc.SetLevelsOfDetail(ctx.order);
117 pvdc.SetCycle(0);
118 pvdc.SetTime(t);
119 pvdc.RegisterField("velocity", u_gf);
120 pvdc.RegisterField("pressure", p_gf);
121 pvdc.RegisterField("vorticity", &w_gf);
122 pvdc.Save();
123
124 for (int step = 0; !last_step; ++step)
125 {
126 if (t + dt >= t_final - dt / 2)
127 {
128 last_step = true;
129 }
130
131 flowsolver.Step(t, dt, step);
132
133 if (step % 10 == 0)
134 {
135 flowsolver.ComputeCurl2D(*u_gf, w_gf);
136 pvdc.SetCycle(step);
137 pvdc.SetTime(t);
138 pvdc.Save();
139 }
140
141 if (Mpi::Root())
142 {
143 printf("%11s %11s\n", "Time", "dt");
144 printf("%.5E %.5E\n", t, dt);
145 fflush(stdout);
146 }
147 }
148
149 flowsolver.PrintTimingData();
150
151 delete pmesh;
152
153 return 0;
154}
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetTime(real_t t)
Set physical time (for time-dependent simulations)
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:31
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Definition hypre.hpp:74
Mesh data type.
Definition mesh.hpp:56
void EnsureNodes()
Make sure that the mesh has valid nodes, i.e. its geometry is described by a vector finite element gr...
Definition mesh.cpp:6159
int GetNE() const
Returns number of elements.
Definition mesh.hpp:1226
void GetNodes(Vector &node_coord) const
Definition mesh.cpp:8973
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Definition mesh.cpp:10970
static bool Root()
Return true if the rank in MPI_COMM_WORLD is zero.
static void Init(int &argc, char **&argv, int required=default_thread_required, int *provided=nullptr)
Singleton creation with Mpi::Init(argc, argv).
Class for parallel grid function.
Definition pgridfunc.hpp:33
void ProjectCoefficient(Coefficient &coeff) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Class for parallel meshes.
Definition pmesh.hpp:34
Helper class for ParaView visualization data.
void SetHighOrderOutput(bool high_order_output_)
void SetLevelsOfDetail(int levels_of_detail_)
virtual void Save() override
void SetDataFormat(VTKFormat fmt)
A general vector function coefficient.
Vector data type.
Definition vector.hpp:80
Transient incompressible Navier Stokes solver in a split scheme formulation.
void Setup(real_t dt)
Initialize forms, solvers and preconditioners.
ParGridFunction * GetCurrentPressure()
Return a pointer to the current pressure ParGridFunction.
void PrintTimingData()
Print timing summary of the solving routine.
void EnablePA(bool pa)
Enable partial assembly for every operator.
void ComputeCurl2D(ParGridFunction &u, ParGridFunction &cu, bool assume_scalar=false)
Compute for .
ParGridFunction * GetCurrentVelocity()
Return a pointer to the current velocity ParGridFunction.
void Step(real_t &time, real_t dt, int cur_step, bool provisional=false)
Compute solution at the next time step t+dt.
int main()
real_t delta
Definition lissajous.cpp:43
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
float real_t
Definition config.hpp:43
struct s_NavierContext ctx
void vel_shear_ic(const Vector &x, real_t t, Vector &u)
RefCoord t[3]