1ccaff030SJeremy L Thompson // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2ccaff030SJeremy L Thompson // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3ccaff030SJeremy L Thompson // reserved. See files LICENSE and NOTICE for details. 4ccaff030SJeremy L Thompson // 5ccaff030SJeremy L Thompson // This file is part of CEED, a collection of benchmarks, miniapps, software 6ccaff030SJeremy L Thompson // libraries and APIs for efficient high-order finite element and spectral 7ccaff030SJeremy L Thompson // element discretizations for exascale applications. For more information and 8ccaff030SJeremy L Thompson // source code availability see http://github.com/ceed. 9ccaff030SJeremy L Thompson // 10ccaff030SJeremy L Thompson // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11ccaff030SJeremy L Thompson // a collaborative effort of two U.S. Department of Energy organizations (Office 12ccaff030SJeremy L Thompson // of Science and the National Nuclear Security Administration) responsible for 13ccaff030SJeremy L Thompson // the planning and preparation of a capable exascale ecosystem, including 14ccaff030SJeremy L Thompson // software, applications, hardware, advanced system engineering and early 15ccaff030SJeremy L Thompson // testbed platforms, in support of the nation's exascale computing imperative. 16ccaff030SJeremy L Thompson 17ccaff030SJeremy L Thompson // libCEED + PETSc Example: Navier-Stokes 18ccaff030SJeremy L Thompson // 19ccaff030SJeremy L Thompson // This example demonstrates a simple usage of libCEED with PETSc to solve a 20ccaff030SJeremy L Thompson // Navier-Stokes problem. 21ccaff030SJeremy L Thompson // 22ccaff030SJeremy L Thompson // The code is intentionally "raw", using only low-level communication 23ccaff030SJeremy L Thompson // primitives. 24ccaff030SJeremy L Thompson // 25ccaff030SJeremy L Thompson // Build with: 26ccaff030SJeremy L Thompson // 27ccaff030SJeremy L Thompson // make [PETSC_DIR=</path/to/petsc>] [CEED_DIR=</path/to/libceed>] navierstokes 28ccaff030SJeremy L Thompson // 29ccaff030SJeremy L Thompson // Sample runs: 30ccaff030SJeremy L Thompson // 31ea6e0f84SLeila Ghaffari // ./navierstokes -ceed /cpu/self -problem density_current -degree_volume 1 32ea6e0f84SLeila Ghaffari // ./navierstokes -ceed /gpu/occa -problem advection -degree_volume 1 33ccaff030SJeremy L Thompson // 34ea6e0f84SLeila Ghaffari //TESTARGS -ceed {ceed_resource} -test -degree_volume 1 35ccaff030SJeremy L Thompson 36ccaff030SJeremy L Thompson /// @file 37ccaff030SJeremy L Thompson /// Navier-Stokes example using PETSc 38ccaff030SJeremy L Thompson 39ccaff030SJeremy L Thompson const char help[] = "Solve Navier-Stokes using PETSc and libCEED\n"; 40ccaff030SJeremy L Thompson 41ccaff030SJeremy L Thompson #include <petscts.h> 42ccaff030SJeremy L Thompson #include <petscdmplex.h> 43ccaff030SJeremy L Thompson #include <ceed.h> 44ccaff030SJeremy L Thompson #include <stdbool.h> 45ccaff030SJeremy L Thompson #include <petscsys.h> 46ccaff030SJeremy L Thompson #include "common.h" 47b0137797SLeila Ghaffari #include "setup-boundary.h" 48ccaff030SJeremy L Thompson #include "advection.h" 49ccaff030SJeremy L Thompson #include "advection2d.h" 50ccaff030SJeremy L Thompson #include "densitycurrent.h" 51ccaff030SJeremy L Thompson 52ccaff030SJeremy L Thompson // Problem Options 53ccaff030SJeremy L Thompson typedef enum { 54ccaff030SJeremy L Thompson NS_DENSITY_CURRENT = 0, 55ccaff030SJeremy L Thompson NS_ADVECTION = 1, 56ccaff030SJeremy L Thompson NS_ADVECTION2D = 2, 57ccaff030SJeremy L Thompson } problemType; 58ccaff030SJeremy L Thompson static const char *const problemTypes[] = { 59ccaff030SJeremy L Thompson "density_current", 60ccaff030SJeremy L Thompson "advection", 61ccaff030SJeremy L Thompson "advection2d", 620c6c0b13SLeila Ghaffari "problemType","NS_",0 63ccaff030SJeremy L Thompson }; 64ccaff030SJeremy L Thompson 65ccaff030SJeremy L Thompson typedef enum { 66ccaff030SJeremy L Thompson STAB_NONE = 0, 67ccaff030SJeremy L Thompson STAB_SU = 1, // Streamline Upwind 68ccaff030SJeremy L Thompson STAB_SUPG = 2, // Streamline Upwind Petrov-Galerkin 69ccaff030SJeremy L Thompson } StabilizationType; 70ccaff030SJeremy L Thompson static const char *const StabilizationTypes[] = { 710c6c0b13SLeila Ghaffari "NONE", 72ccaff030SJeremy L Thompson "SU", 73ccaff030SJeremy L Thompson "SUPG", 74ccaff030SJeremy L Thompson "StabilizationType", "STAB_", NULL 75ccaff030SJeremy L Thompson }; 76ccaff030SJeremy L Thompson 77ccaff030SJeremy L Thompson // Problem specific data 78ccaff030SJeremy L Thompson typedef struct { 798b982baeSLeila Ghaffari CeedInt dim, qdatasizeVol, qdatasizeSur; 80ea6e0f84SLeila Ghaffari CeedQFunctionUser setupVol, setupSur, ics, applyVol_rhs, applySur_rhs, 81ea6e0f84SLeila Ghaffari applyVol_ifunction, applySur_ifunction; 82ccaff030SJeremy L Thompson PetscErrorCode (*bc)(PetscInt, PetscReal, const PetscReal[], PetscInt, 83ccaff030SJeremy L Thompson PetscScalar[], void *); 84ea6e0f84SLeila Ghaffari const char *setupVol_loc, *setupSur_loc, *ics_loc, *applyVol_rhs_loc, 85ea6e0f84SLeila Ghaffari *applySur_rhs_loc, *applyVol_ifunction_loc, *applySur_ifunction_loc; 86ccaff030SJeremy L Thompson const bool non_zero_time; 87ccaff030SJeremy L Thompson } problemData; 88ccaff030SJeremy L Thompson 89ccaff030SJeremy L Thompson problemData problemOptions[] = { 90ccaff030SJeremy L Thompson [NS_DENSITY_CURRENT] = { 91ccaff030SJeremy L Thompson .dim = 3, 92ea6e0f84SLeila Ghaffari .qdatasizeVol = 10, 938b982baeSLeila Ghaffari .qdatasizeSur = 4, 94b0137797SLeila Ghaffari .setupVol = Setup, 95b0137797SLeila Ghaffari .setupVol_loc = Setup_loc, 96356fbf4bSLeila Ghaffari .setupSur = SetupBoundary, 97356fbf4bSLeila Ghaffari .setupSur_loc = SetupBoundary_loc, 98ccaff030SJeremy L Thompson .ics = ICsDC, 99ccaff030SJeremy L Thompson .ics_loc = ICsDC_loc, 100c96c872fSLeila Ghaffari .applyVol_rhs = DC, 101c96c872fSLeila Ghaffari .applyVol_rhs_loc = DC_loc, 1028b982baeSLeila Ghaffari .applySur_rhs = DC_Sur, 1038b982baeSLeila Ghaffari .applySur_rhs_loc = DC_Sur_loc, 104c96c872fSLeila Ghaffari .applyVol_ifunction = IFunction_DC, 105c96c872fSLeila Ghaffari .applyVol_ifunction_loc = IFunction_DC_loc, 106ea6e0f84SLeila Ghaffari //.applySur_ifunction = IFunction_DC_Sur, 107ea6e0f84SLeila Ghaffari //.applySur_ifunction_loc = IFunction_DC_Sur_loc, 108ccaff030SJeremy L Thompson .bc = Exact_DC, 1090c6c0b13SLeila Ghaffari .non_zero_time = false, 110ccaff030SJeremy L Thompson }, 111ccaff030SJeremy L Thompson [NS_ADVECTION] = { 112ccaff030SJeremy L Thompson .dim = 3, 113ea6e0f84SLeila Ghaffari .qdatasizeVol = 10, 1148b982baeSLeila Ghaffari .qdatasizeSur = 4, 115b0137797SLeila Ghaffari .setupVol = Setup, 116b0137797SLeila Ghaffari .setupVol_loc = Setup_loc, 117356fbf4bSLeila Ghaffari .setupSur = SetupBoundary, 118356fbf4bSLeila Ghaffari .setupSur_loc = SetupBoundary_loc, 119ccaff030SJeremy L Thompson .ics = ICsAdvection, 120ccaff030SJeremy L Thompson .ics_loc = ICsAdvection_loc, 121c96c872fSLeila Ghaffari .applyVol_rhs = Advection, 122c96c872fSLeila Ghaffari .applyVol_rhs_loc = Advection_loc, 12329448992SLeila Ghaffari .applySur_rhs = Advection_Sur, 12429448992SLeila Ghaffari .applySur_rhs_loc = Advection_Sur_loc, 125c96c872fSLeila Ghaffari .applyVol_ifunction = IFunction_Advection, 126c96c872fSLeila Ghaffari .applyVol_ifunction_loc = IFunction_Advection_loc, 127ea6e0f84SLeila Ghaffari //.applySur_ifunction = IFunction_Advection_Sur, 128ea6e0f84SLeila Ghaffari //.applySur_ifunction_loc = IFunction_Advection_Sur_loc, 129ccaff030SJeremy L Thompson .bc = Exact_Advection, 1300c6c0b13SLeila Ghaffari .non_zero_time = true, 131ccaff030SJeremy L Thompson }, 132ccaff030SJeremy L Thompson [NS_ADVECTION2D] = { 133ccaff030SJeremy L Thompson .dim = 2, 134ea6e0f84SLeila Ghaffari .qdatasizeVol = 5, 1358b982baeSLeila Ghaffari .qdatasizeSur = 3, 136c96c872fSLeila Ghaffari .setupVol = Setup2d, 137c96c872fSLeila Ghaffari .setupVol_loc = Setup2d_loc, 138b0137797SLeila Ghaffari .setupSur = SetupBoundary2d, 139b0137797SLeila Ghaffari .setupSur_loc = SetupBoundary2d_loc, 140ccaff030SJeremy L Thompson .ics = ICsAdvection2d, 141ccaff030SJeremy L Thompson .ics_loc = ICsAdvection2d_loc, 142c96c872fSLeila Ghaffari .applyVol_rhs = Advection2d, 143c96c872fSLeila Ghaffari .applyVol_rhs_loc = Advection2d_loc, 144b0137797SLeila Ghaffari .applySur_rhs = Advection2d_Sur, 145b0137797SLeila Ghaffari .applySur_rhs_loc = Advection2d_Sur_loc, 146c96c872fSLeila Ghaffari .applyVol_ifunction = IFunction_Advection2d, 147c96c872fSLeila Ghaffari .applyVol_ifunction_loc = IFunction_Advection2d_loc, 148ea6e0f84SLeila Ghaffari //.applySur_ifunction = IFunction_Advection2d_Sur, 149ea6e0f84SLeila Ghaffari //.applySur_ifunction_loc = IFunction_Advection2d_Sur_loc, 150ccaff030SJeremy L Thompson .bc = Exact_Advection2d, 1510c6c0b13SLeila Ghaffari .non_zero_time = true, 152ccaff030SJeremy L Thompson }, 153ccaff030SJeremy L Thompson }; 154ccaff030SJeremy L Thompson 155ccaff030SJeremy L Thompson // PETSc user data 156ccaff030SJeremy L Thompson typedef struct User_ *User; 157ccaff030SJeremy L Thompson typedef struct Units_ *Units; 158ccaff030SJeremy L Thompson 159ccaff030SJeremy L Thompson struct User_ { 160ccaff030SJeremy L Thompson MPI_Comm comm; 161ccaff030SJeremy L Thompson PetscInt outputfreq; 162ccaff030SJeremy L Thompson DM dm; 163ccaff030SJeremy L Thompson DM dmviz; 164ccaff030SJeremy L Thompson Mat interpviz; 165ccaff030SJeremy L Thompson Ceed ceed; 166ccaff030SJeremy L Thompson Units units; 167ccaff030SJeremy L Thompson CeedVector qceed, qdotceed, gceed; 168ea6e0f84SLeila Ghaffari CeedOperator op_rhs_vol, op_rhs_sur, op_rhs, 169ea6e0f84SLeila Ghaffari op_ifunction_vol, op_ifunction_sur, op_ifunction; 170ccaff030SJeremy L Thompson Vec M; 171ccaff030SJeremy L Thompson char outputfolder[PETSC_MAX_PATH_LEN]; 172ccaff030SJeremy L Thompson PetscInt contsteps; 173ccaff030SJeremy L Thompson }; 174ccaff030SJeremy L Thompson 175ccaff030SJeremy L Thompson struct Units_ { 176ccaff030SJeremy L Thompson // fundamental units 177ccaff030SJeremy L Thompson PetscScalar meter; 178ccaff030SJeremy L Thompson PetscScalar kilogram; 179ccaff030SJeremy L Thompson PetscScalar second; 180ccaff030SJeremy L Thompson PetscScalar Kelvin; 181ccaff030SJeremy L Thompson // derived units 182ccaff030SJeremy L Thompson PetscScalar Pascal; 183ccaff030SJeremy L Thompson PetscScalar JperkgK; 184ccaff030SJeremy L Thompson PetscScalar mpersquareds; 185ccaff030SJeremy L Thompson PetscScalar WpermK; 186ccaff030SJeremy L Thompson PetscScalar kgpercubicm; 187ccaff030SJeremy L Thompson PetscScalar kgpersquaredms; 188ccaff030SJeremy L Thompson PetscScalar Joulepercubicm; 189ccaff030SJeremy L Thompson }; 190ccaff030SJeremy L Thompson 191ccaff030SJeremy L Thompson typedef struct SimpleBC_ *SimpleBC; 192ccaff030SJeremy L Thompson struct SimpleBC_ { 193ccaff030SJeremy L Thompson PetscInt nwall, nslip[3]; 1940c6c0b13SLeila Ghaffari PetscInt walls[10], slips[3][10]; 195ccaff030SJeremy L Thompson }; 196ccaff030SJeremy L Thompson 197ccaff030SJeremy L Thompson // Essential BC dofs are encoded in closure indices as -(i+1). 198ccaff030SJeremy L Thompson static PetscInt Involute(PetscInt i) { 199ccaff030SJeremy L Thompson return i >= 0 ? i : -(i+1); 200ccaff030SJeremy L Thompson } 201ccaff030SJeremy L Thompson 202ccaff030SJeremy L Thompson // Utility function to create local CEED restriction 203ccaff030SJeremy L Thompson static PetscErrorCode CreateRestrictionFromPlex(Ceed ceed, DM dm, CeedInt P, 2040c6c0b13SLeila Ghaffari CeedInt height, DMLabel domainLabel, CeedInt value, 205ccaff030SJeremy L Thompson CeedElemRestriction *Erestrict) { 206ccaff030SJeremy L Thompson 207ccaff030SJeremy L Thompson PetscSection section; 2080c6c0b13SLeila Ghaffari PetscInt p, Nelem, Ndof, *erestrict, eoffset, nfields, dim, 2090c6c0b13SLeila Ghaffari depth; 2100c6c0b13SLeila Ghaffari DMLabel depthLabel; 2110c6c0b13SLeila Ghaffari IS depthIS, iterIS; 2120c6c0b13SLeila Ghaffari const PetscInt *iterIndices; 213ccaff030SJeremy L Thompson PetscErrorCode ierr; 214ccaff030SJeremy L Thompson Vec Uloc; 215ccaff030SJeremy L Thompson 216ccaff030SJeremy L Thompson PetscFunctionBeginUser; 217ccaff030SJeremy L Thompson ierr = DMGetDimension(dm, &dim); CHKERRQ(ierr); 218*d1d4a8c6SJed Brown dim -= height; 219ccaff030SJeremy L Thompson ierr = DMGetLocalSection(dm,§ion); CHKERRQ(ierr); 220ccaff030SJeremy L Thompson ierr = PetscSectionGetNumFields(section, &nfields); CHKERRQ(ierr); 221ccaff030SJeremy L Thompson PetscInt ncomp[nfields], fieldoff[nfields+1]; 222ccaff030SJeremy L Thompson fieldoff[0] = 0; 223ccaff030SJeremy L Thompson for (PetscInt f=0; f<nfields; f++) { 224ccaff030SJeremy L Thompson ierr = PetscSectionGetFieldComponents(section, f, &ncomp[f]); CHKERRQ(ierr); 225ccaff030SJeremy L Thompson fieldoff[f+1] = fieldoff[f] + ncomp[f]; 226ccaff030SJeremy L Thompson } 227ccaff030SJeremy L Thompson 2280c6c0b13SLeila Ghaffari ierr = DMPlexGetDepth(dm, &depth); CHKERRQ(ierr); 2290c6c0b13SLeila Ghaffari ierr = DMPlexGetDepthLabel(dm, &depthLabel); CHKERRQ(ierr); 2300c6c0b13SLeila Ghaffari ierr = DMLabelGetStratumIS(depthLabel, depth - height, &depthIS); CHKERRQ(ierr); 2310c6c0b13SLeila Ghaffari if (domainLabel) { 2320c6c0b13SLeila Ghaffari IS domainIS; 2330c6c0b13SLeila Ghaffari ierr = DMLabelGetStratumIS(domainLabel, value, &domainIS); CHKERRQ(ierr); 2340c6c0b13SLeila Ghaffari ierr = ISIntersect(depthIS, domainIS, &iterIS); CHKERRQ(ierr); 2350c6c0b13SLeila Ghaffari ierr = ISDestroy(&domainIS); CHKERRQ(ierr); 2360c6c0b13SLeila Ghaffari ierr = ISDestroy(&depthIS); CHKERRQ(ierr); 2370c6c0b13SLeila Ghaffari } else { 2380c6c0b13SLeila Ghaffari iterIS = depthIS; 2390c6c0b13SLeila Ghaffari } 2400c6c0b13SLeila Ghaffari ierr = ISGetLocalSize(iterIS, &Nelem); CHKERRQ(ierr); 2410c6c0b13SLeila Ghaffari ierr = ISGetIndices(iterIS, &iterIndices); CHKERRQ(ierr); 242ccaff030SJeremy L Thompson ierr = PetscMalloc1(Nelem*PetscPowInt(P, dim), &erestrict); CHKERRQ(ierr); 2430c6c0b13SLeila Ghaffari for (p=0,eoffset=0; p<Nelem; p++) { 2440c6c0b13SLeila Ghaffari PetscInt c = iterIndices[p]; 245ccaff030SJeremy L Thompson PetscInt numindices, *indices, nnodes; 2460c6c0b13SLeila Ghaffari ierr = DMPlexGetClosureIndices(dm, section, section, c, &numindices, 2470c6c0b13SLeila Ghaffari &indices, NULL); CHKERRQ(ierr); 2480c6c0b13SLeila Ghaffari if (numindices % fieldoff[nfields]) 2490c6c0b13SLeila Ghaffari SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, 2500c6c0b13SLeila Ghaffari "Number of closure indices not compatible with Cell %D", c); 251ccaff030SJeremy L Thompson nnodes = numindices / fieldoff[nfields]; 252ccaff030SJeremy L Thompson for (PetscInt i=0; i<nnodes; i++) { 253ccaff030SJeremy L Thompson // Check that indices are blocked by node and thus can be coalesced as a single field with 254ccaff030SJeremy L Thompson // fieldoff[nfields] = sum(ncomp) components. 255ccaff030SJeremy L Thompson for (PetscInt f=0; f<nfields; f++) { 256ccaff030SJeremy L Thompson for (PetscInt j=0; j<ncomp[f]; j++) { 257ccaff030SJeremy L Thompson if (Involute(indices[fieldoff[f]*nnodes + i*ncomp[f] + j]) 258ccaff030SJeremy L Thompson != Involute(indices[i*ncomp[0]]) + fieldoff[f] + j) 259ccaff030SJeremy L Thompson SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP, 260ccaff030SJeremy L Thompson "Cell %D closure indices not interlaced for node %D field %D component %D", 261ccaff030SJeremy L Thompson c, i, f, j); 262ccaff030SJeremy L Thompson } 263ccaff030SJeremy L Thompson } 264ccaff030SJeremy L Thompson // Essential boundary conditions are encoded as -(loc+1), but we don't care so we decode. 265ccaff030SJeremy L Thompson PetscInt loc = Involute(indices[i*ncomp[0]]); 2666f55dfd5Svaleriabarra erestrict[eoffset++] = loc; 267ccaff030SJeremy L Thompson } 2680c6c0b13SLeila Ghaffari ierr = DMPlexRestoreClosureIndices(dm, section, section, c, &numindices, 2690c6c0b13SLeila Ghaffari &indices, NULL); CHKERRQ(ierr); 270ccaff030SJeremy L Thompson } 2710c6c0b13SLeila Ghaffari if (eoffset != Nelem*PetscPowInt(P, dim)) 2720c6c0b13SLeila Ghaffari SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_LIB, 2730c6c0b13SLeila Ghaffari "ElemRestriction of size (%D,%D) initialized %D nodes", Nelem, 274ccaff030SJeremy L Thompson PetscPowInt(P, dim),eoffset); 2750c6c0b13SLeila Ghaffari ierr = ISRestoreIndices(iterIS, &iterIndices); CHKERRQ(ierr); 2760c6c0b13SLeila Ghaffari ierr = ISDestroy(&iterIS); CHKERRQ(ierr); 2770c6c0b13SLeila Ghaffari 278ccaff030SJeremy L Thompson ierr = DMGetLocalVector(dm, &Uloc); CHKERRQ(ierr); 279ccaff030SJeremy L Thompson ierr = VecGetLocalSize(Uloc, &Ndof); CHKERRQ(ierr); 280ccaff030SJeremy L Thompson ierr = DMRestoreLocalVector(dm, &Uloc); CHKERRQ(ierr); 2816f55dfd5Svaleriabarra CeedElemRestrictionCreate(ceed, Nelem, PetscPowInt(P, dim), fieldoff[nfields], 2826f55dfd5Svaleriabarra 1, Ndof, CEED_MEM_HOST, CEED_COPY_VALUES, erestrict, 2836f55dfd5Svaleriabarra Erestrict); 284ccaff030SJeremy L Thompson ierr = PetscFree(erestrict); CHKERRQ(ierr); 285ccaff030SJeremy L Thompson PetscFunctionReturn(0); 286ccaff030SJeremy L Thompson } 287ccaff030SJeremy L Thompson 288c96c872fSLeila Ghaffari // Utility function to get Ceed Restriction for each domain 289bd910870SLeila Ghaffari static PetscErrorCode GetRestrictionForDomain(Ceed ceed, DM dm, CeedInt ncompx, CeedInt dim, 290c96c872fSLeila Ghaffari CeedInt height, DMLabel domainLabel, CeedInt value, CeedInt P, CeedInt Q, 291c96c872fSLeila Ghaffari CeedInt qdatasize, CeedElemRestriction *restrictq, 292c96c872fSLeila Ghaffari CeedElemRestriction *restrictx, CeedElemRestriction *restrictqdi) { 293c96c872fSLeila Ghaffari 294c96c872fSLeila Ghaffari DM dmcoord; 295c96c872fSLeila Ghaffari CeedInt localNelem; 296c96c872fSLeila Ghaffari CeedInt Qdim = CeedIntPow(Q, dim); 297c96c872fSLeila Ghaffari PetscErrorCode ierr; 298c96c872fSLeila Ghaffari 299c96c872fSLeila Ghaffari PetscFunctionBeginUser; 300c96c872fSLeila Ghaffari ierr = DMGetCoordinateDM(dm, &dmcoord); CHKERRQ(ierr); 301c96c872fSLeila Ghaffari ierr = DMPlexSetClosurePermutationTensor(dmcoord, PETSC_DETERMINE, NULL); 302c96c872fSLeila Ghaffari CHKERRQ(ierr); 303c96c872fSLeila Ghaffari ierr = CreateRestrictionFromPlex(ceed, dm, P, height, domainLabel, value, restrictq); 304c96c872fSLeila Ghaffari CHKERRQ(ierr); 305c96c872fSLeila Ghaffari ierr = CreateRestrictionFromPlex(ceed, dmcoord, 2, height, domainLabel, value, restrictx); 306c96c872fSLeila Ghaffari CHKERRQ(ierr); 307c96c872fSLeila Ghaffari CeedElemRestrictionGetNumElements(*restrictq, &localNelem); 308c96c872fSLeila Ghaffari CeedElemRestrictionCreateStrided(ceed, localNelem, Qdim, 309c96c872fSLeila Ghaffari qdatasize, qdatasize*localNelem*Qdim, 310c96c872fSLeila Ghaffari CEED_STRIDES_BACKEND, restrictqdi); 311c96c872fSLeila Ghaffari PetscFunctionReturn(0); 312c96c872fSLeila Ghaffari } 313c96c872fSLeila Ghaffari 314ccaff030SJeremy L Thompson static int CreateVectorFromPetscVec(Ceed ceed, Vec p, CeedVector *v) { 315ccaff030SJeremy L Thompson PetscErrorCode ierr; 316ccaff030SJeremy L Thompson PetscInt m; 317ccaff030SJeremy L Thompson 318ccaff030SJeremy L Thompson PetscFunctionBeginUser; 319ccaff030SJeremy L Thompson ierr = VecGetLocalSize(p, &m); CHKERRQ(ierr); 320ccaff030SJeremy L Thompson ierr = CeedVectorCreate(ceed, m, v); CHKERRQ(ierr); 321ccaff030SJeremy L Thompson PetscFunctionReturn(0); 322ccaff030SJeremy L Thompson } 323ccaff030SJeremy L Thompson 324ccaff030SJeremy L Thompson static int VectorPlacePetscVec(CeedVector c, Vec p) { 325ccaff030SJeremy L Thompson PetscErrorCode ierr; 326ccaff030SJeremy L Thompson PetscInt mceed,mpetsc; 327ccaff030SJeremy L Thompson PetscScalar *a; 328ccaff030SJeremy L Thompson 329ccaff030SJeremy L Thompson PetscFunctionBeginUser; 330ccaff030SJeremy L Thompson ierr = CeedVectorGetLength(c, &mceed); CHKERRQ(ierr); 331ccaff030SJeremy L Thompson ierr = VecGetLocalSize(p, &mpetsc); CHKERRQ(ierr); 332ccaff030SJeremy L Thompson if (mceed != mpetsc) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP, 3330c6c0b13SLeila Ghaffari "Cannot place PETSc Vec of length %D in CeedVector of length %D",mpetsc,mceed); 334ccaff030SJeremy L Thompson ierr = VecGetArray(p, &a); CHKERRQ(ierr); 335ccaff030SJeremy L Thompson CeedVectorSetArray(c, CEED_MEM_HOST, CEED_USE_POINTER, a); 336ccaff030SJeremy L Thompson PetscFunctionReturn(0); 337ccaff030SJeremy L Thompson } 338ccaff030SJeremy L Thompson 339ccaff030SJeremy L Thompson static PetscErrorCode DMPlexInsertBoundaryValues_NS(DM dm, 340ccaff030SJeremy L Thompson PetscBool insertEssential, Vec Qloc, PetscReal time, Vec faceGeomFVM, 341ccaff030SJeremy L Thompson Vec cellGeomFVM, Vec gradFVM) { 342ccaff030SJeremy L Thompson PetscErrorCode ierr; 343ccaff030SJeremy L Thompson Vec Qbc; 344ccaff030SJeremy L Thompson 345ccaff030SJeremy L Thompson PetscFunctionBegin; 346ccaff030SJeremy L Thompson ierr = DMGetNamedLocalVector(dm, "Qbc", &Qbc); CHKERRQ(ierr); 347ccaff030SJeremy L Thompson ierr = VecAXPY(Qloc, 1., Qbc); CHKERRQ(ierr); 348ccaff030SJeremy L Thompson ierr = DMRestoreNamedLocalVector(dm, "Qbc", &Qbc); CHKERRQ(ierr); 349ccaff030SJeremy L Thompson PetscFunctionReturn(0); 350ccaff030SJeremy L Thompson } 351ccaff030SJeremy L Thompson 352ccaff030SJeremy L Thompson // This is the RHS of the ODE, given as u_t = G(t,u) 353ccaff030SJeremy L Thompson // This function takes in a state vector Q and writes into G 354ccaff030SJeremy L Thompson static PetscErrorCode RHS_NS(TS ts, PetscReal t, Vec Q, Vec G, void *userData) { 355ccaff030SJeremy L Thompson PetscErrorCode ierr; 356ccaff030SJeremy L Thompson User user = *(User *)userData; 357ccaff030SJeremy L Thompson PetscScalar *q, *g; 358ccaff030SJeremy L Thompson Vec Qloc, Gloc; 359ccaff030SJeremy L Thompson 360ccaff030SJeremy L Thompson // Global-to-local 361ccaff030SJeremy L Thompson PetscFunctionBeginUser; 362ccaff030SJeremy L Thompson ierr = DMGetLocalVector(user->dm, &Qloc); CHKERRQ(ierr); 363ccaff030SJeremy L Thompson ierr = DMGetLocalVector(user->dm, &Gloc); CHKERRQ(ierr); 364ccaff030SJeremy L Thompson ierr = VecZeroEntries(Qloc); CHKERRQ(ierr); 365ccaff030SJeremy L Thompson ierr = DMGlobalToLocal(user->dm, Q, INSERT_VALUES, Qloc); CHKERRQ(ierr); 366ccaff030SJeremy L Thompson ierr = DMPlexInsertBoundaryValues(user->dm, PETSC_TRUE, Qloc, 0.0, 367ccaff030SJeremy L Thompson NULL, NULL, NULL); CHKERRQ(ierr); 368ccaff030SJeremy L Thompson ierr = VecZeroEntries(Gloc); CHKERRQ(ierr); 369ccaff030SJeremy L Thompson 370ccaff030SJeremy L Thompson // Ceed Vectors 371ccaff030SJeremy L Thompson ierr = VecGetArrayRead(Qloc, (const PetscScalar **)&q); CHKERRQ(ierr); 372ccaff030SJeremy L Thompson ierr = VecGetArray(Gloc, &g); CHKERRQ(ierr); 373ccaff030SJeremy L Thompson CeedVectorSetArray(user->qceed, CEED_MEM_HOST, CEED_USE_POINTER, q); 374ccaff030SJeremy L Thompson CeedVectorSetArray(user->gceed, CEED_MEM_HOST, CEED_USE_POINTER, g); 375ccaff030SJeremy L Thompson 376ccaff030SJeremy L Thompson // Apply CEED operator 377ccaff030SJeremy L Thompson CeedOperatorApply(user->op_rhs, user->qceed, user->gceed, 378ccaff030SJeremy L Thompson CEED_REQUEST_IMMEDIATE); 379ccaff030SJeremy L Thompson 380ccaff030SJeremy L Thompson // Restore vectors 381ccaff030SJeremy L Thompson ierr = VecRestoreArrayRead(Qloc, (const PetscScalar **)&q); CHKERRQ(ierr); 382ccaff030SJeremy L Thompson ierr = VecRestoreArray(Gloc, &g); CHKERRQ(ierr); 383ccaff030SJeremy L Thompson 384ccaff030SJeremy L Thompson ierr = VecZeroEntries(G); CHKERRQ(ierr); 385ccaff030SJeremy L Thompson ierr = DMLocalToGlobal(user->dm, Gloc, ADD_VALUES, G); CHKERRQ(ierr); 386ccaff030SJeremy L Thompson 387ccaff030SJeremy L Thompson // Inverse of the lumped mass matrix 388ccaff030SJeremy L Thompson ierr = VecPointwiseMult(G, G, user->M); // M is Minv 389ccaff030SJeremy L Thompson CHKERRQ(ierr); 390ccaff030SJeremy L Thompson 391ccaff030SJeremy L Thompson ierr = DMRestoreLocalVector(user->dm, &Qloc); CHKERRQ(ierr); 392ccaff030SJeremy L Thompson ierr = DMRestoreLocalVector(user->dm, &Gloc); CHKERRQ(ierr); 393ccaff030SJeremy L Thompson PetscFunctionReturn(0); 394ccaff030SJeremy L Thompson } 395ccaff030SJeremy L Thompson 396ccaff030SJeremy L Thompson static PetscErrorCode IFunction_NS(TS ts, PetscReal t, Vec Q, Vec Qdot, Vec G, 397ccaff030SJeremy L Thompson void *userData) { 398ccaff030SJeremy L Thompson PetscErrorCode ierr; 399ccaff030SJeremy L Thompson User user = *(User *)userData; 400ccaff030SJeremy L Thompson const PetscScalar *q, *qdot; 401ccaff030SJeremy L Thompson PetscScalar *g; 402ccaff030SJeremy L Thompson Vec Qloc, Qdotloc, Gloc; 403ccaff030SJeremy L Thompson 404ccaff030SJeremy L Thompson // Global-to-local 405ccaff030SJeremy L Thompson PetscFunctionBeginUser; 406ccaff030SJeremy L Thompson ierr = DMGetLocalVector(user->dm, &Qloc); CHKERRQ(ierr); 407ccaff030SJeremy L Thompson ierr = DMGetLocalVector(user->dm, &Qdotloc); CHKERRQ(ierr); 408ccaff030SJeremy L Thompson ierr = DMGetLocalVector(user->dm, &Gloc); CHKERRQ(ierr); 409ccaff030SJeremy L Thompson ierr = VecZeroEntries(Qloc); CHKERRQ(ierr); 410ccaff030SJeremy L Thompson ierr = DMGlobalToLocal(user->dm, Q, INSERT_VALUES, Qloc); CHKERRQ(ierr); 411ccaff030SJeremy L Thompson ierr = DMPlexInsertBoundaryValues(user->dm, PETSC_TRUE, Qloc, 0.0, 412ccaff030SJeremy L Thompson NULL, NULL, NULL); CHKERRQ(ierr); 413ccaff030SJeremy L Thompson ierr = VecZeroEntries(Qdotloc); CHKERRQ(ierr); 414ccaff030SJeremy L Thompson ierr = DMGlobalToLocal(user->dm, Qdot, INSERT_VALUES, Qdotloc); CHKERRQ(ierr); 415ccaff030SJeremy L Thompson ierr = VecZeroEntries(Gloc); CHKERRQ(ierr); 416ccaff030SJeremy L Thompson 417ccaff030SJeremy L Thompson // Ceed Vectors 418ccaff030SJeremy L Thompson ierr = VecGetArrayRead(Qloc, &q); CHKERRQ(ierr); 419ccaff030SJeremy L Thompson ierr = VecGetArrayRead(Qdotloc, &qdot); CHKERRQ(ierr); 420ccaff030SJeremy L Thompson ierr = VecGetArray(Gloc, &g); CHKERRQ(ierr); 421ccaff030SJeremy L Thompson CeedVectorSetArray(user->qceed, CEED_MEM_HOST, CEED_USE_POINTER, 422ccaff030SJeremy L Thompson (PetscScalar *)q); 423ccaff030SJeremy L Thompson CeedVectorSetArray(user->qdotceed, CEED_MEM_HOST, CEED_USE_POINTER, 424ccaff030SJeremy L Thompson (PetscScalar *)qdot); 425ccaff030SJeremy L Thompson CeedVectorSetArray(user->gceed, CEED_MEM_HOST, CEED_USE_POINTER, g); 426ccaff030SJeremy L Thompson 427ccaff030SJeremy L Thompson // Apply CEED operator 428ccaff030SJeremy L Thompson CeedOperatorApply(user->op_ifunction, user->qceed, user->gceed, 429ccaff030SJeremy L Thompson CEED_REQUEST_IMMEDIATE); 430ccaff030SJeremy L Thompson 431ccaff030SJeremy L Thompson // Restore vectors 432ccaff030SJeremy L Thompson ierr = VecRestoreArrayRead(Qloc, &q); CHKERRQ(ierr); 433ccaff030SJeremy L Thompson ierr = VecRestoreArrayRead(Qdotloc, &qdot); CHKERRQ(ierr); 434ccaff030SJeremy L Thompson ierr = VecRestoreArray(Gloc, &g); CHKERRQ(ierr); 435ccaff030SJeremy L Thompson 436ccaff030SJeremy L Thompson ierr = VecZeroEntries(G); CHKERRQ(ierr); 437ccaff030SJeremy L Thompson ierr = DMLocalToGlobal(user->dm, Gloc, ADD_VALUES, G); CHKERRQ(ierr); 438ccaff030SJeremy L Thompson 439ccaff030SJeremy L Thompson ierr = DMRestoreLocalVector(user->dm, &Qloc); CHKERRQ(ierr); 440ccaff030SJeremy L Thompson ierr = DMRestoreLocalVector(user->dm, &Qdotloc); CHKERRQ(ierr); 441ccaff030SJeremy L Thompson ierr = DMRestoreLocalVector(user->dm, &Gloc); CHKERRQ(ierr); 442ccaff030SJeremy L Thompson PetscFunctionReturn(0); 443ccaff030SJeremy L Thompson } 444ccaff030SJeremy L Thompson 445ccaff030SJeremy L Thompson // User provided TS Monitor 446ccaff030SJeremy L Thompson static PetscErrorCode TSMonitor_NS(TS ts, PetscInt stepno, PetscReal time, 447ccaff030SJeremy L Thompson Vec Q, void *ctx) { 448ccaff030SJeremy L Thompson User user = ctx; 449ccaff030SJeremy L Thompson Vec Qloc; 450ccaff030SJeremy L Thompson char filepath[PETSC_MAX_PATH_LEN]; 451ccaff030SJeremy L Thompson PetscViewer viewer; 452ccaff030SJeremy L Thompson PetscErrorCode ierr; 453ccaff030SJeremy L Thompson 454ccaff030SJeremy L Thompson // Set up output 455ccaff030SJeremy L Thompson PetscFunctionBeginUser; 456ccaff030SJeremy L Thompson // Print every 'outputfreq' steps 457ccaff030SJeremy L Thompson if (stepno % user->outputfreq != 0) 458ccaff030SJeremy L Thompson PetscFunctionReturn(0); 459ccaff030SJeremy L Thompson ierr = DMGetLocalVector(user->dm, &Qloc); CHKERRQ(ierr); 460ccaff030SJeremy L Thompson ierr = PetscObjectSetName((PetscObject)Qloc, "StateVec"); CHKERRQ(ierr); 461ccaff030SJeremy L Thompson ierr = VecZeroEntries(Qloc); CHKERRQ(ierr); 462ccaff030SJeremy L Thompson ierr = DMGlobalToLocal(user->dm, Q, INSERT_VALUES, Qloc); CHKERRQ(ierr); 463ccaff030SJeremy L Thompson 464ccaff030SJeremy L Thompson // Output 465ccaff030SJeremy L Thompson ierr = PetscSNPrintf(filepath, sizeof filepath, "%s/ns-%03D.vtu", 466ccaff030SJeremy L Thompson user->outputfolder, stepno + user->contsteps); 467ccaff030SJeremy L Thompson CHKERRQ(ierr); 468ccaff030SJeremy L Thompson ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)Q), filepath, 469ccaff030SJeremy L Thompson FILE_MODE_WRITE, &viewer); CHKERRQ(ierr); 470ccaff030SJeremy L Thompson ierr = VecView(Qloc, viewer); CHKERRQ(ierr); 471ccaff030SJeremy L Thompson if (user->dmviz) { 472ccaff030SJeremy L Thompson Vec Qrefined, Qrefined_loc; 473ccaff030SJeremy L Thompson char filepath_refined[PETSC_MAX_PATH_LEN]; 474ccaff030SJeremy L Thompson PetscViewer viewer_refined; 475ccaff030SJeremy L Thompson 476ccaff030SJeremy L Thompson ierr = DMGetGlobalVector(user->dmviz, &Qrefined); CHKERRQ(ierr); 477ccaff030SJeremy L Thompson ierr = DMGetLocalVector(user->dmviz, &Qrefined_loc); CHKERRQ(ierr); 478ccaff030SJeremy L Thompson ierr = PetscObjectSetName((PetscObject)Qrefined_loc, "Refined"); 479ccaff030SJeremy L Thompson CHKERRQ(ierr); 480ccaff030SJeremy L Thompson ierr = MatInterpolate(user->interpviz, Q, Qrefined); CHKERRQ(ierr); 481ccaff030SJeremy L Thompson ierr = VecZeroEntries(Qrefined_loc); CHKERRQ(ierr); 482ccaff030SJeremy L Thompson ierr = DMGlobalToLocal(user->dmviz, Qrefined, INSERT_VALUES, Qrefined_loc); 483ccaff030SJeremy L Thompson CHKERRQ(ierr); 484ccaff030SJeremy L Thompson ierr = PetscSNPrintf(filepath_refined, sizeof filepath_refined, 485ccaff030SJeremy L Thompson "%s/nsrefined-%03D.vtu", 486ccaff030SJeremy L Thompson user->outputfolder, stepno + user->contsteps); 487ccaff030SJeremy L Thompson CHKERRQ(ierr); 488ccaff030SJeremy L Thompson ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)Qrefined), 489ccaff030SJeremy L Thompson filepath_refined, 490ccaff030SJeremy L Thompson FILE_MODE_WRITE, &viewer_refined); CHKERRQ(ierr); 491ccaff030SJeremy L Thompson ierr = VecView(Qrefined_loc, viewer_refined); CHKERRQ(ierr); 492ccaff030SJeremy L Thompson ierr = DMRestoreLocalVector(user->dmviz, &Qrefined_loc); CHKERRQ(ierr); 493ccaff030SJeremy L Thompson ierr = DMRestoreGlobalVector(user->dmviz, &Qrefined); CHKERRQ(ierr); 494ccaff030SJeremy L Thompson ierr = PetscViewerDestroy(&viewer_refined); CHKERRQ(ierr); 495ccaff030SJeremy L Thompson } 4960c6c0b13SLeila Ghaffari ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr); 497ccaff030SJeremy L Thompson ierr = DMRestoreLocalVector(user->dm, &Qloc); CHKERRQ(ierr); 498ccaff030SJeremy L Thompson 499ccaff030SJeremy L Thompson // Save data in a binary file for continuation of simulations 500ccaff030SJeremy L Thompson ierr = PetscSNPrintf(filepath, sizeof filepath, "%s/ns-solution.bin", 501ccaff030SJeremy L Thompson user->outputfolder); CHKERRQ(ierr); 502ccaff030SJeremy L Thompson ierr = PetscViewerBinaryOpen(user->comm, filepath, FILE_MODE_WRITE, &viewer); 503ccaff030SJeremy L Thompson CHKERRQ(ierr); 504ccaff030SJeremy L Thompson ierr = VecView(Q, viewer); CHKERRQ(ierr); 505ccaff030SJeremy L Thompson ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr); 506ccaff030SJeremy L Thompson 507ccaff030SJeremy L Thompson // Save time stamp 508ccaff030SJeremy L Thompson // Dimensionalize time back 509ccaff030SJeremy L Thompson time /= user->units->second; 510ccaff030SJeremy L Thompson ierr = PetscSNPrintf(filepath, sizeof filepath, "%s/ns-time.bin", 511ccaff030SJeremy L Thompson user->outputfolder); CHKERRQ(ierr); 512ccaff030SJeremy L Thompson ierr = PetscViewerBinaryOpen(user->comm, filepath, FILE_MODE_WRITE, &viewer); 513ccaff030SJeremy L Thompson CHKERRQ(ierr); 514ccaff030SJeremy L Thompson #if PETSC_VERSION_GE(3,13,0) 515ccaff030SJeremy L Thompson ierr = PetscViewerBinaryWrite(viewer, &time, 1, PETSC_REAL); 516ccaff030SJeremy L Thompson #else 517ccaff030SJeremy L Thompson ierr = PetscViewerBinaryWrite(viewer, &time, 1, PETSC_REAL, true); 518ccaff030SJeremy L Thompson #endif 519ccaff030SJeremy L Thompson CHKERRQ(ierr); 520ccaff030SJeremy L Thompson ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr); 521ccaff030SJeremy L Thompson 522ccaff030SJeremy L Thompson PetscFunctionReturn(0); 523ccaff030SJeremy L Thompson } 524ccaff030SJeremy L Thompson 5250c6c0b13SLeila Ghaffari static PetscErrorCode ICs_PetscMultiplicity(CeedOperator op_ics, 526ccaff030SJeremy L Thompson CeedVector xcorners, CeedVector q0ceed, DM dm, Vec Qloc, Vec Q, 527ccaff030SJeremy L Thompson CeedElemRestriction restrictq, SetupContext ctxSetup, CeedScalar time) { 528ccaff030SJeremy L Thompson PetscErrorCode ierr; 529ccaff030SJeremy L Thompson CeedVector multlvec; 530ccaff030SJeremy L Thompson Vec Multiplicity, MultiplicityLoc; 531ccaff030SJeremy L Thompson 532ccaff030SJeremy L Thompson ctxSetup->time = time; 533ccaff030SJeremy L Thompson ierr = VecZeroEntries(Qloc); CHKERRQ(ierr); 534ccaff030SJeremy L Thompson ierr = VectorPlacePetscVec(q0ceed, Qloc); CHKERRQ(ierr); 535ccaff030SJeremy L Thompson CeedOperatorApply(op_ics, xcorners, q0ceed, CEED_REQUEST_IMMEDIATE); 536ccaff030SJeremy L Thompson ierr = VecZeroEntries(Q); CHKERRQ(ierr); 537ccaff030SJeremy L Thompson ierr = DMLocalToGlobal(dm, Qloc, ADD_VALUES, Q); CHKERRQ(ierr); 538ccaff030SJeremy L Thompson 539ccaff030SJeremy L Thompson // Fix multiplicity for output of ICs 540ccaff030SJeremy L Thompson ierr = DMGetLocalVector(dm, &MultiplicityLoc); CHKERRQ(ierr); 541ccaff030SJeremy L Thompson CeedElemRestrictionCreateVector(restrictq, &multlvec, NULL); 542ccaff030SJeremy L Thompson ierr = VectorPlacePetscVec(multlvec, MultiplicityLoc); CHKERRQ(ierr); 543ccaff030SJeremy L Thompson CeedElemRestrictionGetMultiplicity(restrictq, multlvec); 544ccaff030SJeremy L Thompson CeedVectorDestroy(&multlvec); 545ccaff030SJeremy L Thompson ierr = DMGetGlobalVector(dm, &Multiplicity); CHKERRQ(ierr); 546ccaff030SJeremy L Thompson ierr = VecZeroEntries(Multiplicity); CHKERRQ(ierr); 547ccaff030SJeremy L Thompson ierr = DMLocalToGlobal(dm, MultiplicityLoc, ADD_VALUES, Multiplicity); 548ccaff030SJeremy L Thompson CHKERRQ(ierr); 549ccaff030SJeremy L Thompson ierr = VecPointwiseDivide(Q, Q, Multiplicity); CHKERRQ(ierr); 550ccaff030SJeremy L Thompson ierr = VecPointwiseDivide(Qloc, Qloc, MultiplicityLoc); CHKERRQ(ierr); 551ccaff030SJeremy L Thompson ierr = DMRestoreLocalVector(dm, &MultiplicityLoc); CHKERRQ(ierr); 552ccaff030SJeremy L Thompson ierr = DMRestoreGlobalVector(dm, &Multiplicity); CHKERRQ(ierr); 553ccaff030SJeremy L Thompson 554ccaff030SJeremy L Thompson PetscFunctionReturn(0); 555ccaff030SJeremy L Thompson } 556ccaff030SJeremy L Thompson 557ccaff030SJeremy L Thompson static PetscErrorCode ComputeLumpedMassMatrix(Ceed ceed, DM dm, 558ccaff030SJeremy L Thompson CeedElemRestriction restrictq, CeedBasis basisq, 559ccaff030SJeremy L Thompson CeedElemRestriction restrictqdi, CeedVector qdata, Vec M) { 560ccaff030SJeremy L Thompson PetscErrorCode ierr; 561ccaff030SJeremy L Thompson CeedQFunction qf_mass; 562ccaff030SJeremy L Thompson CeedOperator op_mass; 563ccaff030SJeremy L Thompson CeedVector mceed; 564ccaff030SJeremy L Thompson Vec Mloc; 565ccaff030SJeremy L Thompson CeedInt ncompq, qdatasize; 566ccaff030SJeremy L Thompson 567ccaff030SJeremy L Thompson PetscFunctionBeginUser; 568ccaff030SJeremy L Thompson CeedElemRestrictionGetNumComponents(restrictq, &ncompq); 569ccaff030SJeremy L Thompson CeedElemRestrictionGetNumComponents(restrictqdi, &qdatasize); 570ccaff030SJeremy L Thompson // Create the Q-function that defines the action of the mass operator 571ccaff030SJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, Mass, Mass_loc, &qf_mass); 572ccaff030SJeremy L Thompson CeedQFunctionAddInput(qf_mass, "q", ncompq, CEED_EVAL_INTERP); 573ccaff030SJeremy L Thompson CeedQFunctionAddInput(qf_mass, "qdata", qdatasize, CEED_EVAL_NONE); 574ccaff030SJeremy L Thompson CeedQFunctionAddOutput(qf_mass, "v", ncompq, CEED_EVAL_INTERP); 575ccaff030SJeremy L Thompson 576ccaff030SJeremy L Thompson // Create the mass operator 577ccaff030SJeremy L Thompson CeedOperatorCreate(ceed, qf_mass, NULL, NULL, &op_mass); 578ccaff030SJeremy L Thompson CeedOperatorSetField(op_mass, "q", restrictq, basisq, CEED_VECTOR_ACTIVE); 579ccaff030SJeremy L Thompson CeedOperatorSetField(op_mass, "qdata", restrictqdi, 580ccaff030SJeremy L Thompson CEED_BASIS_COLLOCATED, qdata); 581ccaff030SJeremy L Thompson CeedOperatorSetField(op_mass, "v", restrictq, basisq, CEED_VECTOR_ACTIVE); 582ccaff030SJeremy L Thompson 583ccaff030SJeremy L Thompson ierr = DMGetLocalVector(dm, &Mloc); CHKERRQ(ierr); 584ccaff030SJeremy L Thompson ierr = VecZeroEntries(Mloc); CHKERRQ(ierr); 585ccaff030SJeremy L Thompson CeedElemRestrictionCreateVector(restrictq, &mceed, NULL); 586ccaff030SJeremy L Thompson ierr = VectorPlacePetscVec(mceed, Mloc); CHKERRQ(ierr); 587ccaff030SJeremy L Thompson 588ccaff030SJeremy L Thompson { 589ccaff030SJeremy L Thompson // Compute a lumped mass matrix 590ccaff030SJeremy L Thompson CeedVector onesvec; 591ccaff030SJeremy L Thompson CeedElemRestrictionCreateVector(restrictq, &onesvec, NULL); 592ccaff030SJeremy L Thompson CeedVectorSetValue(onesvec, 1.0); 593ccaff030SJeremy L Thompson CeedOperatorApply(op_mass, onesvec, mceed, CEED_REQUEST_IMMEDIATE); 594ccaff030SJeremy L Thompson CeedVectorDestroy(&onesvec); 595ccaff030SJeremy L Thompson CeedOperatorDestroy(&op_mass); 596ccaff030SJeremy L Thompson CeedVectorDestroy(&mceed); 597ccaff030SJeremy L Thompson } 598ccaff030SJeremy L Thompson CeedQFunctionDestroy(&qf_mass); 599ccaff030SJeremy L Thompson 600ccaff030SJeremy L Thompson ierr = VecZeroEntries(M); CHKERRQ(ierr); 601ccaff030SJeremy L Thompson ierr = DMLocalToGlobal(dm, Mloc, ADD_VALUES, M); CHKERRQ(ierr); 602ccaff030SJeremy L Thompson ierr = DMRestoreLocalVector(dm, &Mloc); CHKERRQ(ierr); 603ccaff030SJeremy L Thompson 604ccaff030SJeremy L Thompson // Invert diagonally lumped mass vector for RHS function 605ccaff030SJeremy L Thompson ierr = VecReciprocal(M); CHKERRQ(ierr); 606ccaff030SJeremy L Thompson PetscFunctionReturn(0); 607ccaff030SJeremy L Thompson } 608ccaff030SJeremy L Thompson 6090c6c0b13SLeila Ghaffari PetscErrorCode SetUpDM(DM dm, problemData *problem, PetscInt degree, 610ff6701fcSJed Brown SimpleBC bc, void *ctxSetup) { 611ccaff030SJeremy L Thompson PetscErrorCode ierr; 612ccaff030SJeremy L Thompson 613ccaff030SJeremy L Thompson PetscFunctionBeginUser; 614ccaff030SJeremy L Thompson { 615ccaff030SJeremy L Thompson // Configure the finite element space and boundary conditions 616ccaff030SJeremy L Thompson PetscFE fe; 6170c6c0b13SLeila Ghaffari PetscSpace fespace; 618ccaff030SJeremy L Thompson PetscInt ncompq = 5; 619ff6701fcSJed Brown ierr = PetscFECreateLagrange(PETSC_COMM_SELF, problem->dim, ncompq, 620ff6701fcSJed Brown PETSC_FALSE, degree, PETSC_DECIDE, 62132ed2d11SJed Brown &fe); CHKERRQ(ierr); 622ccaff030SJeremy L Thompson ierr = PetscObjectSetName((PetscObject)fe, "Q"); CHKERRQ(ierr); 623ccaff030SJeremy L Thompson ierr = DMAddField(dm,NULL,(PetscObject)fe); CHKERRQ(ierr); 624ccaff030SJeremy L Thompson ierr = DMCreateDS(dm); CHKERRQ(ierr); 6250c6c0b13SLeila Ghaffari /* Wall boundary conditions are zero velocity and zero flux for density and energy */ 6260c6c0b13SLeila Ghaffari { 6270c6c0b13SLeila Ghaffari PetscInt comps[3] = {1, 2, 3}; 6280c6c0b13SLeila Ghaffari ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall", "Face Sets", 0, 6290c6c0b13SLeila Ghaffari 3, comps, (void(*)(void))problem->bc, 6300c6c0b13SLeila Ghaffari bc->nwall, bc->walls, ctxSetup); CHKERRQ(ierr); 6310c6c0b13SLeila Ghaffari } 63207af6069Svaleriabarra { 63307af6069Svaleriabarra PetscInt comps[1] = {1}; 63407af6069Svaleriabarra ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "slipx", "Face Sets", 0, 63507af6069Svaleriabarra 1, comps, (void(*)(void))NULL, bc->nslip[0], 63607af6069Svaleriabarra bc->slips[0], ctxSetup); CHKERRQ(ierr); 63707af6069Svaleriabarra comps[0] = 2; 63807af6069Svaleriabarra ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "slipy", "Face Sets", 0, 63907af6069Svaleriabarra 1, comps, (void(*)(void))NULL, bc->nslip[1], 64007af6069Svaleriabarra bc->slips[1], ctxSetup); CHKERRQ(ierr); 64107af6069Svaleriabarra comps[0] = 3; 64207af6069Svaleriabarra ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "slipz", "Face Sets", 0, 64307af6069Svaleriabarra 1, comps, (void(*)(void))NULL, bc->nslip[2], 64407af6069Svaleriabarra bc->slips[2], ctxSetup); CHKERRQ(ierr); 64507af6069Svaleriabarra } 646ccaff030SJeremy L Thompson ierr = DMPlexSetClosurePermutationTensor(dm, PETSC_DETERMINE,NULL); 647ccaff030SJeremy L Thompson CHKERRQ(ierr); 6480c6c0b13SLeila Ghaffari ierr = PetscFEGetBasisSpace(fe, &fespace); CHKERRQ(ierr); 649ccaff030SJeremy L Thompson ierr = PetscFEDestroy(&fe); CHKERRQ(ierr); 650ccaff030SJeremy L Thompson } 651ccaff030SJeremy L Thompson { 652ccaff030SJeremy L Thompson // Empty name for conserved field (because there is only one field) 653ccaff030SJeremy L Thompson PetscSection section; 654ccaff030SJeremy L Thompson ierr = DMGetLocalSection(dm, §ion); CHKERRQ(ierr); 655ccaff030SJeremy L Thompson ierr = PetscSectionSetFieldName(section, 0, ""); CHKERRQ(ierr); 656ccaff030SJeremy L Thompson ierr = PetscSectionSetComponentName(section, 0, 0, "Density"); 657ccaff030SJeremy L Thompson CHKERRQ(ierr); 658ccaff030SJeremy L Thompson ierr = PetscSectionSetComponentName(section, 0, 1, "MomentumX"); 659ccaff030SJeremy L Thompson CHKERRQ(ierr); 660ccaff030SJeremy L Thompson ierr = PetscSectionSetComponentName(section, 0, 2, "MomentumY"); 661ccaff030SJeremy L Thompson CHKERRQ(ierr); 662ccaff030SJeremy L Thompson ierr = PetscSectionSetComponentName(section, 0, 3, "MomentumZ"); 663ccaff030SJeremy L Thompson CHKERRQ(ierr); 664ccaff030SJeremy L Thompson ierr = PetscSectionSetComponentName(section, 0, 4, "EnergyDensity"); 665ccaff030SJeremy L Thompson CHKERRQ(ierr); 666ccaff030SJeremy L Thompson } 667ccaff030SJeremy L Thompson PetscFunctionReturn(0); 668ccaff030SJeremy L Thompson } 669ccaff030SJeremy L Thompson 670ccaff030SJeremy L Thompson int main(int argc, char **argv) { 671ccaff030SJeremy L Thompson PetscInt ierr; 672ccaff030SJeremy L Thompson MPI_Comm comm; 6730c6c0b13SLeila Ghaffari DM dm, dmcoord, dmviz, dmvizfine; 674ccaff030SJeremy L Thompson Mat interpviz; 675ccaff030SJeremy L Thompson TS ts; 676ccaff030SJeremy L Thompson TSAdapt adapt; 677ccaff030SJeremy L Thompson User user; 678ccaff030SJeremy L Thompson Units units; 679ccaff030SJeremy L Thompson char ceedresource[4096] = "/cpu/self"; 680c96c872fSLeila Ghaffari PetscInt localNelemVol, localNelemSur, lnodes, steps; 681ccaff030SJeremy L Thompson const PetscInt ncompq = 5; 682ccaff030SJeremy L Thompson PetscMPIInt rank; 683ccaff030SJeremy L Thompson PetscScalar ftime; 684ccaff030SJeremy L Thompson Vec Q, Qloc, Xloc; 685ccaff030SJeremy L Thompson Ceed ceed; 686ea6e0f84SLeila Ghaffari CeedInt numP_Vol, numP_Sur, numQ_Vol, numQ_Sur; 6878b982baeSLeila Ghaffari CeedVector xcorners, qdata, qdataSur, q0ceedVol, q0ceedSur; 688ea6e0f84SLeila Ghaffari CeedBasis basisxVol, basisxcVol, basisqVol, basisxSur, basisxcSur, basisqSur; 689bd910870SLeila Ghaffari CeedElemRestriction restrictxVol, restrictqVol, restrictqdiVol, 690bd910870SLeila Ghaffari restrictxSur, restrictqSur, restrictqdiSur; 691ea6e0f84SLeila Ghaffari CeedQFunction qf_setupVol, qf_setupSur, qf_ics, qf_rhsVol, qf_rhsSur, 692ea6e0f84SLeila Ghaffari qf_ifunctionVol, qf_ifunctionSur; 693ea6e0f84SLeila Ghaffari CeedOperator op_setupVol, op_setupSur, op_ics; 694ccaff030SJeremy L Thompson CeedScalar Rd; 695ccaff030SJeremy L Thompson PetscScalar WpermK, Pascal, JperkgK, mpersquareds, kgpercubicm, 696ccaff030SJeremy L Thompson kgpersquaredms, Joulepercubicm; 697ccaff030SJeremy L Thompson problemType problemChoice; 698ccaff030SJeremy L Thompson problemData *problem = NULL; 699ccaff030SJeremy L Thompson StabilizationType stab; 7000c6c0b13SLeila Ghaffari PetscBool test, implicit; 701cb3e2689Svaleriabarra PetscInt viz_refine = 0; 702ccaff030SJeremy L Thompson struct SimpleBC_ bc = { 7030c6c0b13SLeila Ghaffari .nwall = 6, 7040c6c0b13SLeila Ghaffari .walls = {1,2,3,4,5,6}, 705ccaff030SJeremy L Thompson }; 706ccaff030SJeremy L Thompson double start, cpu_time_used; 707ccaff030SJeremy L Thompson 708ccaff030SJeremy L Thompson // Create the libCEED contexts 709ccaff030SJeremy L Thompson PetscScalar meter = 1e-2; // 1 meter in scaled length units 710ccaff030SJeremy L Thompson PetscScalar second = 1e-2; // 1 second in scaled time units 711ccaff030SJeremy L Thompson PetscScalar kilogram = 1e-6; // 1 kilogram in scaled mass units 712ccaff030SJeremy L Thompson PetscScalar Kelvin = 1; // 1 Kelvin in scaled temperature units 713ccaff030SJeremy L Thompson CeedScalar theta0 = 300.; // K 714ccaff030SJeremy L Thompson CeedScalar thetaC = -15.; // K 715ccaff030SJeremy L Thompson CeedScalar P0 = 1.e5; // Pa 716ccaff030SJeremy L Thompson CeedScalar N = 0.01; // 1/s 717ccaff030SJeremy L Thompson CeedScalar cv = 717.; // J/(kg K) 718ccaff030SJeremy L Thompson CeedScalar cp = 1004.; // J/(kg K) 719ccaff030SJeremy L Thompson CeedScalar g = 9.81; // m/s^2 720ccaff030SJeremy L Thompson CeedScalar lambda = -2./3.; // - 721ccaff030SJeremy L Thompson CeedScalar mu = 75.; // Pa s, dynamic viscosity 722ccaff030SJeremy L Thompson // mu = 75 is not physical for air, but is good for numerical stability 723ccaff030SJeremy L Thompson CeedScalar k = 0.02638; // W/(m K) 724ccaff030SJeremy L Thompson CeedScalar CtauS = 0.; // dimensionless 725ccaff030SJeremy L Thompson CeedScalar strong_form = 0.; // [0,1] 726ccaff030SJeremy L Thompson PetscScalar lx = 8000.; // m 727ccaff030SJeremy L Thompson PetscScalar ly = 8000.; // m 728ccaff030SJeremy L Thompson PetscScalar lz = 4000.; // m 729ccaff030SJeremy L Thompson CeedScalar rc = 1000.; // m (Radius of bubble) 730ccaff030SJeremy L Thompson PetscScalar resx = 1000.; // m (resolution in x) 731ccaff030SJeremy L Thompson PetscScalar resy = 1000.; // m (resolution in y) 732ccaff030SJeremy L Thompson PetscScalar resz = 1000.; // m (resolution in z) 733ccaff030SJeremy L Thompson PetscInt outputfreq = 10; // - 734ccaff030SJeremy L Thompson PetscInt contsteps = 0; // - 735ea6e0f84SLeila Ghaffari PetscInt degreeVol = 1; // - 736ea6e0f84SLeila Ghaffari PetscInt degreeSur = 1; // - 737ea6e0f84SLeila Ghaffari PetscInt qextraVol = 2; // - 738ea6e0f84SLeila Ghaffari PetscInt qextraSur = 2; // - 7390c6c0b13SLeila Ghaffari DMBoundaryType periodicity[] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, 7400c6c0b13SLeila Ghaffari DM_BOUNDARY_NONE 7410c6c0b13SLeila Ghaffari }; 742ccaff030SJeremy L Thompson PetscReal center[3], dc_axis[3] = {0, 0, 0}; 743ccaff030SJeremy L Thompson 744ccaff030SJeremy L Thompson ierr = PetscInitialize(&argc, &argv, NULL, help); 745ccaff030SJeremy L Thompson if (ierr) return ierr; 746ccaff030SJeremy L Thompson 747ccaff030SJeremy L Thompson // Allocate PETSc context 748ccaff030SJeremy L Thompson ierr = PetscCalloc1(1, &user); CHKERRQ(ierr); 749ccaff030SJeremy L Thompson ierr = PetscMalloc1(1, &units); CHKERRQ(ierr); 750ccaff030SJeremy L Thompson 751ccaff030SJeremy L Thompson // Parse command line options 752ccaff030SJeremy L Thompson comm = PETSC_COMM_WORLD; 753ccaff030SJeremy L Thompson ierr = PetscOptionsBegin(comm, NULL, "Navier-Stokes in PETSc with libCEED", 754ccaff030SJeremy L Thompson NULL); CHKERRQ(ierr); 755ccaff030SJeremy L Thompson ierr = PetscOptionsString("-ceed", "CEED resource specifier", 756ccaff030SJeremy L Thompson NULL, ceedresource, ceedresource, 757ccaff030SJeremy L Thompson sizeof(ceedresource), NULL); CHKERRQ(ierr); 7580c6c0b13SLeila Ghaffari ierr = PetscOptionsBool("-test", "Run in test mode", 7590c6c0b13SLeila Ghaffari NULL, test=PETSC_FALSE, &test, NULL); CHKERRQ(ierr); 760ccaff030SJeremy L Thompson problemChoice = NS_DENSITY_CURRENT; 761ccaff030SJeremy L Thompson ierr = PetscOptionsEnum("-problem", "Problem to solve", NULL, 762ccaff030SJeremy L Thompson problemTypes, (PetscEnum)problemChoice, 763ccaff030SJeremy L Thompson (PetscEnum *)&problemChoice, NULL); CHKERRQ(ierr); 764ccaff030SJeremy L Thompson problem = &problemOptions[problemChoice]; 765ccaff030SJeremy L Thompson ierr = PetscOptionsEnum("-stab", "Stabilization method", NULL, 766ccaff030SJeremy L Thompson StabilizationTypes, (PetscEnum)(stab = STAB_NONE), 767ccaff030SJeremy L Thompson (PetscEnum *)&stab, NULL); CHKERRQ(ierr); 768ccaff030SJeremy L Thompson ierr = PetscOptionsBool("-implicit", "Use implicit (IFunction) formulation", 769ccaff030SJeremy L Thompson NULL, implicit=PETSC_FALSE, &implicit, NULL); 770ccaff030SJeremy L Thompson CHKERRQ(ierr); 771ccaff030SJeremy L Thompson { 772ccaff030SJeremy L Thompson PetscInt len; 773ccaff030SJeremy L Thompson PetscBool flg; 774ccaff030SJeremy L Thompson ierr = PetscOptionsIntArray("-bc_wall", 775ccaff030SJeremy L Thompson "Use wall boundary conditions on this list of faces", 776ccaff030SJeremy L Thompson NULL, bc.walls, 777ccaff030SJeremy L Thompson (len = sizeof(bc.walls) / sizeof(bc.walls[0]), 778ccaff030SJeremy L Thompson &len), &flg); CHKERRQ(ierr); 779ccaff030SJeremy L Thompson if (flg) bc.nwall = len; 780ccaff030SJeremy L Thompson for (PetscInt j=0; j<3; j++) { 781ccaff030SJeremy L Thompson const char *flags[3] = {"-bc_slip_x", "-bc_slip_y", "-bc_slip_z"}; 782ccaff030SJeremy L Thompson ierr = PetscOptionsIntArray(flags[j], 783ccaff030SJeremy L Thompson "Use slip boundary conditions on this list of faces", 784ccaff030SJeremy L Thompson NULL, bc.slips[j], 785ccaff030SJeremy L Thompson (len = sizeof(bc.slips[j]) / sizeof(bc.slips[j][0]), 786ccaff030SJeremy L Thompson &len), &flg); 787ccaff030SJeremy L Thompson CHKERRQ(ierr); 7880c6c0b13SLeila Ghaffari if (flg) bc.nslip[j] = len; 789ccaff030SJeremy L Thompson } 790ccaff030SJeremy L Thompson } 791cb3e2689Svaleriabarra ierr = PetscOptionsInt("-viz_refine", 792cb3e2689Svaleriabarra "Regular refinement levels for visualization", 793cb3e2689Svaleriabarra NULL, viz_refine, &viz_refine, NULL); 794ccaff030SJeremy L Thompson CHKERRQ(ierr); 795ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-units_meter", "1 meter in scaled length units", 796ccaff030SJeremy L Thompson NULL, meter, &meter, NULL); CHKERRQ(ierr); 797ccaff030SJeremy L Thompson meter = fabs(meter); 798ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-units_second","1 second in scaled time units", 799ccaff030SJeremy L Thompson NULL, second, &second, NULL); CHKERRQ(ierr); 800ccaff030SJeremy L Thompson second = fabs(second); 801ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-units_kilogram","1 kilogram in scaled mass units", 802ccaff030SJeremy L Thompson NULL, kilogram, &kilogram, NULL); CHKERRQ(ierr); 803ccaff030SJeremy L Thompson kilogram = fabs(kilogram); 804ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-units_Kelvin", 805ccaff030SJeremy L Thompson "1 Kelvin in scaled temperature units", 806ccaff030SJeremy L Thompson NULL, Kelvin, &Kelvin, NULL); CHKERRQ(ierr); 807ccaff030SJeremy L Thompson Kelvin = fabs(Kelvin); 808ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-theta0", "Reference potential temperature", 809ccaff030SJeremy L Thompson NULL, theta0, &theta0, NULL); CHKERRQ(ierr); 810ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-thetaC", "Perturbation of potential temperature", 811ccaff030SJeremy L Thompson NULL, thetaC, &thetaC, NULL); CHKERRQ(ierr); 812ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-P0", "Atmospheric pressure", 813ccaff030SJeremy L Thompson NULL, P0, &P0, NULL); CHKERRQ(ierr); 814ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-N", "Brunt-Vaisala frequency", 815ccaff030SJeremy L Thompson NULL, N, &N, NULL); CHKERRQ(ierr); 816ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-cv", "Heat capacity at constant volume", 817ccaff030SJeremy L Thompson NULL, cv, &cv, NULL); CHKERRQ(ierr); 818ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-cp", "Heat capacity at constant pressure", 819ccaff030SJeremy L Thompson NULL, cp, &cp, NULL); CHKERRQ(ierr); 820ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-g", "Gravitational acceleration", 821ccaff030SJeremy L Thompson NULL, g, &g, NULL); CHKERRQ(ierr); 822ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-lambda", 823ccaff030SJeremy L Thompson "Stokes hypothesis second viscosity coefficient", 824ccaff030SJeremy L Thompson NULL, lambda, &lambda, NULL); CHKERRQ(ierr); 825ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-mu", "Shear dynamic viscosity coefficient", 826ccaff030SJeremy L Thompson NULL, mu, &mu, NULL); CHKERRQ(ierr); 827ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-k", "Thermal conductivity", 828ccaff030SJeremy L Thompson NULL, k, &k, NULL); CHKERRQ(ierr); 829ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-CtauS", 830ccaff030SJeremy L Thompson "Scale coefficient for tau (nondimensional)", 831ccaff030SJeremy L Thompson NULL, CtauS, &CtauS, NULL); CHKERRQ(ierr); 832ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-strong_form", 833ccaff030SJeremy L Thompson "Strong (1) or weak/integrated by parts (0) advection residual", 834ccaff030SJeremy L Thompson NULL, strong_form, &strong_form, NULL); 835ccaff030SJeremy L Thompson CHKERRQ(ierr); 836ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-lx", "Length scale in x direction", 837ccaff030SJeremy L Thompson NULL, lx, &lx, NULL); CHKERRQ(ierr); 838ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-ly", "Length scale in y direction", 839ccaff030SJeremy L Thompson NULL, ly, &ly, NULL); CHKERRQ(ierr); 840ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-lz", "Length scale in z direction", 841ccaff030SJeremy L Thompson NULL, lz, &lz, NULL); CHKERRQ(ierr); 842ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-rc", "Characteristic radius of thermal bubble", 843ccaff030SJeremy L Thompson NULL, rc, &rc, NULL); CHKERRQ(ierr); 844ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-resx","Target resolution in x", 845ccaff030SJeremy L Thompson NULL, resx, &resx, NULL); CHKERRQ(ierr); 846ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-resy","Target resolution in y", 847ccaff030SJeremy L Thompson NULL, resy, &resy, NULL); CHKERRQ(ierr); 848ccaff030SJeremy L Thompson ierr = PetscOptionsScalar("-resz","Target resolution in z", 849ccaff030SJeremy L Thompson NULL, resz, &resz, NULL); CHKERRQ(ierr); 850ccaff030SJeremy L Thompson PetscInt n = problem->dim; 8510c6c0b13SLeila Ghaffari ierr = PetscOptionsEnumArray("-periodicity", "Periodicity per direction", 8520c6c0b13SLeila Ghaffari NULL, DMBoundaryTypes, (PetscEnum *)periodicity, 8530c6c0b13SLeila Ghaffari &n, NULL); CHKERRQ(ierr); 8540c6c0b13SLeila Ghaffari n = problem->dim; 855ccaff030SJeremy L Thompson center[0] = 0.5 * lx; 856ccaff030SJeremy L Thompson center[1] = 0.5 * ly; 857ccaff030SJeremy L Thompson center[2] = 0.5 * lz; 858ccaff030SJeremy L Thompson ierr = PetscOptionsRealArray("-center", "Location of bubble center", 859ccaff030SJeremy L Thompson NULL, center, &n, NULL); CHKERRQ(ierr); 860ccaff030SJeremy L Thompson n = problem->dim; 861ccaff030SJeremy L Thompson ierr = PetscOptionsRealArray("-dc_axis", 862ccaff030SJeremy L Thompson "Axis of density current cylindrical anomaly, or {0,0,0} for spherically symmetric", 863ccaff030SJeremy L Thompson NULL, dc_axis, &n, NULL); CHKERRQ(ierr); 864ccaff030SJeremy L Thompson { 865ccaff030SJeremy L Thompson PetscReal norm = PetscSqrtReal(PetscSqr(dc_axis[0]) + 866ccaff030SJeremy L Thompson PetscSqr(dc_axis[1]) + PetscSqr(dc_axis[2])); 867ccaff030SJeremy L Thompson if (norm > 0) { 868ccaff030SJeremy L Thompson for (int i=0; i<3; i++) dc_axis[i] /= norm; 869ccaff030SJeremy L Thompson } 870ccaff030SJeremy L Thompson } 871ccaff030SJeremy L Thompson ierr = PetscOptionsInt("-output_freq", 872ccaff030SJeremy L Thompson "Frequency of output, in number of steps", 873ccaff030SJeremy L Thompson NULL, outputfreq, &outputfreq, NULL); CHKERRQ(ierr); 874ccaff030SJeremy L Thompson ierr = PetscOptionsInt("-continue", "Continue from previous solution", 875ccaff030SJeremy L Thompson NULL, contsteps, &contsteps, NULL); CHKERRQ(ierr); 876ea6e0f84SLeila Ghaffari ierr = PetscOptionsInt("-degree_volume", "Polynomial degree of finite elements for the Volume", 877ea6e0f84SLeila Ghaffari NULL, degreeVol, °reeVol, NULL); CHKERRQ(ierr); 878ea6e0f84SLeila Ghaffari ierr = PetscOptionsInt("-qextra_volume", "Number of extra quadrature points for the Volume", 879ea6e0f84SLeila Ghaffari NULL, qextraVol, &qextraVol, NULL); CHKERRQ(ierr); 8800c6c0b13SLeila Ghaffari PetscStrncpy(user->outputfolder, ".", 2); 881ccaff030SJeremy L Thompson ierr = PetscOptionsString("-of", "Output folder", 882ccaff030SJeremy L Thompson NULL, user->outputfolder, user->outputfolder, 883ccaff030SJeremy L Thompson sizeof(user->outputfolder), NULL); CHKERRQ(ierr); 884ccaff030SJeremy L Thompson ierr = PetscOptionsEnd(); CHKERRQ(ierr); 885ccaff030SJeremy L Thompson 886ccaff030SJeremy L Thompson // Define derived units 887ccaff030SJeremy L Thompson Pascal = kilogram / (meter * PetscSqr(second)); 888ccaff030SJeremy L Thompson JperkgK = PetscSqr(meter) / (PetscSqr(second) * Kelvin); 889ccaff030SJeremy L Thompson mpersquareds = meter / PetscSqr(second); 890ccaff030SJeremy L Thompson WpermK = kilogram * meter / (pow(second,3) * Kelvin); 891ccaff030SJeremy L Thompson kgpercubicm = kilogram / pow(meter,3); 892ccaff030SJeremy L Thompson kgpersquaredms = kilogram / (PetscSqr(meter) * second); 893ccaff030SJeremy L Thompson Joulepercubicm = kilogram / (meter * PetscSqr(second)); 894ccaff030SJeremy L Thompson 895ccaff030SJeremy L Thompson // Scale variables to desired units 896ccaff030SJeremy L Thompson theta0 *= Kelvin; 897ccaff030SJeremy L Thompson thetaC *= Kelvin; 898ccaff030SJeremy L Thompson P0 *= Pascal; 899ccaff030SJeremy L Thompson N *= (1./second); 900ccaff030SJeremy L Thompson cv *= JperkgK; 901ccaff030SJeremy L Thompson cp *= JperkgK; 902ccaff030SJeremy L Thompson Rd = cp - cv; 903ccaff030SJeremy L Thompson g *= mpersquareds; 904ccaff030SJeremy L Thompson mu *= Pascal * second; 905ccaff030SJeremy L Thompson k *= WpermK; 906ccaff030SJeremy L Thompson lx = fabs(lx) * meter; 907ccaff030SJeremy L Thompson ly = fabs(ly) * meter; 908ccaff030SJeremy L Thompson lz = fabs(lz) * meter; 909ccaff030SJeremy L Thompson rc = fabs(rc) * meter; 910ccaff030SJeremy L Thompson resx = fabs(resx) * meter; 911ccaff030SJeremy L Thompson resy = fabs(resy) * meter; 912ccaff030SJeremy L Thompson resz = fabs(resz) * meter; 913ccaff030SJeremy L Thompson for (int i=0; i<3; i++) center[i] *= meter; 914ccaff030SJeremy L Thompson 915ccaff030SJeremy L Thompson const CeedInt dim = problem->dim, ncompx = problem->dim, 9168b982baeSLeila Ghaffari qdatasizeVol = problem->qdatasizeVol, 9178b982baeSLeila Ghaffari qdatasizeSur = problem->qdatasizeSur; 918ccaff030SJeremy L Thompson // Set up the libCEED context 919ccaff030SJeremy L Thompson struct SetupContext_ ctxSetup = { 920ccaff030SJeremy L Thompson .theta0 = theta0, 921ccaff030SJeremy L Thompson .thetaC = thetaC, 922ccaff030SJeremy L Thompson .P0 = P0, 923ccaff030SJeremy L Thompson .N = N, 924ccaff030SJeremy L Thompson .cv = cv, 925ccaff030SJeremy L Thompson .cp = cp, 926ccaff030SJeremy L Thompson .Rd = Rd, 927ccaff030SJeremy L Thompson .g = g, 928ccaff030SJeremy L Thompson .rc = rc, 929ccaff030SJeremy L Thompson .lx = lx, 930ccaff030SJeremy L Thompson .ly = ly, 931ccaff030SJeremy L Thompson .lz = lz, 9320c6c0b13SLeila Ghaffari .periodicity0 = periodicity[0], 9330c6c0b13SLeila Ghaffari .periodicity1 = periodicity[1], 9340c6c0b13SLeila Ghaffari .periodicity2 = periodicity[2], 935ccaff030SJeremy L Thompson .center[0] = center[0], 936ccaff030SJeremy L Thompson .center[1] = center[1], 937ccaff030SJeremy L Thompson .center[2] = center[2], 938ccaff030SJeremy L Thompson .dc_axis[0] = dc_axis[0], 939ccaff030SJeremy L Thompson .dc_axis[1] = dc_axis[1], 940ccaff030SJeremy L Thompson .dc_axis[2] = dc_axis[2], 941ccaff030SJeremy L Thompson .time = 0, 942ccaff030SJeremy L Thompson }; 943ccaff030SJeremy L Thompson 944ccaff030SJeremy L Thompson { 945ccaff030SJeremy L Thompson const PetscReal scale[3] = {lx, ly, lz}; 946ccaff030SJeremy L Thompson ierr = DMPlexCreateBoxMesh(comm, dim, PETSC_FALSE, NULL, NULL, scale, 9470c6c0b13SLeila Ghaffari periodicity, PETSC_TRUE, &dm); 948ccaff030SJeremy L Thompson CHKERRQ(ierr); 949ccaff030SJeremy L Thompson } 9500c6c0b13SLeila Ghaffari if (1) { 951ccaff030SJeremy L Thompson DM dmDist = NULL; 952ccaff030SJeremy L Thompson PetscPartitioner part; 953ccaff030SJeremy L Thompson 954ccaff030SJeremy L Thompson ierr = DMPlexGetPartitioner(dm, &part); CHKERRQ(ierr); 955ccaff030SJeremy L Thompson ierr = PetscPartitionerSetFromOptions(part); CHKERRQ(ierr); 956ccaff030SJeremy L Thompson ierr = DMPlexDistribute(dm, 0, NULL, &dmDist); CHKERRQ(ierr); 957ccaff030SJeremy L Thompson if (dmDist) { 958ccaff030SJeremy L Thompson ierr = DMDestroy(&dm); CHKERRQ(ierr); 959ccaff030SJeremy L Thompson dm = dmDist; 960ccaff030SJeremy L Thompson } 961ccaff030SJeremy L Thompson } 962ccaff030SJeremy L Thompson ierr = DMViewFromOptions(dm, NULL, "-dm_view"); CHKERRQ(ierr); 963ccaff030SJeremy L Thompson 964ccaff030SJeremy L Thompson ierr = DMLocalizeCoordinates(dm); CHKERRQ(ierr); 965ccaff030SJeremy L Thompson ierr = DMSetFromOptions(dm); CHKERRQ(ierr); 966ea6e0f84SLeila Ghaffari ierr = SetUpDM(dm, problem, degreeVol, &bc, &ctxSetup); CHKERRQ(ierr); 9670c6c0b13SLeila Ghaffari if (!test) { 9680c6c0b13SLeila Ghaffari ierr = PetscPrintf(PETSC_COMM_WORLD, 969ea6e0f84SLeila Ghaffari "Degree of Volumetric FEM Space: %D\n", 970ea6e0f84SLeila Ghaffari degreeVol); CHKERRQ(ierr); 9710c6c0b13SLeila Ghaffari } 972ccaff030SJeremy L Thompson dmviz = NULL; 973ccaff030SJeremy L Thompson interpviz = NULL; 974ccaff030SJeremy L Thompson if (viz_refine) { 975ff6701fcSJed Brown DM dmhierarchy[viz_refine+1]; 976ff6701fcSJed Brown 977ccaff030SJeremy L Thompson ierr = DMPlexSetRefinementUniform(dm, PETSC_TRUE); CHKERRQ(ierr); 978ff6701fcSJed Brown dmhierarchy[0] = dm; 979ea6e0f84SLeila Ghaffari for (PetscInt i = 0, d = degreeVol; i < viz_refine; i++) { 980ff6701fcSJed Brown Mat interp_next; 981ff6701fcSJed Brown 982ff6701fcSJed Brown ierr = DMRefine(dmhierarchy[i], MPI_COMM_NULL, &dmhierarchy[i+1]); 983ccaff030SJeremy L Thompson CHKERRQ(ierr); 984ff6701fcSJed Brown ierr = DMSetCoarseDM(dmhierarchy[i+1], dmhierarchy[i]); CHKERRQ(ierr); 985ff6701fcSJed Brown d = (d + 1) / 2; 986ff6701fcSJed Brown if (i + 1 == viz_refine) d = 1; 987ff6701fcSJed Brown ierr = SetUpDM(dmhierarchy[i+1], problem, d, &bc, &ctxSetup); CHKERRQ(ierr); 988ff6701fcSJed Brown ierr = DMCreateInterpolation(dmhierarchy[i], dmhierarchy[i+1], 989ff6701fcSJed Brown &interp_next, NULL); CHKERRQ(ierr); 990ff6701fcSJed Brown if (!i) interpviz = interp_next; 991ff6701fcSJed Brown else { 992ff6701fcSJed Brown Mat C; 993ff6701fcSJed Brown ierr = MatMatMult(interp_next, interpviz, MAT_INITIAL_MATRIX, 994ff6701fcSJed Brown PETSC_DECIDE, &C); CHKERRQ(ierr); 995ff6701fcSJed Brown ierr = MatDestroy(&interp_next); CHKERRQ(ierr); 996ff6701fcSJed Brown ierr = MatDestroy(&interpviz); CHKERRQ(ierr); 997ff6701fcSJed Brown interpviz = C; 998ff6701fcSJed Brown } 999ff6701fcSJed Brown } 1000cb3e2689Svaleriabarra for (PetscInt i=1; i<viz_refine; i++) { 1001ff6701fcSJed Brown ierr = DMDestroy(&dmhierarchy[i]); CHKERRQ(ierr); 1002cb3e2689Svaleriabarra } 1003ff6701fcSJed Brown dmviz = dmhierarchy[viz_refine]; 1004ccaff030SJeremy L Thompson } 1005ccaff030SJeremy L Thompson ierr = DMCreateGlobalVector(dm, &Q); CHKERRQ(ierr); 1006ccaff030SJeremy L Thompson ierr = DMGetLocalVector(dm, &Qloc); CHKERRQ(ierr); 1007ccaff030SJeremy L Thompson ierr = VecGetSize(Qloc, &lnodes); CHKERRQ(ierr); 1008ccaff030SJeremy L Thompson lnodes /= ncompq; 1009ccaff030SJeremy L Thompson 10100c6c0b13SLeila Ghaffari { 10110c6c0b13SLeila Ghaffari // Print grid information 1012ccaff030SJeremy L Thompson CeedInt gdofs, odofs; 1013ccaff030SJeremy L Thompson int comm_size; 1014ccaff030SJeremy L Thompson char box_faces_str[PETSC_MAX_PATH_LEN] = "NONE"; 1015ccaff030SJeremy L Thompson ierr = VecGetSize(Q, &gdofs); CHKERRQ(ierr); 1016ccaff030SJeremy L Thompson ierr = VecGetLocalSize(Q, &odofs); CHKERRQ(ierr); 1017ccaff030SJeremy L Thompson ierr = MPI_Comm_size(comm, &comm_size); CHKERRQ(ierr); 1018ccaff030SJeremy L Thompson ierr = PetscOptionsGetString(NULL, NULL, "-dm_plex_box_faces", box_faces_str, 1019ccaff030SJeremy L Thompson sizeof(box_faces_str), NULL); CHKERRQ(ierr); 10200c6c0b13SLeila Ghaffari if (!test) { 10210c6c0b13SLeila Ghaffari ierr = PetscPrintf(comm, "Global FEM dofs: %D (%D owned) on %d ranks\n", 10220c6c0b13SLeila Ghaffari gdofs, odofs, comm_size); CHKERRQ(ierr); 10230c6c0b13SLeila Ghaffari ierr = PetscPrintf(comm, "Local FEM nodes: %D\n", lnodes); CHKERRQ(ierr); 10240c6c0b13SLeila Ghaffari ierr = PetscPrintf(comm, "dm_plex_box_faces: %s\n", box_faces_str); 1025ccaff030SJeremy L Thompson CHKERRQ(ierr); 1026ccaff030SJeremy L Thompson } 1027ccaff030SJeremy L Thompson 10280c6c0b13SLeila Ghaffari } 10290c6c0b13SLeila Ghaffari 1030ccaff030SJeremy L Thompson // Set up global mass vector 1031ccaff030SJeremy L Thompson ierr = VecDuplicate(Q,&user->M); CHKERRQ(ierr); 1032ccaff030SJeremy L Thompson 10330c6c0b13SLeila Ghaffari // Set up CEED 1034ccaff030SJeremy L Thompson // CEED Bases 1035ccaff030SJeremy L Thompson CeedInit(ceedresource, &ceed); 1036ea6e0f84SLeila Ghaffari numP_Vol = degreeVol + 1; 1037ea6e0f84SLeila Ghaffari numQ_Vol = numP_Vol + qextraVol; 1038ea6e0f84SLeila Ghaffari CeedBasisCreateTensorH1Lagrange(ceed, dim, ncompq, numP_Vol, numQ_Vol, CEED_GAUSS, 1039ea6e0f84SLeila Ghaffari &basisqVol); 1040ea6e0f84SLeila Ghaffari CeedBasisCreateTensorH1Lagrange(ceed, dim, ncompx, 2, numQ_Vol, CEED_GAUSS, 1041ea6e0f84SLeila Ghaffari &basisxVol); 1042ea6e0f84SLeila Ghaffari CeedBasisCreateTensorH1Lagrange(ceed, dim, ncompx, 2, numP_Vol, 1043ea6e0f84SLeila Ghaffari CEED_GAUSS_LOBATTO, &basisxcVol); 1044ccaff030SJeremy L Thompson ierr = DMGetCoordinateDM(dm, &dmcoord); CHKERRQ(ierr); 1045ccaff030SJeremy L Thompson ierr = DMPlexSetClosurePermutationTensor(dmcoord, PETSC_DETERMINE, NULL); 1046ccaff030SJeremy L Thompson CHKERRQ(ierr); 1047ccaff030SJeremy L Thompson 1048ccaff030SJeremy L Thompson // CEED Restrictions 1049c96c872fSLeila Ghaffari // Restrictions on the Volume 10506a0edaf9SLeila Ghaffari ierr = GetRestrictionForDomain(ceed, dm, ncompx, dim, 0, 0, 0, numP_Vol, numQ_Vol, 10516a0edaf9SLeila Ghaffari qdatasizeVol, &restrictqVol, &restrictxVol, 10526a0edaf9SLeila Ghaffari &restrictqdiVol); CHKERRQ(ierr); 1053ccaff030SJeremy L Thompson 1054ccaff030SJeremy L Thompson ierr = DMGetCoordinatesLocal(dm, &Xloc); CHKERRQ(ierr); 1055ccaff030SJeremy L Thompson ierr = CreateVectorFromPetscVec(ceed, Xloc, &xcorners); CHKERRQ(ierr); 1056ccaff030SJeremy L Thompson 1057ccaff030SJeremy L Thompson // Create the CEED vectors that will be needed in setup 1058bd910870SLeila Ghaffari CeedInt NqptsVol; 1059c96c872fSLeila Ghaffari CeedBasisGetNumQuadraturePoints(basisqVol, &NqptsVol); 1060c96c872fSLeila Ghaffari CeedElemRestrictionGetNumElements(restrictqVol, &localNelemVol); 10618b982baeSLeila Ghaffari CeedVectorCreate(ceed, qdatasizeVol*localNelemVol*NqptsVol, &qdata); 1062c96c872fSLeila Ghaffari CeedElemRestrictionCreateVector(restrictqVol, &q0ceedVol, NULL); 1063ccaff030SJeremy L Thompson 1064ccaff030SJeremy L Thompson // Create the Q-function that builds the quadrature data for the NS operator 1065ea6e0f84SLeila Ghaffari CeedQFunctionCreateInterior(ceed, 1, problem->setupVol, problem->setupVol_loc, 1066ea6e0f84SLeila Ghaffari &qf_setupVol); 1067ea6e0f84SLeila Ghaffari CeedQFunctionAddInput(qf_setupVol, "dx", ncompx*dim, CEED_EVAL_GRAD); 1068ea6e0f84SLeila Ghaffari CeedQFunctionAddInput(qf_setupVol, "weight", 1, CEED_EVAL_WEIGHT); 10698b982baeSLeila Ghaffari CeedQFunctionAddOutput(qf_setupVol, "qdata", qdatasizeVol, CEED_EVAL_NONE); 1070ccaff030SJeremy L Thompson 1071ccaff030SJeremy L Thompson // Create the Q-function that sets the ICs of the operator 1072ccaff030SJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem->ics, problem->ics_loc, &qf_ics); 1073ccaff030SJeremy L Thompson CeedQFunctionAddInput(qf_ics, "x", ncompx, CEED_EVAL_INTERP); 1074ccaff030SJeremy L Thompson CeedQFunctionAddOutput(qf_ics, "q0", ncompq, CEED_EVAL_NONE); 1075ccaff030SJeremy L Thompson 1076ea6e0f84SLeila Ghaffari qf_rhsVol = NULL; 1077ea6e0f84SLeila Ghaffari if (problem->applyVol_rhs) { // Create the Q-function that defines the action of the RHS operator 1078ea6e0f84SLeila Ghaffari CeedQFunctionCreateInterior(ceed, 1, problem->applyVol_rhs, 1079ea6e0f84SLeila Ghaffari problem->applyVol_rhs_loc, &qf_rhsVol); 1080ea6e0f84SLeila Ghaffari CeedQFunctionAddInput(qf_rhsVol, "q", ncompq, CEED_EVAL_INTERP); 1081ea6e0f84SLeila Ghaffari CeedQFunctionAddInput(qf_rhsVol, "dq", ncompq*dim, CEED_EVAL_GRAD); 10828b982baeSLeila Ghaffari CeedQFunctionAddInput(qf_rhsVol, "qdata", qdatasizeVol, CEED_EVAL_NONE); 1083ea6e0f84SLeila Ghaffari CeedQFunctionAddInput(qf_rhsVol, "x", ncompx, CEED_EVAL_INTERP); 1084ea6e0f84SLeila Ghaffari CeedQFunctionAddOutput(qf_rhsVol, "v", ncompq, CEED_EVAL_INTERP); 1085ea6e0f84SLeila Ghaffari CeedQFunctionAddOutput(qf_rhsVol, "dv", ncompq*dim, CEED_EVAL_GRAD); 1086ccaff030SJeremy L Thompson } 1087ccaff030SJeremy L Thompson 1088ea6e0f84SLeila Ghaffari qf_ifunctionVol = NULL; 1089ea6e0f84SLeila Ghaffari if (problem->applyVol_ifunction) { // Create the Q-function that defines the action of the IFunction 1090ea6e0f84SLeila Ghaffari CeedQFunctionCreateInterior(ceed, 1, problem->applyVol_ifunction, 1091ea6e0f84SLeila Ghaffari problem->applyVol_ifunction_loc, &qf_ifunctionVol); 1092ea6e0f84SLeila Ghaffari CeedQFunctionAddInput(qf_ifunctionVol, "q", ncompq, CEED_EVAL_INTERP); 1093ea6e0f84SLeila Ghaffari CeedQFunctionAddInput(qf_ifunctionVol, "dq", ncompq*dim, CEED_EVAL_GRAD); 1094ea6e0f84SLeila Ghaffari CeedQFunctionAddInput(qf_ifunctionVol, "qdot", ncompq, CEED_EVAL_INTERP); 10958b982baeSLeila Ghaffari CeedQFunctionAddInput(qf_ifunctionVol, "qdata", qdatasizeVol, CEED_EVAL_NONE); 1096ea6e0f84SLeila Ghaffari CeedQFunctionAddInput(qf_ifunctionVol, "x", ncompx, CEED_EVAL_INTERP); 1097ea6e0f84SLeila Ghaffari CeedQFunctionAddOutput(qf_ifunctionVol, "v", ncompq, CEED_EVAL_INTERP); 1098ea6e0f84SLeila Ghaffari CeedQFunctionAddOutput(qf_ifunctionVol, "dv", ncompq*dim, CEED_EVAL_GRAD); 1099ccaff030SJeremy L Thompson } 1100ccaff030SJeremy L Thompson 1101ccaff030SJeremy L Thompson // Create the operator that builds the quadrature data for the NS operator 1102ea6e0f84SLeila Ghaffari CeedOperatorCreate(ceed, qf_setupVol, NULL, NULL, &op_setupVol); 1103ea6e0f84SLeila Ghaffari CeedOperatorSetField(op_setupVol, "dx", restrictxVol, basisxVol, CEED_VECTOR_ACTIVE); 1104ea6e0f84SLeila Ghaffari CeedOperatorSetField(op_setupVol, "weight", CEED_ELEMRESTRICTION_NONE, 1105ea6e0f84SLeila Ghaffari basisxVol, CEED_VECTOR_NONE); 11068b982baeSLeila Ghaffari CeedOperatorSetField(op_setupVol, "qdata", restrictqdiVol, 1107ccaff030SJeremy L Thompson CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 1108ccaff030SJeremy L Thompson 1109ccaff030SJeremy L Thompson // Create the operator that sets the ICs 1110ccaff030SJeremy L Thompson CeedOperatorCreate(ceed, qf_ics, NULL, NULL, &op_ics); 1111ea6e0f84SLeila Ghaffari CeedOperatorSetField(op_ics, "x", restrictxVol, basisxcVol, CEED_VECTOR_ACTIVE); 1112ea6e0f84SLeila Ghaffari CeedOperatorSetField(op_ics, "q0", restrictqVol, 1113ccaff030SJeremy L Thompson CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 1114ccaff030SJeremy L Thompson 1115ea6e0f84SLeila Ghaffari CeedElemRestrictionCreateVector(restrictqVol, &user->qceed, NULL); 1116ea6e0f84SLeila Ghaffari CeedElemRestrictionCreateVector(restrictqVol, &user->qdotceed, NULL); 1117ea6e0f84SLeila Ghaffari CeedElemRestrictionCreateVector(restrictqVol, &user->gceed, NULL); 1118ccaff030SJeremy L Thompson 1119ea6e0f84SLeila Ghaffari if (qf_rhsVol) { // Create the RHS physics operator 1120ccaff030SJeremy L Thompson CeedOperator op; 1121ea6e0f84SLeila Ghaffari CeedOperatorCreate(ceed, qf_rhsVol, NULL, NULL, &op); 1122ea6e0f84SLeila Ghaffari CeedOperatorSetField(op, "q", restrictqVol, basisqVol, CEED_VECTOR_ACTIVE); 1123ea6e0f84SLeila Ghaffari CeedOperatorSetField(op, "dq", restrictqVol, basisqVol, CEED_VECTOR_ACTIVE); 11248b982baeSLeila Ghaffari CeedOperatorSetField(op, "qdata", restrictqdiVol, 11258b982baeSLeila Ghaffari CEED_BASIS_COLLOCATED, qdata); 1126ea6e0f84SLeila Ghaffari CeedOperatorSetField(op, "x", restrictxVol, basisxVol, xcorners); 1127ea6e0f84SLeila Ghaffari CeedOperatorSetField(op, "v", restrictqVol, basisqVol, CEED_VECTOR_ACTIVE); 1128ea6e0f84SLeila Ghaffari CeedOperatorSetField(op, "dv", restrictqVol, basisqVol, CEED_VECTOR_ACTIVE); 1129ccaff030SJeremy L Thompson user->op_rhs = op; 1130ccaff030SJeremy L Thompson } 1131ccaff030SJeremy L Thompson 1132ea6e0f84SLeila Ghaffari if (qf_ifunctionVol) { // Create the IFunction operator 1133ccaff030SJeremy L Thompson CeedOperator op; 1134ea6e0f84SLeila Ghaffari CeedOperatorCreate(ceed, qf_ifunctionVol, NULL, NULL, &op); 1135ea6e0f84SLeila Ghaffari CeedOperatorSetField(op, "q", restrictqVol, basisqVol, CEED_VECTOR_ACTIVE); 1136ea6e0f84SLeila Ghaffari CeedOperatorSetField(op, "dq", restrictqVol, basisqVol, CEED_VECTOR_ACTIVE); 1137ea6e0f84SLeila Ghaffari CeedOperatorSetField(op, "qdot", restrictqVol, basisqVol, user->qdotceed); 11388b982baeSLeila Ghaffari CeedOperatorSetField(op, "qdata", restrictqdiVol, 11398b982baeSLeila Ghaffari CEED_BASIS_COLLOCATED, qdata); 1140ea6e0f84SLeila Ghaffari CeedOperatorSetField(op, "x", restrictxVol, basisxVol, xcorners); 1141ea6e0f84SLeila Ghaffari CeedOperatorSetField(op, "v", restrictqVol, basisqVol, CEED_VECTOR_ACTIVE); 1142ea6e0f84SLeila Ghaffari CeedOperatorSetField(op, "dv", restrictqVol, basisqVol, CEED_VECTOR_ACTIVE); 1143ccaff030SJeremy L Thompson user->op_ifunction = op; 1144ccaff030SJeremy L Thompson } 1145ccaff030SJeremy L Thompson 11466a0edaf9SLeila Ghaffari //**************************************************************************************// 11476a0edaf9SLeila Ghaffari // Add boundary Integral (TODO: create a function for all faces) 11486a0edaf9SLeila Ghaffari //--------------------------------------------------------------------------------------// 11496a0edaf9SLeila Ghaffari // Set up CEED for the boundaries 11506a0edaf9SLeila Ghaffari // CEED bases 11516a0edaf9SLeila Ghaffari CeedInt height = 1; 11526a0edaf9SLeila Ghaffari CeedInt dimSur = dim - height; 11536a0edaf9SLeila Ghaffari numP_Sur = degreeSur + 1; 11546a0edaf9SLeila Ghaffari numQ_Sur = numP_Sur + qextraSur; 11556a0edaf9SLeila Ghaffari CeedBasisCreateTensorH1Lagrange(ceed, dimSur, ncompq, numP_Sur, numQ_Sur, CEED_GAUSS, 11566a0edaf9SLeila Ghaffari &basisqSur); 11576a0edaf9SLeila Ghaffari CeedBasisCreateTensorH1Lagrange(ceed, dimSur, ncompx, 2, numQ_Sur, CEED_GAUSS, 11586a0edaf9SLeila Ghaffari &basisxSur); 11596a0edaf9SLeila Ghaffari CeedBasisCreateTensorH1Lagrange(ceed, dimSur, ncompx, 2, numP_Sur, 11606a0edaf9SLeila Ghaffari CEED_GAUSS_LOBATTO, &basisxcSur); 11616a0edaf9SLeila Ghaffari // CEED Restrictions 11626a0edaf9SLeila Ghaffari // Restriction on one face 11636a0edaf9SLeila Ghaffari DMLabel domainLabel; 11646a0edaf9SLeila Ghaffari ierr = DMGetLabel(dm, "Face Sets", &domainLabel); CHKERRQ(ierr); 11656a0edaf9SLeila Ghaffari ierr = GetRestrictionForDomain(ceed, dm, ncompx, dimSur, height, domainLabel, 2, numP_Sur, 11666a0edaf9SLeila Ghaffari numQ_Sur, qdatasizeSur, &restrictqSur, &restrictxSur, 11676a0edaf9SLeila Ghaffari &restrictqdiSur); CHKERRQ(ierr); 11686a0edaf9SLeila Ghaffari 11696a0edaf9SLeila Ghaffari // Create the CEED vectors that will be needed in setup 11706a0edaf9SLeila Ghaffari CeedInt NqptsSur; 11716a0edaf9SLeila Ghaffari CeedBasisGetNumQuadraturePoints(basisqSur, &NqptsSur); 11726a0edaf9SLeila Ghaffari CeedElemRestrictionGetNumElements(restrictqSur, &localNelemSur); 11736a0edaf9SLeila Ghaffari CeedVectorCreate(ceed, qdatasizeSur*localNelemSur*NqptsSur, &qdataSur); 11746a0edaf9SLeila Ghaffari 11756a0edaf9SLeila Ghaffari // Create the Q-function that builds the quadrature data for the NS operator 11766a0edaf9SLeila Ghaffari CeedQFunctionCreateInterior(ceed, 1, problem->setupSur, problem->setupSur_loc, 11776a0edaf9SLeila Ghaffari &qf_setupSur); 11786a0edaf9SLeila Ghaffari CeedQFunctionAddInput(qf_setupSur, "dx", ncompx*dimSur, CEED_EVAL_GRAD); 11796a0edaf9SLeila Ghaffari CeedQFunctionAddInput(qf_setupSur, "weight", 1, CEED_EVAL_WEIGHT); 11806a0edaf9SLeila Ghaffari CeedQFunctionAddOutput(qf_setupSur, "qdataSur", qdatasizeSur, CEED_EVAL_NONE); 11816a0edaf9SLeila Ghaffari 11826a0edaf9SLeila Ghaffari 11836a0edaf9SLeila Ghaffari qf_rhsSur = NULL; 11846a0edaf9SLeila Ghaffari if (problem->applySur_rhs) { // Create the Q-function that defines the action of the RHS operator 11856a0edaf9SLeila Ghaffari CeedQFunctionCreateInterior(ceed, 1, problem->applySur_rhs, 11866a0edaf9SLeila Ghaffari problem->applySur_rhs_loc, &qf_rhsSur); 11876a0edaf9SLeila Ghaffari CeedQFunctionAddInput(qf_rhsSur, "q", ncompq, CEED_EVAL_INTERP); 11888b982baeSLeila Ghaffari CeedQFunctionAddInput(qf_rhsSur, "dq", ncompq*dim, CEED_EVAL_GRAD); //assumed volumetric elements 11896a0edaf9SLeila Ghaffari CeedQFunctionAddInput(qf_rhsSur, "qdataSur", qdatasizeSur, CEED_EVAL_NONE); 11906a0edaf9SLeila Ghaffari CeedQFunctionAddInput(qf_rhsSur, "x", ncompx, CEED_EVAL_INTERP); 11918b982baeSLeila Ghaffari CeedQFunctionAddInput(qf_rhsSur, "qdata", qdatasizeVol, CEED_EVAL_NONE); 11926a0edaf9SLeila Ghaffari CeedQFunctionAddOutput(qf_rhsSur, "v", ncompq, CEED_EVAL_INTERP); 11936a0edaf9SLeila Ghaffari } 11946a0edaf9SLeila Ghaffari 11956a0edaf9SLeila Ghaffari qf_ifunctionSur = NULL; 11966a0edaf9SLeila Ghaffari if (problem->applySur_ifunction) { // Create the Q-function that defines the action of the IFunction 11976a0edaf9SLeila Ghaffari CeedQFunctionCreateInterior(ceed, 1, problem->applySur_ifunction, 11986a0edaf9SLeila Ghaffari problem->applySur_ifunction_loc, &qf_ifunctionSur); 11996a0edaf9SLeila Ghaffari CeedQFunctionAddInput(qf_ifunctionSur, "q", ncompq, CEED_EVAL_INTERP); 12008b982baeSLeila Ghaffari CeedQFunctionAddInput(qf_ifunctionSur, "dq", ncompq*dim, CEED_EVAL_GRAD); //assumed volumetric elements 12016a0edaf9SLeila Ghaffari CeedQFunctionAddInput(qf_ifunctionSur, "qdataSur", qdatasizeSur, CEED_EVAL_NONE); 12026a0edaf9SLeila Ghaffari CeedQFunctionAddInput(qf_ifunctionSur, "x", ncompx, CEED_EVAL_INTERP); 12038b982baeSLeila Ghaffari CeedQFunctionAddInput(qf_rhsSur, "qdata", qdatasizeVol, CEED_EVAL_NONE); 12046a0edaf9SLeila Ghaffari CeedQFunctionAddOutput(qf_ifunctionSur, "v", ncompq, CEED_EVAL_INTERP); 12056a0edaf9SLeila Ghaffari } 12066a0edaf9SLeila Ghaffari 12076a0edaf9SLeila Ghaffari // Create the operator that builds the quadrature data for the NS operator 12086a0edaf9SLeila Ghaffari CeedOperatorCreate(ceed, qf_setupSur, NULL, NULL, &op_setupSur); 12096a0edaf9SLeila Ghaffari CeedOperatorSetField(op_setupSur, "dx", restrictxSur, basisxSur, CEED_VECTOR_ACTIVE); 12106a0edaf9SLeila Ghaffari CeedOperatorSetField(op_setupSur, "weight", CEED_ELEMRESTRICTION_NONE, 12116a0edaf9SLeila Ghaffari basisxSur, CEED_VECTOR_NONE); 12126a0edaf9SLeila Ghaffari CeedOperatorSetField(op_setupSur, "qdataSur", restrictqdiSur, 12136a0edaf9SLeila Ghaffari CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 12146a0edaf9SLeila Ghaffari 12156a0edaf9SLeila Ghaffari 12166a0edaf9SLeila Ghaffari if (qf_rhsSur) { // Create the RHS physics operator 12176a0edaf9SLeila Ghaffari CeedOperator op; 12186a0edaf9SLeila Ghaffari CeedOperatorCreate(ceed, qf_rhsSur, NULL, NULL, &op); 12196a0edaf9SLeila Ghaffari CeedOperatorSetField(op, "q", restrictqSur, basisqSur, CEED_VECTOR_ACTIVE); 12206a0edaf9SLeila Ghaffari CeedOperatorSetField(op, "dq", restrictqSur, basisqSur, CEED_VECTOR_ACTIVE); 12216a0edaf9SLeila Ghaffari CeedOperatorSetField(op, "qdataSur", restrictqdiSur, 12226a0edaf9SLeila Ghaffari CEED_BASIS_COLLOCATED, qdataSur); 12236a0edaf9SLeila Ghaffari CeedOperatorSetField(op, "x", restrictxSur, basisxSur, xcorners); 12246a0edaf9SLeila Ghaffari CeedOperatorSetField(op, "v", restrictqSur, basisqSur, CEED_VECTOR_ACTIVE); 12256a0edaf9SLeila Ghaffari user->op_rhs_sur = op; 12266a0edaf9SLeila Ghaffari } 12276a0edaf9SLeila Ghaffari 12286a0edaf9SLeila Ghaffari if (qf_ifunctionSur) { // Create the IFunction operator 12296a0edaf9SLeila Ghaffari CeedOperator op; 12306a0edaf9SLeila Ghaffari CeedOperatorCreate(ceed, qf_ifunctionSur, NULL, NULL, &op); 12316a0edaf9SLeila Ghaffari CeedOperatorSetField(op, "q", restrictqSur, basisqSur, CEED_VECTOR_ACTIVE); 12326a0edaf9SLeila Ghaffari CeedOperatorSetField(op, "dq", restrictqSur, basisqSur, CEED_VECTOR_ACTIVE); 12336a0edaf9SLeila Ghaffari CeedOperatorSetField(op, "qdataSur", restrictqdiSur, 12346a0edaf9SLeila Ghaffari CEED_BASIS_COLLOCATED, qdataSur); 12356a0edaf9SLeila Ghaffari CeedOperatorSetField(op, "x", restrictxSur, basisxSur, xcorners); 12366a0edaf9SLeila Ghaffari CeedOperatorSetField(op, "v", restrictqSur, basisqSur, CEED_VECTOR_ACTIVE); 12376a0edaf9SLeila Ghaffari user->op_ifunction_sur = op; 12386a0edaf9SLeila Ghaffari } 12396a0edaf9SLeila Ghaffari // Composite Operaters 12406a0edaf9SLeila Ghaffari if (user->op_ifunction_vol) { 12416a0edaf9SLeila Ghaffari if (user->op_ifunction_sur) { 12426a0edaf9SLeila Ghaffari // Composite Operators for the IFunction 12436a0edaf9SLeila Ghaffari CeedCompositeOperatorCreate(ceed, &user->op_ifunction); 12446a0edaf9SLeila Ghaffari CeedCompositeOperatorAddSub(user->op_ifunction, user->op_ifunction_vol); 12456a0edaf9SLeila Ghaffari CeedCompositeOperatorAddSub(user->op_ifunction, user->op_ifunction_sur); 12466a0edaf9SLeila Ghaffari } else { 12476a0edaf9SLeila Ghaffari user->op_ifunction = user->op_ifunction_vol; 12486a0edaf9SLeila Ghaffari } 12496a0edaf9SLeila Ghaffari } 12506a0edaf9SLeila Ghaffari if (user->op_rhs_vol) { 12516a0edaf9SLeila Ghaffari if (user->op_rhs_sur) { 12526a0edaf9SLeila Ghaffari // Composite Operators for the RHS 12536a0edaf9SLeila Ghaffari CeedCompositeOperatorCreate(ceed, &user->op_rhs); 12546a0edaf9SLeila Ghaffari CeedCompositeOperatorAddSub(user->op_rhs, user->op_rhs_vol); 12556a0edaf9SLeila Ghaffari CeedCompositeOperatorAddSub(user->op_rhs, user->op_rhs_sur); 12566a0edaf9SLeila Ghaffari } else { 12576a0edaf9SLeila Ghaffari user->op_rhs = user->op_rhs_vol; 12586a0edaf9SLeila Ghaffari } 12596a0edaf9SLeila Ghaffari } 12606a0edaf9SLeila Ghaffari //**************************************************************************************// 1261ccaff030SJeremy L Thompson CeedQFunctionSetContext(qf_ics, &ctxSetup, sizeof ctxSetup); 1262ccaff030SJeremy L Thompson CeedScalar ctxNS[8] = {lambda, mu, k, cv, cp, g, Rd}; 1263ccaff030SJeremy L Thompson struct Advection2dContext_ ctxAdvection2d = { 1264ccaff030SJeremy L Thompson .CtauS = CtauS, 1265ccaff030SJeremy L Thompson .strong_form = strong_form, 1266ccaff030SJeremy L Thompson .stabilization = stab, 1267ccaff030SJeremy L Thompson }; 1268ccaff030SJeremy L Thompson switch (problemChoice) { 1269ccaff030SJeremy L Thompson case NS_DENSITY_CURRENT: 1270ea6e0f84SLeila Ghaffari if (qf_rhsVol) CeedQFunctionSetContext(qf_rhsVol, &ctxNS, sizeof ctxNS); 1271ea6e0f84SLeila Ghaffari if (qf_ifunctionVol) CeedQFunctionSetContext(qf_ifunctionVol, &ctxNS, 1272ccaff030SJeremy L Thompson sizeof ctxNS); 12736a0edaf9SLeila Ghaffari if (qf_rhsSur) CeedQFunctionSetContext(qf_rhsSur, &ctxNS, sizeof ctxNS); 12746a0edaf9SLeila Ghaffari if (qf_ifunctionSur) CeedQFunctionSetContext(qf_ifunctionSur, &ctxNS, 12756a0edaf9SLeila Ghaffari sizeof ctxNS); 1276ccaff030SJeremy L Thompson break; 1277ccaff030SJeremy L Thompson case NS_ADVECTION: 1278ccaff030SJeremy L Thompson case NS_ADVECTION2D: 1279ea6e0f84SLeila Ghaffari if (qf_rhsVol) CeedQFunctionSetContext(qf_rhsVol, &ctxAdvection2d, 1280ccaff030SJeremy L Thompson sizeof ctxAdvection2d); 1281ea6e0f84SLeila Ghaffari if (qf_ifunctionVol) CeedQFunctionSetContext(qf_ifunctionVol, &ctxAdvection2d, 1282ccaff030SJeremy L Thompson sizeof ctxAdvection2d); 12836a0edaf9SLeila Ghaffari if (qf_rhsSur) CeedQFunctionSetContext(qf_rhsSur, &ctxAdvection2d, 12846a0edaf9SLeila Ghaffari sizeof ctxAdvection2d); 12856a0edaf9SLeila Ghaffari if (qf_ifunctionSur) CeedQFunctionSetContext(qf_ifunctionSur, &ctxAdvection2d, 12866a0edaf9SLeila Ghaffari sizeof ctxAdvection2d); 1287ccaff030SJeremy L Thompson } 1288ccaff030SJeremy L Thompson 1289ccaff030SJeremy L Thompson // Set up PETSc context 1290ccaff030SJeremy L Thompson // Set up units structure 1291ccaff030SJeremy L Thompson units->meter = meter; 1292ccaff030SJeremy L Thompson units->kilogram = kilogram; 1293ccaff030SJeremy L Thompson units->second = second; 1294ccaff030SJeremy L Thompson units->Kelvin = Kelvin; 1295ccaff030SJeremy L Thompson units->Pascal = Pascal; 1296ccaff030SJeremy L Thompson units->JperkgK = JperkgK; 1297ccaff030SJeremy L Thompson units->mpersquareds = mpersquareds; 1298ccaff030SJeremy L Thompson units->WpermK = WpermK; 1299ccaff030SJeremy L Thompson units->kgpercubicm = kgpercubicm; 1300ccaff030SJeremy L Thompson units->kgpersquaredms = kgpersquaredms; 1301ccaff030SJeremy L Thompson units->Joulepercubicm = Joulepercubicm; 1302ccaff030SJeremy L Thompson 1303ccaff030SJeremy L Thompson // Set up user structure 1304ccaff030SJeremy L Thompson user->comm = comm; 1305ccaff030SJeremy L Thompson user->outputfreq = outputfreq; 1306ccaff030SJeremy L Thompson user->contsteps = contsteps; 1307ccaff030SJeremy L Thompson user->units = units; 1308ccaff030SJeremy L Thompson user->dm = dm; 1309ccaff030SJeremy L Thompson user->dmviz = dmviz; 1310ccaff030SJeremy L Thompson user->interpviz = interpviz; 1311ccaff030SJeremy L Thompson user->ceed = ceed; 1312ccaff030SJeremy L Thompson 13138b982baeSLeila Ghaffari // Calculate qdata and ICs 1314ccaff030SJeremy L Thompson // Set up state global and local vectors 1315ccaff030SJeremy L Thompson ierr = VecZeroEntries(Q); CHKERRQ(ierr); 1316ccaff030SJeremy L Thompson 1317c96c872fSLeila Ghaffari ierr = VectorPlacePetscVec(q0ceedVol, Qloc); CHKERRQ(ierr); 1318ccaff030SJeremy L Thompson 1319ccaff030SJeremy L Thompson // Apply Setup Ceed Operators 1320ccaff030SJeremy L Thompson ierr = VectorPlacePetscVec(xcorners, Xloc); CHKERRQ(ierr); 13218b982baeSLeila Ghaffari CeedOperatorApply(op_setupVol, xcorners, qdata, CEED_REQUEST_IMMEDIATE); 13228b982baeSLeila Ghaffari ierr = ComputeLumpedMassMatrix(ceed, dm, restrictqVol, basisqVol, restrictqdiVol, qdata, 1323ccaff030SJeremy L Thompson user->M); CHKERRQ(ierr); 1324ccaff030SJeremy L Thompson 1325c96c872fSLeila Ghaffari ierr = ICs_PetscMultiplicity(op_ics, xcorners, q0ceedVol, dm, Qloc, Q, restrictqVol, 13260c6c0b13SLeila Ghaffari &ctxSetup, 0.0); 1327ccaff030SJeremy L Thompson if (1) { // Record boundary values from initial condition and override DMPlexInsertBoundaryValues() 1328ccaff030SJeremy L Thompson // We use this for the main simulation DM because the reference DMPlexInsertBoundaryValues() is very slow. If we 1329ccaff030SJeremy L Thompson // disable this, we should still get the same results due to the problem->bc function, but with potentially much 1330ccaff030SJeremy L Thompson // slower execution. 1331ccaff030SJeremy L Thompson Vec Qbc; 1332ccaff030SJeremy L Thompson ierr = DMGetNamedLocalVector(dm, "Qbc", &Qbc); CHKERRQ(ierr); 1333ccaff030SJeremy L Thompson ierr = VecCopy(Qloc, Qbc); CHKERRQ(ierr); 1334ccaff030SJeremy L Thompson ierr = VecZeroEntries(Qloc); CHKERRQ(ierr); 1335ccaff030SJeremy L Thompson ierr = DMGlobalToLocal(dm, Q, INSERT_VALUES, Qloc); CHKERRQ(ierr); 1336ccaff030SJeremy L Thompson ierr = VecAXPY(Qbc, -1., Qloc); CHKERRQ(ierr); 1337ccaff030SJeremy L Thompson ierr = DMRestoreNamedLocalVector(dm, "Qbc", &Qbc); CHKERRQ(ierr); 1338ccaff030SJeremy L Thompson ierr = PetscObjectComposeFunction((PetscObject)dm, 13390c6c0b13SLeila Ghaffari "DMPlexInsertBoundaryValues_C",DMPlexInsertBoundaryValues_NS); CHKERRQ(ierr); 1340ccaff030SJeremy L Thompson } 1341ccaff030SJeremy L Thompson 1342ccaff030SJeremy L Thompson MPI_Comm_rank(comm, &rank); 1343ccaff030SJeremy L Thompson if (!rank) {ierr = PetscMkdir(user->outputfolder); CHKERRQ(ierr);} 1344ccaff030SJeremy L Thompson // Gather initial Q values 1345ccaff030SJeremy L Thompson // In case of continuation of simulation, set up initial values from binary file 1346ccaff030SJeremy L Thompson if (contsteps) { // continue from existent solution 1347ccaff030SJeremy L Thompson PetscViewer viewer; 1348ccaff030SJeremy L Thompson char filepath[PETSC_MAX_PATH_LEN]; 1349ccaff030SJeremy L Thompson // Read input 1350ccaff030SJeremy L Thompson ierr = PetscSNPrintf(filepath, sizeof filepath, "%s/ns-solution.bin", 1351ccaff030SJeremy L Thompson user->outputfolder); 1352ccaff030SJeremy L Thompson CHKERRQ(ierr); 1353ccaff030SJeremy L Thompson ierr = PetscViewerBinaryOpen(comm, filepath, FILE_MODE_READ, &viewer); 1354ccaff030SJeremy L Thompson CHKERRQ(ierr); 1355ccaff030SJeremy L Thompson ierr = VecLoad(Q, viewer); CHKERRQ(ierr); 1356ccaff030SJeremy L Thompson ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr); 13570c6c0b13SLeila Ghaffari } else { 13580c6c0b13SLeila Ghaffari //ierr = DMLocalToGlobal(dm, Qloc, INSERT_VALUES, Q);CHKERRQ(ierr); 1359ccaff030SJeremy L Thompson } 1360ccaff030SJeremy L Thompson ierr = DMRestoreLocalVector(dm, &Qloc); CHKERRQ(ierr); 1361ccaff030SJeremy L Thompson 1362ccaff030SJeremy L Thompson // Create and setup TS 1363ccaff030SJeremy L Thompson ierr = TSCreate(comm, &ts); CHKERRQ(ierr); 1364ccaff030SJeremy L Thompson ierr = TSSetDM(ts, dm); CHKERRQ(ierr); 1365ccaff030SJeremy L Thompson if (implicit) { 1366ccaff030SJeremy L Thompson ierr = TSSetType(ts, TSBDF); CHKERRQ(ierr); 1367ccaff030SJeremy L Thompson if (user->op_ifunction) { 1368ccaff030SJeremy L Thompson ierr = TSSetIFunction(ts, NULL, IFunction_NS, &user); CHKERRQ(ierr); 1369ccaff030SJeremy L Thompson } else { // Implicit integrators can fall back to using an RHSFunction 1370ccaff030SJeremy L Thompson ierr = TSSetRHSFunction(ts, NULL, RHS_NS, &user); CHKERRQ(ierr); 1371ccaff030SJeremy L Thompson } 1372ccaff030SJeremy L Thompson } else { 1373ccaff030SJeremy L Thompson if (!user->op_rhs) SETERRQ(comm,PETSC_ERR_ARG_NULL, 1374ccaff030SJeremy L Thompson "Problem does not provide RHSFunction"); 1375ccaff030SJeremy L Thompson ierr = TSSetType(ts, TSRK); CHKERRQ(ierr); 1376ccaff030SJeremy L Thompson ierr = TSRKSetType(ts, TSRK5F); CHKERRQ(ierr); 1377ccaff030SJeremy L Thompson ierr = TSSetRHSFunction(ts, NULL, RHS_NS, &user); CHKERRQ(ierr); 1378ccaff030SJeremy L Thompson } 1379ccaff030SJeremy L Thompson ierr = TSSetMaxTime(ts, 500. * units->second); CHKERRQ(ierr); 1380ccaff030SJeremy L Thompson ierr = TSSetExactFinalTime(ts, TS_EXACTFINALTIME_STEPOVER); CHKERRQ(ierr); 1381ccaff030SJeremy L Thompson ierr = TSSetTimeStep(ts, 1.e-2 * units->second); CHKERRQ(ierr); 13820c6c0b13SLeila Ghaffari if (test) {ierr = TSSetMaxSteps(ts, 1); CHKERRQ(ierr);} 1383ccaff030SJeremy L Thompson ierr = TSGetAdapt(ts, &adapt); CHKERRQ(ierr); 1384ccaff030SJeremy L Thompson ierr = TSAdaptSetStepLimits(adapt, 1385ccaff030SJeremy L Thompson 1.e-12 * units->second, 1386ccaff030SJeremy L Thompson 1.e2 * units->second); CHKERRQ(ierr); 1387ccaff030SJeremy L Thompson ierr = TSSetFromOptions(ts); CHKERRQ(ierr); 1388ccaff030SJeremy L Thompson if (!contsteps) { // print initial condition 13890c6c0b13SLeila Ghaffari if (!test) { 1390ccaff030SJeremy L Thompson ierr = TSMonitor_NS(ts, 0, 0., Q, user); CHKERRQ(ierr); 1391ccaff030SJeremy L Thompson } 1392ccaff030SJeremy L Thompson } else { // continue from time of last output 1393ccaff030SJeremy L Thompson PetscReal time; 1394ccaff030SJeremy L Thompson PetscInt count; 1395ccaff030SJeremy L Thompson PetscViewer viewer; 1396ccaff030SJeremy L Thompson char filepath[PETSC_MAX_PATH_LEN]; 1397ccaff030SJeremy L Thompson ierr = PetscSNPrintf(filepath, sizeof filepath, "%s/ns-time.bin", 1398ccaff030SJeremy L Thompson user->outputfolder); CHKERRQ(ierr); 1399ccaff030SJeremy L Thompson ierr = PetscViewerBinaryOpen(comm, filepath, FILE_MODE_READ, &viewer); 1400ccaff030SJeremy L Thompson CHKERRQ(ierr); 1401ccaff030SJeremy L Thompson ierr = PetscViewerBinaryRead(viewer, &time, 1, &count, PETSC_REAL); 1402ccaff030SJeremy L Thompson CHKERRQ(ierr); 1403ccaff030SJeremy L Thompson ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr); 1404ccaff030SJeremy L Thompson ierr = TSSetTime(ts, time * user->units->second); CHKERRQ(ierr); 1405ccaff030SJeremy L Thompson } 14060c6c0b13SLeila Ghaffari if (!test) { 1407ccaff030SJeremy L Thompson ierr = TSMonitorSet(ts, TSMonitor_NS, user, NULL); CHKERRQ(ierr); 1408ccaff030SJeremy L Thompson } 1409ccaff030SJeremy L Thompson 1410ccaff030SJeremy L Thompson // Solve 1411ccaff030SJeremy L Thompson start = MPI_Wtime(); 1412ccaff030SJeremy L Thompson ierr = PetscBarrier((PetscObject)ts); CHKERRQ(ierr); 1413ccaff030SJeremy L Thompson ierr = TSSolve(ts, Q); CHKERRQ(ierr); 1414ccaff030SJeremy L Thompson cpu_time_used = MPI_Wtime() - start; 1415ccaff030SJeremy L Thompson ierr = TSGetSolveTime(ts,&ftime); CHKERRQ(ierr); 1416ccaff030SJeremy L Thompson ierr = MPI_Allreduce(MPI_IN_PLACE, &cpu_time_used, 1, MPI_DOUBLE, MPI_MIN, 1417ccaff030SJeremy L Thompson comm); CHKERRQ(ierr); 14180c6c0b13SLeila Ghaffari if (!test) { 1419ccaff030SJeremy L Thompson ierr = PetscPrintf(PETSC_COMM_WORLD, 14200c6c0b13SLeila Ghaffari "Time taken for solution: %g\n", 1421ccaff030SJeremy L Thompson (double)cpu_time_used); CHKERRQ(ierr); 1422ccaff030SJeremy L Thompson } 1423ccaff030SJeremy L Thompson 1424ccaff030SJeremy L Thompson // Get error 14250c6c0b13SLeila Ghaffari if (problem->non_zero_time && !test) { 1426ccaff030SJeremy L Thompson Vec Qexact, Qexactloc; 1427ccaff030SJeremy L Thompson PetscReal norm; 1428ccaff030SJeremy L Thompson ierr = DMCreateGlobalVector(dm, &Qexact); CHKERRQ(ierr); 1429ccaff030SJeremy L Thompson ierr = DMGetLocalVector(dm, &Qexactloc); CHKERRQ(ierr); 1430ccaff030SJeremy L Thompson ierr = VecGetSize(Qexactloc, &lnodes); CHKERRQ(ierr); 1431ccaff030SJeremy L Thompson 1432c96c872fSLeila Ghaffari ierr = ICs_PetscMultiplicity(op_ics, xcorners, q0ceedVol, dm, Qexactloc, Qexact, 1433ea6e0f84SLeila Ghaffari restrictqVol, &ctxSetup, ftime); CHKERRQ(ierr); 1434ccaff030SJeremy L Thompson 1435ccaff030SJeremy L Thompson ierr = VecAXPY(Q, -1.0, Qexact); CHKERRQ(ierr); 1436ccaff030SJeremy L Thompson ierr = VecNorm(Q, NORM_MAX, &norm); CHKERRQ(ierr); 1437c96c872fSLeila Ghaffari CeedVectorDestroy(&q0ceedVol); 1438ccaff030SJeremy L Thompson ierr = PetscPrintf(PETSC_COMM_WORLD, 1439ccaff030SJeremy L Thompson "Max Error: %g\n", 1440ccaff030SJeremy L Thompson (double)norm); CHKERRQ(ierr); 1441ccaff030SJeremy L Thompson } 1442ccaff030SJeremy L Thompson 1443ccaff030SJeremy L Thompson // Output Statistics 1444ccaff030SJeremy L Thompson ierr = TSGetStepNumber(ts,&steps); CHKERRQ(ierr); 14450c6c0b13SLeila Ghaffari if (!test) { 1446ccaff030SJeremy L Thompson ierr = PetscPrintf(PETSC_COMM_WORLD, 1447ccaff030SJeremy L Thompson "Time integrator took %D time steps to reach final time %g\n", 1448ccaff030SJeremy L Thompson steps,(double)ftime); CHKERRQ(ierr); 1449ccaff030SJeremy L Thompson } 14509cf88b28Svaleriabarra 1451ccaff030SJeremy L Thompson // Clean up libCEED 14528b982baeSLeila Ghaffari CeedVectorDestroy(&qdata); 1453ccaff030SJeremy L Thompson CeedVectorDestroy(&user->qceed); 1454ccaff030SJeremy L Thompson CeedVectorDestroy(&user->qdotceed); 1455ccaff030SJeremy L Thompson CeedVectorDestroy(&user->gceed); 1456ccaff030SJeremy L Thompson CeedVectorDestroy(&xcorners); 1457ea6e0f84SLeila Ghaffari CeedBasisDestroy(&basisqVol); 1458ea6e0f84SLeila Ghaffari CeedBasisDestroy(&basisxVol); 1459ea6e0f84SLeila Ghaffari CeedBasisDestroy(&basisxcVol); 1460ea6e0f84SLeila Ghaffari CeedElemRestrictionDestroy(&restrictqVol); 1461ea6e0f84SLeila Ghaffari CeedElemRestrictionDestroy(&restrictxVol); 1462ea6e0f84SLeila Ghaffari CeedElemRestrictionDestroy(&restrictqdiVol); 1463ea6e0f84SLeila Ghaffari CeedQFunctionDestroy(&qf_setupVol); 1464ccaff030SJeremy L Thompson CeedQFunctionDestroy(&qf_ics); 1465ea6e0f84SLeila Ghaffari CeedQFunctionDestroy(&qf_rhsVol); 1466ea6e0f84SLeila Ghaffari CeedQFunctionDestroy(&qf_ifunctionVol); 1467ea6e0f84SLeila Ghaffari CeedOperatorDestroy(&op_setupVol); 1468ccaff030SJeremy L Thompson CeedOperatorDestroy(&op_ics); 14696a0edaf9SLeila Ghaffari CeedOperatorDestroy(&user->op_rhs_vol); 14706a0edaf9SLeila Ghaffari CeedOperatorDestroy(&user->op_ifunction_vol); 14716a0edaf9SLeila Ghaffari CeedDestroy(&ceed); 14726a0edaf9SLeila Ghaffari 14736a0edaf9SLeila Ghaffari CeedVectorDestroy(&qdataSur); 14746a0edaf9SLeila Ghaffari CeedBasisDestroy(&basisqSur); 14756a0edaf9SLeila Ghaffari CeedBasisDestroy(&basisxSur); 14766a0edaf9SLeila Ghaffari CeedBasisDestroy(&basisxcSur); 14776a0edaf9SLeila Ghaffari CeedElemRestrictionDestroy(&restrictqSur); 14786a0edaf9SLeila Ghaffari CeedElemRestrictionDestroy(&restrictxSur); 14796a0edaf9SLeila Ghaffari CeedElemRestrictionDestroy(&restrictqdiSur); 14806a0edaf9SLeila Ghaffari CeedQFunctionDestroy(&qf_setupSur); 14816a0edaf9SLeila Ghaffari CeedQFunctionDestroy(&qf_rhsSur); 14826a0edaf9SLeila Ghaffari CeedQFunctionDestroy(&qf_ifunctionSur); 14836a0edaf9SLeila Ghaffari CeedOperatorDestroy(&op_setupSur); 14846a0edaf9SLeila Ghaffari CeedOperatorDestroy(&user->op_rhs_sur); 14856a0edaf9SLeila Ghaffari CeedOperatorDestroy(&user->op_ifunction_sur); 14866a0edaf9SLeila Ghaffari 1487ccaff030SJeremy L Thompson CeedOperatorDestroy(&user->op_rhs); 1488ccaff030SJeremy L Thompson CeedOperatorDestroy(&user->op_ifunction); 1489ccaff030SJeremy L Thompson 1490ccaff030SJeremy L Thompson // Clean up PETSc 1491ccaff030SJeremy L Thompson ierr = VecDestroy(&Q); CHKERRQ(ierr); 1492ccaff030SJeremy L Thompson ierr = VecDestroy(&user->M); CHKERRQ(ierr); 1493ccaff030SJeremy L Thompson ierr = MatDestroy(&interpviz); CHKERRQ(ierr); 1494ccaff030SJeremy L Thompson ierr = DMDestroy(&dmviz); CHKERRQ(ierr); 1495ccaff030SJeremy L Thompson ierr = TSDestroy(&ts); CHKERRQ(ierr); 1496ccaff030SJeremy L Thompson ierr = DMDestroy(&dm); CHKERRQ(ierr); 1497ccaff030SJeremy L Thompson ierr = PetscFree(units); CHKERRQ(ierr); 1498ccaff030SJeremy L Thompson ierr = PetscFree(user); CHKERRQ(ierr); 1499ccaff030SJeremy L Thompson return PetscFinalize(); 1500ccaff030SJeremy L Thompson } 1501ccaff030SJeremy L Thompson 1502