xref: /honee/src/honee.c (revision e3db12f8fd36c2c636163113c7ff57d59e00b06c)
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