16 using mfem::internal::tensor;
24 MFEM_ASSERT(gradient_operator_ !=
nullptr,
25 "Operator is not ElasticityGradientOperator");
39 const int ns = num_submats_, sh = submat_height_, nsh = ns * sh;
41 const auto K_diag_submats =
Reshape(K_diag_.
Read(), ns, sh, sh);
46 if (type_ == Type::Diagonal)
51 const int s = si / sh;
52 const int i = si % sh;
53 Y(s, i) = X(s, i) / K_diag_submats(s, i, i);
56 else if (type_ == Type::BlockDiagonal)
60 const auto submat = make_tensor<dim, dim>(
61 [&](
int i,
int j) {
return K_diag_submats(
s, i, j); });
63 const auto submat_inv = inv(submat);
65 const auto x_block = make_tensor<dim>([&](
int i) {
return X(
s, i); });
67 tensor<double, dim> y_block = submat_inv * x_block;
69 for (
int i = 0; i < dim; i++)
77 MFEM_ABORT(
"Unknown ElasticityDiagonalPreconditioner::Type");
void AssembleGradientDiagonal(Vector &Ke_diag, Vector &K_diag_local, Vector &K_diag) const
virtual int GetTrueVSize() const
Return the number of local vector true dofs.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
virtual double * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
int GetVDim() const
Returns vector dimension.
Implementation of the tensor class.
void Mult(const Vector &x, Vector &y) const override
Operator application: y=A(x).
int height
Dimension of the output / number of rows in the matrix.
ElasticityGradientOperator is a wrapper class to pass ElasticityOperator::AssembleGradientDiagonal an...
ElasticityOperator & elasticity_op_
void SetOperator(const Operator &op) override
Set/update the solver for the given operator.
ParFiniteElementSpace h1_fes_
H1 finite element space.
virtual const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
int width
Dimension of the input / number of columns in the matrix.
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims...dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.