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> 509240e0aSJames Wright #include <petsc/private/petscimpl.h> 6487a3b6eSJames Wright 7487a3b6eSJames Wright /** 8487a3b6eSJames Wright @brief Create `BCDefinition` 9487a3b6eSJames Wright 10487a3b6eSJames Wright @param[in] name Name of the boundary condition 11487a3b6eSJames Wright @param[in] num_label_values Number of `DMLabel` values 12487a3b6eSJames Wright @param[in] label_values Array of label values that define the boundaries controlled by the `BCDefinition`, size `num_label_values` 13487a3b6eSJames Wright @param[out] bc_def The new `BCDefinition` 14487a3b6eSJames Wright **/ 15487a3b6eSJames Wright PetscErrorCode BCDefinitionCreate(const char *name, PetscInt num_label_values, PetscInt label_values[], BCDefinition *bc_def) { 16487a3b6eSJames Wright PetscFunctionBeginUser; 17487a3b6eSJames Wright PetscCall(PetscNew(bc_def)); 18487a3b6eSJames Wright 19487a3b6eSJames Wright PetscCall(PetscStrallocpy(name, &(*bc_def)->name)); 20487a3b6eSJames Wright (*bc_def)->num_label_values = num_label_values; 21487a3b6eSJames Wright PetscCall(PetscMalloc1(num_label_values, &(*bc_def)->label_values)); 22487a3b6eSJames Wright for (PetscInt i = 0; i < num_label_values; i++) (*bc_def)->label_values[i] = label_values[i]; 23487a3b6eSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 24487a3b6eSJames Wright } 25487a3b6eSJames Wright 26487a3b6eSJames Wright /** 27487a3b6eSJames Wright @brief Get base information for `BCDefinition` 28487a3b6eSJames Wright 29487a3b6eSJames Wright @param[in] bc_def `BCDefinition` to get information from 30487a3b6eSJames Wright @param[out] name Name of the `BCDefinition` 31487a3b6eSJames Wright @param[out] num_label_values Number of `DMLabel` values 32487a3b6eSJames Wright @param[out] label_values Array of label values that define the boundaries controlled by the `BCDefinition`, size `num_label_values` 33487a3b6eSJames Wright **/ 34487a3b6eSJames Wright PetscErrorCode BCDefinitionGetInfo(BCDefinition bc_def, const char *name[], PetscInt *num_label_values, const PetscInt *label_values[]) { 35487a3b6eSJames Wright PetscFunctionBeginUser; 36487a3b6eSJames Wright if (name) *name = bc_def->name; 37487a3b6eSJames Wright if (label_values) { 38487a3b6eSJames Wright *num_label_values = bc_def->num_label_values; 39487a3b6eSJames Wright *label_values = bc_def->label_values; 40487a3b6eSJames Wright } 41487a3b6eSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 42487a3b6eSJames Wright } 43487a3b6eSJames Wright 44487a3b6eSJames Wright /** 45487a3b6eSJames Wright @brief Destory a `BCDefinition` object 46487a3b6eSJames Wright 47487a3b6eSJames Wright @param[in,out] bc_def `BCDefinition` to be destroyed 48487a3b6eSJames Wright **/ 49487a3b6eSJames Wright PetscErrorCode BCDefinitionDestroy(BCDefinition *bc_def) { 50*2e678684SJames Wright BCDefinition bc_def_ = *bc_def; 51487a3b6eSJames Wright PetscFunctionBeginUser; 52*2e678684SJames Wright if (bc_def_->name) PetscCall(PetscFree(bc_def_->name)); 53*2e678684SJames Wright if (bc_def_->label_values) PetscCall(PetscFree(bc_def_->label_values)); 54*2e678684SJames Wright if (bc_def_->essential_comps) PetscCall(PetscFree(bc_def_->essential_comps)); 55*2e678684SJames Wright if (bc_def_->dm) PetscCall(DMDestroy(&bc_def_->dm)); 56*2e678684SJames Wright if (bc_def_->DestroyCtx) PetscCall((*(bc_def_->DestroyCtx))(&bc_def_->ctx)); 57*2e678684SJames Wright PetscCall(PetscFree(bc_def_)); 58487a3b6eSJames Wright *bc_def = NULL; 59487a3b6eSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 60487a3b6eSJames Wright } 61487a3b6eSJames Wright 62487a3b6eSJames Wright /** 63487a3b6eSJames Wright @brief Set `DM_BC_ESSENTIAL` boundary condition values 64487a3b6eSJames Wright 65487a3b6eSJames Wright @param[in,out] bc_def `BCDefinition` to set values to 66487a3b6eSJames Wright @param[in] num_essential_comps Number of components to set 67487a3b6eSJames Wright @param[in] essential_comps Array of components to set, size `num_essential_comps` 68487a3b6eSJames Wright **/ 69487a3b6eSJames Wright PetscErrorCode BCDefinitionSetEssential(BCDefinition bc_def, PetscInt num_essential_comps, PetscInt essential_comps[]) { 70487a3b6eSJames Wright PetscFunctionBeginUser; 71487a3b6eSJames Wright bc_def->num_essential_comps = num_essential_comps; 72487a3b6eSJames Wright PetscCall(PetscMalloc1(num_essential_comps, &bc_def->essential_comps)); 73487a3b6eSJames Wright PetscCall(PetscArraycpy(bc_def->essential_comps, essential_comps, num_essential_comps)); 74487a3b6eSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 75487a3b6eSJames Wright } 76487a3b6eSJames Wright 77487a3b6eSJames Wright /** 78487a3b6eSJames Wright @brief Get `DM_BC_ESSENTIAL` boundary condition values 79487a3b6eSJames Wright 80487a3b6eSJames Wright @param[in] bc_def `BCDefinition` to set values to 81487a3b6eSJames Wright @param[out] num_essential_comps Number of components to set 82487a3b6eSJames Wright @param[out] essential_comps Array of components to set, size `num_essential_comps` 83487a3b6eSJames Wright **/ 84487a3b6eSJames Wright PetscErrorCode BCDefinitionGetEssential(BCDefinition bc_def, PetscInt *num_essential_comps, const PetscInt *essential_comps[]) { 85487a3b6eSJames Wright PetscFunctionBeginUser; 86487a3b6eSJames Wright *num_essential_comps = bc_def->num_essential_comps; 87487a3b6eSJames Wright *essential_comps = bc_def->essential_comps; 88487a3b6eSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 89487a3b6eSJames Wright } 90487a3b6eSJames Wright 91487a3b6eSJames Wright #define LABEL_ARRAY_SIZE 256 92487a3b6eSJames Wright 93487a3b6eSJames Wright // @brief See `PetscOptionsBCDefinition` 94ddf6e248SJames Wright PetscErrorCode PetscOptionsBCDefinition_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], 95487a3b6eSJames Wright const char name[], BCDefinition *bc_def, PetscBool *set) { 96487a3b6eSJames Wright PetscInt num_label_values = LABEL_ARRAY_SIZE, label_values[LABEL_ARRAY_SIZE] = {0}; 97487a3b6eSJames Wright 98487a3b6eSJames Wright PetscFunctionBeginUser; 99487a3b6eSJames Wright PetscCall(PetscOptionsIntArray(opt, text, man, label_values, &num_label_values, set)); 100487a3b6eSJames Wright if (num_label_values > 0) { 101487a3b6eSJames Wright PetscCall(BCDefinitionCreate(name, num_label_values, label_values, bc_def)); 102487a3b6eSJames Wright } else { 103487a3b6eSJames Wright *bc_def = NULL; 104487a3b6eSJames Wright } 105487a3b6eSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 106487a3b6eSJames Wright } 10709240e0aSJames Wright 10809240e0aSJames Wright /** 10909240e0aSJames Wright @brief Set `DM` for BCDefinition 11009240e0aSJames Wright 11109240e0aSJames Wright @param[in,out] bc_def `BCDefinition` to add `dm` to 11209240e0aSJames Wright @param[in] dm `DM` to assign to BCDefinition, or `NULL` to remove `DM` 11309240e0aSJames Wright **/ 11409240e0aSJames Wright PetscErrorCode BCDefinitionSetDM(BCDefinition bc_def, DM dm) { 11509240e0aSJames Wright PetscFunctionBeginUser; 11609240e0aSJames Wright if (bc_def->dm) PetscCall(DMDestroy(&bc_def->dm)); 11709240e0aSJames Wright if (dm) { 11809240e0aSJames Wright PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 11909240e0aSJames Wright PetscCall(PetscObjectReference((PetscObject)dm)); 12009240e0aSJames Wright bc_def->dm = dm; 12109240e0aSJames Wright } 12209240e0aSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 12309240e0aSJames Wright } 12409240e0aSJames Wright 12509240e0aSJames Wright /** 12609240e0aSJames Wright @brief Get `DM` assigned to BCDefinition 12709240e0aSJames Wright 12809240e0aSJames Wright @param[in] bc_def `BCDefinition` to get `dm` from 12909240e0aSJames Wright @param[out] dm `DM` assigned to BCDefinition 13009240e0aSJames Wright **/ 13109240e0aSJames Wright PetscErrorCode BCDefinitionGetDM(BCDefinition bc_def, DM *dm) { 13209240e0aSJames Wright PetscFunctionBeginUser; 13309240e0aSJames Wright PetscAssertPointer(dm, 2); 13409240e0aSJames Wright *dm = bc_def->dm; 13509240e0aSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 13609240e0aSJames Wright } 137*2e678684SJames Wright 138*2e678684SJames Wright /** 139*2e678684SJames Wright @brief Set custom context struct for use in BCDefinition 140*2e678684SJames Wright 141*2e678684SJames Wright @param[in,out] bc_def `BCDefinition` to add `ctx` to 142*2e678684SJames Wright @param[in] destroy_ctx Optional function pointer that destroys the user context on `BCDefinitionDestroy()` 143*2e678684SJames Wright @param[in] ctx Pointer to context struct 144*2e678684SJames Wright **/ 145*2e678684SJames Wright PetscErrorCode BCDefinitionSetContext(BCDefinition bc_def, PetscCtxDestroyFn *destroy_ctx, void *ctx) { 146*2e678684SJames Wright PetscFunctionBeginUser; 147*2e678684SJames Wright if (bc_def->DestroyCtx) PetscCall((*(bc_def->DestroyCtx))(&bc_def->ctx)); 148*2e678684SJames Wright bc_def->ctx = ctx; 149*2e678684SJames Wright bc_def->DestroyCtx = destroy_ctx; 150*2e678684SJames Wright PetscFunctionReturn(PETSC_SUCCESS); 151*2e678684SJames Wright } 152*2e678684SJames Wright 153*2e678684SJames Wright /** 154*2e678684SJames Wright @brief Set custom context struct for use in BCDefinition 155*2e678684SJames Wright 156*2e678684SJames Wright @param[in] bc_def `BCDefinition` to get `ctx` from 157*2e678684SJames Wright @param[out] ctx Pointer to context struct 158*2e678684SJames Wright **/ 159*2e678684SJames Wright PetscErrorCode BCDefinitionGetContext(BCDefinition bc_def, void *ctx) { 160*2e678684SJames Wright PetscFunctionBeginUser; 161*2e678684SJames Wright PetscAssertPointer(ctx, 2); 162*2e678684SJames Wright *(void **)ctx = bc_def->ctx; 163*2e678684SJames Wright PetscFunctionReturn(PETSC_SUCCESS); 164*2e678684SJames Wright } 165