xref: /honee/src/inverse_multiplicity.c (revision 7ecf6641c340caefd7fa9f7fc7a6efebf89ae19d)
1*ae2b091fSJames Wright // SPDX-FileCopyrightText: Copyright (c) 2017-2024, HONEE contributors.
2*ae2b091fSJames Wright // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause
35930f037SJames Wright 
45930f037SJames Wright #include "../qfunctions/inverse_multiplicity.h"
5149fb536SJames Wright #include <navierstokes.h>
65930f037SJames Wright 
75930f037SJames Wright /**
85930f037SJames Wright  * @brief Get the inverse of the node multiplicity
95930f037SJames Wright  *
105930f037SJames Wright  * Local multiplicity concerns only the number of elements associated with a node in the current rank's partition.
115930f037SJames Wright  * Global multiplicity is the multiplicity for the global mesh, including periodicity.
125930f037SJames Wright  *
135930f037SJames Wright  * @param[in]  ceed                        `Ceed` object for the output `CeedVector` and `CeedElemRestriction`
145930f037SJames Wright  * @param[in]  dm                          `DM` for the grid
155930f037SJames Wright  * @param[in]  domain_label                `DMLabel` for `DMPlex` domain
165930f037SJames Wright  * @param[in]  label_value                 Stratum value
175930f037SJames Wright  * @param[in]  height                      Height of `DMPlex` topology
185930f037SJames Wright  * @param[in]  dm_field                    Index of `DMPlex` field
195930f037SJames Wright  * @param[in]  get_global_multiplicity     Whether the multiplicity should be global or local
205930f037SJames Wright  * @param[out] elem_restr_inv_multiplicity `CeedElemRestriction` needed to use the multiplicity vector
215930f037SJames Wright  * @param[out] inv_multiplicity            `CeedVector` containing the inverse of the multiplicity
225930f037SJames Wright  */
GetInverseMultiplicity(Ceed ceed,DM dm,DMLabel domain_label,PetscInt label_value,PetscInt height,PetscInt dm_field,PetscBool get_global_multiplicity,CeedElemRestriction * elem_restr_inv_multiplicity,CeedVector * inv_multiplicity)235930f037SJames Wright PetscErrorCode GetInverseMultiplicity(Ceed ceed, DM dm, DMLabel domain_label, PetscInt label_value, PetscInt height, PetscInt dm_field,
245930f037SJames Wright                                       PetscBool get_global_multiplicity, CeedElemRestriction *elem_restr_inv_multiplicity,
255930f037SJames Wright                                       CeedVector *inv_multiplicity) {
265930f037SJames Wright   Vec                 Multiplicity, Multiplicity_loc;
275930f037SJames Wright   PetscMemType        m_mem_type;
285930f037SJames Wright   CeedVector          multiplicity;
295930f037SJames Wright   CeedQFunction       qf_multiplicity;
305930f037SJames Wright   CeedOperator        op_multiplicity;
315930f037SJames Wright   CeedInt             num_comp;
325930f037SJames Wright   CeedElemRestriction elem_restr;
335930f037SJames Wright 
345930f037SJames Wright   PetscFunctionBeginUser;
355930f037SJames Wright   PetscCall(DMPlexCeedElemRestrictionCollocatedCreate(ceed, dm, domain_label, label_value, height, 1, elem_restr_inv_multiplicity));
365930f037SJames Wright   PetscCallCeed(ceed, CeedElemRestrictionCreateVector(*elem_restr_inv_multiplicity, inv_multiplicity, NULL));
375930f037SJames Wright 
385930f037SJames Wright   PetscCall(DMPlexCeedElemRestrictionCreate(ceed, dm, domain_label, label_value, height, dm_field, &elem_restr));
395930f037SJames Wright   PetscCallCeed(ceed, CeedElemRestrictionGetNumComponents(elem_restr, &num_comp));
405930f037SJames Wright   PetscCallCeed(ceed, CeedElemRestrictionCreateVector(elem_restr, &multiplicity, NULL));
415930f037SJames Wright 
425930f037SJames Wright   if (get_global_multiplicity) {
435930f037SJames Wright     // In order to get global multiplicity, we need to run through DMLocalToGlobal -> DMGlobalToLocal.
445930f037SJames Wright     PetscCall(DMGetLocalVector(dm, &Multiplicity_loc));
455930f037SJames Wright     PetscCall(DMGetGlobalVector(dm, &Multiplicity));
465930f037SJames Wright 
475930f037SJames Wright     PetscCall(VecPetscToCeed(Multiplicity_loc, &m_mem_type, multiplicity));
485930f037SJames Wright     PetscCallCeed(ceed, CeedElemRestrictionGetMultiplicity(elem_restr, multiplicity));
495930f037SJames Wright     PetscCall(VecCeedToPetsc(multiplicity, m_mem_type, Multiplicity_loc));
505930f037SJames Wright     PetscCall(VecZeroEntries(Multiplicity));
515930f037SJames Wright     PetscCall(DMLocalToGlobal(dm, Multiplicity_loc, ADD_VALUES, Multiplicity));
525930f037SJames Wright     PetscCall(DMGlobalToLocal(dm, Multiplicity, INSERT_VALUES, Multiplicity_loc));
535930f037SJames Wright     PetscCall(VecPetscToCeed(Multiplicity_loc, &m_mem_type, multiplicity));
545930f037SJames Wright   } else {
555930f037SJames Wright     PetscCallCeed(ceed, CeedElemRestrictionGetMultiplicity(elem_restr, multiplicity));
565930f037SJames Wright   }
575930f037SJames Wright 
585930f037SJames Wright   PetscCallCeed(ceed, CeedQFunctionCreateInterior(ceed, 1, InverseMultiplicity, InverseMultiplicity_loc, &qf_multiplicity));
595930f037SJames Wright   PetscCallCeed(ceed, CeedQFunctionAddInput(qf_multiplicity, "multiplicity", num_comp, CEED_EVAL_NONE));
605930f037SJames Wright   PetscCallCeed(ceed, CeedQFunctionAddOutput(qf_multiplicity, "inverse multiplicity", 1, CEED_EVAL_NONE));
615930f037SJames Wright 
625930f037SJames Wright   PetscCallCeed(ceed, CeedOperatorCreate(ceed, qf_multiplicity, NULL, NULL, &op_multiplicity));
635930f037SJames Wright   PetscCallCeed(ceed, CeedOperatorSetName(op_multiplicity, "InverseMultiplicity"));
645930f037SJames Wright   PetscCallCeed(ceed, CeedOperatorSetField(op_multiplicity, "multiplicity", elem_restr, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE));
655930f037SJames Wright   PetscCallCeed(ceed,
665930f037SJames Wright                 CeedOperatorSetField(op_multiplicity, "inverse multiplicity", *elem_restr_inv_multiplicity, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE));
675930f037SJames Wright 
685930f037SJames Wright   PetscCallCeed(ceed, CeedOperatorApply(op_multiplicity, multiplicity, *inv_multiplicity, CEED_REQUEST_IMMEDIATE));
695930f037SJames Wright 
705930f037SJames Wright   if (get_global_multiplicity) {
715930f037SJames Wright     PetscCall(VecCeedToPetsc(multiplicity, m_mem_type, Multiplicity_loc));
725930f037SJames Wright     PetscCall(DMRestoreLocalVector(dm, &Multiplicity_loc));
735930f037SJames Wright     PetscCall(DMRestoreGlobalVector(dm, &Multiplicity));
745930f037SJames Wright   }
755930f037SJames Wright   PetscCallCeed(ceed, CeedVectorDestroy(&multiplicity));
765930f037SJames Wright   PetscCallCeed(ceed, CeedElemRestrictionDestroy(&elem_restr));
775930f037SJames Wright   PetscCallCeed(ceed, CeedQFunctionDestroy(&qf_multiplicity));
785930f037SJames Wright   PetscCallCeed(ceed, CeedOperatorDestroy(&op_multiplicity));
795930f037SJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
805930f037SJames Wright }
81