// Copyright (c) 2010-2023, 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 "pweakform.hpp" #ifdef MFEM_USE_MPI namespace mfem { void ParDPGWeakForm::FillEssTdofLists(const Array & ess_tdof_list) { int j; for (int i = 0; i tdof) { break; } } ess_tdofs[j]->Append(tdof-tdof_offsets[j]); } } void ParDPGWeakForm::Assemble(int skip_zeros) { DPGWeakForm::Assemble(skip_zeros); } void ParDPGWeakForm::ParallelAssemble(BlockMatrix *m) { if (!P) { BuildProlongation(); } p_mat = new BlockOperator(tdof_offsets); p_mat_e = new BlockOperator(tdof_offsets); p_mat->owns_blocks = 1; p_mat_e->owns_blocks = 1; HypreParMatrix * A = nullptr; HypreParMatrix * PtAP = nullptr; for (int i = 0; iGetBlock(i,i)); HypreParMatrix * Pit = Pi->Transpose(); for (int j = 0; jIsZeroBlock(i,j)) { continue; } if (i == j) { // Make block diagonal square hypre matrix A = new HypreParMatrix(trial_pfes[i]->GetComm(), trial_pfes[i]->GlobalVSize(), trial_pfes[i]->GetDofOffsets(),&m->GetBlock(i,i)); PtAP = RAP(A,Pi); delete A; p_mat_e->SetBlock(i,i,PtAP->EliminateRowsCols(*ess_tdofs[i])); } else { HypreParMatrix * Pj = (HypreParMatrix*)(&P->GetBlock(j,j)); A = new HypreParMatrix(trial_pfes[i]->GetComm(), trial_pfes[i]->GlobalVSize(), trial_pfes[j]->GlobalVSize(), trial_pfes[i]->GetDofOffsets(), trial_pfes[j]->GetDofOffsets(), &m->GetBlock(i,j)); HypreParMatrix * APj = ParMult(A, Pj,true); delete A; PtAP = ParMult(Pit,APj,true); delete APj; p_mat_e->SetBlock(i,j,PtAP->EliminateCols(*ess_tdofs[j])); PtAP->EliminateRows(*ess_tdofs[i]); } p_mat->SetBlock(i,j,PtAP); } delete Pit; } } void ParDPGWeakForm::BuildProlongation() { P = new BlockOperator(dof_offsets, tdof_offsets); R = new BlockMatrix(tdof_offsets, dof_offsets); P->owns_blocks = 0; R->owns_blocks = 0; for (int i = 0; iDof_TrueDof_Matrix(); P->SetBlock(i,i,P_); const SparseMatrix * R_ = trial_pfes[i]->GetRestrictionMatrix(); R->SetBlock(i,i,const_cast(R_)); } } void ParDPGWeakForm::FormLinearSystem(const Array &ess_tdof_list, Vector &x, OperatorHandle &A, Vector &X, Vector &B, int copy_interior) { FormSystemMatrix(ess_tdof_list, A); if (static_cond) { static_cond->ReduceSystem(x, X, B, copy_interior); } else { B.SetSize(P->Width()); P->MultTranspose(*y,B); X.SetSize(R->Height()); R->Mult(x,X); // eliminate tdof in RHS // B -= Ae*X Vector tmp(B.Size()); p_mat_e->Mult(X,tmp); B-=tmp; for (int j = 0; jSize()) { continue; } for (int i = 0; i < ess_tdofs[j]->Size(); i++) { int tdof = (*ess_tdofs[j])[i]; int gdof = tdof + tdof_offsets[j]; B(gdof) = X(gdof); // diagonal policy in always one in parallel } } if (!copy_interior) { X.SetSubVectorComplement(ess_tdof_list, 0.0); } } } void ParDPGWeakForm::FormSystemMatrix(const Array &ess_tdof_list, OperatorHandle &A) { if (static_cond) { if (!static_cond->HasEliminatedBC()) { static_cond->SetEssentialTrueDofs(ess_tdof_list); static_cond->FormSystemMatrix(Operator::DiagonalPolicy::DIAG_ONE); } A.Reset(&static_cond->GetParallelSchurMatrix(), false); } else { FillEssTdofLists(ess_tdof_list); if (mat) { const int remove_zeros = 0; Finalize(remove_zeros); ParallelAssemble(mat); delete mat; mat = nullptr; delete mat_e; mat_e = nullptr; } A.Reset(p_mat,false); } } void ParDPGWeakForm::RecoverFEMSolution(const Vector &X, Vector &x) { if (static_cond) { static_cond->ComputeSolution(X, x); } else { x.SetSize(P->Height()); P->Mult(X, x); } } void ParDPGWeakForm::Update() { DPGWeakForm::Update(); delete p_mat_e; p_mat_e = nullptr; delete p_mat; p_mat = nullptr; for (int i = 0; i(); } delete P; P = nullptr; delete R; R = nullptr; } ParDPGWeakForm::~ParDPGWeakForm() { delete p_mat_e; p_mat_e = nullptr; delete p_mat; p_mat = nullptr; for (int i = 0; i