1 // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 2 // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3 // 4 // SPDX-License-Identifier: BSD-2-Clause 5 // 6 // This file is part of CEED: http://github.com/ceed 7 8 #ifndef libceed_fluids_examples_navier_stokes_h 9 #define libceed_fluids_examples_navier_stokes_h 10 11 #include <ceed.h> 12 #include <petscdm.h> 13 #include <petscdmplex.h> 14 #include <petscsys.h> 15 #include <petscts.h> 16 #include <stdbool.h> 17 18 // ----------------------------------------------------------------------------- 19 // PETSc Version 20 // ----------------------------------------------------------------------------- 21 #if PETSC_VERSION_LT(3,17,0) 22 #error "PETSc v3.17 or later is required" 23 #endif 24 25 // ----------------------------------------------------------------------------- 26 // Enums 27 // ----------------------------------------------------------------------------- 28 // Translate PetscMemType to CeedMemType 29 static inline CeedMemType MemTypeP2C(PetscMemType mem_type) { 30 return PetscMemTypeDevice(mem_type) ? CEED_MEM_DEVICE : CEED_MEM_HOST; 31 } 32 33 // Advection - Wind Options 34 typedef enum { 35 WIND_ROTATION = 0, 36 WIND_TRANSLATION = 1, 37 } WindType; 38 static const char *const WindTypes[] = { 39 "rotation", 40 "translation", 41 "WindType", "WIND_", NULL 42 }; 43 44 // Advection - Bubble Types 45 typedef enum { 46 BUBBLE_SPHERE = 0, // dim=3 47 BUBBLE_CYLINDER = 1, // dim=2 48 } BubbleType; 49 static const char *const BubbleTypes[] = { 50 "sphere", 51 "cylinder", 52 "BubbleType", "BUBBLE_", NULL 53 }; 54 55 // Advection - Bubble Continuity Types 56 typedef enum { 57 BUBBLE_CONTINUITY_SMOOTH = 0, // Original continuous, smooth shape 58 BUBBLE_CONTINUITY_BACK_SHARP = 1, // Discontinuous, sharp back half shape 59 BUBBLE_CONTINUITY_THICK = 2, // Define a finite thickness 60 } BubbleContinuityType; 61 static const char *const BubbleContinuityTypes[] = { 62 "smooth", 63 "back_sharp", 64 "thick", 65 "BubbleContinuityType", "BUBBLE_CONTINUITY_", NULL 66 }; 67 68 // Euler - test cases 69 typedef enum { 70 EULER_TEST_ISENTROPIC_VORTEX = 0, 71 EULER_TEST_1 = 1, 72 EULER_TEST_2 = 2, 73 EULER_TEST_3 = 3, 74 EULER_TEST_4 = 4, 75 EULER_TEST_5 = 5, 76 } EulerTestType; 77 static const char *const EulerTestTypes[] = { 78 "isentropic_vortex", 79 "test_1", 80 "test_2", 81 "test_3", 82 "test_4", 83 "test_5", 84 "EulerTestType", "EULER_TEST_", NULL 85 }; 86 87 // Stabilization methods 88 typedef enum { 89 STAB_NONE = 0, 90 STAB_SU = 1, // Streamline Upwind 91 STAB_SUPG = 2, // Streamline Upwind Petrov-Galerkin 92 } StabilizationType; 93 static const char *const StabilizationTypes[] = { 94 "none", 95 "SU", 96 "SUPG", 97 "StabilizationType", "STAB_", NULL 98 }; 99 100 // ----------------------------------------------------------------------------- 101 // Structs 102 // ----------------------------------------------------------------------------- 103 // Structs declarations 104 typedef struct AppCtx_private *AppCtx; 105 typedef struct CeedData_private *CeedData; 106 typedef struct User_private *User; 107 typedef struct Units_private *Units; 108 typedef struct SimpleBC_private *SimpleBC; 109 typedef struct Physics_private *Physics; 110 111 // Application context from user command line options 112 struct AppCtx_private { 113 // libCEED arguments 114 char ceed_resource[PETSC_MAX_PATH_LEN]; // libCEED backend 115 PetscInt degree; 116 PetscInt q_extra; 117 // Post-processing arguments 118 PetscInt output_freq; 119 PetscInt viz_refine; 120 PetscInt cont_steps; 121 char output_dir[PETSC_MAX_PATH_LEN]; 122 // Problem type arguments 123 PetscFunctionList problems; 124 char problem_name[PETSC_MAX_PATH_LEN]; 125 // Test mode arguments 126 PetscBool test_mode; 127 PetscScalar test_tol; 128 char file_path[PETSC_MAX_PATH_LEN]; 129 }; 130 131 // libCEED data struct 132 struct CeedData_private { 133 CeedVector x_coord, q_data; 134 CeedQFunctionContext setup_context, newt_ig_context, advection_context, 135 euler_context, channel_context, blasius_context; 136 CeedQFunction qf_setup_vol, qf_ics, qf_rhs_vol, qf_ifunction_vol, 137 qf_setup_sur, qf_apply_inflow, qf_apply_outflow; 138 CeedBasis basis_x, basis_xc, basis_q, basis_x_sur, basis_q_sur; 139 CeedElemRestriction elem_restr_x, elem_restr_q, elem_restr_qd_i; 140 CeedOperator op_setup_vol, op_ics; 141 }; 142 143 // PETSc user data 144 struct User_private { 145 MPI_Comm comm; 146 DM dm; 147 DM dm_viz; 148 Mat interp_viz; 149 Ceed ceed; 150 Units units; 151 Vec M; 152 Physics phys; 153 AppCtx app_ctx; 154 CeedVector q_ceed, q_dot_ceed, g_ceed; 155 CeedOperator op_rhs_vol, op_rhs, op_ifunction_vol, op_ifunction; 156 }; 157 158 // Units 159 struct Units_private { 160 // fundamental units 161 PetscScalar meter; 162 PetscScalar kilogram; 163 PetscScalar second; 164 PetscScalar Kelvin; 165 // derived units 166 PetscScalar Pascal; 167 PetscScalar J_per_kg_K; 168 PetscScalar m_per_squared_s; 169 PetscScalar W_per_m_K; 170 PetscScalar Joule; 171 }; 172 173 // Boundary conditions 174 struct SimpleBC_private { 175 PetscInt num_wall, // Number of faces with wall BCs 176 wall_comps[5], // An array of constrained component numbers 177 num_comps, 178 num_slip[3], // Number of faces with slip BCs 179 num_inflow, 180 num_outflow; 181 PetscInt walls[16], slips[3][16], inflows[16], outflows[16]; 182 PetscBool user_bc; 183 }; 184 185 // Initial conditions 186 #ifndef setup_context_struct 187 #define setup_context_struct 188 typedef struct SetupContext_ *SetupContext; 189 struct SetupContext_ { 190 CeedScalar theta0; 191 CeedScalar thetaC; 192 CeedScalar P0; 193 CeedScalar N; 194 CeedScalar cv; 195 CeedScalar cp; 196 CeedScalar g[3]; 197 CeedScalar rc; 198 CeedScalar lx; 199 CeedScalar ly; 200 CeedScalar lz; 201 CeedScalar center[3]; 202 CeedScalar dc_axis[3]; 203 CeedScalar wind[3]; 204 CeedScalar time; 205 int wind_type; // See WindType: 0=ROTATION, 1=TRANSLATION 206 int bubble_type; // See BubbleType: 0=SPHERE, 1=CYLINDER 207 int bubble_continuity_type; // See BubbleContinuityType: 0=SMOOTH, 1=BACK_SHARP 2=THICK 208 }; 209 #endif 210 211 // DENSITY_CURRENT 212 #ifndef dc_context_struct 213 #define dc_context_struct 214 typedef struct DCContext_ *DCContext; 215 struct DCContext_ { 216 CeedScalar lambda; 217 CeedScalar mu; 218 CeedScalar k; 219 CeedScalar cv; 220 CeedScalar cp; 221 CeedScalar g; 222 CeedScalar c_tau; 223 int stabilization; // See StabilizationType: 0=none, 1=SU, 2=SUPG 224 }; 225 #endif 226 227 // EULER_VORTEX 228 #ifndef euler_context_struct 229 #define euler_context_struct 230 typedef struct EulerContext_ *EulerContext; 231 struct EulerContext_ { 232 CeedScalar center[3]; 233 CeedScalar curr_time; 234 CeedScalar vortex_strength; 235 CeedScalar c_tau; 236 CeedScalar mean_velocity[3]; 237 bool implicit; 238 int euler_test; 239 int stabilization; // See StabilizationType: 0=none, 1=SU, 2=SUPG 240 }; 241 #endif 242 243 // ADVECTION and ADVECTION2D 244 #ifndef advection_context_struct 245 #define advection_context_struct 246 typedef struct AdvectionContext_ *AdvectionContext; 247 struct AdvectionContext_ { 248 CeedScalar CtauS; 249 CeedScalar strong_form; 250 CeedScalar E_wind; 251 bool implicit; 252 int stabilization; // See StabilizationType: 0=none, 1=SU, 2=SUPG 253 }; 254 #endif 255 256 // Newtonian Ideal Gas 257 #ifndef newtonian_context_struct 258 #define newtonian_context_struct 259 typedef struct NewtonianIdealGasContext_ *NewtonianIdealGasContext; 260 struct NewtonianIdealGasContext_ { 261 CeedScalar lambda; 262 CeedScalar mu; 263 CeedScalar k; 264 CeedScalar cv; 265 CeedScalar cp; 266 CeedScalar g[3]; 267 CeedScalar c_tau; 268 CeedScalar Ctau_t; 269 CeedScalar Ctau_v; 270 CeedScalar Ctau_C; 271 CeedScalar Ctau_M; 272 CeedScalar Ctau_E; 273 CeedScalar dt; 274 StabilizationType stabilization; 275 }; 276 #endif 277 278 #ifndef channel_context_struct 279 #define channel_context_struct 280 typedef struct ChannelContext_ *ChannelContext; 281 struct ChannelContext_ { 282 bool implicit; // !< Using implicit timesteping or not 283 CeedScalar theta0; // !< Reference temperature 284 CeedScalar P0; // !< Reference Pressure 285 CeedScalar umax; // !< Centerline velocity 286 CeedScalar center; // !< Y Coordinate for center of channel 287 CeedScalar H; // !< Channel half-height 288 CeedScalar B; // !< Body-force driving the flow 289 struct NewtonianIdealGasContext_ newtonian_ctx; 290 }; 291 #endif 292 293 #ifndef blasius_context_struct 294 #define blasius_context_struct 295 typedef struct BlasiusContext_ *BlasiusContext; 296 struct BlasiusContext_ { 297 bool implicit; // !< Using implicit timesteping or not 298 bool weakT; // !< flag to set Temperature at inflow 299 CeedScalar delta0; // !< Boundary layer height at inflow 300 CeedScalar Uinf; // !< Velocity at boundary layer edge 301 CeedScalar P0; // !< Pressure at outflow 302 CeedScalar theta0; // !< Temperature at inflow 303 struct NewtonianIdealGasContext_ newtonian_ctx; 304 }; 305 #endif 306 307 // Struct that contains all enums and structs used for the physics of all problems 308 struct Physics_private { 309 BlasiusContext blasius_ctx; 310 ChannelContext channel_ctx; 311 NewtonianIdealGasContext newtonian_ig_ctx; 312 EulerContext euler_ctx; 313 AdvectionContext advection_ctx; 314 WindType wind_type; 315 BubbleType bubble_type; 316 BubbleContinuityType bubble_continuity_type; 317 EulerTestType euler_test; 318 StabilizationType stab; 319 PetscBool implicit; 320 PetscBool has_curr_time; 321 PetscBool has_neumann; 322 CeedContextFieldLabel solution_time_label; 323 CeedContextFieldLabel timestep_size_label; 324 }; 325 326 // Problem specific data 327 // *INDENT-OFF* 328 typedef struct { 329 CeedInt dim, q_data_size_vol, q_data_size_sur; 330 CeedScalar dm_scale; 331 CeedQFunctionUser setup_vol, setup_sur, ics, apply_vol_rhs, apply_vol_ifunction, 332 apply_inflow, apply_outflow; 333 const char *setup_vol_loc, *setup_sur_loc, *ics_loc, 334 *apply_vol_rhs_loc, *apply_vol_ifunction_loc, *apply_inflow_loc, *apply_outflow_loc; 335 bool non_zero_time; 336 PetscErrorCode (*bc)(PetscInt, PetscReal, const PetscReal[], PetscInt, 337 PetscScalar[], void *); 338 PetscErrorCode (*setup_ctx)(Ceed, CeedData, AppCtx, SetupContext, Physics); 339 PetscErrorCode (*print_info)(Physics, SetupContext, AppCtx); 340 } ProblemData; 341 // *INDENT-ON* 342 343 // ----------------------------------------------------------------------------- 344 // Set up problems 345 // ----------------------------------------------------------------------------- 346 // Set up function for each problem 347 extern PetscErrorCode NS_CHANNEL(ProblemData *problem, DM dm, 348 void *setup_ctx, void *ctx); 349 extern PetscErrorCode NS_BLASIUS(ProblemData *problem, DM dm, 350 void *setup_ctx, void *ctx); 351 extern PetscErrorCode NS_NEWTONIAN_IG(ProblemData *problem, DM dm, 352 void *setup_ctx, void *ctx); 353 extern PetscErrorCode NS_DENSITY_CURRENT(ProblemData *problem, DM dm, 354 void *setup_ctx, void *ctx); 355 extern PetscErrorCode NS_EULER_VORTEX(ProblemData *problem, DM dm, 356 void *setup_ctx, void *ctx); 357 extern PetscErrorCode NS_ADVECTION(ProblemData *problem, DM dm, void *setup_ctx, 358 void *ctx); 359 extern PetscErrorCode NS_ADVECTION2D(ProblemData *problem, DM dm, 360 void *setup_ctx, void *ctx); 361 362 // Set up context for each problem 363 extern PetscErrorCode SetupContext_CHANNEL(Ceed ceed, CeedData ceed_data, 364 AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 365 366 extern PetscErrorCode SetupContext_BLASIUS(Ceed ceed, CeedData ceed_data, 367 AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 368 369 extern PetscErrorCode SetupContext_NEWTONIAN_IG(Ceed ceed, CeedData ceed_data, 370 AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 371 372 extern PetscErrorCode SetupContext_DENSITY_CURRENT(Ceed ceed, 373 CeedData ceed_data, AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 374 375 extern PetscErrorCode SetupContext_EULER_VORTEX(Ceed ceed, CeedData ceed_data, 376 AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 377 378 extern PetscErrorCode SetupContext_ADVECTION(Ceed ceed, CeedData ceed_data, 379 AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 380 381 extern PetscErrorCode SetupContext_ADVECTION2D(Ceed ceed, CeedData ceed_data, 382 AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 383 384 // Boundary condition function for each problem 385 extern PetscErrorCode BC_DENSITY_CURRENT(DM dm, SimpleBC bc, Physics phys, 386 void *setup_ctx); 387 388 extern PetscErrorCode BC_EULER_VORTEX(DM dm, SimpleBC bc, Physics phys, 389 void *setup_ctx); 390 391 extern PetscErrorCode BC_ADVECTION(DM dm, SimpleBC bc, Physics phys, 392 void *setup_ctx); 393 394 extern PetscErrorCode BC_ADVECTION2D(DM dm, SimpleBC bc, Physics phys, 395 void *setup_ctx); 396 397 // Print function for each problem 398 extern PetscErrorCode PRINT_DENSITY_CURRENT(Physics phys, 399 SetupContext setup_ctx, AppCtx app_ctx); 400 401 extern PetscErrorCode PRINT_EULER_VORTEX(Physics phys, SetupContext setup_ctx, 402 AppCtx app_ctx); 403 404 extern PetscErrorCode PRINT_ADVECTION(Physics phys, SetupContext setup_ctx, 405 AppCtx app_ctx); 406 407 extern PetscErrorCode PRINT_ADVECTION2D(Physics phys, SetupContext setup_ctx, 408 AppCtx app_ctx); 409 410 // ----------------------------------------------------------------------------- 411 // libCEED functions 412 // ----------------------------------------------------------------------------- 413 // Utility function - essential BC dofs are encoded in closure indices as -(i+1). 414 PetscInt Involute(PetscInt i); 415 416 // Utility function to create local CEED restriction 417 PetscErrorCode CreateRestrictionFromPlex(Ceed ceed, DM dm, CeedInt height, 418 DMLabel domain_label, CeedInt value, CeedElemRestriction *elem_restr); 419 420 // Utility function to get Ceed Restriction for each domain 421 PetscErrorCode GetRestrictionForDomain(Ceed ceed, DM dm, CeedInt height, 422 DMLabel domain_label, PetscInt value, 423 CeedInt Q, CeedInt q_data_size, 424 CeedElemRestriction *elem_restr_q, 425 CeedElemRestriction *elem_restr_x, 426 CeedElemRestriction *elem_restr_qd_i); 427 428 // Utility function to create CEED Composite Operator for the entire domain 429 PetscErrorCode CreateOperatorForDomain(Ceed ceed, DM dm, SimpleBC bc, 430 CeedData ceed_data, Physics phys, 431 CeedOperator op_apply_vol, CeedInt height, 432 CeedInt P_sur, CeedInt Q_sur, CeedInt q_data_size_sur, 433 CeedOperator *op_apply); 434 435 PetscErrorCode SetupLibceed(Ceed ceed, CeedData ceed_data, DM dm, User user, 436 AppCtx app_ctx, ProblemData *problem, SimpleBC bc, SetupContext setup_ctx); 437 438 // ----------------------------------------------------------------------------- 439 // Time-stepping functions 440 // ----------------------------------------------------------------------------- 441 // Compute mass matrix for explicit scheme 442 PetscErrorCode ComputeLumpedMassMatrix(Ceed ceed, DM dm, CeedData ceed_data, 443 Vec M); 444 445 // RHS (Explicit time-stepper) function setup 446 PetscErrorCode RHS_NS(TS ts, PetscReal t, Vec Q, Vec G, void *user_data); 447 448 // Implicit time-stepper function setup 449 PetscErrorCode IFunction_NS(TS ts, PetscReal t, Vec Q, Vec Q_dot, Vec G, 450 void *user_data); 451 452 // User provided TS Monitor 453 PetscErrorCode TSMonitor_NS(TS ts, PetscInt step_no, PetscReal time, Vec Q, 454 void *ctx); 455 456 // TS: Create, setup, and solve 457 PetscErrorCode TSSolve_NS(DM dm, User user, AppCtx app_ctx, Physics phys, 458 Vec *Q, PetscScalar *f_time, TS *ts); 459 460 // ----------------------------------------------------------------------------- 461 // Setup DM 462 // ----------------------------------------------------------------------------- 463 // Create mesh 464 PetscErrorCode CreateDM(MPI_Comm comm, ProblemData *problem, DM *dm); 465 466 // Set up DM 467 PetscErrorCode SetUpDM(DM dm, ProblemData *problem, PetscInt degree, 468 SimpleBC bc, Physics phys, void *setup_ctx); 469 470 // Refine DM for high-order viz 471 PetscErrorCode VizRefineDM(DM dm, User user, ProblemData *problem, 472 SimpleBC bc, Physics phys, void *setup_ctx); 473 474 // ----------------------------------------------------------------------------- 475 // Process command line options 476 // ----------------------------------------------------------------------------- 477 // Register problems to be available on the command line 478 PetscErrorCode RegisterProblems_NS(AppCtx app_ctx); 479 480 // Process general command line options 481 PetscErrorCode ProcessCommandLineOptions(MPI_Comm comm, AppCtx app_ctx, 482 SimpleBC bc); 483 484 // ----------------------------------------------------------------------------- 485 // Miscellaneous utility functions 486 // ----------------------------------------------------------------------------- 487 PetscErrorCode ICs_FixMultiplicity(DM dm, CeedData ceed_data, Vec Q_loc, Vec Q, 488 CeedScalar time); 489 490 PetscErrorCode DMPlexInsertBoundaryValues_NS(DM dm, 491 PetscBool insert_essential, Vec Q_loc, PetscReal time, Vec face_geom_FVM, 492 Vec cell_geom_FVM, Vec grad_FVM); 493 494 // Compare reference solution values with current test run for CI 495 PetscErrorCode RegressionTests_NS(AppCtx app_ctx, Vec Q); 496 497 // Get error for problems with exact solutions 498 PetscErrorCode GetError_NS(CeedData ceed_data, DM dm, AppCtx app_ctx, Vec Q, 499 PetscScalar final_time); 500 501 // Post-processing 502 PetscErrorCode PostProcess_NS(TS ts, CeedData ceed_data, DM dm, 503 ProblemData *problem, AppCtx app_ctx, 504 Vec Q, PetscScalar final_time); 505 506 // -- Gather initial Q values in case of continuation of simulation 507 PetscErrorCode SetupICsFromBinary(MPI_Comm comm, AppCtx app_ctx, Vec Q); 508 509 // Record boundary values from initial condition 510 PetscErrorCode SetBCsFromICs_NS(DM dm, Vec Q, Vec Q_loc); 511 512 // ----------------------------------------------------------------------------- 513 514 #endif // libceed_fluids_examples_navier_stokes_h 515