MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
doftrans.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
12#include "fem.hpp"
13
14namespace mfem
15{
16
18{
19 if (IsIdentity()) { return; }
20 int size = dof_trans_->Size();
21
23 {
24 for (int i=0; i<vdim_; i++)
25 {
26 dof_trans_->TransformPrimal(Fo_, &v[i*size]);
27 }
28 }
29 else
30 {
31 Vector vec(size);
32 for (int i=0; i<vdim_; i++)
33 {
34 for (int j=0; j<size; j++)
35 {
36 vec(j) = v[j*vdim_+i];
37 }
39 for (int j=0; j<size; j++)
40 {
41 v[j*vdim_+i] = vec(j);
42 }
43 }
44 }
45}
46
48{
49 if (IsIdentity()) { return; }
50 int size = dof_trans_->Height();
51
53 {
54 for (int i=0; i<vdim_; i++)
55 {
56 dof_trans_->InvTransformPrimal(Fo_, &v[i*size]);
57 }
58 }
59 else
60 {
61 Vector vec(size);
62 for (int i=0; i<vdim_; i++)
63 {
64 for (int j=0; j<size; j++)
65 {
66 vec(j) = v[j*vdim_+i];
67 }
69 for (int j=0; j<size; j++)
70 {
71 v[j*vdim_+i] = vec(j);
72 }
73 }
74 }
75}
76
78{
79 if (IsIdentity()) { return; }
80 int size = dof_trans_->Size();
81
83 {
84 for (int i=0; i<vdim_; i++)
85 {
86 dof_trans_->TransformDual(Fo_, &v[i*size]);
87 }
88 }
89 else
90 {
91 Vector vec(size);
92 for (int i=0; i<vdim_; i++)
93 {
94 for (int j=0; j<size; j++)
95 {
96 vec(j) = v[j*vdim_+i];
97 }
99 for (int j=0; j<size; j++)
100 {
101 v[j*vdim_+i] = vec(j);
102 }
103 }
104 }
105}
106
108{
109 if (IsIdentity()) { return; }
110 int size = dof_trans_->Size();
111
113 {
114 for (int i=0; i<vdim_; i++)
115 {
116 dof_trans_->InvTransformDual(Fo_, &v[i*size]);
117 }
118 }
119 else
120 {
121 Vector vec(size);
122 for (int i=0; i<vdim_; i++)
123 {
124 for (int j=0; j<size; j++)
125 {
126 vec(j) = v[j*vdim_+i];
127 }
129 for (int j=0; j<size; j++)
130 {
131 v[j*vdim_+i] = vec(j);
132 }
133 }
134 }
135}
136
137void TransformPrimal(const DofTransformation &ran_dof_trans,
138 const DofTransformation &dom_dof_trans,
139 DenseMatrix &elmat)
140{
141 // No action if both transformations are NULL
142 if (!ran_dof_trans.IsIdentity())
143 {
144 ran_dof_trans.TransformPrimalCols(elmat);
145 }
146 if (!dom_dof_trans.IsIdentity())
147 {
148 dom_dof_trans.TransformDualRows(elmat);
149 }
150}
151
152void TransformDual(const DofTransformation &ran_dof_trans,
153 const DofTransformation &dom_dof_trans,
154 DenseMatrix &elmat)
155{
156 // No action if both transformations are NULL
157 if (!ran_dof_trans.IsIdentity())
158 {
159 ran_dof_trans.TransformDualCols(elmat);
160 }
161 if (!dom_dof_trans.IsIdentity())
162 {
163 dom_dof_trans.TransformDualRows(elmat);
164 }
165}
166
167// ordering (i0j0, i1j0, i0j1, i1j1), each row is a column major matrix
168const real_t ND_DofTransformation::T_data[24] =
169{
170 1.0, 0.0, 0.0, 1.0,
171 -1.0, -1.0, 0.0, 1.0,
172 0.0, 1.0, -1.0, -1.0,
173 1.0, 0.0, -1.0, -1.0,
174 -1.0, -1.0, 1.0, 0.0,
175 0.0, 1.0, 1.0, 0.0
176};
177
178const DenseTensor ND_DofTransformation
179::T(const_cast<real_t *>(ND_DofTransformation::T_data), 2, 2, 6);
180
181// ordering (i0j0, i1j0, i0j1, i1j1), each row is a column major matrix
182const real_t ND_DofTransformation::TInv_data[24] =
183{
184 1.0, 0.0, 0.0, 1.0,
185 -1.0, -1.0, 0.0, 1.0,
186 -1.0, -1.0, 1.0, 0.0,
187 1.0, 0.0, -1.0, -1.0,
188 0.0, 1.0, -1.0, -1.0,
189 0.0, 1.0, 1.0, 0.0
190};
191
192const DenseTensor ND_DofTransformation
193::TInv(const_cast<real_t *>(TInv_data), 2, 2, 6);
194
196 int num_faces,
197 int face_types[])
199 , order(p)
200 , nedofs(p)
201 , ntdofs(p*(p-1))
202 , nqdofs(2*p*(p-1))
203 , nedges(num_edges)
204 , nfaces(num_faces)
205 , ftypes(face_types)
206{
207}
208
210 real_t *v) const
211{
212 // Return immediately when no face DoFs are present
213 if (IsIdentity()) { return; }
214
215 MFEM_VERIFY(Fo.Size() >= nfaces,
216 "Face orientation array is shorter than the number of faces in "
217 "ND_DofTransformation");
218
219 int of = 0;
220 real_t data[2];
221 Vector v2(data, 2);
222 DenseMatrix T2;
223
224 // Transform face DoFs
225 for (int f=0; f<nfaces; f++)
226 {
228 {
229 for (int i=0; i<ntdofs/2; i++)
230 {
231 v2 = &v[nedges*nedofs + of + 2*i];
232 T2.UseExternalData(const_cast<real_t *>(T.GetData(Fo[f])), 2, 2);
233 T2.Mult(v2, &v[nedges*nedofs + of + 2*i]);
234 }
235 of += ntdofs;
236 }
237 else
238 {
239 of += nqdofs;
240 }
241 }
242}
243
245 real_t *v) const
246{
247 // Return immediately when no face DoFs are present
248 if (IsIdentity()) { return; }
249
250 MFEM_VERIFY(Fo.Size() >= nfaces,
251 "Face orientation array is shorter than the number of faces in "
252 "ND_DofTransformation");
253
254 int of = 0;
255 real_t data[2];
256 Vector v2(data, 2);
257 DenseMatrix T2Inv;
258
259 // Transform face DoFs
260 for (int f=0; f<nfaces; f++)
261 {
263 {
264 for (int i=0; i<ntdofs/2; i++)
265 {
266 v2 = &v[nedges*nedofs + of + 2*i];
267 T2Inv.UseExternalData(const_cast<real_t *>(TInv.GetData(Fo[f])), 2, 2);
268 T2Inv.Mult(v2, &v[nedges*nedofs + of + 2*i]);
269 }
270 of += ntdofs;
271 }
272 else
273 {
274 of += nqdofs;
275 }
276 }
277}
278
280{
281 // Return immediately when no face DoFs are present
282 if (IsIdentity()) { return; }
283
284 MFEM_VERIFY(Fo.Size() >= nfaces,
285 "Face orientation array is shorter than the number of faces in "
286 "ND_DofTransformation");
287
288 int of = 0;
289 real_t data[2];
290 Vector v2(data, 2);
291 DenseMatrix T2Inv;
292
293 // Transform face DoFs
294 for (int f=0; f<nfaces; f++)
295 {
297 {
298 for (int i=0; i<ntdofs/2; i++)
299 {
300 v2 = &v[nedges*nedofs + of + 2*i];
301 T2Inv.UseExternalData(const_cast<real_t *>(TInv.GetData(Fo[f])), 2, 2);
302 T2Inv.MultTranspose(v2, &v[nedges*nedofs + of + 2*i]);
303 }
304 of += ntdofs;
305 }
306 else
307 {
308 of += nqdofs;
309 }
310
311 }
312}
313
315 real_t *v) const
316{
317 // Return immediately when no face DoFs are present
318 if (IsIdentity()) { return; }
319
320 MFEM_VERIFY(Fo.Size() >= nfaces,
321 "Face orientation array is shorter than the number of faces in "
322 "ND_DofTransformation");
323
324 int of = 0;
325 real_t data[2];
326 Vector v2(data, 2);
327 DenseMatrix T2;
328
329 // Transform face DoFs
330 for (int f=0; f<nfaces; f++)
331 {
333 {
334 for (int i=0; i<ntdofs/2; i++)
335 {
336 v2 = &v[nedges*nedofs + of + 2*i];
337 T2.UseExternalData(const_cast<real_t *>(T.GetData(Fo[f])), 2, 2);
338 T2.MultTranspose(v2, &v[nedges*nedofs + of + 2*i]);
339 }
340 of += ntdofs;
341 }
342 else
343 {
344 of += nqdofs;
345 }
346 }
347}
348
349} // namespace mfem
int Size() const
Return the logical size of the array.
Definition array.hpp:166
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication.
Definition densemat.cpp:108
void MultTranspose(const real_t *x, real_t *y) const
Multiply a vector with the transpose matrix.
Definition densemat.cpp:158
void UseExternalData(real_t *d, int h, int w)
Change the data array and the size of the DenseMatrix.
Definition densemat.hpp:88
real_t * GetData(int k)
void TransformDual(real_t *v) const
Definition doftrans.cpp:77
void InvTransformPrimal(real_t *v) const
Definition doftrans.cpp:47
void TransformPrimalCols(DenseMatrix &V) const
Transform groups of DoFs stored as dense matrices.
Definition doftrans.hpp:214
const StatelessDofTransformation * dof_trans_
Definition doftrans.hpp:145
void TransformDualRows(DenseMatrix &V) const
Transform rows of a dense matrix containing dual DoFs.
Definition doftrans.hpp:252
void InvTransformDual(real_t *v) const
Definition doftrans.cpp:107
void TransformDualCols(DenseMatrix &V) const
Transform columns of a dense matrix containing dual DoFs.
Definition doftrans.hpp:265
bool IsIdentity() const
Definition doftrans.hpp:204
void TransformPrimal(real_t *v) const
Definition doftrans.cpp:17
bool IsIdentity() const override
If the DofTransformation performs no transformation.
Definition doftrans.hpp:330
void InvTransformDual(const Array< int > &Fo, real_t *v) const override
Definition doftrans.cpp:314
void TransformPrimal(const Array< int > &Fo, real_t *v) const override
Definition doftrans.cpp:209
void TransformDual(const Array< int > &Fo, real_t *v) const override
Definition doftrans.cpp:279
ND_DofTransformation(int size, int order, int num_edges, int num_faces, int *face_types)
Definition doftrans.cpp:195
void InvTransformPrimal(const Array< int > &Fo, real_t *v) const override
Definition doftrans.cpp:244
Type
Ordering methods:
Definition ordering.hpp:17
virtual void InvTransformPrimal(const Array< int > &face_orientation, real_t *v) const =0
virtual void TransformPrimal(const Array< int > &face_orientation, real_t *v) const =0
virtual void InvTransformDual(const Array< int > &face_orientation, real_t *v) const =0
virtual void TransformDual(const Array< int > &face_orientation, real_t *v) const =0
Vector data type.
Definition vector.hpp:82
mfem::real_t real_t
void TransformDual(const DofTransformation &ran_dof_trans, const DofTransformation &dom_dof_trans, DenseMatrix &elmat)
Definition doftrans.cpp:152
float real_t
Definition config.hpp:46
void TransformPrimal(const DofTransformation &ran_dof_trans, const DofTransformation &dom_dof_trans, DenseMatrix &elmat)
Definition doftrans.cpp:137
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Definition lor_mms.hpp:30
real_t p(const Vector &x, real_t t)