23 using namespace navier;
25 struct s_NavierContext
28 double Re_tau = 180.0;
29 double kin_vis = 1.0 / Re_tau;
30 double t_final = 50.0;
39 return delta * tanh(C * (2.0 * y - 1.0)) / tanh(C);
62 yp = (1.0 + y) *
ctx.Re_tau;
66 yp = (1.0 - y) *
ctx.Re_tau;
69 u(0) = 1.0 / k * log(1.0 + k * yp) + (C - (1.0 / k) * log(k)) * (1 - exp(
70 -yp / 11.0) - yp / 11.0 * exp(-yp / 3.0));
75 double alpha = kx * 2.0 * M_PI / 2.0 * M_PI;
76 double beta = kz * 2.0 * M_PI / M_PI;
78 u(0) += eps * beta * sin(alpha * x) * cos(beta * z);
79 u(1) = eps * sin(alpha * x) * sin(beta * z);
80 u(2) = -eps * alpha * cos(alpha * x) * sin(beta * z);
90 int main(
int argc,
char *argv[])
95 double Lx = 2.0 * M_PI;
99 int N =
ctx.order + 1;
100 int NL =
static_cast<int>(std::round(64.0 / N));
103 double LC = M_PI / NL;
105 int NY = 2 *
static_cast<int>(std::round(48.0 / N));
110 for (
int i = 0; i < mesh.
GetNV(); ++i)
117 Vector x_translation({Lx, 0.0, 0.0});
118 Vector z_translation({0.0, 0.0, Lz});
119 std::vector<Vector> translations = {x_translation, z_translation};
127 printf(
"NL=%d NX=%d NY=%d NZ=%d dx+=%f\n", NL, NX, NY, NZ, LC *
ctx.Re_tau);
128 std::cout <<
"Number of elements: " << mesh.
GetNE() << std::endl;
131 double hmin, hmax, kappa_min, kappa_max;
135 ctx.dt = 1.0 / pow(
ctx.order, 1.5) * hmin / umax;
137 auto *pmesh =
new ParMesh(MPI_COMM_WORLD, periodic_mesh);
161 double t_final =
ctx.t_final;
162 bool last_step =
false;
164 flowsolver.
Setup(dt);
176 for (
int step = 0; !last_step; ++step)
178 if (t + dt >= t_final - dt / 2)
183 flowsolver.
Step(t, dt, step);
185 if (step % 1000 == 0)
199 printf(
"%11s %11s\n",
"Time",
"dt");
200 printf(
"%.5E %.5E\n", t, dt);
static Mesh MakePeriodic(const Mesh &orig_mesh, const std::vector< int > &v2v)
Create a periodic mesh by identifying vertices of orig_mesh.
void PrintTimingData()
Print timing summary of the solving routine.
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(), hypre will be finalized automatically at program exit.
const double * GetVertex(int i) const
Return pointer to vertex i's coordinates.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetDataFormat(VTKFormat fmt)
void GetCharacteristics(double &h_min, double &h_max, double &kappa_min, double &kappa_max, Vector *Vh=NULL, Vector *Vk=NULL)
Helper class for ParaView visualization data.
static Mesh MakeCartesian3D(int nx, int ny, int nz, Element::Type type, double sx=1.0, double sy=1.0, double sz=1.0, bool sfc_ordering=true)
int GetNE() const
Returns number of elements.
double mesh_stretching_func(const double y)
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
void Setup(double dt)
Initialize forms, solvers and preconditioners.
std::vector< int > CreatePeriodicVertexMapping(const std::vector< Vector > &translations, double tol=1e-8) const
Creates a mapping v2v from the vertex indices of the mesh such that coincident vertices under the giv...
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
double f(const Vector &xvec)
struct s_NavierContext ctx
ParGridFunction * GetCurrentPressure()
Return a pointer to the current pressure ParGridFunction.
void vel_ic_reichardt(const Vector &coords, double t, Vector &u)
void EnablePA(bool pa)
Enable partial assembly for every operator.
void AddVelDirichletBC(VectorCoefficient *coeff, Array< int > &attr)
Add a Dirichlet boundary condition to the velocity field.
void SetHighOrderOutput(bool high_order_output_)
static void Init()
Singleton creation with Mpi::Init();.
void SetTime(double t)
Set physical time (for time-dependent simulations)
void vel_wall(const Vector &x, double t, Vector &u)
static bool Root()
Return true if the rank in MPI_COMM_WORLD is zero.
A general vector function coefficient.
ParGridFunction * GetCurrentVelocity()
Return a pointer to the current velocity ParGridFunction.
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
void SetLevelsOfDetail(int levels_of_detail_)
void accel(const Vector &x, double t, Vector &u)
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)
Class for parallel grid function.
Class for parallel meshes.
Transient incompressible Navier Stokes solver in a split scheme formulation.
void AddAccelTerm(VectorCoefficient *coeff, Array< int > &attr)
Add an acceleration term to the RHS of the equation.