xref: /libCEED/examples/fluids/src/inverse_multiplicity.c (revision d4cc18453651bd0f94c1a2e078b2646a92dafdcc)
1*9ba83ac0SJeremy L Thompson // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors.
23a10b0eeSJames Wright // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
33a10b0eeSJames Wright //
43a10b0eeSJames Wright // SPDX-License-Identifier: BSD-2-Clause
53a10b0eeSJames Wright //
63a10b0eeSJames Wright // This file is part of CEED:  http://github.com/ceed
73a10b0eeSJames Wright 
83a10b0eeSJames Wright #include "../qfunctions/inverse_multiplicity.h"
93a10b0eeSJames Wright #include "../navierstokes.h"
103a10b0eeSJames Wright 
113a10b0eeSJames Wright /**
123a10b0eeSJames Wright  * @brief Get the inverse of the node multiplicity
133a10b0eeSJames Wright  *
143a10b0eeSJames Wright  * Local multiplicity concerns only the number of elements associated with a node in the current rank's partition.
153a10b0eeSJames Wright  * Global multiplicity is the multiplicity for the global mesh, including periodicity.
163a10b0eeSJames Wright  *
173a10b0eeSJames Wright  * @param[in]  ceed                        `Ceed` object for the output `CeedVector` and `CeedElemRestriction`
183a10b0eeSJames Wright  * @param[in]  dm                          `DM` for the grid
193a10b0eeSJames Wright  * @param[in]  domain_label                `DMLabel` for `DMPlex` domain
203a10b0eeSJames Wright  * @param[in]  label_value                 Stratum value
213a10b0eeSJames Wright  * @param[in]  height                      Height of `DMPlex` topology
223a10b0eeSJames Wright  * @param[in]  dm_field                    Index of `DMPlex` field
233a10b0eeSJames Wright  * @param[in]  get_global_multiplicity     Whether the multiplicity should be global or local
243a10b0eeSJames Wright  * @param[out] elem_restr_inv_multiplicity `CeedElemRestriction` needed to use the multiplicity vector
253a10b0eeSJames Wright  * @param[out] inv_multiplicity            `CeedVector` containing the inverse of the multiplicity
263a10b0eeSJames 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)273a10b0eeSJames Wright PetscErrorCode GetInverseMultiplicity(Ceed ceed, DM dm, DMLabel domain_label, PetscInt label_value, PetscInt height, PetscInt dm_field,
283a10b0eeSJames Wright                                       PetscBool get_global_multiplicity, CeedElemRestriction *elem_restr_inv_multiplicity,
293a10b0eeSJames Wright                                       CeedVector *inv_multiplicity) {
303a10b0eeSJames Wright   Vec                 Multiplicity, Multiplicity_loc;
313a10b0eeSJames Wright   PetscMemType        m_mem_type;
323a10b0eeSJames Wright   CeedVector          multiplicity;
333a10b0eeSJames Wright   CeedQFunction       qf_multiplicity;
343a10b0eeSJames Wright   CeedOperator        op_multiplicity;
353a10b0eeSJames Wright   CeedInt             num_comp;
363a10b0eeSJames Wright   CeedElemRestriction elem_restr;
373a10b0eeSJames Wright 
383a10b0eeSJames Wright   PetscFunctionBeginUser;
393a10b0eeSJames Wright 
403a10b0eeSJames Wright   PetscCall(DMPlexCeedElemRestrictionCollocatedCreate(ceed, dm, domain_label, label_value, height, 1, elem_restr_inv_multiplicity));
413a10b0eeSJames Wright   PetscCallCeed(ceed, CeedElemRestrictionCreateVector(*elem_restr_inv_multiplicity, inv_multiplicity, NULL));
423a10b0eeSJames Wright 
433a10b0eeSJames Wright   PetscCall(DMPlexCeedElemRestrictionCreate(ceed, dm, domain_label, label_value, height, dm_field, &elem_restr));
443a10b0eeSJames Wright   PetscCallCeed(ceed, CeedElemRestrictionGetNumComponents(elem_restr, &num_comp));
453a10b0eeSJames Wright   PetscCallCeed(ceed, CeedElemRestrictionCreateVector(elem_restr, &multiplicity, NULL));
463a10b0eeSJames Wright 
473a10b0eeSJames Wright   if (get_global_multiplicity) {
483a10b0eeSJames Wright     // In order to get global multiplicity, we need to run through DMLocalToGlobal -> DMGlobalToLocal.
493a10b0eeSJames Wright     PetscCall(DMGetLocalVector(dm, &Multiplicity_loc));
503a10b0eeSJames Wright     PetscCall(DMGetGlobalVector(dm, &Multiplicity));
513a10b0eeSJames Wright 
523a10b0eeSJames Wright     PetscCall(VecPetscToCeed(Multiplicity_loc, &m_mem_type, multiplicity));
533a10b0eeSJames Wright     PetscCallCeed(ceed, CeedElemRestrictionGetMultiplicity(elem_restr, multiplicity));
543a10b0eeSJames Wright     PetscCall(VecCeedToPetsc(multiplicity, m_mem_type, Multiplicity_loc));
553a10b0eeSJames Wright     PetscCall(VecZeroEntries(Multiplicity));
563a10b0eeSJames Wright     PetscCall(DMLocalToGlobal(dm, Multiplicity_loc, ADD_VALUES, Multiplicity));
573a10b0eeSJames Wright     PetscCall(DMGlobalToLocal(dm, Multiplicity, INSERT_VALUES, Multiplicity_loc));
583a10b0eeSJames Wright     PetscCall(VecPetscToCeed(Multiplicity_loc, &m_mem_type, multiplicity));
593a10b0eeSJames Wright   } else {
603a10b0eeSJames Wright     PetscCallCeed(ceed, CeedElemRestrictionGetMultiplicity(elem_restr, multiplicity));
613a10b0eeSJames Wright   }
623a10b0eeSJames Wright 
633a10b0eeSJames Wright   PetscCallCeed(ceed, CeedQFunctionCreateInterior(ceed, 1, InverseMultiplicity, InverseMultiplicity_loc, &qf_multiplicity));
643a10b0eeSJames Wright   PetscCallCeed(ceed, CeedQFunctionAddInput(qf_multiplicity, "multiplicity", num_comp, CEED_EVAL_NONE));
653a10b0eeSJames Wright   PetscCallCeed(ceed, CeedQFunctionAddOutput(qf_multiplicity, "inverse multiplicity", 1, CEED_EVAL_NONE));
663a10b0eeSJames Wright 
673a10b0eeSJames Wright   PetscCallCeed(ceed, CeedOperatorCreate(ceed, qf_multiplicity, NULL, NULL, &op_multiplicity));
683a10b0eeSJames Wright   PetscCallCeed(ceed, CeedOperatorSetName(op_multiplicity, "InverseMultiplicity"));
693a10b0eeSJames Wright   PetscCallCeed(ceed, CeedOperatorSetField(op_multiplicity, "multiplicity", elem_restr, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE));
703a10b0eeSJames Wright   PetscCallCeed(ceed,
713a10b0eeSJames Wright                 CeedOperatorSetField(op_multiplicity, "inverse multiplicity", *elem_restr_inv_multiplicity, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE));
723a10b0eeSJames Wright 
733a10b0eeSJames Wright   PetscCallCeed(ceed, CeedOperatorApply(op_multiplicity, multiplicity, *inv_multiplicity, CEED_REQUEST_IMMEDIATE));
743a10b0eeSJames Wright 
753a10b0eeSJames Wright   if (get_global_multiplicity) {
763a10b0eeSJames Wright     PetscCall(VecCeedToPetsc(multiplicity, m_mem_type, Multiplicity_loc));
773a10b0eeSJames Wright     PetscCall(DMRestoreLocalVector(dm, &Multiplicity_loc));
783a10b0eeSJames Wright     PetscCall(DMRestoreGlobalVector(dm, &Multiplicity));
793a10b0eeSJames Wright   }
803a10b0eeSJames Wright   PetscCallCeed(ceed, CeedVectorDestroy(&multiplicity));
813a10b0eeSJames Wright   PetscCallCeed(ceed, CeedElemRestrictionDestroy(&elem_restr));
823a10b0eeSJames Wright   PetscCallCeed(ceed, CeedQFunctionDestroy(&qf_multiplicity));
833a10b0eeSJames Wright   PetscCallCeed(ceed, CeedOperatorDestroy(&op_multiplicity));
843a10b0eeSJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
853a10b0eeSJames Wright }
86