MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
bilininteg_trace_jump_ea.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
14#include "../bilininteg.hpp"
16
17namespace mfem
18{
19
21 const FiniteElementSpace &trial_fes,
22 const FiniteElementSpace &test_fes,
23 Vector &emat,
24 const bool add)
25{
26 Mesh &mesh = *trial_fes.GetMesh();
27 const int dim = mesh.Dimension();
28 const FaceType ftype = FaceType::Interior;
29 const int nf = mesh.GetNFbyType(ftype);
30
31 const Geometry::Type geom = mesh.GetFaceGeometry(0);
32 const int trial_order = trial_fes.GetMaxElementOrder();
33 const int test_order = test_fes.GetMaxElementOrder();
34 const int qorder = test_order + trial_order - 1;
35 const IntegrationRule &ir = IntRule ? *IntRule : IntRules.Get(geom, qorder);
36 const int nquad = ir.Size();
37
38 Vector pa_data(nquad * nf);
39 {
40 const auto d_w = ir.GetWeights().Read();
41 auto d_pa_data = Reshape(pa_data.Write(), nquad, nf);
42 mfem::forall(nquad * nf, [=] MFEM_HOST_DEVICE (int idx)
43 {
44 const int q = idx % nquad;
45 const int f = idx / nquad;
46 d_pa_data(q, f) = d_w[q];
47 });
48 }
49
50 const FiniteElement &trial_face_el = *trial_fes.GetFaceElement(0);
51 const auto maps = &trial_face_el.GetDofToQuad(ir, DofToQuad::TENSOR);
52 const int ndof_face = trial_face_el.GetDof();
53
54 const Array<real_t> &B = maps->B;
55 const int d1d = maps->ndof;
56 const int q1d = maps->nqpt;
57
58 Vector mass_emat(ndof_face*ndof_face*nf);
59
60 // Note: dim is the element dimension, and we integrate over the faces (one
61 // dimension less)
62 if (dim == 2)
63 {
64 internal::EAMassAssemble1D(nf, B, pa_data, mass_emat, false, d1d, q1d);
65 }
66 else if (dim == 3)
67 {
68 internal::EAMassAssemble2D(nf, B, pa_data, mass_emat, false, d1d, q1d);
69 }
70 else
71 {
72 MFEM_ABORT("Unknown kernel.");
73 }
74
75 const FiniteElement &test_el = *test_fes.GetFE(0);
76 const int n_faces_per_el = 2*dim; // assuming tensor product
77 // Get all the local face maps (mapping from lexicographic face index to
78 // lexicographic volume index, depending on the local face index).
79 Array<int> face_maps(ndof_face * n_faces_per_el);
80 for (int lf_i = 0; lf_i < n_faces_per_el; ++lf_i)
81 {
82 Array<int> face_map(ndof_face);
83 test_el.GetFaceMap(lf_i, face_map);
84 for (int i = 0; i < ndof_face; ++i)
85 {
86 face_maps[i + lf_i*ndof_face] = face_map[i];
87 }
88 }
89
90 Array<int> face_info(nf * 4);
91 {
92 int fidx = 0;
93 for (int f = 0; f < mesh.GetNumFaces(); ++f)
94 {
96 if (!finfo.IsInterior()) { continue; }
97 face_info[0 + fidx*4] = finfo.element[0].local_face_id;
98 face_info[1 + fidx*4] = finfo.element[0].orientation;
99 face_info[2 + fidx*4] = finfo.element[1].local_face_id;
100 face_info[3 + fidx*4] = finfo.element[1].orientation;
101 fidx++;
102 }
103 }
104
105 const int ndof_vol = test_el.GetDof();
106 const auto d_face_maps = Reshape(face_maps.Read(), ndof_face, n_faces_per_el);
107 const auto d_face_info = Reshape(face_info.Read(), 2, 2, nf);
108
109 real_t *d_emat;
110 if (add)
111 {
112 d_emat = emat.ReadWrite();
113 }
114 else
115 {
116 d_emat = emat.Write();
117 mfem::forall(emat.Size(), [=] MFEM_HOST_DEVICE (int i) { d_emat[i] = 0.0; });
118 }
119
120 const auto face_mats = Reshape(mass_emat.Read(), ndof_face, ndof_face, nf);
121 auto el_mats = Reshape(d_emat, ndof_vol, ndof_face, 2, nf);
122
123 auto permute_face = [=] MFEM_HOST_DEVICE(int local_face_id, int orient,
124 int size1d, int index)
125 {
126 if (dim == 2)
127 {
128 return internal::PermuteFace2D(local_face_id, orient, size1d, index);
129 }
130 else // dim == 3
131 {
132 return internal::PermuteFace3D(local_face_id, orient, size1d, index);
133 }
134 };
135
136 mfem::forall_3D(nf, ndof_face, ndof_face, 2, [=] MFEM_HOST_DEVICE (int f)
137 {
138 MFEM_FOREACH_THREAD(el_i, z, 2)
139 {
140 const int lf_i = d_face_info(0, el_i, f);
141 const int orient = d_face_info(1, el_i, f);
142 // Loop over face indices in "native ordering"
143 MFEM_FOREACH_THREAD(i_lex, x, ndof_face)
144 {
145 // Convert to lexicographic relative to the face itself
146 const int i_face = permute_face(lf_i, orient, d1d, i_lex);
147 // Convert from lexicographic face DOF to volume DOF
148 const int i = d_face_maps(i_lex, lf_i);
149 MFEM_FOREACH_THREAD(j, y, ndof_face)
150 {
151 el_mats(i, j, el_i, f) += face_mats(i_face, j, f);
152 }
153 }
154 }
155 });
156}
157
158}
int Size() const
Return the logical size of the array.
Definition array.hpp:147
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:337
@ TENSOR
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
Definition fe_base.hpp:165
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:244
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
Definition fespace.cpp:3835
const FiniteElement * GetFaceElement(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th face in the ...
Definition fespace.cpp:3914
Mesh * GetMesh() const
Returns the mesh.
Definition fespace.hpp:679
virtual int GetMaxElementOrder() const
Return the maximum polynomial order over all elements.
Definition fespace.hpp:705
Abstract class for all finite elements.
Definition fe_base.hpp:244
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Return a DofToQuad structure corresponding to the given IntegrationRule using the given DofToQuad::Mo...
Definition fe_base.cpp:365
virtual void GetFaceMap(const int face_id, Array< int > &face_map) const
Return the mapping from lexicographic face DOFs to lexicographic element DOFs for the given local fac...
Definition fe_base.cpp:507
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition fe_base.hpp:334
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:100
const Array< real_t > & GetWeights() const
Return the quadrature weights in a contiguous array.
Definition intrules.cpp:86
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
const IntegrationRule * IntRule
Mesh data type.
Definition mesh.hpp:64
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
Definition mesh.cpp:6531
Geometry::Type GetFaceGeometry(int i) const
Return the Geometry::Type associated with face i.
Definition mesh.cpp:1476
virtual int GetNFbyType(FaceType type) const
Returns the number of faces according to the requested type, does not count master nonconforming face...
Definition mesh.cpp:6547
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1216
FaceInformation GetFaceInformation(int f) const
Definition mesh.cpp:1193
void AssembleEAInteriorFaces(const FiniteElementSpace &trial_fes, const FiniteElementSpace &test_fes, Vector &emat, const bool add=true) override
Method defining element assembly for mixed trace integrators.
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:494
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:510
int Size() const
Returns the size of the vector.
Definition vector.hpp:226
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:502
int dim
Definition ex24.cpp:53
int index(int i, int j, int nx, int ny)
Definition life.cpp:236
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition vector.cpp:391
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_3D(int N, int X, int Y, int Z, lambda &&body)
Definition forall.hpp:774
float real_t
Definition config.hpp:43
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Definition lor_mms.hpp:30
void forall(int N, lambda &&body)
Definition forall.hpp:753
FaceType
Definition mesh.hpp:48
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition intrules.hpp:492
This structure is used as a human readable output format that deciphers the information contained in ...
Definition mesh.hpp:1980
struct mfem::Mesh::FaceInformation::@15 element[2]
bool IsInterior() const
return true if the face is an interior face to the computation domain, either a local or shared inter...
Definition mesh.hpp:2014