Files
mfem/fem/qspace.cpp
T
Will Pazner 26073f789d Deprecate GetFaceGeometryType and GetFaceBaseGeometry
Now both of these functions call GetFaceGeometry.

GetFaceGeometry has been updated to handle ghost faces.
2022-12-06 12:21:12 -08:00

172 lines
4.7 KiB
C++

// Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
#include "qspace.hpp"
namespace mfem
{
QuadratureSpaceBase::QuadratureSpaceBase(Mesh &mesh_, Geometry::Type geom,
const IntegrationRule &ir)
: mesh(mesh_), order(ir.GetOrder())
{
for (int g = 0; g < Geometry::NumGeom; g++)
{
int_rule[g] = NULL;
}
int_rule[geom] = &ir;
}
void QuadratureSpaceBase::ConstructIntRules(int dim)
{
Array<Geometry::Type> geoms;
mesh.GetGeometries(dim, geoms);
for (Geometry::Type geom : geoms)
{
int_rule[geom] = &IntRules.Get(geom, order);
}
}
void QuadratureSpace::ConstructOffsets()
{
const int num_elem = mesh.GetNE();
offsets.SetSize(num_elem + 1);
int offset = 0;
for (int i = 0; i < num_elem; i++)
{
offsets[i] = offset;
int geom = mesh.GetElementBaseGeometry(i);
MFEM_ASSERT(int_rule[geom] != NULL, "Missing integration rule.");
offset += int_rule[geom]->GetNPoints();
}
offsets[num_elem] = size = offset;
}
void QuadratureSpace::Construct()
{
ConstructIntRules(mesh.Dimension());
ConstructOffsets();
}
QuadratureSpace::QuadratureSpace(Mesh *mesh_, std::istream &in)
: QuadratureSpaceBase(*mesh_)
{
const char *msg = "invalid input stream";
std::string ident;
in >> ident; MFEM_VERIFY(ident == "QuadratureSpace", msg);
in >> ident; MFEM_VERIFY(ident == "Type:", msg);
in >> ident;
if (ident == "default_quadrature")
{
in >> ident; MFEM_VERIFY(ident == "Order:", msg);
in >> order;
}
else
{
MFEM_ABORT("unknown QuadratureSpace type: " << ident);
return;
}
Construct();
}
QuadratureSpace::QuadratureSpace(Mesh &mesh_, const IntegrationRule &ir)
: QuadratureSpaceBase(mesh_, mesh_.GetElementGeometry(0), ir)
{
MFEM_VERIFY(mesh.GetNumGeometries(mesh.Dimension()) == 1,
"Constructor not valid for mixed meshes");
ConstructOffsets();
}
void QuadratureSpace::Save(std::ostream &os) const
{
os << "QuadratureSpace\n"
<< "Type: default_quadrature\n"
<< "Order: " << order << '\n';
}
FaceQuadratureSpace::FaceQuadratureSpace(Mesh &mesh_, int order_,
FaceType face_type_)
: QuadratureSpaceBase(mesh_, order_),
face_type(face_type_),
num_faces(mesh.GetNFbyType(face_type))
{
Construct();
}
FaceQuadratureSpace::FaceQuadratureSpace(Mesh &mesh_, const IntegrationRule &ir,
FaceType face_type_)
: QuadratureSpaceBase(mesh_, mesh_.GetFaceGeometry(0), ir),
face_type(face_type_),
num_faces(mesh.GetNFbyType(face_type))
{
MFEM_VERIFY(mesh.GetNumGeometries(mesh.Dimension() - 1) == 1,
"Constructor not valid for mixed meshes");
ConstructOffsets();
}
void FaceQuadratureSpace::ConstructOffsets()
{
face_indices.SetSize(num_faces);
offsets.SetSize(num_faces + 1);
int offset = 0;
int f_idx = 0;
for (int i = 0; i < mesh.GetNumFacesWithGhost(); i++)
{
const Mesh::FaceInformation face = mesh.GetFaceInformation(i);
if (face.IsNonconformingCoarse() || !face.IsOfFaceType(face_type))
{
continue;
}
face_indices[f_idx] = i;
offsets[f_idx] = offset;
Geometry::Type geom = mesh.GetFaceGeometry(i);
MFEM_ASSERT(int_rule[geom] != NULL, "Missing integration rule");
offset += int_rule[geom]->GetNPoints();
f_idx++;
}
offsets[num_faces] = size = offset;
}
void FaceQuadratureSpace::Construct()
{
ConstructIntRules(mesh.Dimension() - 1);
ConstructOffsets();
}
int FaceQuadratureSpace::GetPermutedIndex(int idx, int iq) const
{
const int f_idx = face_indices[idx];
if (Geometry::IsTensorProduct(GetGeometry(idx)))
{
const int dim = mesh.Dimension();
const IntegrationRule &ir = GetIntRule(idx);
const int q1d = (int)floor(pow(ir.GetNPoints(), 1.0/(dim-1)) + 0.5);
const Mesh::FaceInformation face = mesh.GetFaceInformation(f_idx);
return ToLexOrdering(dim, face.element[0].local_face_id, q1d, iq);
}
else
{
return iq;
}
}
void FaceQuadratureSpace::Save(std::ostream &os) const
{
os << "FaceQuadratureSpace\n"
<< "Type: default_quadrature\n"
<< "Order: " << order << '\n';
}
} // namespace mfem