xref: /honee/src/honee.c (revision f27c220418155a7918b0a48083dda8631b5f4377)
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   for (PetscInt i = 0; i < problem->num_components; i++) {
134     PetscCall(PetscFree(problem->component_names[i]));
135   }
136   PetscCall(PetscFree(problem->component_names));
137   PetscCall(PetscFree(problem));
138   PetscCall(PetscFree(honee_->units));
139   PetscCall(PetscFree(honee_->phys));
140   PetscCall(PetscFree(app_ctx));
141 
142   PetscCall(PetscHeaderDestroy(&honee_));
143   *honee = NULL;
144   PetscFunctionReturn(PETSC_SUCCESS);
145 }
146 
147 /**
148   @brief Saves a pointer-to-data in a `Honee` object by key
149 
150   This also checks whether `key` has been used previously and will error out if it has.
151 
152   @param[in] honee             `Honee` object to save pointer to
153   @param[in] key               String used to identify the pointer
154   @param[in] container         Pointer to the data
155   @param[in] container_destroy Function to destroy the struct after it is used
156 **/
157 PetscErrorCode HoneeSetContainer(Honee honee, const char key[], void *container, PetscCtxDestroyFn *container_destroy) {
158   PetscFunctionBeginUser;
159   {  // Verify that key is not already taken
160     void *test_data;
161     PetscCall(PetscObjectContainerQuery((PetscObject)honee, key, &test_data));
162     PetscCheck(test_data == NULL, PetscObjectComm((PetscObject)honee), PETSC_ERR_SUP, "Cannot set container with key '%s'; key is already in use.",
163                key);
164   }
165   PetscCall(PetscObjectContainerCompose((PetscObject)honee, key, container, container_destroy));
166   PetscFunctionReturn(PETSC_SUCCESS);
167 }
168 
169 /**
170   @brief Retrieve a pointer-to-data in a `Honee` object by key
171 
172   This will error out if `honee` does not have a container identified by `key`.
173 
174   @param[in]  honee     `Honee` object to retrieve pointer from
175   @param[in]  key       String used to identify the pointer
176   @param[out] container Pointer to the data
177 **/
178 PetscErrorCode HoneeGetContainer(Honee honee, const char key[], void *container) {
179   PetscFunctionBeginUser;
180   PetscCall(PetscObjectContainerQuery((PetscObject)honee, key, container));
181   PetscCheck(*(void **)container != NULL, PetscObjectComm((PetscObject)honee), PETSC_ERR_SUP, "Container with key '%s' not found.", key);
182   PetscFunctionReturn(PETSC_SUCCESS);
183 }
184 
185 /**
186   @brief Check if `Honee` object as pointer-to-data identified by key
187 
188   @param[in]  honee   `Honee` object to query for key
189   @param[in]  key     String to search for
190   @param[out] has_key Whether key has been set
191 **/
192 PetscErrorCode HoneeHasContainer(Honee honee, const char key[], PetscBool *has_key) {
193   void *test_data;
194 
195   PetscFunctionBeginUser;
196   PetscCall(PetscObjectContainerQuery((PetscObject)honee, key, &test_data));
197   *has_key = test_data == NULL ? PETSC_FALSE : PETSC_TRUE;
198   PetscFunctionReturn(PETSC_SUCCESS);
199 }
200