MFEM  v4.6.0
Finite element discretization library
tmop_pa_h3d_c0.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, 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 
12 #include "../tmop.hpp"
13 #include "tmop_pa.hpp"
14 #include "../../general/forall.hpp"
15 #include "../../linalg/kernels.hpp"
16 
17 namespace mfem
18 {
19 
20 MFEM_REGISTER_TMOP_KERNELS(void, AssembleDiagonalPA_Kernel_C0_3D,
21  const int NE,
22  const Array<double> &b,
23  const Vector &h0,
24  Vector &diagonal,
25  const int d1d,
26  const int q1d)
27 {
28  constexpr int DIM = 3;
29  const int D1D = T_D1D ? T_D1D : d1d;
30  const int Q1D = T_Q1D ? T_Q1D : q1d;
31 
32  const auto B = Reshape(b.Read(), Q1D, D1D);
33  const auto H0 = Reshape(h0.Read(), DIM, DIM, Q1D, Q1D, Q1D, NE);
34 
35  auto D = Reshape(diagonal.ReadWrite(), D1D, D1D, D1D, DIM, NE);
36 
37  mfem::forall_3D(NE, Q1D, Q1D, Q1D, [=] MFEM_HOST_DEVICE (int e)
38  {
39  constexpr int DIM = 3;
40  const int D1D = T_D1D ? T_D1D : d1d;
41  const int Q1D = T_Q1D ? T_Q1D : q1d;
42  constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
43  constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
44 
45  MFEM_SHARED double qqd[MQ1*MQ1*MD1];
46  MFEM_SHARED double qdd[MQ1*MD1*MD1];
47  DeviceTensor<3,double> QQD(qqd, MQ1, MQ1, MD1);
48  DeviceTensor<3,double> QDD(qdd, MQ1, MD1, MD1);
49 
50  for (int v = 0; v < DIM; ++v)
51  {
52  // first tensor contraction, along z direction
53  MFEM_FOREACH_THREAD(qx,x,Q1D)
54  {
55  MFEM_FOREACH_THREAD(qy,y,Q1D)
56  {
57  MFEM_FOREACH_THREAD(dz,z,D1D)
58  {
59  QQD(qx,qy,dz) = 0.0;
60  MFEM_UNROLL(MQ1)
61  for (int qz = 0; qz < Q1D; ++qz)
62  {
63  const double Bz = B(qz,dz);
64  QQD(qx,qy,dz) += Bz * H0(v,v,qx,qy,qz,e) * Bz;
65  }
66  }
67  }
68  }
69  MFEM_SYNC_THREAD;
70  // second tensor contraction, along y direction
71  MFEM_FOREACH_THREAD(qx,x,Q1D)
72  {
73  MFEM_FOREACH_THREAD(dz,z,D1D)
74  {
75  MFEM_FOREACH_THREAD(dy,y,D1D)
76  {
77  QDD(qx,dy,dz) = 0.0;
78  MFEM_UNROLL(MQ1)
79  for (int qy = 0; qy < Q1D; ++qy)
80  {
81  const double By = B(qy,dy);
82  QDD(qx,dy,dz) += By * QQD(qx,qy,dz) * By;
83  }
84  }
85  }
86  }
87  MFEM_SYNC_THREAD;
88  // third tensor contraction, along x direction
89  MFEM_FOREACH_THREAD(dz,z,D1D)
90  {
91  MFEM_FOREACH_THREAD(dy,y,D1D)
92  {
93  MFEM_FOREACH_THREAD(dx,x,D1D)
94  {
95  double d = 0.0;
96  MFEM_UNROLL(MQ1)
97  for (int qx = 0; qx < Q1D; ++qx)
98  {
99  const double Bx = B(qx,dx);
100  d += Bx * QDD(qx,dy,dz) * Bx;
101  }
102  D(dx,dy,dz, v, e) += d;
103  }
104  }
105  }
106  MFEM_SYNC_THREAD;
107  }
108  });
109 }
110 
112 {
113  const int N = PA.ne;
114  const int D1D = PA.maps->ndof;
115  const int Q1D = PA.maps->nqpt;
116  const int id = (D1D << 4 ) | Q1D;
117  const Array<double> &B = PA.maps->B;
118  const Vector &H0 = PA.H0;
119 
120  MFEM_LAUNCH_TMOP_KERNEL(AssembleDiagonalPA_Kernel_C0_3D,id,N,B,H0,D);
121 }
122 
123 } // namespace mfem
void forall_3D(int N, int X, int Y, int Z, lambda &&body)
Definition: forall.hpp:763
struct mfem::TMOP_Integrator::@23 PA
virtual const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
Definition: vector.hpp:453
constexpr int DIM
MFEM_REGISTER_TMOP_KERNELS(void, DatcSize, const int NE, const int ncomp, const int sizeidx, const double input_min_size, const DenseMatrix &w_, const Array< double > &b_, const Vector &x_, const Vector &nc_reduce, DenseTensor &j_, const int d1d, const int q1d)
Definition: tmop_pa_da3.cpp:20
double b
Definition: lissajous.cpp:42
A basic generic Tensor class, appropriate for use on the GPU.
Definition: dtensor.hpp:81
virtual double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
Definition: vector.hpp:469
void AssembleDiagonalPA_C0_3D(Vector &) const
Vector data type.
Definition: vector.hpp:58
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:131