xref: /honee/src/honee.c (revision 0ebaa86a9e7b959b0930e06f5bf2e8cfa7e7daf4)
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_x));
69 
70   // -- Restrictions
71   PetscCallCeed(ceed, CeedElemRestrictionDestroy(&honee_->elem_restr_x));
72 
73   // Destroy QFunction contexts after using
74   {
75     PetscCallCeed(ceed, CeedQFunctionContextDestroy(&problem->ics.qfctx));
76     PetscCallCeed(ceed, CeedQFunctionContextDestroy(&problem->apply_vol_rhs.qfctx));
77     PetscCallCeed(ceed, CeedQFunctionContextDestroy(&problem->apply_vol_ifunction.qfctx));
78     PetscCallCeed(ceed, CeedQFunctionContextDestroy(&problem->apply_vol_ijacobian.qfctx));
79   }
80 
81   // -- Operators
82   PetscCall(OperatorApplyContextDestroy(honee_->op_ics_ctx));
83   PetscCall(OperatorApplyContextDestroy(honee_->op_rhs_ctx));
84   PetscCall(OperatorApplyContextDestroy(honee_->op_strong_bc_ctx));
85   PetscCallCeed(ceed, CeedOperatorDestroy(&honee_->op_ifunction));
86 
87   // -- Ceed
88   PetscCheck(CeedDestroy(&ceed) == CEED_ERROR_SUCCESS, comm, PETSC_ERR_LIB, "Destroying Ceed object failed");
89 
90   // ---------------------------------------------------------------------------
91   // Clean up PETSc
92   // ---------------------------------------------------------------------------
93   // -- Vectors
94   PetscCall(VecDestroy(&honee_->Q_loc));
95   PetscCall(VecDestroy(&honee_->Q_dot_loc));
96 
97   PetscCall(KSPDestroy(&honee_->mass_ksp));
98 
99   // -- Matrices
100   PetscCall(MatDestroy(&honee_->interp_viz));
101   PetscCall(MatDestroy(&honee_->mat_ijacobian));
102 
103   // -- DM
104   PetscCall(DMDestroy(&honee_->dm_viz));
105 
106   // -- Function list
107   PetscCall(PetscFunctionListDestroy(&app_ctx->problems));
108 
109   PetscCall(PetscFree(app_ctx->amat_type));
110   PetscCall(PetscFree(app_ctx->wall_forces.walls));
111   PetscCall(PetscViewerDestroy(&app_ctx->wall_forces.viewer));
112 
113   // -- Structs
114   for (PetscInt i = 0; i < problem->num_bc_defs; i++) {
115     PetscCall(BCDefinitionDestroy(&problem->bc_defs[i]));
116   }
117   PetscCall(PetscFree(problem->bc_defs));
118   for (PetscInt i = 0; i < problem->num_components; i++) {
119     PetscCall(PetscFree(problem->component_names[i]));
120   }
121   PetscCall(PetscFree(problem->component_names));
122 
123   PetscCall(PetscFree4(honee_->app_ctx, honee_->problem_data, honee_->phys, honee_->units));
124   PetscCall(PetscHeaderDestroy(&honee_));
125   *honee = NULL;
126   PetscFunctionReturn(PETSC_SUCCESS);
127 }
128 
129 /**
130   @brief Saves a pointer-to-data in a `Honee` object by key
131 
132   This also checks whether `key` has been used previously and will error out if it has.
133 
134   @param[in] honee             `Honee` object to save pointer to
135   @param[in] key               String used to identify the pointer
136   @param[in] container         Pointer to the data
137   @param[in] container_destroy Function to destroy the struct after it is used
138 **/
139 PetscErrorCode HoneeSetContainer(Honee honee, const char key[], void *container, PetscCtxDestroyFn *container_destroy) {
140   PetscFunctionBeginUser;
141   {  // Verify that key is not already taken
142     void *test_data;
143     PetscCall(PetscObjectContainerQuery((PetscObject)honee, key, &test_data));
144     PetscCheck(test_data == NULL, PetscObjectComm((PetscObject)honee), PETSC_ERR_SUP, "Cannot set container with key '%s'; key is already in use.",
145                key);
146   }
147   PetscCall(PetscObjectContainerCompose((PetscObject)honee, key, container, container_destroy));
148   PetscFunctionReturn(PETSC_SUCCESS);
149 }
150 
151 /**
152   @brief Retrieve a pointer-to-data in a `Honee` object by key
153 
154   This will error out if `honee` does not have a container identified by `key`.
155 
156   @param[in]  honee     `Honee` object to retrieve pointer from
157   @param[in]  key       String used to identify the pointer
158   @param[out] container Pointer to the data
159 **/
160 PetscErrorCode HoneeGetContainer(Honee honee, const char key[], void *container) {
161   PetscFunctionBeginUser;
162   PetscCall(PetscObjectContainerQuery((PetscObject)honee, key, container));
163   PetscCheck(*(void **)container != NULL, PetscObjectComm((PetscObject)honee), PETSC_ERR_SUP, "Container with key '%s' not found.", key);
164   PetscFunctionReturn(PETSC_SUCCESS);
165 }
166 
167 /**
168   @brief Check if `Honee` object as pointer-to-data identified by key
169 
170   @param[in]  honee   `Honee` object to query for key
171   @param[in]  key     String to search for
172   @param[out] has_key Whether key has been set
173 **/
174 PetscErrorCode HoneeHasContainer(Honee honee, const char key[], PetscBool *has_key) {
175   void *test_data;
176 
177   PetscFunctionBeginUser;
178   PetscCall(PetscObjectContainerQuery((PetscObject)honee, key, &test_data));
179   *has_key = test_data == NULL ? PETSC_FALSE : PETSC_TRUE;
180   PetscFunctionReturn(PETSC_SUCCESS);
181 }
182 
183 const DMLabel  DMLABEL_DEFAULT       = NULL;
184 const PetscInt DMLABEL_DEFAULT_VALUE = 0;
185