MFEM  v4.6.0
Finite element discretization library
qfunction.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 "qfunction.hpp"
13 #include "quadinterpolator.hpp"
15 
16 namespace mfem
17 {
18 
20 {
21  Vector::operator=(value);
22  return *this;
23 }
24 
26 {
27  MFEM_ASSERT(qspace && v.Size() == this->Size(), "");
29  return *this;
30 }
31 
32 
35 {
36  const char *msg = "invalid input stream";
37  std::string ident;
38 
39  qspace = new QuadratureSpace(mesh, in);
40  own_qspace = true;
41 
42  in >> ident; MFEM_VERIFY(ident == "VDim:", msg);
43  in >> vdim;
44 
45  Load(in, vdim*qspace->GetSize());
46 }
47 
48 void QuadratureFunction::Save(std::ostream &os) const
49 {
50  GetSpace()->Save(os);
51  os << "VDim: " << vdim << '\n'
52  << '\n';
53  Vector::Print(os, vdim);
54  os.flush();
55 }
56 
58 {
59  SetVDim(gf.VectorDim());
60 
61  if (auto *qs_elem = dynamic_cast<QuadratureSpace*>(qspace))
62  {
63  const FiniteElementSpace &gf_fes = *gf.FESpace();
64  const bool use_tensor_products = UsesTensorBasis(gf_fes);
65  const ElementDofOrdering ordering = use_tensor_products ?
68 
69  // Use element restriction to go from L-vector to E-vector
70  const Operator *R = gf_fes.GetElementRestriction(ordering);
71  Vector e_vec(R->Height());
72  R->Mult(gf, e_vec);
73 
74  // Use quadrature interpolator to go from E-vector to Q-vector
75  const QuadratureInterpolator *qi =
76  gf_fes.GetQuadratureInterpolator(*qs_elem);
78  qi->DisableTensorProducts(!use_tensor_products);
79  qi->Values(e_vec, *this);
80  }
81  else if (auto *qs_face = dynamic_cast<FaceQuadratureSpace*>(qspace))
82  {
83  const FiniteElementSpace &gf_fes = *gf.FESpace();
84  const bool use_tensor_products = UsesTensorBasis(gf_fes);
85  const ElementDofOrdering ordering = use_tensor_products ?
88 
89  const FaceType face_type = qs_face->GetFaceType();
90 
91  // Use element restriction to go from L-vector to E-vector
92  const Operator *R = gf_fes.GetFaceRestriction(
93  ordering, face_type, L2FaceValues::SingleValued);
94  Vector e_vec(R->Height());
95  R->Mult(gf, e_vec);
96 
97  // Use quadrature interpolator to go from E-vector to Q-vector
98  const FaceQuadratureInterpolator *qi =
99  gf_fes.GetFaceQuadratureInterpolator(qspace->GetIntRule(0), face_type);
101  qi->DisableTensorProducts(!use_tensor_products);
102  qi->Values(e_vec, *this);
103  }
104  else
105  {
106  // This branch should be unreachable
107  MFEM_ABORT("Unsupported case.");
108  }
109 }
110 
111 std::ostream &operator<<(std::ostream &os, const QuadratureFunction &qf)
112 {
113  qf.Save(os);
114  return os;
115 }
116 
117 void QuadratureFunction::SaveVTU(std::ostream &os, VTKFormat format,
118  int compression_level,
119  const std::string &field_name) const
120 {
121  os << R"(<VTKFile type="UnstructuredGrid" version="0.1")";
122  if (compression_level != 0)
123  {
124  os << R"( compressor="vtkZLibDataCompressor")";
125  }
126  os << " byte_order=\"" << VTKByteOrder() << "\">\n";
127  os << "<UnstructuredGrid>\n";
128 
129  const char *fmt_str = (format == VTKFormat::ASCII) ? "ascii" : "binary";
130  const char *type_str = (format != VTKFormat::BINARY32) ? "Float64" : "Float32";
131  std::vector<char> buf;
132 
133  const int np = qspace->GetSize();
134  const int ne = qspace->GetNE();
135  const int sdim = qspace->GetMesh()->SpaceDimension();
136 
137  // For quadrature functions, each point is a vertex cell, so number of cells
138  // is equal to number of points
139  os << "<Piece NumberOfPoints=\"" << np
140  << "\" NumberOfCells=\"" << np << "\">\n";
141 
142  // print out the points
143  os << "<Points>\n";
144  os << "<DataArray type=\"" << type_str
145  << "\" NumberOfComponents=\"3\" format=\"" << fmt_str << "\">\n";
146 
147  Vector pt(sdim);
148  for (int i = 0; i < ne; i++)
149  {
151  const IntegrationRule &ir = GetIntRule(i);
152  for (int j = 0; j < ir.Size(); j++)
153  {
154  T.Transform(ir[j], pt);
155  WriteBinaryOrASCII(os, buf, pt[0], " ", format);
156  if (sdim > 1) { WriteBinaryOrASCII(os, buf, pt[1], " ", format); }
157  else { WriteBinaryOrASCII(os, buf, 0.0, " ", format); }
158  if (sdim > 2) { WriteBinaryOrASCII(os, buf, pt[2], "", format); }
159  else { WriteBinaryOrASCII(os, buf, 0.0, "", format); }
160  if (format == VTKFormat::ASCII) { os << '\n'; }
161  }
162  }
163  if (format != VTKFormat::ASCII)
164  {
165  WriteBase64WithSizeAndClear(os, buf, compression_level);
166  }
167  os << "</DataArray>\n";
168  os << "</Points>\n";
169 
170  // Write cells (each cell is just a vertex)
171  os << "<Cells>\n";
172  // Connectivity
173  os << R"(<DataArray type="Int32" Name="connectivity" format=")"
174  << fmt_str << "\">\n";
175 
176  for (int i=0; i<np; ++i) { WriteBinaryOrASCII(os, buf, i, "\n", format); }
177  if (format != VTKFormat::ASCII)
178  {
179  WriteBase64WithSizeAndClear(os, buf, compression_level);
180  }
181  os << "</DataArray>\n";
182  // Offsets
183  os << R"(<DataArray type="Int32" Name="offsets" format=")"
184  << fmt_str << "\">\n";
185  for (int i=0; i<np; ++i) { WriteBinaryOrASCII(os, buf, i, "\n", format); }
186  if (format != VTKFormat::ASCII)
187  {
188  WriteBase64WithSizeAndClear(os, buf, compression_level);
189  }
190  os << "</DataArray>\n";
191  // Types
192  os << R"(<DataArray type="UInt8" Name="types" format=")"
193  << fmt_str << "\">\n";
194  for (int i = 0; i < np; i++)
195  {
196  uint8_t vtk_cell_type = VTKGeometry::POINT;
197  WriteBinaryOrASCII(os, buf, vtk_cell_type, "\n", format);
198  }
199  if (format != VTKFormat::ASCII)
200  {
201  WriteBase64WithSizeAndClear(os, buf, compression_level);
202  }
203  os << "</DataArray>\n";
204  os << "</Cells>\n";
205 
206  os << "<PointData>\n";
207  os << "<DataArray type=\"" << type_str << "\" Name=\"" << field_name
208  << "\" format=\"" << fmt_str << "\" NumberOfComponents=\"" << vdim
209  << "\">\n";
210  for (int i = 0; i < ne; i++)
211  {
212  DenseMatrix vals;
213  GetValues(i, vals);
214  for (int j = 0; j < vals.Size(); ++j)
215  {
216  for (int vd = 0; vd < vdim; ++vd)
217  {
218  WriteBinaryOrASCII(os, buf, vals(vd, j), " ", format);
219  }
220  if (format == VTKFormat::ASCII) { os << '\n'; }
221  }
222  }
223  if (format != VTKFormat::ASCII)
224  {
225  WriteBase64WithSizeAndClear(os, buf, compression_level);
226  }
227  os << "</DataArray>\n";
228  os << "</PointData>\n";
229 
230  os << "</Piece>\n";
231  os << "</UnstructuredGrid>\n";
232  os << "</VTKFile>" << std::endl;
233 }
234 
235 void QuadratureFunction::SaveVTU(const std::string &filename, VTKFormat format,
236  int compression_level,
237  const std::string &field_name) const
238 {
239  std::ofstream f(filename + ".vtu");
240  SaveVTU(f, format, compression_level, field_name);
241 }
242 
243 }
int GetNE() const
Return the number of entities.
Definition: qspace.hpp:61
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:96
Class for grid function - Vector with associated FE space.
Definition: gridfunc.hpp:30
void ProjectGridFunction(const GridFunction &gf)
Evaluate a grid function at each quadrature point.
Definition: qfunction.cpp:57
QuadratureSpaceBase * qspace
Associated QuadratureSpaceBase object.
Definition: qfunction.hpp:26
bool own_qspace
Does this own the associated QuadratureSpaceBase?
Definition: qfunction.hpp:27
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
Definition: vector.cpp:756
void DisableTensorProducts(bool disable=true) const
Disable the use of tensor product evaluations, for tensor-product elements, e.g. quads and hexes...
virtual const FaceRestriction * GetFaceRestriction(ElementDofOrdering f_ordering, FaceType, L2FaceValues mul=L2FaceValues::DoubleValued) const
Return an Operator that converts L-vectors to E-vectors on each face.
Definition: fespace.cpp:1335
int Size() const
Returns the size of the vector.
Definition: vector.hpp:197
Data type dense matrix using column-major storage.
Definition: densemat.hpp:23
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
int vdim
Vector dimension.
Definition: qfunction.hpp:28
void SaveVTU(std::ostream &out, VTKFormat format=VTKFormat::ASCII, int compression_level=0, const std::string &field_name="u") const
Write the QuadratureFunction to out in VTU (ParaView) format.
Definition: qfunction.cpp:117
bool UsesTensorBasis(const FiniteElementSpace &fes)
Return true if the mesh contains only one topology and the elements are tensor elements.
Definition: fespace.hpp:1306
Data arrays will be written in ASCII format.
void WriteBinaryOrASCII(std::ostream &os, std::vector< char > &buf, const T &val, const char *suffix, VTKFormat format)
Write either ASCII data to the stream or binary data to the buffer depending on the given format...
Definition: vtk.hpp:147
virtual ElementTransformation * GetTransformation(int idx)=0
Get the (element or face) transformation of entity idx.
const ElementRestrictionOperator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
Definition: fespace.cpp:1302
std::function< double(const Vector &)> f(double mass_coeff)
Definition: lor_mms.hpp:30
Vector & operator=(const double *v)
Copy Size() entries from v.
Definition: vector.cpp:119
void Load(std::istream **in, int np, int *dim)
Reads a vector from multiple files.
Definition: vector.cpp:50
FaceType
Definition: mesh.hpp:45
Native ordering as defined by the FiniteElement.
int Size() const
For backward compatibility define Size to be synonym of Width()
Definition: densemat.hpp:102
A class that performs interpolation from an E-vector to quadrature point values and/or derivatives (Q...
const IntegrationRule & GetIntRule(int idx) const
Get the IntegrationRule associated with entity (element or face) idx.
Definition: qfunction.hpp:176
QuadratureFunction()
Default constructor, results in an empty vector.
Definition: qfunction.hpp:32
VTKFormat
Data array format for VTK and VTU files.
Definition: vtk.hpp:98
const FaceQuadratureInterpolator * GetFaceQuadratureInterpolator(const IntegrationRule &ir, FaceType type) const
Return a FaceQuadratureInterpolator that interpolates E-vectors to quadrature point values and/or der...
Definition: fespace.cpp:1399
Mesh * GetMesh() const
Returns the mesh.
Definition: qspace.hpp:64
void SetVDim(int vdim_)
Set the vector dimension, updating the size by calling Vector::SetSize().
Definition: qfunction.hpp:78
FiniteElementSpace * FESpace()
Definition: gridfunc.hpp:691
A class that performs interpolation from a face E-vector to quadrature point values and/or derivative...
void DisableTensorProducts(bool disable=true) const
Disable the use of tensor product evaluations, for tensor-product elements, e.g. quads and hexes...
QuadratureFunction & operator=(double value)
Set this equal to a constant value.
Definition: qfunction.cpp:19
virtual void Save(std::ostream &out) const =0
Write the QuadratureSpace to the stream out.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition: fespace.hpp:219
void Values(const Vector &e_vec, Vector &q_val) const
Interpolate the values of the E-vector e_vec at quadrature points.
void Save(std::ostream &out) const
Write the QuadratureFunction to the stream out.
Definition: qfunction.cpp:48
void Values(const Vector &e_vec, Vector &q_val) const
Interpolate the values of the E-vector e_vec at quadrature points.
const IntegrationRule & GetIntRule(int idx) const
Return the IntegrationRule associated with entity idx.
Definition: qspace.hpp:73
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:66
void GetValues(int idx, Vector &values)
Return all values associated with mesh element idx in a Vector.
Definition: qfunction.hpp:206
int SpaceDimension() const
Dimension of the physical space containing the mesh.
Definition: mesh.hpp:1023
QuadratureSpaceBase * GetSpace()
Get the associated QuadratureSpaceBase object.
Definition: qfunction.hpp:82
void SetOutputLayout(QVectorLayout layout) const
Set the desired output Q-vector layout. The default value is QVectorLayout::byNODES.
const QuadratureInterpolator * GetQuadratureInterpolator(const IntegrationRule &ir) const
Return a QuadratureInterpolator that interpolates E-vectors to quadrature point values and/or derivat...
Definition: fespace.cpp:1370
int VectorDim() const
Definition: gridfunc.cpp:323
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
Definition: fespace.hpp:74
const char * VTKByteOrder()
Determine the byte order and return either "BigEndian" or "LittleEndian".
Definition: vtk.cpp:602
static const int POINT
Definition: vtk.hpp:32
Lexicographic ordering for tensor-product FiniteElements.
std::ostream & operator<<(std::ostream &os, SparseMatrix const &mat)
Definition: sparsemat.hpp:711
int Size() const
Return the logical size of the array.
Definition: array.hpp:141
Vector data type.
Definition: vector.hpp:58
void SetOutputLayout(QVectorLayout layout) const
Set the desired output Q-vector layout. The default value is QVectorLayout::byNODES.
Class representing the storage layout of a QuadratureFunction.
Definition: qspace.hpp:101
int GetSize() const
Return the total number of quadrature points.
Definition: qspace.hpp:55
Abstract operator.
Definition: operator.hpp:24
void WriteBase64WithSizeAndClear(std::ostream &os, std::vector< char > &buf, int compression_level)
Encode in base 64 (and potentially compress) the given data, write it to the output stream (with a he...
Definition: vtk.cpp:654
Represents values or vectors of values at quadrature points on a mesh.
Definition: qfunction.hpp:23
VDIM x NQPT x NE (values) / VDIM x DIM x NQPT x NE (grads)