// Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights // reserved. See files LICENSE and NOTICE for details. // // This file is part of CEED, a collection of benchmarks, miniapps, software // libraries and APIs for efficient high-order finite element and spectral // element discretizations for exascale applications. For more information and // source code availability see http://github.com/ceed. // // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, // a collaborative effort of two U.S. Department of Energy organizations (Office // of Science and the National Nuclear Security Administration) responsible for // the planning and preparation of a capable exascale ecosystem, including // software, applications, hardware, advanced system engineering and early // testbed platforms, in support of the nation's exascale computing imperative. /// @file /// Advection initial condition and operator for Navier-Stokes example using PETSc #ifndef advection_h #define advection_h #include #ifndef setup_context_struct #define setup_context_struct typedef struct SetupContext_ *SetupContext; struct SetupContext_ { CeedScalar theta0; CeedScalar thetaC; CeedScalar P0; CeedScalar N; CeedScalar cv; CeedScalar cp; CeedScalar g; CeedScalar rc; CeedScalar lx; CeedScalar ly; CeedScalar lz; CeedScalar center[3]; CeedScalar dc_axis[3]; CeedScalar wind[3]; CeedScalar time; int wind_type; // See WindType: 0=ROTATION, 1=TRANSLATION int bubble_type; // See BubbleType: 0=SPHERE, 1=CYLINDER int bubble_continuity_type; // See BubbleContinuityType: 0=SMOOTH, 1=BACK_SHARP 2=THICK }; #endif #ifndef advection_context_struct #define advection_context_struct typedef struct AdvectionContext_ *AdvectionContext; struct AdvectionContext_ { CeedScalar CtauS; CeedScalar strong_form; CeedScalar E_wind; bool implicit; int stabilization; // See StabilizationType: 0=none, 1=SU, 2=SUPG }; #endif // ***************************************************************************** // This QFunction sets the initial conditions and the boundary conditions // for two test cases: ROTATION and TRANSLATION // // -- ROTATION (default) // Initial Conditions: // Mass Density: // Constant mass density of 1.0 // Momentum Density: // Rotational field in x,y // Energy Density: // Maximum of 1. x0 decreasing linearly to 0. as radial distance // increases to (1.-r/rc), then 0. everywhere else // // Boundary Conditions: // Mass Density: // 0.0 flux // Momentum Density: // 0.0 // Energy Density: // 0.0 flux // // -- TRANSLATION // Initial Conditions: // Mass Density: // Constant mass density of 1.0 // Momentum Density: // Constant rectilinear field in x,y // Energy Density: // Maximum of 1. x0 decreasing linearly to 0. as radial distance // increases to (1.-r/rc), then 0. everywhere else // // Boundary Conditions: // Mass Density: // 0.0 flux // Momentum Density: // 0.0 // Energy Density: // Inflow BCs: // E = E_wind // Outflow BCs: // E = E(boundary) // Both In/Outflow BCs for E are applied weakly in the // QFunction "Advection_Sur" // // ***************************************************************************** // ***************************************************************************** // This helper function provides support for the exact, time-dependent solution // (currently not implemented) and IC formulation for 3D advection // ***************************************************************************** CEED_QFUNCTION_HELPER int Exact_Advection(CeedInt dim, CeedScalar time, const CeedScalar X[], CeedInt Nf, CeedScalar q[], void *ctx) { const SetupContext context = (SetupContext)ctx; const CeedScalar rc = context->rc; const CeedScalar lx = context->lx; const CeedScalar ly = context->ly; const CeedScalar lz = context->lz; const CeedScalar *wind = context->wind; // Setup const CeedScalar x0[3] = {0.25*lx, 0.5*ly, 0.5*lz}; const CeedScalar center[3] = {0.5*lx, 0.5*ly, 0.5*lz}; // -- Coordinates const CeedScalar x = X[0]; const CeedScalar y = X[1]; const CeedScalar z = X[2]; // -- Energy CeedScalar r = 0.; switch (context->bubble_type) { // original sphere case 0: { // (dim=3) r = sqrt(pow((x - x0[0]), 2) + pow((y - x0[1]), 2) + pow((z - x0[2]), 2)); } break; // cylinder (needs periodicity to work properly) case 1: { // (dim=2) r = sqrt(pow((x - x0[0]), 2) + pow((y - x0[1]), 2) ); } break; } // Initial Conditions switch (context->wind_type) { case 0: // Rotation q[0] = 1.; q[1] = -(y - center[1]); q[2] = (x - center[0]); q[3] = 0; break; case 1: // Translation q[0] = 1.; q[1] = wind[0]; q[2] = wind[1]; q[3] = wind[2]; break; } switch (context->bubble_continuity_type) { // original continuous, smooth shape case 0: { q[4] = r <= rc ? (1.-r/rc) : 0.; } break; // discontinuous, sharp back half shape case 1: { q[4] = ((r <= rc) && (yCtauS; const CeedScalar strong_form = context->strong_form; CeedPragmaSIMD // Quadrature Point Loop for (CeedInt i=0; iCtauS; const CeedScalar strong_form = context->strong_form; CeedPragmaSIMD // Quadrature Point Loop for (CeedInt i=0; istabilization) { case 0: break; case 1: dv[j][4][i] += wdetJ * TauS * strong_conv * uX[j]; //SU break; case 2: dv[j][4][i] += wdetJ * TauS * strong_res * uX[j]; //SUPG break; } } // End Quadrature Point Loop return 0; } // ***************************************************************************** // This QFunction implements consistent outflow and inflow BCs // for 3D advection // // Inflow and outflow faces are determined based on sign(dot(wind, normal)): // sign(dot(wind, normal)) > 0 : outflow BCs // sign(dot(wind, normal)) < 0 : inflow BCs // // Outflow BCs: // The validity of the weak form of the governing equations is extended // to the outflow and the current values of E are applied. // // Inflow BCs: // A prescribed Total Energy (E_wind) is applied weakly. // // ***************************************************************************** CEED_QFUNCTION(Advection_Sur)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { // *INDENT-OFF* // Inputs const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[1]; // Outputs CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; // *INDENT-ON* AdvectionContext context = (AdvectionContext)ctx; const CeedScalar E_wind = context->E_wind; const CeedScalar strong_form = context->strong_form; const bool implicit = context->implicit; CeedPragmaSIMD // Quadrature Point Loop for (CeedInt i=0; i 0) { // outflow v[4][i] = -(1 - strong_form) * wdetJb * E * u_normal; } else { // inflow v[4][i] = -(1 - strong_form) * wdetJb * E_wind * u_normal; } } // End Quadrature Point Loop return 0; } // ***************************************************************************** #endif // advection_h