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 */ 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