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, shocktube_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 CeedScalar mid_point; 206 CeedScalar P_high; 207 CeedScalar rho_high; 208 CeedScalar P_low; 209 CeedScalar rho_low; 210 int wind_type; // See WindType: 0=ROTATION, 1=TRANSLATION 211 int bubble_type; // See BubbleType: 0=SPHERE, 1=CYLINDER 212 int bubble_continuity_type; // See BubbleContinuityType: 0=SMOOTH, 1=BACK_SHARP 2=THICK 213 }; 214 #endif 215 216 // DENSITY_CURRENT 217 #ifndef dc_context_struct 218 #define dc_context_struct 219 typedef struct DCContext_ *DCContext; 220 struct DCContext_ { 221 CeedScalar lambda; 222 CeedScalar mu; 223 CeedScalar k; 224 CeedScalar cv; 225 CeedScalar cp; 226 CeedScalar g; 227 CeedScalar c_tau; 228 int stabilization; // See StabilizationType: 0=none, 1=SU, 2=SUPG 229 }; 230 #endif 231 232 // EULER_VORTEX 233 #ifndef euler_context_struct 234 #define euler_context_struct 235 typedef struct EulerContext_ *EulerContext; 236 struct EulerContext_ { 237 CeedScalar center[3]; 238 CeedScalar curr_time; 239 CeedScalar vortex_strength; 240 CeedScalar c_tau; 241 CeedScalar mean_velocity[3]; 242 bool implicit; 243 int euler_test; 244 int stabilization; // See StabilizationType: 0=none, 1=SU, 2=SUPG 245 }; 246 #endif 247 248 // SHOCKTUBE 249 #ifndef shocktube_context_struct 250 #define shocktube_context_struct 251 typedef struct ShockTubeContext_ *ShockTubeContext; 252 struct ShockTubeContext_ { 253 CeedScalar Cyzb; 254 CeedScalar Byzb; 255 CeedScalar c_tau; 256 bool implicit; 257 bool yzb; 258 int stabilization; 259 }; 260 #endif 261 262 // ADVECTION and ADVECTION2D 263 #ifndef advection_context_struct 264 #define advection_context_struct 265 typedef struct AdvectionContext_ *AdvectionContext; 266 struct AdvectionContext_ { 267 CeedScalar CtauS; 268 CeedScalar strong_form; 269 CeedScalar E_wind; 270 bool implicit; 271 int stabilization; // See StabilizationType: 0=none, 1=SU, 2=SUPG 272 }; 273 #endif 274 275 // Newtonian Ideal Gas 276 #ifndef newtonian_context_struct 277 #define newtonian_context_struct 278 typedef struct NewtonianIdealGasContext_ *NewtonianIdealGasContext; 279 struct NewtonianIdealGasContext_ { 280 CeedScalar lambda; 281 CeedScalar mu; 282 CeedScalar k; 283 CeedScalar cv; 284 CeedScalar cp; 285 CeedScalar g[3]; 286 CeedScalar c_tau; 287 CeedScalar Ctau_t; 288 CeedScalar Ctau_v; 289 CeedScalar Ctau_C; 290 CeedScalar Ctau_M; 291 CeedScalar Ctau_E; 292 CeedScalar dt; 293 StabilizationType stabilization; 294 }; 295 #endif 296 297 #ifndef channel_context_struct 298 #define channel_context_struct 299 typedef struct ChannelContext_ *ChannelContext; 300 struct ChannelContext_ { 301 bool implicit; // !< Using implicit timesteping or not 302 CeedScalar theta0; // !< Reference temperature 303 CeedScalar P0; // !< Reference Pressure 304 CeedScalar umax; // !< Centerline velocity 305 CeedScalar center; // !< Y Coordinate for center of channel 306 CeedScalar H; // !< Channel half-height 307 CeedScalar B; // !< Body-force driving the flow 308 struct NewtonianIdealGasContext_ newtonian_ctx; 309 }; 310 #endif 311 312 #ifndef blasius_context_struct 313 #define blasius_context_struct 314 typedef struct BlasiusContext_ *BlasiusContext; 315 struct BlasiusContext_ { 316 bool implicit; // !< Using implicit timesteping or not 317 bool weakT; // !< flag to set Temperature at inflow 318 CeedScalar delta0; // !< Boundary layer height at inflow 319 CeedScalar Uinf; // !< Velocity at boundary layer edge 320 CeedScalar P0; // !< Pressure at outflow 321 CeedScalar theta0; // !< Temperature at inflow 322 struct NewtonianIdealGasContext_ newtonian_ctx; 323 }; 324 #endif 325 326 // Struct that contains all enums and structs used for the physics of all problems 327 struct Physics_private { 328 BlasiusContext blasius_ctx; 329 ChannelContext channel_ctx; 330 NewtonianIdealGasContext newtonian_ig_ctx; 331 EulerContext euler_ctx; 332 ShockTubeContext shocktube_ctx; 333 AdvectionContext advection_ctx; 334 WindType wind_type; 335 BubbleType bubble_type; 336 BubbleContinuityType bubble_continuity_type; 337 EulerTestType euler_test; 338 StabilizationType stab; 339 PetscBool implicit; 340 PetscBool has_curr_time; 341 PetscBool has_neumann; 342 CeedContextFieldLabel solution_time_label; 343 CeedContextFieldLabel timestep_size_label; 344 }; 345 346 // Problem specific data 347 // *INDENT-OFF* 348 typedef struct { 349 CeedInt dim, q_data_size_vol, q_data_size_sur; 350 CeedScalar dm_scale; 351 CeedQFunctionUser setup_vol, setup_sur, ics, apply_vol_rhs, apply_vol_ifunction, 352 apply_inflow, apply_outflow; 353 const char *setup_vol_loc, *setup_sur_loc, *ics_loc, 354 *apply_vol_rhs_loc, *apply_vol_ifunction_loc, *apply_inflow_loc, *apply_outflow_loc; 355 bool non_zero_time; 356 PetscErrorCode (*bc)(PetscInt, PetscReal, const PetscReal[], PetscInt, 357 PetscScalar[], void *); 358 PetscErrorCode (*setup_ctx)(Ceed, CeedData, AppCtx, SetupContext, Physics); 359 PetscErrorCode (*print_info)(Physics, SetupContext, AppCtx); 360 } ProblemData; 361 // *INDENT-ON* 362 363 // ----------------------------------------------------------------------------- 364 // Set up problems 365 // ----------------------------------------------------------------------------- 366 // Set up function for each problem 367 extern PetscErrorCode NS_CHANNEL(ProblemData *problem, DM dm, 368 void *setup_ctx, void *ctx); 369 extern PetscErrorCode NS_BLASIUS(ProblemData *problem, DM dm, 370 void *setup_ctx, void *ctx); 371 extern PetscErrorCode NS_NEWTONIAN_IG(ProblemData *problem, DM dm, 372 void *setup_ctx, void *ctx); 373 extern PetscErrorCode NS_DENSITY_CURRENT(ProblemData *problem, DM dm, 374 void *setup_ctx, 375 void *ctx); 376 377 extern PetscErrorCode NS_EULER_VORTEX(ProblemData *problem, DM dm, 378 void *setup_ctx, void *ctx); 379 extern PetscErrorCode NS_SHOCKTUBE(ProblemData *problem, DM dm, void *setup_ctx, 380 void *ctx); 381 extern PetscErrorCode NS_ADVECTION(ProblemData *problem, DM dm, void *setup_ctx, 382 void *ctx); 383 extern PetscErrorCode NS_ADVECTION2D(ProblemData *problem, DM dm, 384 void *setup_ctx, void *ctx); 385 386 // Set up context for each problem 387 extern PetscErrorCode SetupContext_CHANNEL(Ceed ceed, CeedData ceed_data, 388 AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 389 390 extern PetscErrorCode SetupContext_BLASIUS(Ceed ceed, CeedData ceed_data, 391 AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 392 393 extern PetscErrorCode SetupContext_NEWTONIAN_IG(Ceed ceed, CeedData ceed_data, 394 AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 395 396 extern PetscErrorCode SetupContext_DENSITY_CURRENT(Ceed ceed, 397 CeedData ceed_data, AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 398 399 extern PetscErrorCode SetupContext_EULER_VORTEX(Ceed ceed, CeedData ceed_data, 400 AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 401 402 extern PetscErrorCode SetupContext_SHOCKTUBE(Ceed ceed, CeedData ceed_data, 403 AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 404 405 extern PetscErrorCode SetupContext_ADVECTION(Ceed ceed, CeedData ceed_data, 406 AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 407 408 extern PetscErrorCode SetupContext_ADVECTION2D(Ceed ceed, CeedData ceed_data, 409 AppCtx app_ctx, SetupContext setup_ctx, Physics phys); 410 411 // Boundary condition function for each problem 412 extern PetscErrorCode BC_DENSITY_CURRENT(DM dm, SimpleBC bc, Physics phys, 413 void *setup_ctx); 414 415 extern PetscErrorCode BC_EULER_VORTEX(DM dm, SimpleBC bc, Physics phys, 416 void *setup_ctx); 417 418 extern PetscErrorCode BC_SHOCKTUBE(DM dm, SimpleBC bc, Physics phys, 419 void *setup_ctx); 420 421 extern PetscErrorCode BC_ADVECTION(DM dm, SimpleBC bc, Physics phys, 422 void *setup_ctx); 423 424 extern PetscErrorCode BC_ADVECTION2D(DM dm, SimpleBC bc, Physics phys, 425 void *setup_ctx); 426 427 // Print function for each problem 428 extern PetscErrorCode PRINT_DENSITY_CURRENT(Physics phys, 429 SetupContext setup_ctx, AppCtx app_ctx); 430 431 extern PetscErrorCode PRINT_EULER_VORTEX(Physics phys, SetupContext setup_ctx, 432 AppCtx app_ctx); 433 434 extern PetscErrorCode PRINT_SHOCKTUBE(Physics phys, SetupContext setup_ctx, 435 AppCtx app_ctx); 436 437 extern PetscErrorCode PRINT_ADVECTION(Physics phys, SetupContext setup_ctx, 438 AppCtx app_ctx); 439 440 extern PetscErrorCode PRINT_ADVECTION2D(Physics phys, SetupContext setup_ctx, 441 AppCtx app_ctx); 442 443 // ----------------------------------------------------------------------------- 444 // libCEED functions 445 // ----------------------------------------------------------------------------- 446 // Utility function - essential BC dofs are encoded in closure indices as -(i+1). 447 PetscInt Involute(PetscInt i); 448 449 // Utility function to create local CEED restriction 450 PetscErrorCode CreateRestrictionFromPlex(Ceed ceed, DM dm, CeedInt height, 451 DMLabel domain_label, CeedInt value, CeedElemRestriction *elem_restr); 452 453 // Utility function to get Ceed Restriction for each domain 454 PetscErrorCode GetRestrictionForDomain(Ceed ceed, DM dm, CeedInt height, 455 DMLabel domain_label, PetscInt value, 456 CeedInt Q, CeedInt q_data_size, 457 CeedElemRestriction *elem_restr_q, 458 CeedElemRestriction *elem_restr_x, 459 CeedElemRestriction *elem_restr_qd_i); 460 461 // Utility function to create CEED Composite Operator for the entire domain 462 PetscErrorCode CreateOperatorForDomain(Ceed ceed, DM dm, SimpleBC bc, 463 CeedData ceed_data, Physics phys, 464 CeedOperator op_apply_vol, CeedInt height, 465 CeedInt P_sur, CeedInt Q_sur, CeedInt q_data_size_sur, 466 CeedOperator *op_apply); 467 468 PetscErrorCode SetupLibceed(Ceed ceed, CeedData ceed_data, DM dm, User user, 469 AppCtx app_ctx, ProblemData *problem, SimpleBC bc, SetupContext setup_ctx); 470 471 // ----------------------------------------------------------------------------- 472 // Time-stepping functions 473 // ----------------------------------------------------------------------------- 474 // Compute mass matrix for explicit scheme 475 PetscErrorCode ComputeLumpedMassMatrix(Ceed ceed, DM dm, CeedData ceed_data, 476 Vec M); 477 478 // RHS (Explicit time-stepper) function setup 479 PetscErrorCode RHS_NS(TS ts, PetscReal t, Vec Q, Vec G, void *user_data); 480 481 // Implicit time-stepper function setup 482 PetscErrorCode IFunction_NS(TS ts, PetscReal t, Vec Q, Vec Q_dot, Vec G, 483 void *user_data); 484 485 // User provided TS Monitor 486 PetscErrorCode TSMonitor_NS(TS ts, PetscInt step_no, PetscReal time, Vec Q, 487 void *ctx); 488 489 // TS: Create, setup, and solve 490 PetscErrorCode TSSolve_NS(DM dm, User user, AppCtx app_ctx, Physics phys, 491 Vec *Q, PetscScalar *f_time, TS *ts); 492 493 // ----------------------------------------------------------------------------- 494 // Setup DM 495 // ----------------------------------------------------------------------------- 496 // Create mesh 497 PetscErrorCode CreateDM(MPI_Comm comm, ProblemData *problem, DM *dm); 498 499 // Set up DM 500 PetscErrorCode SetUpDM(DM dm, ProblemData *problem, PetscInt degree, 501 SimpleBC bc, Physics phys, void *setup_ctx); 502 503 // Refine DM for high-order viz 504 PetscErrorCode VizRefineDM(DM dm, User user, ProblemData *problem, 505 SimpleBC bc, Physics phys, void *setup_ctx); 506 507 // ----------------------------------------------------------------------------- 508 // Process command line options 509 // ----------------------------------------------------------------------------- 510 // Register problems to be available on the command line 511 PetscErrorCode RegisterProblems_NS(AppCtx app_ctx); 512 513 // Process general command line options 514 PetscErrorCode ProcessCommandLineOptions(MPI_Comm comm, AppCtx app_ctx, 515 SimpleBC bc); 516 517 // ----------------------------------------------------------------------------- 518 // Miscellaneous utility functions 519 // ----------------------------------------------------------------------------- 520 PetscErrorCode ICs_FixMultiplicity(DM dm, CeedData ceed_data, Vec Q_loc, Vec Q, 521 CeedScalar time); 522 523 PetscErrorCode DMPlexInsertBoundaryValues_NS(DM dm, 524 PetscBool insert_essential, Vec Q_loc, PetscReal time, Vec face_geom_FVM, 525 Vec cell_geom_FVM, Vec grad_FVM); 526 527 // Compare reference solution values with current test run for CI 528 PetscErrorCode RegressionTests_NS(AppCtx app_ctx, Vec Q); 529 530 // Get error for problems with exact solutions 531 PetscErrorCode GetError_NS(CeedData ceed_data, DM dm, AppCtx app_ctx, Vec Q, 532 PetscScalar final_time); 533 534 // Post-processing 535 PetscErrorCode PostProcess_NS(TS ts, CeedData ceed_data, DM dm, 536 ProblemData *problem, AppCtx app_ctx, 537 Vec Q, PetscScalar final_time); 538 539 // -- Gather initial Q values in case of continuation of simulation 540 PetscErrorCode SetupICsFromBinary(MPI_Comm comm, AppCtx app_ctx, Vec Q); 541 542 // Record boundary values from initial condition 543 PetscErrorCode SetBCsFromICs_NS(DM dm, Vec Q, Vec Q_loc); 544 545 // ----------------------------------------------------------------------------- 546 547 #endif // libceed_fluids_examples_navier_stokes_h 548