MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
tmop_pa_w2.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, 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 "../linearform.hpp"
18
19namespace mfem
20{
21
22using Args = kernels::InvariantsEvaluator2D::Buffers;
23
24static MFEM_HOST_DEVICE inline
25real_t EvalW_001(const real_t *Jpt)
26{
27 kernels::InvariantsEvaluator2D ie(Args().J(Jpt));
28 return ie.Get_I1();
29}
30
31static MFEM_HOST_DEVICE inline
32real_t EvalW_002(const real_t *Jpt)
33{
34 kernels::InvariantsEvaluator2D ie(Args().J(Jpt));
35 return 0.5 * ie.Get_I1b() - 1.0;
36}
37
38static MFEM_HOST_DEVICE inline
39real_t EvalW_007(const real_t *Jpt)
40{
41 kernels::InvariantsEvaluator2D ie(Args().J(Jpt));
42 return ie.Get_I1() * (1.0 + 1.0/ie.Get_I2()) - 4.0;
43}
44
45// mu_56 = 0.5*(I2b + 1/I2b) - 1.
46static MFEM_HOST_DEVICE inline
47real_t EvalW_056(const real_t *Jpt)
48{
49 kernels::InvariantsEvaluator2D ie(Args().J(Jpt));
50 const real_t I2b = ie.Get_I2b();
51 return 0.5*(I2b + 1.0/I2b) - 1.0;
52}
53
54static MFEM_HOST_DEVICE inline
55real_t EvalW_077(const real_t *Jpt)
56{
57 kernels::InvariantsEvaluator2D ie(Args().J(Jpt));
58 const real_t I2b = ie.Get_I2b();
59 return 0.5*(I2b*I2b + 1./(I2b*I2b) - 2.);
60}
61
62static MFEM_HOST_DEVICE inline
63real_t EvalW_080(const real_t *Jpt, const real_t *w)
64{
65 return w[0] * EvalW_002(Jpt) + w[1] * EvalW_077(Jpt);
66}
67
68static MFEM_HOST_DEVICE inline
69real_t EvalW_094(const real_t *Jpt, const real_t *w)
70{
71 return w[0] * EvalW_002(Jpt) + w[1] * EvalW_056(Jpt);
72}
73
75 const real_t metric_normal,
76 const Vector &mc_,
77 const Array<real_t> &metric_param,
78 const int mid,
79 const int NE,
80 const DenseTensor &j_,
81 const Array<real_t> &w_,
82 const Array<real_t> &b_,
83 const Array<real_t> &g_,
84 const Vector &x_,
85 const Vector &ones,
86 Vector &energy,
87 const int d1d,
88 const int q1d)
89{
90 MFEM_VERIFY(mid == 1 || mid == 2 || mid == 7 || mid == 77
91 || mid == 80 || mid == 94,
92 "2D metric not yet implemented!");
93
94 const bool const_m0 = mc_.Size() == 1;
95
96 constexpr int DIM = 2;
97 constexpr int NBZ = 1;
98
99 const int D1D = T_D1D ? T_D1D : d1d;
100 const int Q1D = T_Q1D ? T_Q1D : q1d;
101
102 const auto MC = const_m0 ?
103 Reshape(mc_.Read(), 1, 1, 1) :
104 Reshape(mc_.Read(), Q1D, Q1D, NE);
105 const auto J = Reshape(j_.Read(), DIM, DIM, Q1D, Q1D, NE);
106 const auto b = Reshape(b_.Read(), Q1D, D1D);
107 const auto g = Reshape(g_.Read(), Q1D, D1D);
108 const auto W = Reshape(w_.Read(), Q1D, Q1D);
109 const auto X = Reshape(x_.Read(), D1D, D1D, DIM, NE);
110
111 auto E = Reshape(energy.Write(), Q1D, Q1D, NE);
112
113 const real_t *metric_data = metric_param.Read();
114
115 mfem::forall_2D_batch(NE, Q1D, Q1D, NBZ, [=] MFEM_HOST_DEVICE (int e)
116 {
117 constexpr int NBZ = 1;
118 constexpr int MQ1 = T_Q1D ? T_Q1D : T_MAX;
119 constexpr int MD1 = T_D1D ? T_D1D : T_MAX;
120 const int D1D = T_D1D ? T_D1D : d1d;
121 const int Q1D = T_Q1D ? T_Q1D : q1d;
122
123 MFEM_SHARED real_t BG[2][MQ1*MD1];
124 MFEM_SHARED real_t XY[2][NBZ][MD1*MD1];
125 MFEM_SHARED real_t DQ[4][NBZ][MD1*MQ1];
126 MFEM_SHARED real_t QQ[4][NBZ][MQ1*MQ1];
127
128 kernels::internal::LoadX<MD1,NBZ>(e,D1D,X,XY);
129 kernels::internal::LoadBG<MD1,MQ1>(D1D,Q1D,b,g,BG);
130
131 kernels::internal::GradX<MD1,MQ1,NBZ>(D1D,Q1D,BG,XY,DQ);
132 kernels::internal::GradY<MD1,MQ1,NBZ>(D1D,Q1D,BG,DQ,QQ);
133
134 MFEM_FOREACH_THREAD(qy,y,Q1D)
135 {
136 MFEM_FOREACH_THREAD(qx,x,Q1D)
137 {
138 const real_t *Jtr = &J(0,0,qx,qy,e);
139 const real_t detJtr = kernels::Det<2>(Jtr);
140 const real_t m_coef = const_m0 ? MC(0,0,0) : MC(qx,qy,e);
141 const real_t weight = metric_normal * m_coef * W(qx,qy) * detJtr;
142
143 // Jrt = Jtr^{-1}
144 real_t Jrt[4];
145 kernels::CalcInverse<2>(Jtr, Jrt);
146
147 // Jpr = X^t.DSh
148 real_t Jpr[4];
149 kernels::internal::PullGrad<MQ1,NBZ>(Q1D,qx,qy,QQ,Jpr);
150
151 // Jpt = X^T.DS = (X^T.DSh).Jrt = Jpr.Jrt
152 real_t Jpt[4];
153 kernels::Mult(2,2,2,Jpr,Jrt,Jpt);
154
155 // metric->EvalW(Jpt);
156 const real_t EvalW =
157 mid == 1 ? EvalW_001(Jpt) :
158 mid == 2 ? EvalW_002(Jpt) :
159 mid == 7 ? EvalW_007(Jpt) :
160 mid == 77 ? EvalW_077(Jpt) :
161 mid == 80 ? EvalW_080(Jpt, metric_data) :
162 mid == 94 ? EvalW_094(Jpt, metric_data) : 0.0;
163
164 E(qx,qy,e) = weight * EvalW;
165 }
166 }
167 });
168 return energy * ones;
169}
170
172{
173 const int N = PA.ne;
174 const int M = metric->Id();
175 const int D1D = PA.maps->ndof;
176 const int Q1D = PA.maps->nqpt;
177 const int id = (D1D << 4 ) | Q1D;
178 const real_t mn = metric_normal;
179 const Vector &MC = PA.MC;
180 const DenseTensor &J = PA.Jtr;
181 const Array<real_t> &W = PA.ir->GetWeights();
182 const Array<real_t> &B = PA.maps->B;
183 const Array<real_t> &G = PA.maps->G;
184 const Vector &O = PA.O;
185 Vector &E = PA.E;
186
187 Array<real_t> mp;
188 if (auto m = dynamic_cast<TMOP_Combo_QualityMetric *>(metric))
189 {
190 m->GetWeights(mp);
191 }
192
193 MFEM_LAUNCH_TMOP_KERNEL(EnergyPA_2D,id,mn,MC,mp,M,N,J,W,B,G,X,O,E);
194}
195
196} // namespace mfem
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:317
Rank 3 tensor (array of matrices)
const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
TMOP_QualityMetric * metric
Definition tmop.hpp:1744
real_t GetLocalStateEnergyPA_2D(const Vector &) const
struct mfem::TMOP_Integrator::@23 PA
virtual int Id() const
Return the metric ID.
Definition tmop.hpp:78
Vector data type.
Definition vector.hpp:80
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:474
int Size() const
Returns the size of the vector.
Definition vector.hpp:218
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:482
real_t b
Definition lissajous.cpp:42
constexpr int DIM
MFEM_HOST_DEVICE void CalcInverse(const T *data, T *inv_data)
Return the inverse of a matrix with given size and data into the matrix with data inv_data.
Definition kernels.hpp:246
MFEM_HOST_DEVICE void Mult(const int height, const int width, const TA *data, const TX *x, TY *y)
Matrix vector multiplication: y = A x, where the matrix A is of size height x width with given data,...
Definition kernels.hpp:163
MFEM_HOST_DEVICE T Det(const T *data)
Compute the determinant of a square matrix of size dim with given data.
Definition kernels.hpp:237
MFEM_REGISTER_TMOP_KERNELS(void, DatcSize, const int NE, const int ncomp, const int sizeidx, const real_t input_min_size, const DenseMatrix &w_, const Array< real_t > &b_, const Vector &x_, const Vector &nc_reduce, DenseTensor &j_, const int d1d, const int q1d)
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
void forall_2D_batch(int N, int X, int Y, int BZ, lambda &&body)
Definition forall.hpp:769
kernels::InvariantsEvaluator2D::Buffers Args
float real_t
Definition config.hpp:43