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