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