1ae2b091fSJames Wright // SPDX-FileCopyrightText: Copyright (c) 2017-2024, HONEE contributors.
2ae2b091fSJames Wright // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause
3487a3b6eSJames Wright
4487a3b6eSJames Wright #include <bc_definition.h>
577aa5ad7SJames Wright #include <dm-utils.h>
677aa5ad7SJames Wright #include <petsc-ceed.h>
709240e0aSJames Wright #include <petsc/private/petscimpl.h>
8487a3b6eSJames Wright
996f347c2SJames Wright PetscClassId BC_DEFINITION_CLASSID;
1096f347c2SJames Wright
1196f347c2SJames Wright /**
1296f347c2SJames Wright @brief Initalize `BCDefinition` class.
1396f347c2SJames Wright
1496f347c2SJames Wright Not collective across MPI processes.
1596f347c2SJames Wright
1696f347c2SJames Wright @return An error code: 0 - success, otherwise - failure
1796f347c2SJames Wright **/
BCDefinitionInitalize()1896f347c2SJames Wright static PetscErrorCode BCDefinitionInitalize() {
1996f347c2SJames Wright static PetscBool registered = PETSC_FALSE;
2096f347c2SJames Wright
2196f347c2SJames Wright PetscFunctionBeginUser;
2296f347c2SJames Wright if (registered) PetscFunctionReturn(PETSC_SUCCESS);
2396f347c2SJames Wright PetscCall(PetscClassIdRegister("BCDefinition", &BC_DEFINITION_CLASSID));
2496f347c2SJames Wright registered = PETSC_TRUE;
2596f347c2SJames Wright PetscFunctionReturn(PETSC_SUCCESS);
2696f347c2SJames Wright }
2796f347c2SJames Wright
28487a3b6eSJames Wright /**
29487a3b6eSJames Wright @brief Create `BCDefinition`
30487a3b6eSJames Wright
3196f347c2SJames Wright @param[in] comm `MPI_Comm` for the object
32487a3b6eSJames Wright @param[in] name Name of the boundary condition
33487a3b6eSJames Wright @param[in] num_label_values Number of `DMLabel` values
34487a3b6eSJames Wright @param[in] label_values Array of label values that define the boundaries controlled by the `BCDefinition`, size `num_label_values`
35487a3b6eSJames Wright @param[out] bc_def The new `BCDefinition`
36487a3b6eSJames Wright **/
BCDefinitionCreate(MPI_Comm comm,const char * name,PetscInt num_label_values,PetscInt label_values[],BCDefinition * bc_def)3796f347c2SJames Wright PetscErrorCode BCDefinitionCreate(MPI_Comm comm, const char *name, PetscInt num_label_values, PetscInt label_values[], BCDefinition *bc_def) {
3896f347c2SJames Wright BCDefinition bc_def_;
39487a3b6eSJames Wright
4096f347c2SJames Wright PetscFunctionBeginUser;
4196f347c2SJames Wright PetscCall(BCDefinitionInitalize());
42*9eadbee4SJames Wright PetscCall(PetscHeaderCreate(bc_def_, BC_DEFINITION_CLASSID, "BCDefinition", "BCDefinition", "BCDefinition", comm, BCDefinitionDestroy,
43*9eadbee4SJames Wright BCDefinitionView));
4496f347c2SJames Wright
4596f347c2SJames Wright PetscCall(PetscStrallocpy(name, &bc_def_->name));
4696f347c2SJames Wright PetscCall(PetscObjectSetName((PetscObject)bc_def_, name));
4796f347c2SJames Wright bc_def_->num_label_values = num_label_values;
4896f347c2SJames Wright PetscCall(PetscMalloc1(num_label_values, &bc_def_->label_values));
4996f347c2SJames Wright for (PetscInt i = 0; i < num_label_values; i++) bc_def_->label_values[i] = label_values[i];
5096f347c2SJames Wright *bc_def = bc_def_;
5196f347c2SJames Wright PetscFunctionReturn(PETSC_SUCCESS);
5296f347c2SJames Wright }
5396f347c2SJames Wright
5496f347c2SJames Wright /**
5596f347c2SJames Wright @brief Destory a `BCDefinition` object
5696f347c2SJames Wright
5796f347c2SJames Wright @param[in,out] bc_def `BCDefinition` to be destroyed
5896f347c2SJames Wright **/
BCDefinitionDestroy(BCDefinition * bc_def)5996f347c2SJames Wright PetscErrorCode BCDefinitionDestroy(BCDefinition *bc_def) {
6096f347c2SJames Wright BCDefinition bc_def_ = *bc_def;
6114bd2a07SJames Wright
6296f347c2SJames Wright PetscFunctionBeginUser;
6396f347c2SJames Wright if (!bc_def_) PetscFunctionReturn(PETSC_SUCCESS);
6496f347c2SJames Wright PetscValidHeaderSpecific(bc_def_, BC_DEFINITION_CLASSID, 1);
6596f347c2SJames Wright if (bc_def_->name) PetscCall(PetscFree(bc_def_->name));
6696f347c2SJames Wright if (bc_def_->label_values) PetscCall(PetscFree(bc_def_->label_values));
6796f347c2SJames Wright if (bc_def_->essential_comps) PetscCall(PetscFree(bc_def_->essential_comps));
6896f347c2SJames Wright if (bc_def_->dm) PetscCall(DMDestroy(&bc_def_->dm));
6914bd2a07SJames Wright if (bc_def_->DestroyCtx) PetscCall((*bc_def_->DestroyCtx)(&bc_def_->ctx));
7096f347c2SJames Wright PetscCall(PetscHeaderDestroy(&bc_def_));
7196f347c2SJames Wright *bc_def = NULL;
7296f347c2SJames Wright PetscFunctionReturn(PETSC_SUCCESS);
7396f347c2SJames Wright }
7496f347c2SJames Wright
7596f347c2SJames Wright /**
7696f347c2SJames Wright @brief View a `BCDefinition` object.
7796f347c2SJames Wright
7896f347c2SJames Wright Not collective across MPI processes.
7996f347c2SJames Wright
8096f347c2SJames Wright @param[in] bc_def `BCDefinition` object
8196f347c2SJames Wright @param[in] viewer Optional `PetscViewer` context or `NULL`
8296f347c2SJames Wright
8396f347c2SJames Wright @return An error code: 0 - success, otherwise - failure
8496f347c2SJames Wright **/
BCDefinitionView(BCDefinition bc_def,PetscViewer viewer)8596f347c2SJames Wright PetscErrorCode BCDefinitionView(BCDefinition bc_def, PetscViewer viewer) {
8696f347c2SJames Wright PetscBool is_ascii;
8796f347c2SJames Wright PetscViewerFormat format;
8896f347c2SJames Wright PetscMPIInt size;
8996f347c2SJames Wright
9096f347c2SJames Wright PetscFunctionBeginUser;
9196f347c2SJames Wright PetscValidHeaderSpecific(bc_def, BC_DEFINITION_CLASSID, 1);
9296f347c2SJames Wright PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
9396f347c2SJames Wright if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)bc_def), &viewer));
9496f347c2SJames Wright
9596f347c2SJames Wright PetscCall(PetscViewerGetFormat(viewer, &format));
9696f347c2SJames Wright PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)bc_def), &size));
9796f347c2SJames Wright if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(PETSC_SUCCESS);
9896f347c2SJames Wright
9996f347c2SJames Wright PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &is_ascii));
10096f347c2SJames Wright {
10196f347c2SJames Wright PetscBool is_detailed = format == PETSC_VIEWER_ASCII_INFO_DETAIL;
10296f347c2SJames Wright
10396f347c2SJames Wright PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)bc_def, viewer));
10496f347c2SJames Wright PetscCall(PetscViewerASCIIPushTab(viewer)); // BCDefinition
10596f347c2SJames Wright
10696f347c2SJames Wright if (is_detailed) PetscCall(DMView(bc_def->dm, viewer));
10796f347c2SJames Wright PetscCall(PetscViewerASCIIPrintf(viewer, "DM Field: %" PetscInt_FMT "\n", bc_def->dm_field));
10896f347c2SJames Wright PetscCall(PetscViewerASCIIPrintf(viewer, "Face Sets:"));
10996f347c2SJames Wright PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
11096f347c2SJames Wright if (bc_def->num_label_values > 0) {
11196f347c2SJames Wright for (PetscInt i = 0; i < bc_def->num_label_values; i++) {
11296f347c2SJames Wright PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, bc_def->label_values[i]));
11396f347c2SJames Wright }
11496f347c2SJames Wright PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
11596f347c2SJames Wright } else {
11696f347c2SJames Wright PetscCall(PetscViewerASCIIPrintf(viewer, " None\n"));
11796f347c2SJames Wright }
11896f347c2SJames Wright PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
11996f347c2SJames Wright
12096f347c2SJames Wright PetscCall(PetscViewerASCIIPrintf(viewer, "Essential Components:"));
12196f347c2SJames Wright PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
12296f347c2SJames Wright if (bc_def->num_essential_comps > 0) {
12396f347c2SJames Wright for (PetscInt i = 0; i < bc_def->num_essential_comps; i++) {
12496f347c2SJames Wright PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, bc_def->essential_comps[i]));
12596f347c2SJames Wright }
12696f347c2SJames Wright PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
12796f347c2SJames Wright } else {
12896f347c2SJames Wright PetscCall(PetscViewerASCIIPrintf(viewer, " None\n"));
12996f347c2SJames Wright }
13096f347c2SJames Wright PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
13196f347c2SJames Wright
13296f347c2SJames Wright PetscCall(PetscViewerASCIIPopTab(viewer)); // BCDefinition
13396f347c2SJames Wright }
13496f347c2SJames Wright PetscFunctionReturn(PETSC_SUCCESS);
13596f347c2SJames Wright }
13696f347c2SJames Wright
13796f347c2SJames Wright /**
13896f347c2SJames Wright @brief View `BCDefinition` from options database (command line/YAML)
13996f347c2SJames Wright
14096f347c2SJames Wright @param[in] bc_def `BCDefintion` to view
14196f347c2SJames Wright @param[in] obj Optional object that provides the prefix for the options database (if `NULL` then the prefix in `bc_def` is used)
14296f347c2SJames Wright @param[in] name Option string that is used to activate viewing
14396f347c2SJames Wright **/
BCDefinitionViewFromOptions(BCDefinition bc_def,PetscObject obj,const char name[])14496f347c2SJames Wright PetscErrorCode BCDefinitionViewFromOptions(BCDefinition bc_def, PetscObject obj, const char name[]) {
14596f347c2SJames Wright PetscFunctionBegin;
14696f347c2SJames Wright PetscValidHeaderSpecific(bc_def, BC_DEFINITION_CLASSID, 1);
14796f347c2SJames Wright PetscCall(PetscObjectViewFromOptions((PetscObject)bc_def, obj, name));
148487a3b6eSJames Wright PetscFunctionReturn(PETSC_SUCCESS);
149487a3b6eSJames Wright }
150487a3b6eSJames Wright
151487a3b6eSJames Wright /**
152487a3b6eSJames Wright @brief Get base information for `BCDefinition`
153487a3b6eSJames Wright
154487a3b6eSJames Wright @param[in] bc_def `BCDefinition` to get information from
155487a3b6eSJames Wright @param[out] name Name of the `BCDefinition`
156487a3b6eSJames Wright @param[out] num_label_values Number of `DMLabel` values
157487a3b6eSJames Wright @param[out] label_values Array of label values that define the boundaries controlled by the `BCDefinition`, size `num_label_values`
158487a3b6eSJames Wright **/
BCDefinitionGetInfo(BCDefinition bc_def,const char * name[],PetscInt * num_label_values,const PetscInt * label_values[])159487a3b6eSJames Wright PetscErrorCode BCDefinitionGetInfo(BCDefinition bc_def, const char *name[], PetscInt *num_label_values, const PetscInt *label_values[]) {
160487a3b6eSJames Wright PetscFunctionBeginUser;
16196f347c2SJames Wright PetscValidHeaderSpecific(bc_def, BC_DEFINITION_CLASSID, 1);
1620990a807SJames Wright if (name) {
1630990a807SJames Wright PetscAssertPointer(name, 2);
1640990a807SJames Wright *name = bc_def->name;
1650990a807SJames Wright }
166487a3b6eSJames Wright if (label_values) {
1670990a807SJames Wright PetscAssertPointer(num_label_values, 3);
1680990a807SJames Wright PetscAssertPointer(label_values, 4);
169487a3b6eSJames Wright *num_label_values = bc_def->num_label_values;
170487a3b6eSJames Wright *label_values = bc_def->label_values;
171487a3b6eSJames Wright }
172487a3b6eSJames Wright PetscFunctionReturn(PETSC_SUCCESS);
173487a3b6eSJames Wright }
174487a3b6eSJames Wright
175487a3b6eSJames Wright /**
176487a3b6eSJames Wright @brief Set `DM_BC_ESSENTIAL` boundary condition values
177487a3b6eSJames Wright
178487a3b6eSJames Wright @param[in,out] bc_def `BCDefinition` to set values to
179487a3b6eSJames Wright @param[in] num_essential_comps Number of components to set
180487a3b6eSJames Wright @param[in] essential_comps Array of components to set, size `num_essential_comps`
181487a3b6eSJames Wright **/
BCDefinitionSetEssential(BCDefinition bc_def,PetscInt num_essential_comps,PetscInt essential_comps[])182487a3b6eSJames Wright PetscErrorCode BCDefinitionSetEssential(BCDefinition bc_def, PetscInt num_essential_comps, PetscInt essential_comps[]) {
183487a3b6eSJames Wright PetscFunctionBeginUser;
18496f347c2SJames Wright PetscValidHeaderSpecific(bc_def, BC_DEFINITION_CLASSID, 1);
185487a3b6eSJames Wright bc_def->num_essential_comps = num_essential_comps;
186487a3b6eSJames Wright PetscCall(PetscMalloc1(num_essential_comps, &bc_def->essential_comps));
187487a3b6eSJames Wright PetscCall(PetscArraycpy(bc_def->essential_comps, essential_comps, num_essential_comps));
188487a3b6eSJames Wright PetscFunctionReturn(PETSC_SUCCESS);
189487a3b6eSJames Wright }
190487a3b6eSJames Wright
191487a3b6eSJames Wright /**
192487a3b6eSJames Wright @brief Get `DM_BC_ESSENTIAL` boundary condition values
193487a3b6eSJames Wright
194487a3b6eSJames Wright @param[in] bc_def `BCDefinition` to set values to
195487a3b6eSJames Wright @param[out] num_essential_comps Number of components to set
196487a3b6eSJames Wright @param[out] essential_comps Array of components to set, size `num_essential_comps`
197487a3b6eSJames Wright **/
BCDefinitionGetEssential(BCDefinition bc_def,PetscInt * num_essential_comps,const PetscInt * essential_comps[])198487a3b6eSJames Wright PetscErrorCode BCDefinitionGetEssential(BCDefinition bc_def, PetscInt *num_essential_comps, const PetscInt *essential_comps[]) {
199487a3b6eSJames Wright PetscFunctionBeginUser;
20096f347c2SJames Wright PetscValidHeaderSpecific(bc_def, BC_DEFINITION_CLASSID, 1);
2010990a807SJames Wright PetscAssertPointer(num_essential_comps, 2);
2020990a807SJames Wright PetscAssertPointer(essential_comps, 3);
203487a3b6eSJames Wright *num_essential_comps = bc_def->num_essential_comps;
204487a3b6eSJames Wright *essential_comps = bc_def->essential_comps;
205487a3b6eSJames Wright PetscFunctionReturn(PETSC_SUCCESS);
206487a3b6eSJames Wright }
207487a3b6eSJames Wright
208487a3b6eSJames Wright #define LABEL_ARRAY_SIZE 256
209487a3b6eSJames Wright
210487a3b6eSJames Wright // @brief See `PetscOptionsBCDefinition`
PetscOptionsBCDefinition_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],const char name[],BCDefinition * bc_def,PetscBool * set)211ddf6e248SJames Wright PetscErrorCode PetscOptionsBCDefinition_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[],
212487a3b6eSJames Wright const char name[], BCDefinition *bc_def, PetscBool *set) {
213487a3b6eSJames Wright PetscInt num_label_values = LABEL_ARRAY_SIZE, label_values[LABEL_ARRAY_SIZE] = {0};
214487a3b6eSJames Wright
215487a3b6eSJames Wright PetscFunctionBeginUser;
216487a3b6eSJames Wright PetscCall(PetscOptionsIntArray(opt, text, man, label_values, &num_label_values, set));
217487a3b6eSJames Wright if (num_label_values > 0) {
21896f347c2SJames Wright PetscCall(BCDefinitionCreate(PetscOptionsObject->comm, name, num_label_values, label_values, bc_def));
219487a3b6eSJames Wright } else {
220487a3b6eSJames Wright *bc_def = NULL;
221487a3b6eSJames Wright }
222487a3b6eSJames Wright PetscFunctionReturn(PETSC_SUCCESS);
223487a3b6eSJames Wright }
22409240e0aSJames Wright
22509240e0aSJames Wright /**
22609240e0aSJames Wright @brief Set `DM` for BCDefinition
22709240e0aSJames Wright
22809240e0aSJames Wright @param[in,out] bc_def `BCDefinition` to add `dm` to
22909240e0aSJames Wright @param[in] dm `DM` to assign to BCDefinition, or `NULL` to remove `DM`
23009240e0aSJames Wright **/
BCDefinitionSetDM(BCDefinition bc_def,DM dm)23109240e0aSJames Wright PetscErrorCode BCDefinitionSetDM(BCDefinition bc_def, DM dm) {
23209240e0aSJames Wright PetscFunctionBeginUser;
23396f347c2SJames Wright PetscValidHeaderSpecific(bc_def, BC_DEFINITION_CLASSID, 1);
23409240e0aSJames Wright if (bc_def->dm) PetscCall(DMDestroy(&bc_def->dm));
23509240e0aSJames Wright if (dm) {
23609240e0aSJames Wright PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
23709240e0aSJames Wright PetscCall(PetscObjectReference((PetscObject)dm));
23809240e0aSJames Wright bc_def->dm = dm;
23909240e0aSJames Wright }
24009240e0aSJames Wright PetscFunctionReturn(PETSC_SUCCESS);
24109240e0aSJames Wright }
24209240e0aSJames Wright
24309240e0aSJames Wright /**
24409240e0aSJames Wright @brief Get `DM` assigned to BCDefinition
24509240e0aSJames Wright
24609240e0aSJames Wright @param[in] bc_def `BCDefinition` to get `dm` from
24709240e0aSJames Wright @param[out] dm `DM` assigned to BCDefinition
24809240e0aSJames Wright **/
BCDefinitionGetDM(BCDefinition bc_def,DM * dm)24909240e0aSJames Wright PetscErrorCode BCDefinitionGetDM(BCDefinition bc_def, DM *dm) {
25096f347c2SJames Wright PetscValidHeaderSpecific(bc_def, BC_DEFINITION_CLASSID, 1);
25114bd2a07SJames Wright
25209240e0aSJames Wright PetscFunctionBeginUser;
25309240e0aSJames Wright PetscAssertPointer(dm, 2);
25409240e0aSJames Wright *dm = bc_def->dm;
25509240e0aSJames Wright PetscFunctionReturn(PETSC_SUCCESS);
25609240e0aSJames Wright }
2572e678684SJames Wright
2582e678684SJames Wright /**
2592e678684SJames Wright @brief Set custom context struct for use in BCDefinition
2602e678684SJames Wright
2612e678684SJames Wright @param[in,out] bc_def `BCDefinition` to add `ctx` to
2622e678684SJames Wright @param[in] destroy_ctx Optional function pointer that destroys the user context on `BCDefinitionDestroy()`
2632e678684SJames Wright @param[in] ctx Pointer to context struct
2642e678684SJames Wright **/
BCDefinitionSetContext(BCDefinition bc_def,PetscCtxDestroyFn * destroy_ctx,void * ctx)2652e678684SJames Wright PetscErrorCode BCDefinitionSetContext(BCDefinition bc_def, PetscCtxDestroyFn *destroy_ctx, void *ctx) {
2662e678684SJames Wright PetscFunctionBeginUser;
26796f347c2SJames Wright PetscValidHeaderSpecific(bc_def, BC_DEFINITION_CLASSID, 1);
26814bd2a07SJames Wright if (bc_def->DestroyCtx) PetscCall((*bc_def->DestroyCtx)(&bc_def->ctx));
2692e678684SJames Wright bc_def->ctx = ctx;
2702e678684SJames Wright bc_def->DestroyCtx = destroy_ctx;
2712e678684SJames Wright PetscFunctionReturn(PETSC_SUCCESS);
2722e678684SJames Wright }
2732e678684SJames Wright
2742e678684SJames Wright /**
2752e678684SJames Wright @brief Set custom context struct for use in BCDefinition
2762e678684SJames Wright
2772e678684SJames Wright @param[in] bc_def `BCDefinition` to get `ctx` from
2782e678684SJames Wright @param[out] ctx Pointer to context struct
2792e678684SJames Wright **/
BCDefinitionGetContext(BCDefinition bc_def,void * ctx)2802e678684SJames Wright PetscErrorCode BCDefinitionGetContext(BCDefinition bc_def, void *ctx) {
2812e678684SJames Wright PetscFunctionBeginUser;
28296f347c2SJames Wright PetscValidHeaderSpecific(bc_def, BC_DEFINITION_CLASSID, 1);
2832e678684SJames Wright PetscAssertPointer(ctx, 2);
2842e678684SJames Wright *(void **)ctx = bc_def->ctx;
2852e678684SJames Wright PetscFunctionReturn(PETSC_SUCCESS);
2862e678684SJames Wright }
28777aa5ad7SJames Wright
28877aa5ad7SJames Wright /**
28977aa5ad7SJames Wright @brief Add function pointers to create `CeedQFunction` and `CeedOperator` for IFunction of boundary condition
29077aa5ad7SJames Wright
29177aa5ad7SJames Wright @param[in,out] bc_def `BCDefinition` to add function pointers to
29277aa5ad7SJames Wright @param[in] create_qf Function to create `CeedQFunction`
29377aa5ad7SJames Wright @param[in] add_op Function to create and add `CeedOperator` to composite `CeedOperator`
29477aa5ad7SJames Wright **/
BCDefinitionSetIFunction(BCDefinition bc_def,BCDefinitionCreateQFunction create_qf,BCDefinitionAddIFunctionOperator add_op)29577aa5ad7SJames Wright PetscErrorCode BCDefinitionSetIFunction(BCDefinition bc_def, BCDefinitionCreateQFunction create_qf, BCDefinitionAddIFunctionOperator add_op) {
29677aa5ad7SJames Wright PetscFunctionBeginUser;
29796f347c2SJames Wright PetscValidHeaderSpecific(bc_def, BC_DEFINITION_CLASSID, 1);
29877aa5ad7SJames Wright bc_def->CreateIFunctionQF = create_qf;
29977aa5ad7SJames Wright bc_def->AddIFunctionOperator = add_op;
30077aa5ad7SJames Wright PetscFunctionReturn(PETSC_SUCCESS);
30177aa5ad7SJames Wright }
30277aa5ad7SJames Wright
30377aa5ad7SJames Wright /**
30477aa5ad7SJames Wright @brief Add function pointers to create `CeedQFunction` and `CeedOperator` for IJacobian of boundary condition
30577aa5ad7SJames Wright
30677aa5ad7SJames Wright @param[in,out] bc_def `BCDefinition` to add function pointers to
30777aa5ad7SJames Wright @param[in] create_qf Function to create `CeedQFunction`
30877aa5ad7SJames Wright @param[in] add_op Function to create and add `CeedOperator` to composite `CeedOperator`
30977aa5ad7SJames Wright **/
BCDefinitionSetIJacobian(BCDefinition bc_def,BCDefinitionCreateQFunction create_qf,BCDefinitionAddIJacobianOperator add_op)31077aa5ad7SJames Wright PetscErrorCode BCDefinitionSetIJacobian(BCDefinition bc_def, BCDefinitionCreateQFunction create_qf, BCDefinitionAddIJacobianOperator add_op) {
31177aa5ad7SJames Wright PetscFunctionBeginUser;
31296f347c2SJames Wright PetscValidHeaderSpecific(bc_def, BC_DEFINITION_CLASSID, 1);
31377aa5ad7SJames Wright bc_def->CreateIJacobianQF = create_qf;
31477aa5ad7SJames Wright bc_def->AddIJacobianOperator = add_op;
31577aa5ad7SJames Wright PetscFunctionReturn(PETSC_SUCCESS);
31677aa5ad7SJames Wright }
31777aa5ad7SJames Wright
31877aa5ad7SJames Wright /**
31977aa5ad7SJames Wright @brief Add operators (IFunction, IJacobian) to composite operator
32077aa5ad7SJames Wright
32177aa5ad7SJames Wright This loops over orientations for each face label specified by `bc_def` and adds the IFunction and IJacobian operator to respective composite operator.
32277aa5ad7SJames Wright
32377aa5ad7SJames Wright @param[in] bc_def `BCDefinition` from which operators are created and added
32477aa5ad7SJames Wright @param[in,out] op_ifunc Composite operator for IFunction operators to be added to
32577aa5ad7SJames Wright @param[in,out] op_ijac Composite operator for IJacobian operators to be added to
32677aa5ad7SJames Wright **/
BCDefinitionAddOperators(BCDefinition bc_def,CeedOperator op_ifunc,CeedOperator op_ijac)32777aa5ad7SJames Wright PetscErrorCode BCDefinitionAddOperators(BCDefinition bc_def, CeedOperator op_ifunc, CeedOperator op_ijac) {
32877aa5ad7SJames Wright Ceed ceed = CeedOperatorReturnCeed(op_ifunc);
32977aa5ad7SJames Wright CeedQFunction qf_ifunction, qf_ijacobian;
33077aa5ad7SJames Wright DMLabel face_sets_label;
33177aa5ad7SJames Wright PetscInt num_face_set_values;
33277aa5ad7SJames Wright const PetscInt *face_set_values;
33377aa5ad7SJames Wright
33477aa5ad7SJames Wright PetscFunctionBeginUser;
33596f347c2SJames Wright PetscValidHeaderSpecific(bc_def, BC_DEFINITION_CLASSID, 1);
33677aa5ad7SJames Wright if (!bc_def->CreateIFunctionQF || !bc_def->AddIFunctionOperator) PetscFunctionReturn(PETSC_SUCCESS);
337ea091b8eSJames Wright PetscBool add_ijac = (!bc_def->CreateIJacobianQF || !bc_def->AddIJacobianOperator || !op_ijac) ? PETSC_FALSE : PETSC_TRUE;
33877aa5ad7SJames Wright PetscCheck(bc_def->dm, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "BCDefinition must have DM set using BCDefinitionSetDM()");
33977aa5ad7SJames Wright
34077aa5ad7SJames Wright PetscCall(bc_def->CreateIFunctionQF(bc_def, &qf_ifunction));
34177aa5ad7SJames Wright if (add_ijac) PetscCall(bc_def->CreateIJacobianQF(bc_def, &qf_ijacobian));
34277aa5ad7SJames Wright
34377aa5ad7SJames Wright PetscCall(DMGetLabel(bc_def->dm, "Face Sets", &face_sets_label));
34477aa5ad7SJames Wright PetscCall(BCDefinitionGetInfo(bc_def, NULL, &num_face_set_values, &face_set_values));
34577aa5ad7SJames Wright for (PetscInt f = 0; f < num_face_set_values; f++) {
34677aa5ad7SJames Wright DMLabel face_orientation_label;
34777aa5ad7SJames Wright PetscInt num_orientations_values, *orientation_values;
34877aa5ad7SJames Wright
34977aa5ad7SJames Wright {
35077aa5ad7SJames Wright char *face_orientation_label_name;
35177aa5ad7SJames Wright
35277aa5ad7SJames Wright PetscCall(DMPlexCreateFaceLabel(bc_def->dm, face_set_values[f], &face_orientation_label_name));
35377aa5ad7SJames Wright PetscCall(DMGetLabel(bc_def->dm, face_orientation_label_name, &face_orientation_label));
35477aa5ad7SJames Wright PetscCall(PetscFree(face_orientation_label_name));
35577aa5ad7SJames Wright }
35677aa5ad7SJames Wright PetscCall(DMLabelCreateGlobalValueArray(bc_def->dm, face_orientation_label, &num_orientations_values, &orientation_values));
35777aa5ad7SJames Wright for (PetscInt o = 0; o < num_orientations_values; o++) {
35877aa5ad7SJames Wright CeedOperator sub_op_ifunc;
35977aa5ad7SJames Wright PetscInt orientation = orientation_values[o];
36077aa5ad7SJames Wright
36177aa5ad7SJames Wright PetscCall(bc_def->AddIFunctionOperator(bc_def, face_orientation_label, orientation, qf_ifunction, op_ifunc, &sub_op_ifunc));
36277aa5ad7SJames Wright if (add_ijac) PetscCall(bc_def->AddIJacobianOperator(bc_def, sub_op_ifunc, face_orientation_label, orientation, qf_ijacobian, op_ijac));
36377aa5ad7SJames Wright PetscCallCeed(ceed, CeedOperatorDestroy(&sub_op_ifunc));
36477aa5ad7SJames Wright }
36577aa5ad7SJames Wright PetscCall(PetscFree(orientation_values));
36677aa5ad7SJames Wright }
36777aa5ad7SJames Wright PetscCallCeed(ceed, CeedQFunctionDestroy(&qf_ifunction));
36877aa5ad7SJames Wright if (add_ijac) PetscCallCeed(ceed, CeedQFunctionDestroy(&qf_ijacobian));
36977aa5ad7SJames Wright PetscFunctionReturn(PETSC_SUCCESS);
37077aa5ad7SJames Wright PetscFunctionReturn(PETSC_SUCCESS);
37177aa5ad7SJames Wright }
372