MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
diagonal_preconditioner.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
13#include "linalg/tensor.hpp"
14
16
17namespace mfem
18{
19
21{
22 gradient_operator_ = dynamic_cast<const ElasticityGradientOperator *>(&op);
23 MFEM_ASSERT(gradient_operator_ != nullptr,
24 "Operator is not ElasticityGradientOperator");
25
26 width = height = op.Height();
27
28 gradient_operator_->AssembleGradientDiagonal(Ke_diag_, K_diag_local_,
29 K_diag_);
30
31 submat_height_ = gradient_operator_->elasticity_op_.h1_fes_.GetVDim();
32 num_submats_ = gradient_operator_->elasticity_op_.h1_fes_.GetTrueVSize() /
33 gradient_operator_->elasticity_op_.h1_fes_.GetVDim();
34}
35
37{
38 const int ns = num_submats_, sh = submat_height_, nsh = ns * sh;
39
40 const auto K_diag_submats = Reshape(K_diag_.Read(), ns, sh, sh);
41 const auto X = Reshape(x.Read(), ns, dim);
42
43 auto Y = Reshape(y.Write(), ns, dim);
44
45 if (type_ == Type::Diagonal)
46 {
47 // Assuming Y and X are ordered byNODES. K_diag is ordered byVDIM.
48 mfem::forall(nsh, [=] MFEM_HOST_DEVICE (int si)
49 {
50 const int s = si / sh;
51 const int i = si % sh;
52 Y(s, i) = X(s, i) / K_diag_submats(s, i, i);
53 });
54 }
55 else if (type_ == Type::BlockDiagonal)
56 {
57 mfem::forall(ns, [=] MFEM_HOST_DEVICE (int s)
58 {
59 const auto submat = make_tensor<dim, dim>(
60 [&](int i, int j) { return K_diag_submats(s, i, j); });
61
62 const auto submat_inv = inv(submat);
63
64 const auto x_block = make_tensor<dim>([&](int i) { return X(s, i); });
65
66 tensor<real_t, dim> y_block = submat_inv * x_block;
67
68 for (int i = 0; i < dim; i++)
69 {
70 Y(s, i) = y_block(i);
71 }
72 });
73 }
74 else
75 {
76 MFEM_ABORT("Unknown ElasticityDiagonalPreconditioner::Type");
77 }
78}
79
80} // namespace mfem
void SetOperator(const Operator &op) override
Set/update the solver for the given operator.
void Mult(const Vector &x, Vector &y) const override
Operator application: y=A(x).
ElasticityGradientOperator is a wrapper class to pass ElasticityOperator::AssembleGradientDiagonal an...
void AssembleGradientDiagonal(Vector &Ke_diag, Vector &K_diag_local, Vector &K_diag) const
ParFiniteElementSpace h1_fes_
H1 finite element space.
int GetVDim() const
Returns the vector dimension of the finite element space.
Definition fespace.hpp:819
Abstract operator.
Definition operator.hpp:25
int width
Dimension of the input / number of columns in the matrix.
Definition operator.hpp:28
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:66
int height
Dimension of the output / number of rows in the matrix.
Definition operator.hpp:27
int GetTrueVSize() const override
Return the number of local vector true dofs.
Definition pfespace.hpp:353
Vector data type.
Definition vector.hpp:82
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:520
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:528
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
Definition dtensor.hpp:138
void forall(int N, lambda &&body)
Definition forall.hpp:839
Implementation of the tensor class.