1 // SPDX-FileCopyrightText: Copyright (c) 2017-2024, HONEE contributors. 2 // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause 3 4 #include <navierstokes.h> 5 6 PetscClassId HONEE_CLASSID; 7 8 // @brief Initalize `HONEE` class. 9 static PetscErrorCode HoneeInitClass_Private() { 10 static PetscBool registered = PETSC_FALSE; 11 12 PetscFunctionBeginUser; 13 if (registered) PetscFunctionReturn(PETSC_SUCCESS); 14 PetscCall(PetscClassIdRegister("Honee", &HONEE_CLASSID)); 15 registered = PETSC_TRUE; 16 PetscFunctionReturn(PETSC_SUCCESS); 17 } 18 19 /** 20 @brief Initialize `Honee` object 21 22 @param[in] comm `MPI_Comm` for the object 23 @param[out] honee The initialized `Honee` object 24 **/ 25 PetscErrorCode HoneeInit(MPI_Comm comm, Honee *honee) { 26 Honee honee_; 27 AppCtx app_ctx; 28 ProblemData problem; 29 Physics phys_ctx; 30 Units units; 31 32 PetscFunctionBeginUser; 33 PetscCall(HoneeInitClass_Private()); 34 PetscCall(PetscHeaderCreate(honee_, HONEE_CLASSID, "Honee", "HONEE", "Honee", comm, HoneeDestroy, NULL)); 35 PetscCall(PetscNew(&app_ctx)); 36 PetscCall(PetscNew(&problem)); 37 PetscCall(PetscNew(&phys_ctx)); 38 PetscCall(PetscNew(&units)); 39 honee_->app_ctx = app_ctx; 40 honee_->units = units; 41 honee_->phys = phys_ctx; 42 honee_->problem_data = problem; 43 problem->set_bc_from_ics = PETSC_TRUE; 44 honee_->comm = PETSC_COMM_WORLD; 45 honee_->start_time = time(NULL); 46 47 PetscCall(RegisterLogEvents()); 48 49 *honee = honee_; 50 PetscFunctionReturn(PETSC_SUCCESS); 51 } 52 53 /** 54 @brief Destroy `Honee` object 55 56 @param[in] honee Object to be destroyed 57 **/ 58 PetscErrorCode HoneeDestroy(Honee *honee) { 59 Honee honee_ = *honee; 60 Ceed ceed; 61 62 PetscFunctionBeginUser; 63 if (!honee_) PetscFunctionReturn(PETSC_SUCCESS); 64 PetscValidHeaderSpecific(honee_, HONEE_CLASSID, 1); 65 66 ceed = honee_->ceed; 67 MPI_Comm comm = honee_->comm; 68 AppCtx app_ctx = honee_->app_ctx; 69 ProblemData problem = honee_->problem_data; 70 71 PetscCall(QDataClearStoredData()); 72 PetscCall(DivDiffFluxProjectionDataDestroy(honee_->diff_flux_proj)); 73 74 // -- Vectors 75 PetscCallCeed(ceed, CeedVectorDestroy(&honee_->x_coord)); 76 PetscCallCeed(ceed, CeedVectorDestroy(&honee_->q_ceed)); 77 PetscCallCeed(ceed, CeedVectorDestroy(&honee_->q_dot_ceed)); 78 PetscCallCeed(ceed, CeedVectorDestroy(&honee_->g_ceed)); 79 80 // -- Bases 81 PetscCallCeed(ceed, CeedBasisDestroy(&honee_->basis_q)); 82 PetscCallCeed(ceed, CeedBasisDestroy(&honee_->basis_x)); 83 84 // -- Restrictions 85 PetscCallCeed(ceed, CeedElemRestrictionDestroy(&honee_->elem_restr_q)); 86 PetscCallCeed(ceed, CeedElemRestrictionDestroy(&honee_->elem_restr_x)); 87 88 // Destroy QFunction contexts after using 89 { 90 PetscCallCeed(ceed, CeedQFunctionContextDestroy(&problem->ics.qfctx)); 91 PetscCallCeed(ceed, CeedQFunctionContextDestroy(&problem->apply_vol_rhs.qfctx)); 92 PetscCallCeed(ceed, CeedQFunctionContextDestroy(&problem->apply_vol_ifunction.qfctx)); 93 PetscCallCeed(ceed, CeedQFunctionContextDestroy(&problem->apply_vol_ijacobian.qfctx)); 94 } 95 96 // -- Operators 97 PetscCall(OperatorApplyContextDestroy(honee_->op_ics_ctx)); 98 PetscCall(OperatorApplyContextDestroy(honee_->op_rhs_ctx)); 99 PetscCall(OperatorApplyContextDestroy(honee_->op_strong_bc_ctx)); 100 PetscCallCeed(ceed, CeedOperatorDestroy(&honee_->op_ifunction)); 101 102 // -- Ceed 103 PetscCheck(CeedDestroy(&ceed) == CEED_ERROR_SUCCESS, comm, PETSC_ERR_LIB, "Destroying Ceed object failed"); 104 105 // --------------------------------------------------------------------------- 106 // Clean up PETSc 107 // --------------------------------------------------------------------------- 108 // -- Vectors 109 PetscCall(VecDestroy(&honee_->Q_loc)); 110 PetscCall(VecDestroy(&honee_->Q_dot_loc)); 111 112 PetscCall(KSPDestroy(&honee_->mass_ksp)); 113 114 // -- Matrices 115 PetscCall(MatDestroy(&honee_->interp_viz)); 116 PetscCall(MatDestroy(&honee_->mat_ijacobian)); 117 118 // -- DM 119 PetscCall(DMDestroy(&honee_->dm_viz)); 120 121 // -- Function list 122 PetscCall(PetscFunctionListDestroy(&app_ctx->problems)); 123 124 PetscCall(PetscFree(app_ctx->amat_type)); 125 PetscCall(PetscFree(app_ctx->wall_forces.walls)); 126 PetscCall(PetscViewerDestroy(&app_ctx->wall_forces.viewer)); 127 128 // -- Structs 129 for (PetscInt i = 0; i < problem->num_bc_defs; i++) { 130 PetscCall(BCDefinitionDestroy(&problem->bc_defs[i])); 131 } 132 PetscCall(PetscFree(problem->bc_defs)); 133 PetscCall(PetscFree(honee_->units)); 134 PetscCall(PetscFree(problem)); 135 PetscCall(PetscFree(honee_->phys)); 136 PetscCall(PetscFree(app_ctx)); 137 PetscCall(PetscHeaderDestroy(&honee_)); 138 *honee = NULL; 139 PetscFunctionReturn(PETSC_SUCCESS); 140 } 141 142 /** 143 @brief Saves a pointer-to-data in a `Honee` object by key 144 145 This also checks whether `key` has been used previously and will error out if it has. 146 147 @param[in] honee `Honee` object to save pointer to 148 @param[in] key String used to identify the pointer 149 @param[in] container Pointer to the data 150 @param[in] container_destroy Function to destroy the struct after it is used 151 **/ 152 PetscErrorCode HoneeSetContainer(Honee honee, const char key[], void *container, PetscCtxDestroyFn *container_destroy) { 153 PetscFunctionBeginUser; 154 { // Verify that key is not already taken 155 void *test_data; 156 PetscCall(PetscObjectContainerQuery((PetscObject)honee, key, &test_data)); 157 PetscCheck(test_data == NULL, PetscObjectComm((PetscObject)honee), PETSC_ERR_SUP, "Cannot set container with key '%s'; key is already in use.", 158 key); 159 } 160 PetscCall(PetscObjectContainerCompose((PetscObject)honee, key, container, container_destroy)); 161 PetscFunctionReturn(PETSC_SUCCESS); 162 } 163 164 /** 165 @brief Retrieve a pointer-to-data in a `Honee` object by key 166 167 This will error out if `honee` does not have a container identified by `key`. 168 169 @param[in] honee `Honee` object to retrieve pointer from 170 @param[in] key String used to identify the pointer 171 @param[out] container Pointer to the data 172 **/ 173 PetscErrorCode HoneeGetContainer(Honee honee, const char key[], void *container) { 174 PetscFunctionBeginUser; 175 PetscCall(PetscObjectContainerQuery((PetscObject)honee, key, container)); 176 PetscCheck(*(void **)container != NULL, PetscObjectComm((PetscObject)honee), PETSC_ERR_SUP, "Container with key '%s' not found.", key); 177 PetscFunctionReturn(PETSC_SUCCESS); 178 } 179 180 /** 181 @brief Check if `Honee` object as pointer-to-data identified by key 182 183 @param[in] honee `Honee` object to query for key 184 @param[in] key String to search for 185 @param[out] has_key Whether key has been set 186 **/ 187 PetscErrorCode HoneeHasContainer(Honee honee, const char key[], PetscBool *has_key) { 188 void *test_data; 189 190 PetscFunctionBeginUser; 191 PetscCall(PetscObjectContainerQuery((PetscObject)honee, key, &test_data)); 192 *has_key = test_data == NULL ? PETSC_FALSE : PETSC_TRUE; 193 PetscFunctionReturn(PETSC_SUCCESS); 194 } 195