This is an internal macro which switches between MPI_CXX_BOOL and MPI_C_BOOL if MPI_CXX_BOOL happens to not be defined (ex.: in Windows).
113 lines
2.9 KiB
C++
113 lines
2.9 KiB
C++
// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
|
|
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
|
|
// LICENSE and NOTICE for details. LLNL-CODE-806117.
|
|
//
|
|
// This file is part of the MFEM library. For more information and source code
|
|
// availability visit https://mfem.org.
|
|
//
|
|
// MFEM is free software; you can redistribute it and/or modify it under the
|
|
// terms of the BSD-3 license. We welcome feedback and contributions, see file
|
|
// CONTRIBUTING.md for details.
|
|
|
|
#include "../config/config.hpp"
|
|
|
|
#ifdef MFEM_USE_MPI
|
|
|
|
#include "fem.hpp"
|
|
|
|
namespace mfem
|
|
{
|
|
|
|
void ParLinearForm::Update(ParFiniteElementSpace *pf)
|
|
{
|
|
if (pf) { pfes = pf; }
|
|
LinearForm::Update(pfes);
|
|
}
|
|
|
|
void ParLinearForm::Update(ParFiniteElementSpace *pf, Vector &v, int v_offset)
|
|
{
|
|
pfes = pf;
|
|
LinearForm::Update(pf,v,v_offset);
|
|
}
|
|
|
|
void ParLinearForm::MakeRef(FiniteElementSpace *f, Vector &v, int v_offset)
|
|
{
|
|
LinearForm::MakeRef(f, v, v_offset);
|
|
pfes = dynamic_cast<ParFiniteElementSpace*>(f);
|
|
MFEM_ASSERT(pfes != NULL, "not a ParFiniteElementSpace");
|
|
}
|
|
|
|
void ParLinearForm::MakeRef(ParFiniteElementSpace *pf, Vector &v, int v_offset)
|
|
{
|
|
LinearForm::MakeRef(pf, v, v_offset);
|
|
pfes = pf;
|
|
}
|
|
|
|
void ParLinearForm::Assemble()
|
|
{
|
|
LinearForm::Assemble();
|
|
|
|
if (interior_face_integs.Size())
|
|
{
|
|
pfes->ExchangeFaceNbrData();
|
|
AssembleSharedFaces();
|
|
}
|
|
}
|
|
|
|
bool ParLinearForm::SupportsDevice() const
|
|
{
|
|
bool parallel;
|
|
bool local = LinearForm::SupportsDevice();
|
|
MPI_Allreduce(&local, ¶llel, 1, MFEM_MPI_CXX_BOOL, MPI_LAND,
|
|
pfes->GetComm());
|
|
return parallel;
|
|
}
|
|
|
|
void ParLinearForm::AssembleSharedFaces()
|
|
{
|
|
Array<int> vdofs;
|
|
Vector elemvect;
|
|
|
|
if (interior_face_integs.Size())
|
|
{
|
|
ParMesh *pmesh = pfes->GetParMesh();
|
|
for (int k = 0; k < interior_face_integs.Size(); k++)
|
|
{
|
|
for (int i = 0; i < pmesh->GetNSharedFaces(); i++)
|
|
{
|
|
FaceElementTransformations *tr = NULL;
|
|
tr = pmesh->GetSharedFaceTransformations(i);
|
|
|
|
if (tr != NULL)
|
|
{
|
|
int Elem2Nbr = tr->Elem2No - pmesh->GetNE();
|
|
fes -> GetElementVDofs (tr -> Elem1No, vdofs);
|
|
interior_face_integs[k]->
|
|
AssembleRHSElementVect(*fes->GetFE(tr->Elem1No),
|
|
*pfes->GetFaceNbrFE(Elem2Nbr),
|
|
*tr, elemvect);
|
|
AddElementVector (vdofs, elemvect);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ParLinearForm::ParallelAssemble(Vector &tv)
|
|
{
|
|
const Operator* prolong = pfes->GetProlongationMatrix();
|
|
prolong->MultTranspose(*this, tv);
|
|
}
|
|
|
|
HypreParVector *ParLinearForm::ParallelAssemble()
|
|
{
|
|
HypreParVector *tv = pfes->NewTrueDofVector();
|
|
const Operator* prolong = pfes->GetProlongationMatrix();
|
|
prolong->MultTranspose(*this, *tv);
|
|
return tv;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|