177841947SLeila Ghaffari // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 277841947SLeila Ghaffari // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 377841947SLeila Ghaffari // reserved. See files LICENSE and NOTICE for details. 477841947SLeila Ghaffari // 577841947SLeila Ghaffari // This file is part of CEED, a collection of benchmarks, miniapps, software 677841947SLeila Ghaffari // libraries and APIs for efficient high-order finite element and spectral 777841947SLeila Ghaffari // element discretizations for exascale applications. For more information and 877841947SLeila Ghaffari // source code availability see http://github.com/ceed. 977841947SLeila Ghaffari // 1077841947SLeila Ghaffari // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 1177841947SLeila Ghaffari // a collaborative effort of two U.S. Department of Energy organizations (Office 1277841947SLeila Ghaffari // of Science and the National Nuclear Security Administration) responsible for 1377841947SLeila Ghaffari // the planning and preparation of a capable exascale ecosystem, including 1477841947SLeila Ghaffari // software, applications, hardware, advanced system engineering and early 1577841947SLeila Ghaffari // testbed platforms, in support of the nation's exascale computing imperative. 1677841947SLeila Ghaffari 1777841947SLeila Ghaffari /// @file 1877841947SLeila Ghaffari /// Utility functions for setting up DENSITY_CURRENT 1977841947SLeila Ghaffari 2077841947SLeila Ghaffari #include "../navierstokes.h" 2177841947SLeila Ghaffari #include "../qfunctions/setupgeo.h" 2277841947SLeila Ghaffari #include "../qfunctions/densitycurrent.h" 2377841947SLeila Ghaffari 241864f1c2SLeila Ghaffari PetscErrorCode NS_DENSITY_CURRENT(ProblemData *problem, DM dm, void *setup_ctx, 2577841947SLeila Ghaffari void *ctx) { 2677841947SLeila Ghaffari SetupContext setup_context = *(SetupContext *)setup_ctx; 2777841947SLeila Ghaffari User user = *(User *)ctx; 2877841947SLeila Ghaffari StabilizationType stab; 2977841947SLeila Ghaffari MPI_Comm comm = PETSC_COMM_WORLD; 3077841947SLeila Ghaffari PetscBool implicit; 3177841947SLeila Ghaffari PetscBool has_curr_time = PETSC_FALSE; 3277841947SLeila Ghaffari PetscInt ierr; 3377841947SLeila Ghaffari PetscFunctionBeginUser; 3477841947SLeila Ghaffari 3577841947SLeila Ghaffari ierr = PetscCalloc1(1, &user->phys->dc_ctx); CHKERRQ(ierr); 3677841947SLeila Ghaffari 3777841947SLeila Ghaffari // ------------------------------------------------------ 3877841947SLeila Ghaffari // SET UP DENSITY_CURRENT 3977841947SLeila Ghaffari // ------------------------------------------------------ 4077841947SLeila Ghaffari problem->dim = 3; 4177841947SLeila Ghaffari problem->q_data_size_vol = 10; 4277841947SLeila Ghaffari problem->q_data_size_sur = 4; 4377841947SLeila Ghaffari problem->setup_vol = Setup; 4477841947SLeila Ghaffari problem->setup_vol_loc = Setup_loc; 4577841947SLeila Ghaffari problem->setup_sur = SetupBoundary; 4677841947SLeila Ghaffari problem->setup_sur_loc = SetupBoundary_loc; 4777841947SLeila Ghaffari problem->ics = ICsDC; 4877841947SLeila Ghaffari problem->ics_loc = ICsDC_loc; 4977841947SLeila Ghaffari problem->apply_vol_rhs = DC; 5077841947SLeila Ghaffari problem->apply_vol_rhs_loc = DC_loc; 5177841947SLeila Ghaffari problem->apply_vol_ifunction = IFunction_DC; 5277841947SLeila Ghaffari problem->apply_vol_ifunction_loc = IFunction_DC_loc; 5377841947SLeila Ghaffari problem->bc = Exact_DC; 54d0b732dbSLeila Ghaffari problem->setup_ctx = SetupContext_DENSITY_CURRENT; 5577841947SLeila Ghaffari problem->non_zero_time = PETSC_FALSE; 5677841947SLeila Ghaffari problem->print_info = PRINT_DENSITY_CURRENT; 5777841947SLeila Ghaffari 5877841947SLeila Ghaffari // ------------------------------------------------------ 5977841947SLeila Ghaffari // Create the libCEED context 6077841947SLeila Ghaffari // ------------------------------------------------------ 6177841947SLeila Ghaffari CeedScalar theta0 = 300.; // K 6277841947SLeila Ghaffari CeedScalar thetaC = -15.; // K 6377841947SLeila Ghaffari CeedScalar P0 = 1.e5; // Pa 6477841947SLeila Ghaffari CeedScalar N = 0.01; // 1/s 6577841947SLeila Ghaffari CeedScalar cv = 717.; // J/(kg K) 6677841947SLeila Ghaffari CeedScalar cp = 1004.; // J/(kg K) 6777841947SLeila Ghaffari CeedScalar g = 9.81; // m/s^2 6877841947SLeila Ghaffari CeedScalar lambda = -2./3.; // - 6977841947SLeila Ghaffari CeedScalar mu = 75.; // Pa s, dynamic viscosity 7077841947SLeila Ghaffari // mu = 75 is not physical for air, but is good for numerical stability 7177841947SLeila Ghaffari CeedScalar k = 0.02638; // W/(m K) 72504dc8e0SLeila Ghaffari CeedScalar c_tau = 0.5; // - 73932417b3SJed Brown // c_tau = 0.5 is reported as "optimal" in Hughes et al 2010 7477841947SLeila Ghaffari CeedScalar rc = 1000.; // m (Radius of bubble) 7577841947SLeila Ghaffari PetscReal center[3], dc_axis[3] = {0, 0, 0}; 761864f1c2SLeila Ghaffari PetscReal domain_min[3], domain_max[3], domain_size[3]; 771864f1c2SLeila Ghaffari ierr = DMGetBoundingBox(dm, domain_min, domain_max); CHKERRQ(ierr); 781864f1c2SLeila Ghaffari for (int i=0; i<3; i++) domain_size[i] = domain_max[i] - domain_min[i]; 7977841947SLeila Ghaffari 8077841947SLeila Ghaffari // ------------------------------------------------------ 8177841947SLeila Ghaffari // Create the PETSc context 8277841947SLeila Ghaffari // ------------------------------------------------------ 8377841947SLeila Ghaffari PetscScalar meter = 1e-2; // 1 meter in scaled length units 8477841947SLeila Ghaffari PetscScalar kilogram = 1e-6; // 1 kilogram in scaled mass units 8577841947SLeila Ghaffari PetscScalar second = 1e-2; // 1 second in scaled time units 8677841947SLeila Ghaffari PetscScalar Kelvin = 1; // 1 Kelvin in scaled temperature units 8777841947SLeila Ghaffari PetscScalar W_per_m_K, Pascal, J_per_kg_K, m_per_squared_s; 8877841947SLeila Ghaffari 8977841947SLeila Ghaffari // ------------------------------------------------------ 9077841947SLeila Ghaffari // Command line Options 9177841947SLeila Ghaffari // ------------------------------------------------------ 9277841947SLeila Ghaffari ierr = PetscOptionsBegin(comm, NULL, "Options for DENSITY_CURRENT problem", 9377841947SLeila Ghaffari NULL); CHKERRQ(ierr); 9477841947SLeila Ghaffari // -- Physics 9577841947SLeila Ghaffari ierr = PetscOptionsScalar("-theta0", "Reference potential temperature", 9677841947SLeila Ghaffari NULL, theta0, &theta0, NULL); CHKERRQ(ierr); 9777841947SLeila Ghaffari ierr = PetscOptionsScalar("-thetaC", "Perturbation of potential temperature", 9877841947SLeila Ghaffari NULL, thetaC, &thetaC, NULL); CHKERRQ(ierr); 9977841947SLeila Ghaffari ierr = PetscOptionsScalar("-P0", "Atmospheric pressure", 10077841947SLeila Ghaffari NULL, P0, &P0, NULL); CHKERRQ(ierr); 10177841947SLeila Ghaffari ierr = PetscOptionsScalar("-N", "Brunt-Vaisala frequency", 10277841947SLeila Ghaffari NULL, N, &N, NULL); CHKERRQ(ierr); 10377841947SLeila Ghaffari ierr = PetscOptionsScalar("-cv", "Heat capacity at constant volume", 10477841947SLeila Ghaffari NULL, cv, &cv, NULL); CHKERRQ(ierr); 10577841947SLeila Ghaffari ierr = PetscOptionsScalar("-cp", "Heat capacity at constant pressure", 10677841947SLeila Ghaffari NULL, cp, &cp, NULL); CHKERRQ(ierr); 10777841947SLeila Ghaffari ierr = PetscOptionsScalar("-g", "Gravitational acceleration", 10877841947SLeila Ghaffari NULL, g, &g, NULL); CHKERRQ(ierr); 10977841947SLeila Ghaffari ierr = PetscOptionsScalar("-lambda", 11077841947SLeila Ghaffari "Stokes hypothesis second viscosity coefficient", 11177841947SLeila Ghaffari NULL, lambda, &lambda, NULL); CHKERRQ(ierr); 11277841947SLeila Ghaffari ierr = PetscOptionsScalar("-mu", "Shear dynamic viscosity coefficient", 11377841947SLeila Ghaffari NULL, mu, &mu, NULL); CHKERRQ(ierr); 11477841947SLeila Ghaffari ierr = PetscOptionsScalar("-k", "Thermal conductivity", 11577841947SLeila Ghaffari NULL, k, &k, NULL); CHKERRQ(ierr); 11677841947SLeila Ghaffari ierr = PetscOptionsScalar("-rc", "Characteristic radius of thermal bubble", 11777841947SLeila Ghaffari NULL, rc, &rc, NULL); CHKERRQ(ierr); 1181864f1c2SLeila Ghaffari for (int i=0; i<3; i++) center[i] = .5*domain_size[i]; 11977841947SLeila Ghaffari PetscInt n = problem->dim; 12077841947SLeila Ghaffari ierr = PetscOptionsRealArray("-center", "Location of bubble center", 12177841947SLeila Ghaffari NULL, center, &n, NULL); CHKERRQ(ierr); 12277841947SLeila Ghaffari n = problem->dim; 12377841947SLeila Ghaffari ierr = PetscOptionsRealArray("-dc_axis", 12477841947SLeila Ghaffari "Axis of density current cylindrical anomaly, or {0,0,0} for spherically symmetric", 12577841947SLeila Ghaffari NULL, dc_axis, &n, NULL); CHKERRQ(ierr); 12677841947SLeila Ghaffari { 12777841947SLeila Ghaffari PetscReal norm = PetscSqrtReal(PetscSqr(dc_axis[0]) + PetscSqr(dc_axis[1]) + 12877841947SLeila Ghaffari PetscSqr(dc_axis[2])); 12977841947SLeila Ghaffari if (norm > 0) { 13077841947SLeila Ghaffari for (int i=0; i<3; i++) dc_axis[i] /= norm; 13177841947SLeila Ghaffari } 13277841947SLeila Ghaffari } 13377841947SLeila Ghaffari ierr = PetscOptionsEnum("-stab", "Stabilization method", NULL, 13477841947SLeila Ghaffari StabilizationTypes, (PetscEnum)(stab = STAB_NONE), 13577841947SLeila Ghaffari (PetscEnum *)&stab, NULL); CHKERRQ(ierr); 136932417b3SJed Brown ierr = PetscOptionsScalar("-c_tau", "Stabilization constant", 137932417b3SJed Brown NULL, c_tau, &c_tau, NULL); CHKERRQ(ierr); 13877841947SLeila Ghaffari ierr = PetscOptionsBool("-implicit", "Use implicit (IFunction) formulation", 13977841947SLeila Ghaffari NULL, implicit=PETSC_FALSE, &implicit, NULL); 14077841947SLeila Ghaffari CHKERRQ(ierr); 14177841947SLeila Ghaffari 14277841947SLeila Ghaffari // -- Units 14377841947SLeila Ghaffari ierr = PetscOptionsScalar("-units_meter", "1 meter in scaled length units", 14477841947SLeila Ghaffari NULL, meter, &meter, NULL); CHKERRQ(ierr); 14577841947SLeila Ghaffari meter = fabs(meter); 14677841947SLeila Ghaffari ierr = PetscOptionsScalar("-units_kilogram","1 kilogram in scaled mass units", 14777841947SLeila Ghaffari NULL, kilogram, &kilogram, NULL); CHKERRQ(ierr); 14877841947SLeila Ghaffari kilogram = fabs(kilogram); 14977841947SLeila Ghaffari ierr = PetscOptionsScalar("-units_second","1 second in scaled time units", 15077841947SLeila Ghaffari NULL, second, &second, NULL); CHKERRQ(ierr); 15177841947SLeila Ghaffari second = fabs(second); 15277841947SLeila Ghaffari ierr = PetscOptionsScalar("-units_Kelvin", 15377841947SLeila Ghaffari "1 Kelvin in scaled temperature units", 15477841947SLeila Ghaffari NULL, Kelvin, &Kelvin, NULL); CHKERRQ(ierr); 15577841947SLeila Ghaffari Kelvin = fabs(Kelvin); 15677841947SLeila Ghaffari 15777841947SLeila Ghaffari // -- Warnings 15877841947SLeila Ghaffari if (stab == STAB_SUPG && !implicit) { 15977841947SLeila Ghaffari ierr = PetscPrintf(comm, 16077841947SLeila Ghaffari "Warning! Use -stab supg only with -implicit\n"); 16177841947SLeila Ghaffari CHKERRQ(ierr); 16277841947SLeila Ghaffari } 16377841947SLeila Ghaffari 16477841947SLeila Ghaffari ierr = PetscOptionsEnd(); CHKERRQ(ierr); 16577841947SLeila Ghaffari 16677841947SLeila Ghaffari // ------------------------------------------------------ 16777841947SLeila Ghaffari // Set up the PETSc context 16877841947SLeila Ghaffari // ------------------------------------------------------ 16977841947SLeila Ghaffari // -- Define derived units 17077841947SLeila Ghaffari Pascal = kilogram / (meter * PetscSqr(second)); 17177841947SLeila Ghaffari J_per_kg_K = PetscSqr(meter) / (PetscSqr(second) * Kelvin); 17277841947SLeila Ghaffari m_per_squared_s = meter / PetscSqr(second); 17377841947SLeila Ghaffari W_per_m_K = kilogram * meter / (pow(second,3) * Kelvin); 17477841947SLeila Ghaffari 17577841947SLeila Ghaffari user->units->meter = meter; 17677841947SLeila Ghaffari user->units->kilogram = kilogram; 17777841947SLeila Ghaffari user->units->second = second; 17877841947SLeila Ghaffari user->units->Kelvin = Kelvin; 17977841947SLeila Ghaffari user->units->Pascal = Pascal; 18077841947SLeila Ghaffari user->units->J_per_kg_K = J_per_kg_K; 18177841947SLeila Ghaffari user->units->m_per_squared_s = m_per_squared_s; 18277841947SLeila Ghaffari user->units->W_per_m_K = W_per_m_K; 18377841947SLeila Ghaffari 18477841947SLeila Ghaffari // ------------------------------------------------------ 18577841947SLeila Ghaffari // Set up the libCEED context 18677841947SLeila Ghaffari // ------------------------------------------------------ 18777841947SLeila Ghaffari // -- Scale variables to desired units 18877841947SLeila Ghaffari theta0 *= Kelvin; 18977841947SLeila Ghaffari thetaC *= Kelvin; 19077841947SLeila Ghaffari P0 *= Pascal; 19177841947SLeila Ghaffari N *= (1./second); 19277841947SLeila Ghaffari cv *= J_per_kg_K; 19377841947SLeila Ghaffari cp *= J_per_kg_K; 19477841947SLeila Ghaffari g *= m_per_squared_s; 19577841947SLeila Ghaffari mu *= Pascal * second; 19677841947SLeila Ghaffari k *= W_per_m_K; 19777841947SLeila Ghaffari rc = fabs(rc) * meter; 1981864f1c2SLeila Ghaffari for (int i=0; i<3; i++) domain_size[i] *= meter; 19977841947SLeila Ghaffari for (int i=0; i<3; i++) center[i] *= meter; 2001864f1c2SLeila Ghaffari problem->dm_scale = meter; 20177841947SLeila Ghaffari 20277841947SLeila Ghaffari // -- Setup Context 20377841947SLeila Ghaffari setup_context->theta0 = theta0; 20477841947SLeila Ghaffari setup_context->thetaC = thetaC; 20577841947SLeila Ghaffari setup_context->P0 = P0; 20677841947SLeila Ghaffari setup_context->N = N; 20777841947SLeila Ghaffari setup_context->cv = cv; 20877841947SLeila Ghaffari setup_context->cp = cp; 20977841947SLeila Ghaffari setup_context->g = g; 21077841947SLeila Ghaffari setup_context->rc = rc; 2111864f1c2SLeila Ghaffari setup_context->lx = domain_size[0]; 2121864f1c2SLeila Ghaffari setup_context->ly = domain_size[1]; 2131864f1c2SLeila Ghaffari setup_context->lz = domain_size[2]; 21477841947SLeila Ghaffari setup_context->center[0] = center[0]; 21577841947SLeila Ghaffari setup_context->center[1] = center[1]; 21677841947SLeila Ghaffari setup_context->center[2] = center[2]; 21777841947SLeila Ghaffari setup_context->dc_axis[0] = dc_axis[0]; 21877841947SLeila Ghaffari setup_context->dc_axis[1] = dc_axis[1]; 21977841947SLeila Ghaffari setup_context->dc_axis[2] = dc_axis[2]; 22077841947SLeila Ghaffari setup_context->time = 0; 22177841947SLeila Ghaffari 22277841947SLeila Ghaffari // -- QFunction Context 22377841947SLeila Ghaffari user->phys->stab = stab; 22477841947SLeila Ghaffari user->phys->implicit = implicit; 22577841947SLeila Ghaffari user->phys->has_curr_time = has_curr_time; 22677841947SLeila Ghaffari user->phys->dc_ctx->lambda = lambda; 22777841947SLeila Ghaffari user->phys->dc_ctx->mu = mu; 22877841947SLeila Ghaffari user->phys->dc_ctx->k = k; 22977841947SLeila Ghaffari user->phys->dc_ctx->cv = cv; 23077841947SLeila Ghaffari user->phys->dc_ctx->cp = cp; 23177841947SLeila Ghaffari user->phys->dc_ctx->g = g; 232932417b3SJed Brown user->phys->dc_ctx->c_tau = c_tau; 23377841947SLeila Ghaffari user->phys->dc_ctx->stabilization = stab; 23477841947SLeila Ghaffari 23577841947SLeila Ghaffari PetscFunctionReturn(0); 23677841947SLeila Ghaffari } 23777841947SLeila Ghaffari 238d0b732dbSLeila Ghaffari PetscErrorCode SetupContext_DENSITY_CURRENT(Ceed ceed, CeedData ceed_data, 239*2fe7aee7SLeila Ghaffari AppCtx app_ctx, SetupContext setup_ctx, Physics phys) { 240d0b732dbSLeila Ghaffari PetscFunctionBeginUser; 241d0b732dbSLeila Ghaffari CeedQFunctionContextCreate(ceed, &ceed_data->setup_context); 242d0b732dbSLeila Ghaffari CeedQFunctionContextSetData(ceed_data->setup_context, CEED_MEM_HOST, 243d0b732dbSLeila Ghaffari CEED_USE_POINTER, sizeof(*setup_ctx), setup_ctx); 244d0b732dbSLeila Ghaffari CeedQFunctionSetContext(ceed_data->qf_ics, ceed_data->setup_context); 245d0b732dbSLeila Ghaffari CeedQFunctionContextCreate(ceed, &ceed_data->dc_context); 246d0b732dbSLeila Ghaffari CeedQFunctionContextSetData(ceed_data->dc_context, CEED_MEM_HOST, 247d0b732dbSLeila Ghaffari CEED_USE_POINTER, 248d0b732dbSLeila Ghaffari sizeof(*phys->dc_ctx), phys->dc_ctx); 249d0b732dbSLeila Ghaffari if (ceed_data->qf_rhs_vol) 250d0b732dbSLeila Ghaffari CeedQFunctionSetContext(ceed_data->qf_rhs_vol, ceed_data->dc_context); 251d0b732dbSLeila Ghaffari if (ceed_data->qf_ifunction_vol) 252d0b732dbSLeila Ghaffari CeedQFunctionSetContext(ceed_data->qf_ifunction_vol, ceed_data->dc_context); 25377841947SLeila Ghaffari PetscFunctionReturn(0); 25477841947SLeila Ghaffari } 25577841947SLeila Ghaffari 25677841947SLeila Ghaffari PetscErrorCode PRINT_DENSITY_CURRENT(Physics phys, SetupContext setup_ctx, 25777841947SLeila Ghaffari AppCtx app_ctx) { 25877841947SLeila Ghaffari MPI_Comm comm = PETSC_COMM_WORLD; 25977841947SLeila Ghaffari PetscErrorCode ierr; 26077841947SLeila Ghaffari PetscFunctionBeginUser; 26177841947SLeila Ghaffari 26277841947SLeila Ghaffari ierr = PetscPrintf(comm, 26377841947SLeila Ghaffari " Problem:\n" 26477841947SLeila Ghaffari " Problem Name : %s\n" 26577841947SLeila Ghaffari " Stabilization : %s\n", 26677841947SLeila Ghaffari app_ctx->problem_name, StabilizationTypes[phys->stab]); 26777841947SLeila Ghaffari CHKERRQ(ierr); 26877841947SLeila Ghaffari 26977841947SLeila Ghaffari PetscFunctionReturn(0); 27077841947SLeila Ghaffari } 271