Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8501138bc | ||
|
|
c679c99b35 | ||
|
|
3f9a3658a6 |
@@ -50,7 +50,6 @@ variables:
|
||||
AUTOTEST_REPO: ssh://git@mybitbucket.llnl.gov:7999/mfem/autotest.git
|
||||
MFEM_DATA_REPO: https://github.com/mfem/data.git
|
||||
ARTIFACTS_DIR: artifacts
|
||||
SLURM_OVERLAP: 1
|
||||
|
||||
# The pipeline is divided into stages. Usually, jobs in a given stage wait for
|
||||
# the preceding stages to complete before to start. However, we sometimes use
|
||||
|
||||
@@ -12,21 +12,6 @@ Version 4.3.1 (development)
|
||||
===========================
|
||||
- Added support for hr-adaptivity using TMOP-based error estimator.
|
||||
|
||||
- Adding lowest order Nedelec and Raviart-Thomas basis functions on wedge
|
||||
shaped elements.
|
||||
|
||||
- Added initial support for meshes with pyramidal elements, including several
|
||||
pyramidal meshes in the data/ directory and support for the lowest order H1,
|
||||
Nedelec, Raviart-Thomas, and L2 basis functions on pyramids.
|
||||
|
||||
- Updated the hypre interface according to changes in hypre-2.22.1. The ADS
|
||||
solver is now fully working on GPUs.
|
||||
|
||||
- Tetrahedral meshes no longer need to be reordered to support high order
|
||||
Nedelec basis functions. This will allow future support for Nedelec basis
|
||||
functions on wedges and pyramids which are not amenable to reordering. The
|
||||
ReorientTetMesh method of the Mesh and ParMesh classes has been deprecated.
|
||||
|
||||
|
||||
Version 4.3, released on July 29, 2021
|
||||
======================================
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
cff-version: 1.2.0
|
||||
message: "If you use MFEM, please cite it as follows."
|
||||
authors:
|
||||
- family-names: "MFEM Team"
|
||||
title: "MFEM: Modular Finite Element Methods [Software]"
|
||||
doi: 10.11578/dc.20171025.1248
|
||||
url: "https://mfem.org"
|
||||
preferred-citation:
|
||||
type: article
|
||||
authors:
|
||||
- family-names: "Anderson"
|
||||
given-names: "Robert"
|
||||
orcid: "https://orcid.org/0000-0002-3508-9944"
|
||||
- family-names: "Andrej"
|
||||
given-names: "Julian"
|
||||
orcid: "https://orcid.org/0000-0001-7661-4840"
|
||||
- family-names: "Barker"
|
||||
given-names: "Andrew"
|
||||
orcid: "https://orcid.org/0000-0003-3572-911X"
|
||||
- family-names: "Bramwell"
|
||||
given-names: "Jamie"
|
||||
- family-names: "Camier"
|
||||
given-names: "Jean-Sylvain"
|
||||
orcid: "https://orcid.org/0000-0003-2421-1999"
|
||||
- family-names: "Cerveny"
|
||||
given-names: "Jakub"
|
||||
orcid: "https://orcid.org/0000-0003-4231-2531"
|
||||
- family-names: "Dobrev"
|
||||
given-names: "Veselin"
|
||||
orcid: "https://orcid.org/0000-0003-1793-5622"
|
||||
- family-names: "Dudouit"
|
||||
given-names: "Yohann"
|
||||
orcid: "https://orcid.org/0000-0001-5831-561X"
|
||||
- family-names: "Fisher"
|
||||
given-names: "Aaron"
|
||||
- family-names: "Kolev"
|
||||
given-names: "Tzanio"
|
||||
orcid: "https://orcid.org/0000-0002-2810-3090"
|
||||
- family-names: "Pazner"
|
||||
given-names: "Will"
|
||||
orcid: "https://orcid.org/0000-0003-4885-2934"
|
||||
- family-names: "Stowell"
|
||||
given-names: "Mark"
|
||||
orcid: "https://orcid.org/0000-0002-5389-7435"
|
||||
- family-names: "Tomov"
|
||||
given-names: "Vladimir"
|
||||
orcid: "https://orcid.org/0000-0002-1846-6816"
|
||||
- family-names: "Akkerman"
|
||||
given-names: "Ido"
|
||||
orcid: "https://orcid.org/0000-0002-5937-0300"
|
||||
- family-names: "Dahm"
|
||||
given-names: "Johann"
|
||||
orcid: "https://orcid.org/0000-0001-9657-3564"
|
||||
- family-names: "Medina"
|
||||
given-names: "David"
|
||||
- family-names: "Zampini"
|
||||
given-names: "Stefano"
|
||||
orcid: "https://orcid.org/0000-0002-0435-0433"
|
||||
doi: "10.1016/j.camwa.2020.06.009"
|
||||
journal: "Computers \\& Mathematics with Applications"
|
||||
month: 1
|
||||
start: 42 # First page number
|
||||
end: 74 # Last page number
|
||||
title: "MFEM: A Modular Finite Element Methods Library"
|
||||
volume: 81
|
||||
year: 2021
|
||||
@@ -175,10 +175,6 @@ else()
|
||||
set(MFEM_DEBUG OFF)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
add_definitions(-D_USE_MATH_DEFINES)
|
||||
endif()
|
||||
|
||||
# MPI -> hypre; PETSc (optional)
|
||||
if (MFEM_USE_MPI)
|
||||
find_package(MPI REQUIRED)
|
||||
|
||||
@@ -549,7 +549,7 @@ The specific libraries and their options are:
|
||||
Options: HYPRE_OPT, HYPRE_LIB.
|
||||
Versions: HYPRE >= 2.10.0b (HYPRE built without CUDA)
|
||||
HYPRE >= 2.20.0 (HYPRE built with '--enable-mixedint')
|
||||
HYPRE >= 2.22.1 (HYPRE built with CUDA)
|
||||
HYPRE >= 2.22.0 (HYPRE built with CUDA)
|
||||
|
||||
- METIS, used when MFEM_USE_METIS = YES. If using METIS 5, set
|
||||
MFEM_USE_METIS_5 = YES (default is to use METIS 4).
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
MFEM INLINE mesh v1.0
|
||||
|
||||
type = pyramid
|
||||
nx = 4
|
||||
ny = 4
|
||||
nz = 4
|
||||
sx = 1.0
|
||||
sy = 1.0
|
||||
sz = 1.0
|
||||
@@ -1,43 +0,0 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
# PYRAMID = 7
|
||||
#
|
||||
|
||||
dimension
|
||||
3
|
||||
|
||||
elements
|
||||
2
|
||||
1 7 4 3 2 1 0
|
||||
1 7 1 2 3 4 5
|
||||
|
||||
boundary
|
||||
8
|
||||
1 2 0 2 1
|
||||
2 2 0 3 2
|
||||
3 2 0 4 3
|
||||
4 2 0 1 4
|
||||
5 2 1 2 5
|
||||
6 2 2 3 5
|
||||
7 2 3 4 5
|
||||
8 2 4 1 5
|
||||
|
||||
vertices
|
||||
6
|
||||
3
|
||||
0 0 -1
|
||||
1 0 0
|
||||
0 1 0
|
||||
-1 0 0
|
||||
0 -1 0
|
||||
0 0 1
|
||||
@@ -1,38 +0,0 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
# PYRAMID = 7
|
||||
#
|
||||
|
||||
dimension
|
||||
3
|
||||
|
||||
elements
|
||||
1
|
||||
1 7 0 1 2 3 4
|
||||
|
||||
boundary
|
||||
5
|
||||
1 3 3 2 1 0
|
||||
2 2 0 1 4
|
||||
3 2 1 2 4
|
||||
4 2 2 3 4
|
||||
5 2 3 0 4
|
||||
|
||||
vertices
|
||||
5
|
||||
3
|
||||
0 0 0
|
||||
1 0 0
|
||||
1 1 0
|
||||
0 1 0
|
||||
0 0 1
|
||||
@@ -206,9 +206,9 @@ int main(int argc, char *argv[])
|
||||
cout << "Size of linear system: " << A->Height() << endl;
|
||||
|
||||
// 11. Solve the linear system A X = B.
|
||||
MFEM_PERF_BEGIN("Solve A X=B");
|
||||
if (!pa)
|
||||
{
|
||||
MFEM_PERF_SCOPE("Solve A X=B (FA)");
|
||||
#ifndef MFEM_USE_SUITESPARSE
|
||||
// Use a simple symmetric Gauss-Seidel preconditioner with PCG.
|
||||
GSSmoother M((SparseMatrix&)(*A));
|
||||
@@ -223,7 +223,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
else // Jacobi preconditioning in partial assembly mode
|
||||
{
|
||||
MFEM_PERF_SCOPE("Solve A X=B (PA)");
|
||||
if (UsesTensorBasis(fespace))
|
||||
{
|
||||
OperatorJacobiSmoother M(a, ess_tdof_list);
|
||||
@@ -234,6 +233,7 @@ int main(int argc, char *argv[])
|
||||
CG(*A, B, X, 1, 400, 1e-12, 0.0);
|
||||
}
|
||||
}
|
||||
MFEM_PERF_END("Solve A X=B");
|
||||
// 12. Recover the solution as a finite element grid function.
|
||||
a.RecoverFEMSolution(X, b, x);
|
||||
|
||||
|
||||
+18
-19
@@ -231,29 +231,28 @@ int main(int argc, char *argv[])
|
||||
// 13. Solve the linear system A X = B.
|
||||
// * With full assembly, use the BoomerAMG preconditioner from hypre.
|
||||
// * With partial assembly, use Jacobi smoothing, for now.
|
||||
MFEM_PERF_BEGIN("Solve A X = B");
|
||||
Solver *prec = NULL;
|
||||
if (pa)
|
||||
{
|
||||
MFEM_PERF_SCOPE("Solve A X=B");
|
||||
Solver *prec = NULL;
|
||||
if (pa)
|
||||
if (UsesTensorBasis(fespace))
|
||||
{
|
||||
if (UsesTensorBasis(fespace))
|
||||
{
|
||||
prec = new OperatorJacobiSmoother(a, ess_tdof_list);
|
||||
}
|
||||
prec = new OperatorJacobiSmoother(a, ess_tdof_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
prec = new HypreBoomerAMG;
|
||||
}
|
||||
CGSolver cg(MPI_COMM_WORLD);
|
||||
cg.SetRelTol(1e-12);
|
||||
cg.SetMaxIter(2000);
|
||||
cg.SetPrintLevel(1);
|
||||
if (prec) { cg.SetPreconditioner(*prec); }
|
||||
cg.SetOperator(*A);
|
||||
cg.Mult(B, X);
|
||||
delete prec;
|
||||
}
|
||||
else
|
||||
{
|
||||
prec = new HypreBoomerAMG;
|
||||
}
|
||||
CGSolver cg(MPI_COMM_WORLD);
|
||||
cg.SetRelTol(1e-12);
|
||||
cg.SetMaxIter(2000);
|
||||
cg.SetPrintLevel(1);
|
||||
if (prec) { cg.SetPreconditioner(*prec); }
|
||||
cg.SetOperator(*A);
|
||||
cg.Mult(B, X);
|
||||
delete prec;
|
||||
MFEM_PERF_END("Solve A X = B");
|
||||
// 14. Recover the parallel grid function corresponding to X. This is the
|
||||
// local finite element solution on each processor.
|
||||
a.RecoverFEMSolution(X, b, x);
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
// ex1 -m ../data/fichera.mesh
|
||||
// ex1 -m ../data/fichera-mixed.mesh
|
||||
// ex1 -m ../data/toroid-wedge.mesh
|
||||
// ex1 -m ../data/octahedron.mesh -o 1
|
||||
// ex1 -m ../data/periodic-annulus-sector.msh
|
||||
// ex1 -m ../data/periodic-torus-sector.msh
|
||||
// ex1 -m ../data/square-disc-p2.vtk -o 2
|
||||
|
||||
@@ -118,6 +118,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
pmesh->UniformRefinement();
|
||||
}
|
||||
pmesh->ReorientTetMesh();
|
||||
|
||||
// 7. Define a parallel finite element space on the parallel mesh. Here we
|
||||
// use the Nedelec finite elements of the specified order.
|
||||
|
||||
+4
-7
@@ -24,10 +24,7 @@
|
||||
// class ConductionOperator defining C(u)), as well as their
|
||||
// implicit time integration. Note that implementing the method
|
||||
// ConductionOperator::ImplicitSolve is the only requirement for
|
||||
// high-order implicit (SDIRK) time integration. In this example,
|
||||
// the diffusion operator is linearized by evaluating with the
|
||||
// lagged solution from the previous timestep, so there is only
|
||||
// a linear solve.
|
||||
// high-order implicit (SDIRK) time integration.
|
||||
//
|
||||
// We recommend viewing examples 2, 9 and 10 before viewing this
|
||||
// example.
|
||||
@@ -329,8 +326,8 @@ ConductionOperator::ConductionOperator(FiniteElementSpace &f, double al,
|
||||
void ConductionOperator::Mult(const Vector &u, Vector &du_dt) const
|
||||
{
|
||||
// Compute:
|
||||
// du_dt = M^{-1}*-Ku
|
||||
// for du_dt, where K is linearized by using u from the previous timestep
|
||||
// du_dt = M^{-1}*-K(u)
|
||||
// for du_dt
|
||||
Kmat.Mult(u, z);
|
||||
z.Neg(); // z = -z
|
||||
M_solver.Mult(z, du_dt);
|
||||
@@ -341,7 +338,7 @@ void ConductionOperator::ImplicitSolve(const double dt,
|
||||
{
|
||||
// Solve the equation:
|
||||
// du_dt = M^{-1}*[-K(u + dt*du_dt)]
|
||||
// for du_dt, where K is linearized by using u from the previous timestep
|
||||
// for du_dt
|
||||
if (!T)
|
||||
{
|
||||
T = Add(1.0, Mmat, dt, Kmat);
|
||||
|
||||
+5
-8
@@ -24,11 +24,8 @@
|
||||
// class ConductionOperator defining C(u)), as well as their
|
||||
// implicit time integration. Note that implementing the method
|
||||
// ConductionOperator::ImplicitSolve is the only requirement for
|
||||
// high-order implicit (SDIRK) time integration. In this example,
|
||||
// the diffusion operator is linearized by evaluating with the
|
||||
// lagged solution from the previous timestep, so there is only
|
||||
// a linear solve. Optional saving with ADIOS2
|
||||
// (adios2.readthedocs.io) is also illustrated.
|
||||
// high-order implicit (SDIRK) time integration. Optional saving
|
||||
// with ADIOS2 (adios2.readthedocs.io) is also illustrated.
|
||||
//
|
||||
// We recommend viewing examples 2, 9 and 10 before viewing this
|
||||
// example.
|
||||
@@ -423,8 +420,8 @@ ConductionOperator::ConductionOperator(ParFiniteElementSpace &f, double al,
|
||||
void ConductionOperator::Mult(const Vector &u, Vector &du_dt) const
|
||||
{
|
||||
// Compute:
|
||||
// du_dt = M^{-1}*-Ku
|
||||
// for du_dt, where K is linearized by using u from the previous timestep
|
||||
// du_dt = M^{-1}*-K(u)
|
||||
// for du_dt
|
||||
Kmat.Mult(u, z);
|
||||
z.Neg(); // z = -z
|
||||
M_solver.Mult(z, du_dt);
|
||||
@@ -435,7 +432,7 @@ void ConductionOperator::ImplicitSolve(const double dt,
|
||||
{
|
||||
// Solve the equation:
|
||||
// du_dt = M^{-1}*[-K(u + dt*du_dt)]
|
||||
// for du_dt, where K is linearized by using u from the previous timestep
|
||||
// for du_dt
|
||||
if (!T)
|
||||
{
|
||||
T = Add(1.0, Mmat, dt, Kmat);
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
// mpirun -np 4 ex1p -m ../data/fichera.mesh
|
||||
// mpirun -np 4 ex1p -m ../data/fichera-mixed.mesh
|
||||
// mpirun -np 4 ex1p -m ../data/toroid-wedge.mesh
|
||||
// mpirun -np 4 ex1p -m ../data/octahedron.mesh -o 1
|
||||
// mpirun -np 4 ex1p -m ../data/periodic-annulus-sector.msh
|
||||
// mpirun -np 4 ex1p -m ../data/periodic-torus-sector.msh
|
||||
// mpirun -np 4 ex1p -m ../data/square-disc-p2.vtk -o 2
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
// ex22 -m ../data/inline-hex.mesh -o 2 -p 1
|
||||
// ex22 -m ../data/inline-hex.mesh -o 2 -p 2
|
||||
// ex22 -m ../data/inline-hex.mesh -o 2 -p 2 -pa
|
||||
// ex22 -m ../data/inline-wedge.mesh -o 1
|
||||
// ex22 -m ../data/inline-pyramid.mesh -o 1
|
||||
// ex22 -m ../data/star.mesh -r 1 -o 2 -sigma 10.0
|
||||
//
|
||||
// Device sample runs:
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
// mpirun -np 4 ex22p -m ../data/inline-hex.mesh -o 2 -p 1
|
||||
// mpirun -np 4 ex22p -m ../data/inline-hex.mesh -o 2 -p 2
|
||||
// mpirun -np 4 ex22p -m ../data/inline-hex.mesh -o 1 -p 2 -pa
|
||||
// mpirun -np 4 ex22p -m ../data/inline-wedge.mesh -o 1
|
||||
// mpirun -np 4 ex22p -m ../data/inline-pyramid.mesh -o 1
|
||||
// mpirun -np 4 ex22p -m ../data/star.mesh -o 2 -sigma 10.0
|
||||
//
|
||||
// Device sample runs:
|
||||
|
||||
@@ -113,6 +113,7 @@ int main(int argc, char *argv[])
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
}
|
||||
mesh->ReorientTetMesh();
|
||||
|
||||
// 5. Define a finite element space on the mesh. Here we use Nedelec or
|
||||
// Raviart-Thomas finite elements of the specified order.
|
||||
|
||||
@@ -141,6 +141,7 @@ int main(int argc, char *argv[])
|
||||
pmesh->UniformRefinement();
|
||||
}
|
||||
}
|
||||
pmesh->ReorientTetMesh();
|
||||
|
||||
// 7. Define a parallel finite element space on the parallel mesh. Here we
|
||||
// use Nedelec or Raviart-Thomas finite elements of the specified order.
|
||||
|
||||
+5
-3
@@ -92,7 +92,7 @@ class PMLDiagMatrixCoefficient : public VectorCoefficient
|
||||
{
|
||||
private:
|
||||
CartesianPML * pml = nullptr;
|
||||
void (*Function)(const Vector &, CartesianPML *, Vector &);
|
||||
void (*Function)(const Vector &, CartesianPML * , Vector &);
|
||||
public:
|
||||
PMLDiagMatrixCoefficient(int dim, void(*F)(const Vector &, CartesianPML *,
|
||||
Vector &),
|
||||
@@ -277,8 +277,10 @@ int main(int argc, char *argv[])
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
|
||||
// 6. Set element attributes in order to distinguish elements in the
|
||||
// PML region
|
||||
// 6. Reorient mesh in case of a tet mesh
|
||||
mesh->ReorientTetMesh();
|
||||
|
||||
// Set element attributes in order to distinguish elements in the PML region
|
||||
pml->SetAttributes(mesh);
|
||||
|
||||
// 7. Define a finite element space on the mesh. Here we use the Nedelec
|
||||
|
||||
+4
-1
@@ -92,7 +92,7 @@ class PMLDiagMatrixCoefficient : public VectorCoefficient
|
||||
{
|
||||
private:
|
||||
CartesianPML * pml = nullptr;
|
||||
void (*Function)(const Vector &, CartesianPML *, Vector &);
|
||||
void (*Function)(const Vector &, CartesianPML * , Vector &);
|
||||
public:
|
||||
PMLDiagMatrixCoefficient(int dim, void(*F)(const Vector &, CartesianPML *,
|
||||
Vector &),
|
||||
@@ -316,6 +316,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
// 7a. Reorient mesh in case of a tet mesh
|
||||
pmesh->ReorientTetMesh();
|
||||
|
||||
// 8. Set element attributes in order to distinguish elements in the PML
|
||||
pml->SetAttributes(pmesh);
|
||||
|
||||
|
||||
+1
-2
@@ -16,8 +16,6 @@
|
||||
// ex3 -m ../data/beam-hex-nurbs.mesh
|
||||
// ex3 -m ../data/amr-hex.mesh
|
||||
// ex3 -m ../data/fichera-amr.mesh
|
||||
// ex3 -m ../data/ref-prism.mesh -o 1
|
||||
// ex3 -m ../data/octahedron.mesh -o 1
|
||||
// ex3 -m ../data/star-surf.mesh -o 1
|
||||
// ex3 -m ../data/mobius-strip.mesh -f 0.1
|
||||
// ex3 -m ../data/klein-bottle.mesh -f 0.1
|
||||
@@ -115,6 +113,7 @@ int main(int argc, char *argv[])
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
}
|
||||
mesh->ReorientTetMesh();
|
||||
|
||||
// 5. Define a finite element space on the mesh. Here we use the Nedelec
|
||||
// finite elements of the specified order.
|
||||
|
||||
+4
-3
@@ -16,8 +16,6 @@
|
||||
// mpirun -np 4 ex3p -m ../data/beam-hex-nurbs.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/amr-quad.mesh -o 2
|
||||
// mpirun -np 4 ex3p -m ../data/amr-hex.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/ref-prism.mesh -o 1
|
||||
// mpirun -np 4 ex3p -m ../data/octahedron.mesh -o 1
|
||||
// mpirun -np 4 ex3p -m ../data/star-surf.mesh -o 2
|
||||
// mpirun -np 4 ex3p -m ../data/mobius-strip.mesh -o 2 -f 0.1
|
||||
// mpirun -np 4 ex3p -m ../data/klein-bottle.mesh -o 2 -f 0.1
|
||||
@@ -141,7 +139,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 6. Define a parallel mesh by a partitioning of the serial mesh. Refine
|
||||
// this mesh further in parallel to increase the resolution. Once the
|
||||
// parallel mesh is defined, the serial mesh can be deleted.
|
||||
// parallel mesh is defined, the serial mesh can be deleted. Tetrahedral
|
||||
// meshes need to be reoriented before we can define high-order Nedelec
|
||||
// spaces on them.
|
||||
ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
|
||||
delete mesh;
|
||||
{
|
||||
@@ -151,6 +151,7 @@ int main(int argc, char *argv[])
|
||||
pmesh->UniformRefinement();
|
||||
}
|
||||
}
|
||||
pmesh->ReorientTetMesh();
|
||||
|
||||
// 7. Define a parallel finite element space on the parallel mesh. Here we
|
||||
// use the Nedelec finite elements of the specified order.
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
// ex4 -m ../data/amr-hex.mesh
|
||||
// ex4 -m ../data/amr-hex.mesh -o 2 -hb
|
||||
// ex4 -m ../data/fichera-amr.mesh -o 2 -sc
|
||||
// ex4 -m ../data/ref-prism.mesh -o 1
|
||||
// ex4 -m ../data/octahedron.mesh -o 1
|
||||
// ex4 -m ../data/star-surf.mesh -o 1
|
||||
//
|
||||
// Device sample runs:
|
||||
|
||||
+4
-3
@@ -19,8 +19,6 @@
|
||||
// mpirun -np 3 ex4p -m ../data/amr-quad.mesh -o 2 -hb
|
||||
// mpirun -np 4 ex4p -m ../data/amr-hex.mesh -o 2 -sc
|
||||
// mpirun -np 4 ex4p -m ../data/amr-hex.mesh -o 2 -hb
|
||||
// mpirun -np 4 ex4p -m ../data/ref-prism.mesh -o 1
|
||||
// mpirun -np 4 ex4p -m ../data/octahedron.mesh -o 1
|
||||
// mpirun -np 4 ex4p -m ../data/star-surf.mesh -o 3 -hb
|
||||
//
|
||||
// Device sample runs:
|
||||
@@ -137,7 +135,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 6. Define a parallel mesh by a partitioning of the serial mesh. Refine
|
||||
// this mesh further in parallel to increase the resolution. Once the
|
||||
// parallel mesh is defined, the serial mesh can be deleted.
|
||||
// parallel mesh is defined, the serial mesh can be deleted. Tetrahedral
|
||||
// meshes need to be reoriented before we can define high-order Nedelec
|
||||
// spaces on them (this is needed in the ADS solver below).
|
||||
ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
|
||||
delete mesh;
|
||||
{
|
||||
@@ -147,6 +147,7 @@ int main(int argc, char *argv[])
|
||||
pmesh->UniformRefinement();
|
||||
}
|
||||
}
|
||||
pmesh->ReorientTetMesh();
|
||||
|
||||
// 7. Define a parallel finite element space on the parallel mesh. Here we
|
||||
// use the Raviart-Thomas finite elements of the specified order.
|
||||
|
||||
@@ -106,6 +106,7 @@ int main(int argc, char *argv[])
|
||||
pmesh->UniformRefinement();
|
||||
}
|
||||
}
|
||||
pmesh->ReorientTetMesh();
|
||||
|
||||
// 6. Define the trial, interfacial (trace) and test DPG spaces:
|
||||
// - The trial space, x0_space, contains the non-interfacial unknowns and
|
||||
|
||||
@@ -121,7 +121,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 5. Define a parallel mesh by a partitioning of the serial mesh. Refine
|
||||
// this mesh further in parallel to increase the resolution. Once the
|
||||
// parallel mesh is defined, the serial mesh can be deleted.
|
||||
// parallel mesh is defined, the serial mesh can be deleted. Tetrahedral
|
||||
// meshes need to be reoriented before we can define high-order Nedelec
|
||||
// spaces on them.
|
||||
ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
|
||||
delete mesh;
|
||||
{
|
||||
@@ -131,6 +133,7 @@ int main(int argc, char *argv[])
|
||||
pmesh->UniformRefinement();
|
||||
}
|
||||
}
|
||||
pmesh->ReorientTetMesh();
|
||||
|
||||
// 6. Define a parallel finite element space on the parallel mesh. Here we
|
||||
// use the Nedelec finite elements of the specified order.
|
||||
|
||||
@@ -122,7 +122,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 5. Define a parallel mesh by a partitioning of the serial mesh. Refine
|
||||
// this mesh further in parallel to increase the resolution. Once the
|
||||
// parallel mesh is defined, the serial mesh can be deleted.
|
||||
// parallel mesh is defined, the serial mesh can be deleted. Tetrahedral
|
||||
// meshes need to be reoriented before we can define high-order Nedelec
|
||||
// spaces on them (this is needed in the ADS solver below).
|
||||
ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
|
||||
delete mesh;
|
||||
{
|
||||
@@ -132,6 +134,7 @@ int main(int argc, char *argv[])
|
||||
pmesh->UniformRefinement();
|
||||
}
|
||||
}
|
||||
pmesh->ReorientTetMesh();
|
||||
|
||||
// 6. Define a parallel finite element space on the parallel mesh. Here we
|
||||
// use the Raviart-Thomas finite elements of the specified order.
|
||||
|
||||
@@ -39,7 +39,6 @@ set(SRCS
|
||||
complex_fem.cpp
|
||||
convergence.cpp
|
||||
datacollection.cpp
|
||||
doftrans.cpp
|
||||
eltrans.cpp
|
||||
estimators.cpp
|
||||
fe.cpp
|
||||
@@ -120,7 +119,6 @@ set(HDRS
|
||||
complex_fem.hpp
|
||||
convergence.hpp
|
||||
datacollection.hpp
|
||||
doftrans.hpp
|
||||
eltrans.hpp
|
||||
estimators.hpp
|
||||
fe.hpp
|
||||
|
||||
+24
-58
@@ -391,7 +391,6 @@ void BilinearForm::Assemble(int skip_zeros)
|
||||
}
|
||||
|
||||
ElementTransformation *eltrans;
|
||||
DofTransformation * doftrans;
|
||||
Mesh *mesh = fes -> GetMesh();
|
||||
DenseMatrix elmat, *elmat_p;
|
||||
|
||||
@@ -425,7 +424,7 @@ void BilinearForm::Assemble(int skip_zeros)
|
||||
for (int i = 0; i < fes -> GetNE(); i++)
|
||||
{
|
||||
int elem_attr = fes->GetMesh()->GetAttribute(i);
|
||||
doftrans = fes->GetElementVDofs(i, vdofs);
|
||||
fes->GetElementVDofs(i, vdofs);
|
||||
if (element_matrices)
|
||||
{
|
||||
elmat_p = &(*element_matrices)(i);
|
||||
@@ -459,11 +458,6 @@ void BilinearForm::Assemble(int skip_zeros)
|
||||
{
|
||||
elmat_p = &elmat;
|
||||
}
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->TransformDual(elmat);
|
||||
}
|
||||
elmat_p = &elmat;
|
||||
}
|
||||
if (static_cond)
|
||||
{
|
||||
@@ -509,7 +503,7 @@ void BilinearForm::Assemble(int skip_zeros)
|
||||
if (bdr_attr_marker[bdr_attr-1] == 0) { continue; }
|
||||
|
||||
const FiniteElement &be = *fes->GetBE(i);
|
||||
doftrans = fes -> GetBdrElementVDofs (i, vdofs);
|
||||
fes -> GetBdrElementVDofs (i, vdofs);
|
||||
eltrans = fes -> GetBdrElementTransformation (i);
|
||||
int k = 0;
|
||||
for (; k < boundary_integs.Size(); k++)
|
||||
@@ -529,22 +523,17 @@ void BilinearForm::Assemble(int skip_zeros)
|
||||
boundary_integs[k]->AssembleElementMatrix(be, *eltrans, elemmat);
|
||||
elmat += elemmat;
|
||||
}
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->TransformDual(elmat);
|
||||
}
|
||||
elmat_p = &elmat;
|
||||
if (!static_cond)
|
||||
{
|
||||
mat->AddSubMatrix(vdofs, vdofs, *elmat_p, skip_zeros);
|
||||
mat->AddSubMatrix(vdofs, vdofs, elmat, skip_zeros);
|
||||
if (hybridization)
|
||||
{
|
||||
hybridization->AssembleBdrMatrix(i, *elmat_p);
|
||||
hybridization->AssembleBdrMatrix(i, elmat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static_cond->AssembleBdrMatrix(i, *elmat_p);
|
||||
static_cond->AssembleBdrMatrix(i, elmat);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1329,10 +1318,9 @@ void MixedBilinearForm::Assemble (int skip_zeros)
|
||||
return;
|
||||
}
|
||||
|
||||
Array<int> tr_vdofs, te_vdofs;
|
||||
ElementTransformation *eltrans;
|
||||
DofTransformation * dom_dof_trans;
|
||||
DofTransformation * ran_dof_trans;
|
||||
DenseMatrix elmat;
|
||||
DenseMatrix elemmat;
|
||||
|
||||
Mesh *mesh = test_fes -> GetMesh();
|
||||
|
||||
@@ -1345,24 +1333,16 @@ void MixedBilinearForm::Assemble (int skip_zeros)
|
||||
{
|
||||
for (int i = 0; i < test_fes -> GetNE(); i++)
|
||||
{
|
||||
dom_dof_trans = trial_fes -> GetElementVDofs (i, trial_vdofs);
|
||||
ran_dof_trans = test_fes -> GetElementVDofs (i, test_vdofs);
|
||||
trial_fes -> GetElementVDofs (i, tr_vdofs);
|
||||
test_fes -> GetElementVDofs (i, te_vdofs);
|
||||
eltrans = test_fes -> GetElementTransformation (i);
|
||||
|
||||
elmat.SetSize(test_vdofs.Size(), trial_vdofs.Size());
|
||||
elmat = 0.0;
|
||||
for (int k = 0; k < domain_integs.Size(); k++)
|
||||
{
|
||||
domain_integs[k] -> AssembleElementMatrix2 (*trial_fes -> GetFE(i),
|
||||
*test_fes -> GetFE(i),
|
||||
*eltrans, elemmat);
|
||||
elmat += elemmat;
|
||||
mat -> AddSubMatrix (te_vdofs, tr_vdofs, elemmat, skip_zeros);
|
||||
}
|
||||
if (ran_dof_trans || dom_dof_trans)
|
||||
{
|
||||
TransformDual(ran_dof_trans, dom_dof_trans, elmat);
|
||||
}
|
||||
mat -> AddSubMatrix (test_vdofs, trial_vdofs, elmat, skip_zeros);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1394,12 +1374,9 @@ void MixedBilinearForm::Assemble (int skip_zeros)
|
||||
const int bdr_attr = mesh->GetBdrAttribute(i);
|
||||
if (bdr_attr_marker[bdr_attr-1] == 0) { continue; }
|
||||
|
||||
dom_dof_trans = trial_fes -> GetBdrElementVDofs (i, trial_vdofs);
|
||||
ran_dof_trans = test_fes -> GetBdrElementVDofs (i, test_vdofs);
|
||||
trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
|
||||
test_fes -> GetBdrElementVDofs (i, te_vdofs);
|
||||
eltrans = test_fes -> GetBdrElementTransformation (i);
|
||||
|
||||
elmat.SetSize(test_vdofs.Size(), trial_vdofs.Size());
|
||||
elmat = 0.0;
|
||||
for (int k = 0; k < boundary_integs.Size(); k++)
|
||||
{
|
||||
if (boundary_integs_marker[k] &&
|
||||
@@ -1408,34 +1385,29 @@ void MixedBilinearForm::Assemble (int skip_zeros)
|
||||
boundary_integs[k]->AssembleElementMatrix2 (*trial_fes -> GetBE(i),
|
||||
*test_fes -> GetBE(i),
|
||||
*eltrans, elemmat);
|
||||
elmat += elemmat;
|
||||
mat -> AddSubMatrix (te_vdofs, tr_vdofs, elemmat, skip_zeros);
|
||||
}
|
||||
if (ran_dof_trans || dom_dof_trans)
|
||||
{
|
||||
TransformDual(ran_dof_trans, dom_dof_trans, elmat);
|
||||
}
|
||||
mat -> AddSubMatrix (test_vdofs, trial_vdofs, elmat, skip_zeros);
|
||||
}
|
||||
}
|
||||
|
||||
if (trace_face_integs.Size())
|
||||
{
|
||||
FaceElementTransformations *ftr;
|
||||
Array<int> test_vdofs2;
|
||||
Array<int> te_vdofs2;
|
||||
const FiniteElement *trial_face_fe, *test_fe1, *test_fe2;
|
||||
|
||||
int nfaces = mesh->GetNumFaces();
|
||||
for (int i = 0; i < nfaces; i++)
|
||||
{
|
||||
ftr = mesh->GetFaceElementTransformations(i);
|
||||
trial_fes->GetFaceVDofs(i, trial_vdofs);
|
||||
test_fes->GetElementVDofs(ftr->Elem1No, test_vdofs);
|
||||
trial_fes->GetFaceVDofs(i, tr_vdofs);
|
||||
test_fes->GetElementVDofs(ftr->Elem1No, te_vdofs);
|
||||
trial_face_fe = trial_fes->GetFaceElement(i);
|
||||
test_fe1 = test_fes->GetFE(ftr->Elem1No);
|
||||
if (ftr->Elem2No >= 0)
|
||||
{
|
||||
test_fes->GetElementVDofs(ftr->Elem2No, test_vdofs2);
|
||||
test_vdofs.Append(test_vdofs2);
|
||||
test_fes->GetElementVDofs(ftr->Elem2No, te_vdofs2);
|
||||
te_vdofs.Append(te_vdofs2);
|
||||
test_fe2 = test_fes->GetFE(ftr->Elem2No);
|
||||
}
|
||||
else
|
||||
@@ -1449,7 +1421,7 @@ void MixedBilinearForm::Assemble (int skip_zeros)
|
||||
{
|
||||
trace_face_integs[k]->AssembleFaceMatrix(*trial_face_fe, *test_fe1,
|
||||
*test_fe2, *ftr, elemmat);
|
||||
mat->AddSubMatrix(test_vdofs, trial_vdofs, elemmat, skip_zeros);
|
||||
mat->AddSubMatrix(te_vdofs, tr_vdofs, elemmat, skip_zeros);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1489,8 +1461,8 @@ void MixedBilinearForm::Assemble (int skip_zeros)
|
||||
ftr = mesh->GetBdrFaceTransformations(i);
|
||||
if (ftr)
|
||||
{
|
||||
trial_fes->GetFaceVDofs(ftr->ElementNo, trial_vdofs);
|
||||
test_fes->GetElementVDofs(ftr->Elem1No, test_vdofs);
|
||||
trial_fes->GetFaceVDofs(ftr->ElementNo, tr_vdofs);
|
||||
test_fes->GetElementVDofs(ftr->Elem1No, te_vdofs);
|
||||
trial_face_fe = trial_fes->GetFaceElement(ftr->ElementNo);
|
||||
test_fe1 = test_fes->GetFE(ftr->Elem1No);
|
||||
// The test_fe2 object is really a dummy and not used on the
|
||||
@@ -1507,7 +1479,7 @@ void MixedBilinearForm::Assemble (int skip_zeros)
|
||||
*test_fe1,
|
||||
*test_fe2,
|
||||
*ftr, elemmat);
|
||||
mat->AddSubMatrix(test_vdofs, trial_vdofs, elemmat, skip_zeros);
|
||||
mat->AddSubMatrix(te_vdofs, tr_vdofs, elemmat, skip_zeros);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1869,8 +1841,6 @@ void DiscreteLinearOperator::Assemble(int skip_zeros)
|
||||
|
||||
Array<int> dom_vdofs, ran_vdofs;
|
||||
ElementTransformation *T;
|
||||
DofTransformation * dom_dof_trans;
|
||||
DofTransformation * ran_dof_trans;
|
||||
const FiniteElement *dom_fe, *ran_fe;
|
||||
DenseMatrix totelmat, elmat;
|
||||
|
||||
@@ -1883,8 +1853,8 @@ void DiscreteLinearOperator::Assemble(int skip_zeros)
|
||||
{
|
||||
for (int i = 0; i < test_fes->GetNE(); i++)
|
||||
{
|
||||
dom_dof_trans = trial_fes->GetElementVDofs(i, dom_vdofs);
|
||||
ran_dof_trans = test_fes->GetElementVDofs(i, ran_vdofs);
|
||||
trial_fes->GetElementVDofs(i, dom_vdofs);
|
||||
test_fes->GetElementVDofs(i, ran_vdofs);
|
||||
T = test_fes->GetElementTransformation(i);
|
||||
dom_fe = trial_fes->GetFE(i);
|
||||
ran_fe = test_fes->GetFE(i);
|
||||
@@ -1897,10 +1867,6 @@ void DiscreteLinearOperator::Assemble(int skip_zeros)
|
||||
elmat);
|
||||
totelmat += elmat;
|
||||
}
|
||||
if (ran_dof_trans || dom_dof_trans)
|
||||
{
|
||||
TransformPrimal(ran_dof_trans, dom_dof_trans, totelmat);
|
||||
}
|
||||
mat->SetSubMatrix(ran_vdofs, dom_vdofs, totelmat, skip_zeros);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@ namespace mfem
|
||||
{
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void EAConvectionAssemble1D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void EAConvectionAssemble1D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -69,14 +69,14 @@ void EAConvectionAssemble1D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void EAConvectionAssemble2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void EAConvectionAssemble2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -146,14 +146,14 @@ void EAConvectionAssemble2D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void EAConvectionAssemble3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void EAConvectionAssemble3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
|
||||
@@ -21,13 +21,13 @@ namespace mfem
|
||||
// PA Convection Integrator
|
||||
|
||||
// PA Convection Assemble 2D kernel
|
||||
void PAConvectionSetup2D(const int NQ,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const Vector &vel,
|
||||
const double alpha,
|
||||
Vector &op)
|
||||
static void PAConvectionSetup2D(const int NQ,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const Vector &vel,
|
||||
const double alpha,
|
||||
Vector &op)
|
||||
{
|
||||
constexpr int DIM = 2;
|
||||
|
||||
@@ -60,13 +60,13 @@ void PAConvectionSetup2D(const int NQ,
|
||||
}
|
||||
|
||||
// PA Convection Assemble 3D kernel
|
||||
void PAConvectionSetup3D(const int NQ,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const Vector &vel,
|
||||
const double alpha,
|
||||
Vector &op)
|
||||
static void PAConvectionSetup3D(const int NQ,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const Vector &vel,
|
||||
const double alpha,
|
||||
Vector &op)
|
||||
{
|
||||
constexpr int DIM = 3;
|
||||
constexpr int SDIM = DIM;
|
||||
@@ -135,7 +135,7 @@ static void PAConvectionSetup(const int dim,
|
||||
}
|
||||
|
||||
// PA Convection Apply 2D kernel
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
template<int T_D1D = 0, int T_Q1D = 0> static
|
||||
void PAConvectionApply2D(const int ne,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
@@ -254,7 +254,7 @@ void PAConvectionApply2D(const int ne,
|
||||
}
|
||||
|
||||
// Optimized PA Convection Apply 2D kernel
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0> static
|
||||
void SmemPAConvectionApply2D(const int ne,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
@@ -382,7 +382,7 @@ void SmemPAConvectionApply2D(const int ne,
|
||||
}
|
||||
|
||||
// PA Convection Apply 3D kernel
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
template<int T_D1D = 0, int T_Q1D = 0> static
|
||||
void PAConvectionApply3D(const int ne,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
@@ -563,7 +563,7 @@ void PAConvectionApply3D(const int ne,
|
||||
}
|
||||
|
||||
// Optimized PA Convection Apply 3D kernel
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
template<int T_D1D = 0, int T_Q1D = 0> static
|
||||
void SmemPAConvectionApply3D(const int ne,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
namespace mfem
|
||||
{
|
||||
|
||||
void EADGTraceAssemble1DInt(const int NF,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata_int,
|
||||
Vector &eadata_ext,
|
||||
const bool add)
|
||||
static void EADGTraceAssemble1DInt(const int NF,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata_int,
|
||||
Vector &eadata_ext,
|
||||
const bool add)
|
||||
{
|
||||
auto D = Reshape(padata.Read(), 2, 2, NF);
|
||||
auto A_int = Reshape(eadata_int.ReadWrite(), 2, NF);
|
||||
@@ -50,11 +50,11 @@ void EADGTraceAssemble1DInt(const int NF,
|
||||
});
|
||||
}
|
||||
|
||||
void EADGTraceAssemble1DBdr(const int NF,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata_bdr,
|
||||
const bool add)
|
||||
static void EADGTraceAssemble1DBdr(const int NF,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata_bdr,
|
||||
const bool add)
|
||||
{
|
||||
auto D = Reshape(padata.Read(), 2, 2, NF);
|
||||
auto A_bdr = Reshape(eadata_bdr.ReadWrite(), NF);
|
||||
@@ -72,14 +72,14 @@ void EADGTraceAssemble1DBdr(const int NF,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void EADGTraceAssemble2DInt(const int NF,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata_int,
|
||||
Vector &eadata_ext,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void EADGTraceAssemble2DInt(const int NF,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata_int,
|
||||
Vector &eadata_ext,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -128,13 +128,13 @@ void EADGTraceAssemble2DInt(const int NF,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void EADGTraceAssemble2DBdr(const int NF,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata_bdr,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void EADGTraceAssemble2DBdr(const int NF,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata_bdr,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -170,14 +170,14 @@ void EADGTraceAssemble2DBdr(const int NF,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void EADGTraceAssemble3DInt(const int NF,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata_int,
|
||||
Vector &eadata_ext,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void EADGTraceAssemble3DInt(const int NF,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata_int,
|
||||
Vector &eadata_ext,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -268,13 +268,13 @@ void EADGTraceAssemble3DInt(const int NF,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void EADGTraceAssemble3DBdr(const int NF,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata_bdr,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void EADGTraceAssemble3DBdr(const int NF,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata_bdr,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
|
||||
@@ -19,16 +19,16 @@ using namespace std;
|
||||
namespace mfem
|
||||
{
|
||||
// PA DG Trace Integrator
|
||||
void PADGTraceSetup2D(const int Q1D,
|
||||
const int NF,
|
||||
const Array<double> &w,
|
||||
const Vector &det,
|
||||
const Vector &nor,
|
||||
const Vector &rho,
|
||||
const Vector &vel,
|
||||
const double alpha,
|
||||
const double beta,
|
||||
Vector &op)
|
||||
static void PADGTraceSetup2D(const int Q1D,
|
||||
const int NF,
|
||||
const Array<double> &w,
|
||||
const Vector &det,
|
||||
const Vector &nor,
|
||||
const Vector &rho,
|
||||
const Vector &vel,
|
||||
const double alpha,
|
||||
const double beta,
|
||||
Vector &op)
|
||||
{
|
||||
const int VDIM = 2;
|
||||
|
||||
@@ -61,16 +61,16 @@ void PADGTraceSetup2D(const int Q1D,
|
||||
});
|
||||
}
|
||||
|
||||
void PADGTraceSetup3D(const int Q1D,
|
||||
const int NF,
|
||||
const Array<double> &w,
|
||||
const Vector &det,
|
||||
const Vector &nor,
|
||||
const Vector &rho,
|
||||
const Vector &vel,
|
||||
const double alpha,
|
||||
const double beta,
|
||||
Vector &op)
|
||||
static void PADGTraceSetup3D(const int Q1D,
|
||||
const int NF,
|
||||
const Array<double> &w,
|
||||
const Vector &det,
|
||||
const Vector &nor,
|
||||
const Vector &rho,
|
||||
const Vector &vel,
|
||||
const double alpha,
|
||||
const double beta,
|
||||
Vector &op)
|
||||
{
|
||||
const int VDIM = 3;
|
||||
|
||||
@@ -301,7 +301,7 @@ void DGTraceIntegrator::AssemblePABoundaryFaces(const FiniteElementSpace& fes)
|
||||
}
|
||||
|
||||
// PA DGTrace Apply 2D kernel for Gauss-Lobatto/Bernstein
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
template<int T_D1D = 0, int T_Q1D = 0> static
|
||||
void PADGTraceApply2D(const int NF,
|
||||
const Array<double> &b,
|
||||
const Array<double> &bt,
|
||||
@@ -392,7 +392,7 @@ void PADGTraceApply2D(const int NF,
|
||||
}
|
||||
|
||||
// PA DGTrace Apply 3D kernel for Gauss-Lobatto/Bernstein
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
template<int T_D1D = 0, int T_Q1D = 0> static
|
||||
void PADGTraceApply3D(const int NF,
|
||||
const Array<double> &b,
|
||||
const Array<double> &bt,
|
||||
@@ -537,7 +537,7 @@ void PADGTraceApply3D(const int NF,
|
||||
}
|
||||
|
||||
// Optimized PA DGTrace Apply 3D kernel for Gauss-Lobatto/Bernstein
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0> static
|
||||
void SmemPADGTraceApply3D(const int NF,
|
||||
const Array<double> &b,
|
||||
const Array<double> &bt,
|
||||
@@ -701,7 +701,7 @@ static void PADGTraceApply(const int dim,
|
||||
}
|
||||
|
||||
// PA DGTrace Apply 2D kernel for Gauss-Lobatto/Bernstein
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
template<int T_D1D = 0, int T_Q1D = 0> static
|
||||
void PADGTraceApplyTranspose2D(const int NF,
|
||||
const Array<double> &b,
|
||||
const Array<double> &bt,
|
||||
@@ -797,7 +797,7 @@ void PADGTraceApplyTranspose2D(const int NF,
|
||||
}
|
||||
|
||||
// PA DGTrace Apply Transpose 3D kernel for Gauss-Lobatto/Bernstein
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
template<int T_D1D = 0, int T_Q1D = 0> static
|
||||
void PADGTraceApplyTranspose3D(const int NF,
|
||||
const Array<double> &b,
|
||||
const Array<double> &bt,
|
||||
@@ -953,7 +953,7 @@ void PADGTraceApplyTranspose3D(const int NF,
|
||||
}
|
||||
|
||||
// Optimized PA DGTrace Apply Transpose 3D kernel for Gauss-Lobatto/Bernstein
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0> static
|
||||
void SmemPADGTraceApplyTranspose3D(const int NF,
|
||||
const Array<double> &b,
|
||||
const Array<double> &bt,
|
||||
|
||||
@@ -17,14 +17,14 @@ namespace mfem
|
||||
{
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void EADiffusionAssemble1D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void EADiffusionAssemble1D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -68,14 +68,14 @@ void EADiffusionAssemble1D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void EADiffusionAssemble2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void EADiffusionAssemble2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -145,14 +145,14 @@ void EADiffusionAssemble2D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void EADiffusionAssemble3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void EADiffusionAssemble3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
|
||||
@@ -496,14 +496,14 @@ void DiffusionIntegrator::AssemblePA(const FiniteElementSpace &fes)
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void PADiffusionDiagonal2D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &d,
|
||||
Vector &y,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PADiffusionDiagonal2D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &d,
|
||||
Vector &y,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -562,14 +562,14 @@ void PADiffusionDiagonal2D(const int NE,
|
||||
|
||||
// Shared memory PA Diffusion Diagonal 2D kernel
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
|
||||
void SmemPADiffusionDiagonal2D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Vector &d_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void SmemPADiffusionDiagonal2D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Vector &d_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -656,14 +656,14 @@ void SmemPADiffusionDiagonal2D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void PADiffusionDiagonal3D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &d,
|
||||
Vector &y,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PADiffusionDiagonal3D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &d,
|
||||
Vector &y,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
constexpr int DIM = 3;
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
@@ -757,14 +757,14 @@ void PADiffusionDiagonal3D(const int NE,
|
||||
|
||||
// Shared memory PA Diffusion Diagonal 3D kernel
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void SmemPADiffusionDiagonal3D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Vector &d_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void SmemPADiffusionDiagonal3D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Vector &d_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
constexpr int DIM = 3;
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
@@ -1034,17 +1034,17 @@ static void OccaPADiffusionApply3D(const int D1D,
|
||||
|
||||
// PA Diffusion Apply 2D kernel
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void PADiffusionApply2D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Array<double> &bt_,
|
||||
const Array<double> >_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PADiffusionApply2D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Array<double> &bt_,
|
||||
const Array<double> >_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -1156,15 +1156,15 @@ void PADiffusionApply2D(const int NE,
|
||||
|
||||
// Shared memory PA Diffusion Apply 2D kernel
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
|
||||
void SmemPADiffusionApply2D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void SmemPADiffusionApply2D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -1314,16 +1314,16 @@ void SmemPADiffusionApply2D(const int NE,
|
||||
|
||||
// PA Diffusion Apply 3D kernel
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void PADiffusionApply3D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Array<double> >,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
int d1d = 0, int q1d = 0)
|
||||
static void PADiffusionApply3D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Array<double> >,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
int d1d = 0, int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -1533,15 +1533,15 @@ static MFEM_HOST_DEVICE inline double sign(const int q, const int d)
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void SmemPADiffusionApply3D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void SmemPADiffusionApply3D(const int NE,
|
||||
const bool symmetric,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
|
||||
@@ -21,12 +21,12 @@ namespace mfem
|
||||
// PA Divergence Integrator
|
||||
|
||||
// PA Divergence Assemble 2D kernel
|
||||
void PADivergenceSetup2D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const double COEFF,
|
||||
Vector &op)
|
||||
static void PADivergenceSetup2D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const double COEFF,
|
||||
Vector &op)
|
||||
{
|
||||
const int NQ = Q1D*Q1D;
|
||||
auto W = w.Read();
|
||||
@@ -51,12 +51,12 @@ void PADivergenceSetup2D(const int Q1D,
|
||||
}
|
||||
|
||||
// PA Divergence Assemble 3D kernel
|
||||
void PADivergenceSetup3D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const double COEFF,
|
||||
Vector &op)
|
||||
static void PADivergenceSetup3D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const double COEFF,
|
||||
Vector &op)
|
||||
{
|
||||
const int NQ = Q1D*Q1D*Q1D;
|
||||
auto W = w.Read();
|
||||
@@ -160,16 +160,16 @@ void VectorDivergenceIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
|
||||
|
||||
// PA Divergence Apply 2D kernel
|
||||
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
|
||||
void PADivergenceApply2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int tr_d1d = 0,
|
||||
const int te_d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PADivergenceApply2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int tr_d1d = 0,
|
||||
const int te_d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
|
||||
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
|
||||
@@ -281,16 +281,16 @@ void PADivergenceApply2D(const int NE,
|
||||
// Shared memory PA Divergence Apply 2D kernel
|
||||
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0,
|
||||
const int T_NBZ = 0>
|
||||
void SmemPADivergenceApply2D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int tr_d1d = 0,
|
||||
const int te_d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void SmemPADivergenceApply2D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int tr_d1d = 0,
|
||||
const int te_d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
// TODO
|
||||
MFEM_ASSERT(false, "SHARED MEM NOT PROGRAMMED YET");
|
||||
@@ -298,16 +298,16 @@ void SmemPADivergenceApply2D(const int NE,
|
||||
|
||||
// PA Divergence Apply 2D kernel transpose
|
||||
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
|
||||
void PADivergenceApplyTranspose2D(const int NE,
|
||||
const Array<double> &bt,
|
||||
const Array<double> >,
|
||||
const Array<double> &b,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int tr_d1d = 0,
|
||||
const int te_d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PADivergenceApplyTranspose2D(const int NE,
|
||||
const Array<double> &bt,
|
||||
const Array<double> >,
|
||||
const Array<double> &b,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int tr_d1d = 0,
|
||||
const int te_d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
|
||||
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
|
||||
@@ -414,16 +414,16 @@ void PADivergenceApplyTranspose2D(const int NE,
|
||||
|
||||
// PA Vector Divergence Apply 3D kernel
|
||||
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
|
||||
void PADivergenceApply3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
int tr_d1d = 0,
|
||||
int te_d1d = 0,
|
||||
int q1d = 0)
|
||||
static void PADivergenceApply3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
int tr_d1d = 0,
|
||||
int te_d1d = 0,
|
||||
int q1d = 0)
|
||||
{
|
||||
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
|
||||
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
|
||||
@@ -597,16 +597,16 @@ void PADivergenceApply3D(const int NE,
|
||||
|
||||
// PA Vector Divergence Apply 3D kernel
|
||||
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
|
||||
void PADivergenceApplyTranspose3D(const int NE,
|
||||
const Array<double> &bt,
|
||||
const Array<double> >,
|
||||
const Array<double> &b,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
int tr_d1d = 0,
|
||||
int te_d1d = 0,
|
||||
int q1d = 0)
|
||||
static void PADivergenceApplyTranspose3D(const int NE,
|
||||
const Array<double> &bt,
|
||||
const Array<double> >,
|
||||
const Array<double> &b,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
int tr_d1d = 0,
|
||||
int te_d1d = 0,
|
||||
int q1d = 0)
|
||||
{
|
||||
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
|
||||
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
|
||||
@@ -775,16 +775,16 @@ void PADivergenceApplyTranspose3D(const int NE,
|
||||
|
||||
// Shared memory PA Vector Divergence Apply 3D kernel
|
||||
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
|
||||
void SmemPADivergenceApply3D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &q_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int tr_d1d = 0,
|
||||
const int te_d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void SmemPADivergenceApply3D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &q_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int tr_d1d = 0,
|
||||
const int te_d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
|
||||
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
|
||||
|
||||
+42
-42
@@ -70,12 +70,12 @@ namespace mfem
|
||||
the \b MFEM_SHARED keyword for local arrays. */
|
||||
|
||||
// PA Gradient Assemble 2D kernel
|
||||
void PAGradientSetup2D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const Vector &c,
|
||||
Vector &op)
|
||||
static void PAGradientSetup2D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const Vector &c,
|
||||
Vector &op)
|
||||
{
|
||||
const int NQ = Q1D*Q1D;
|
||||
auto W = w.Read();
|
||||
@@ -105,12 +105,12 @@ void PAGradientSetup2D(const int Q1D,
|
||||
}
|
||||
|
||||
// PA Gradient Assemble 3D kernel
|
||||
void PAGradientSetup3D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const Vector &c,
|
||||
Vector &op)
|
||||
static void PAGradientSetup3D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const Vector &c,
|
||||
Vector &op)
|
||||
{
|
||||
const int NQ = Q1D*Q1D*Q1D;
|
||||
auto W = w.Read();
|
||||
@@ -254,16 +254,16 @@ void GradientIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
|
||||
|
||||
// PA Gradient Apply 2D kernel
|
||||
template<int T_TR_D1D = 0, int T_TE_D1D = 0, int T_Q1D = 0>
|
||||
void PAGradientApply2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int tr_d1d = 0,
|
||||
const int te_d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PAGradientApply2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int tr_d1d = 0,
|
||||
const int te_d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
|
||||
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
|
||||
@@ -384,16 +384,16 @@ static void PAGradientApplyTranspose2D(const int NE,
|
||||
|
||||
// PA Gradient Apply 3D kernel
|
||||
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
|
||||
void PAGradientApply3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
int tr_d1d = 0,
|
||||
int te_d1d = 0,
|
||||
int q1d = 0)
|
||||
static void PAGradientApply3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
int tr_d1d = 0,
|
||||
int te_d1d = 0,
|
||||
int q1d = 0)
|
||||
{
|
||||
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
|
||||
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
|
||||
@@ -579,16 +579,16 @@ static void PAGradientApplyTranspose3D(const int NE,
|
||||
|
||||
// Shared memory PA Gradient Apply 3D kernel
|
||||
template<const int T_TR_D1D = 0, const int T_TE_D1D = 0, const int T_Q1D = 0>
|
||||
void SmemPAGradientApply3D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int tr_d1d = 0,
|
||||
const int te_d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void SmemPAGradientApply3D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int tr_d1d = 0,
|
||||
const int te_d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int TR_D1D = T_TR_D1D ? T_TR_D1D : tr_d1d;
|
||||
const int TE_D1D = T_TE_D1D ? T_TE_D1D : te_d1d;
|
||||
|
||||
+194
-194
@@ -791,12 +791,12 @@ void SmemPAHcurlMassApply3D(const int D1D,
|
||||
}
|
||||
|
||||
// PA H(curl) curl-curl assemble 2D kernel
|
||||
void PACurlCurlSetup2D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
Vector &coeff,
|
||||
Vector &op)
|
||||
static void PACurlCurlSetup2D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
Vector &coeff,
|
||||
Vector &op)
|
||||
{
|
||||
const int NQ = Q1D*Q1D;
|
||||
auto W = w.Read();
|
||||
@@ -818,13 +818,13 @@ void PACurlCurlSetup2D(const int Q1D,
|
||||
}
|
||||
|
||||
// PA H(curl) curl-curl assemble 3D kernel
|
||||
void PACurlCurlSetup3D(const int Q1D,
|
||||
const int coeffDim,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
Vector &coeff,
|
||||
Vector &op)
|
||||
static void PACurlCurlSetup3D(const int Q1D,
|
||||
const int coeffDim,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
Vector &coeff,
|
||||
Vector &op)
|
||||
{
|
||||
const int NQ = Q1D*Q1D*Q1D;
|
||||
const bool symmetric = (coeffDim != 9);
|
||||
@@ -1045,16 +1045,16 @@ void CurlCurlIntegrator::AssemblePA(const FiniteElementSpace &fes)
|
||||
}
|
||||
}
|
||||
|
||||
void PACurlCurlApply2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bot,
|
||||
const Array<double> &gc,
|
||||
const Array<double> &gct,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
static void PACurlCurlApply2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bot,
|
||||
const Array<double> &gc,
|
||||
const Array<double> &gct,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
{
|
||||
constexpr static int VDIM = 2;
|
||||
constexpr static int MAX_D1D = HCURL_MAX_D1D;
|
||||
@@ -1166,19 +1166,19 @@ void PACurlCurlApply2D(const int D1D,
|
||||
}
|
||||
|
||||
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
|
||||
void PACurlCurlApply3D(const int D1D,
|
||||
const int Q1D,
|
||||
const bool symmetric,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &bot,
|
||||
const Array<double> &bct,
|
||||
const Array<double> &gc,
|
||||
const Array<double> &gct,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
static void PACurlCurlApply3D(const int D1D,
|
||||
const int Q1D,
|
||||
const bool symmetric,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &bot,
|
||||
const Array<double> &bct,
|
||||
const Array<double> &gc,
|
||||
const Array<double> &gct,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
{
|
||||
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
|
||||
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
|
||||
@@ -1677,19 +1677,19 @@ void PACurlCurlApply3D(const int D1D,
|
||||
}
|
||||
|
||||
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
|
||||
void SmemPACurlCurlApply3D(const int D1D,
|
||||
const int Q1D,
|
||||
const bool symmetric,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &bot,
|
||||
const Array<double> &bct,
|
||||
const Array<double> &gc,
|
||||
const Array<double> &gct,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
static void SmemPACurlCurlApply3D(const int D1D,
|
||||
const int Q1D,
|
||||
const bool symmetric,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &bot,
|
||||
const Array<double> &bct,
|
||||
const Array<double> &gc,
|
||||
const Array<double> &gct,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
{
|
||||
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
|
||||
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
|
||||
@@ -2032,13 +2032,13 @@ void CurlCurlIntegrator::AddMultPA(const Vector &x, Vector &y) const
|
||||
}
|
||||
}
|
||||
|
||||
void PACurlCurlAssembleDiagonal2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
Vector &diag)
|
||||
static void PACurlCurlAssembleDiagonal2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
Vector &diag)
|
||||
{
|
||||
constexpr static int VDIM = 2;
|
||||
constexpr static int MAX_Q1D = HCURL_MAX_Q1D;
|
||||
@@ -2087,16 +2087,16 @@ void PACurlCurlAssembleDiagonal2D(const int D1D,
|
||||
}
|
||||
|
||||
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
|
||||
void PACurlCurlAssembleDiagonal3D(const int D1D,
|
||||
const int Q1D,
|
||||
const bool symmetric,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &go,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
Vector &diag)
|
||||
static void PACurlCurlAssembleDiagonal3D(const int D1D,
|
||||
const int Q1D,
|
||||
const bool symmetric,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &go,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
Vector &diag)
|
||||
{
|
||||
constexpr static int VDIM = 3;
|
||||
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
|
||||
@@ -2273,16 +2273,16 @@ void PACurlCurlAssembleDiagonal3D(const int D1D,
|
||||
}
|
||||
|
||||
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
|
||||
void SmemPACurlCurlAssembleDiagonal3D(const int D1D,
|
||||
const int Q1D,
|
||||
const bool symmetric,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &go,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
Vector &diag)
|
||||
static void SmemPACurlCurlAssembleDiagonal3D(const int D1D,
|
||||
const int Q1D,
|
||||
const bool symmetric,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &go,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
Vector &diag)
|
||||
{
|
||||
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
|
||||
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
|
||||
@@ -2955,18 +2955,18 @@ void MixedVectorCurlIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
|
||||
// Apply to x corresponding to DOF's in H(curl) (trial), whose curl is
|
||||
// integrated against H(curl) test functions corresponding to y.
|
||||
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
|
||||
void PAHcurlL2Apply3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int coeffDim,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &bot,
|
||||
const Array<double> &bct,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
static void PAHcurlL2Apply3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int coeffDim,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &bot,
|
||||
const Array<double> &bct,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
{
|
||||
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
|
||||
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
|
||||
@@ -3297,16 +3297,16 @@ void PAHcurlL2Apply3D(const int D1D,
|
||||
// Apply to x corresponding to DOF's in H(curl) (trial), whose curl is
|
||||
// integrated against H(curl) test functions corresponding to y.
|
||||
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
|
||||
void SmemPAHcurlL2Apply3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int coeffDim,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
static void SmemPAHcurlL2Apply3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int coeffDim,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
{
|
||||
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
|
||||
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
|
||||
@@ -3585,18 +3585,18 @@ void SmemPAHcurlL2Apply3D(const int D1D,
|
||||
// Apply to x corresponding to DOF's in H(curl) (trial), whose curl is
|
||||
// integrated against H(div) test functions corresponding to y.
|
||||
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
|
||||
void PAHcurlHdivApply3D(const int D1D,
|
||||
const int D1Dtest,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &bot,
|
||||
const Array<double> &bct,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
static void PAHcurlHdivApply3D(const int D1D,
|
||||
const int D1Dtest,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &bot,
|
||||
const Array<double> &bct,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
{
|
||||
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
|
||||
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
|
||||
@@ -4071,18 +4071,18 @@ void MixedVectorWeakCurlIntegrator::AssemblePA(const FiniteElementSpace
|
||||
// Apply to x corresponding to DOF's in H(curl) (trial), integrated against curl
|
||||
// of H(curl) test functions corresponding to y.
|
||||
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
|
||||
void PAHcurlL2Apply3DTranspose(const int D1D,
|
||||
const int Q1D,
|
||||
const int coeffDim,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &bot,
|
||||
const Array<double> &bct,
|
||||
const Array<double> &gct,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
static void PAHcurlL2Apply3DTranspose(const int D1D,
|
||||
const int Q1D,
|
||||
const int coeffDim,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &bot,
|
||||
const Array<double> &bct,
|
||||
const Array<double> &gct,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
{
|
||||
// See PAHcurlL2Apply3D for comments.
|
||||
|
||||
@@ -4413,16 +4413,16 @@ void PAHcurlL2Apply3DTranspose(const int D1D,
|
||||
}
|
||||
|
||||
template<int MAX_D1D = HCURL_MAX_D1D, int MAX_Q1D = HCURL_MAX_Q1D>
|
||||
void SmemPAHcurlL2Apply3DTranspose(const int D1D,
|
||||
const int Q1D,
|
||||
const int coeffDim,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
static void SmemPAHcurlL2Apply3DTranspose(const int D1D,
|
||||
const int Q1D,
|
||||
const int coeffDim,
|
||||
const int NE,
|
||||
const Array<double> &bo,
|
||||
const Array<double> &bc,
|
||||
const Array<double> &gc,
|
||||
const Vector &pa_data,
|
||||
const Vector &x,
|
||||
Vector &y)
|
||||
{
|
||||
MFEM_VERIFY(D1D <= MAX_D1D, "Error: D1D > MAX_D1D");
|
||||
MFEM_VERIFY(Q1D <= MAX_Q1D, "Error: Q1D > MAX_Q1D");
|
||||
@@ -4675,13 +4675,13 @@ void MixedVectorWeakCurlIntegrator::AddMultPA(const Vector &x, Vector &y) const
|
||||
// Apply to x corresponding to DOFs in H^1 (domain) the (topological) gradient
|
||||
// to get a dof in H(curl) (range). You can think of the range as the "test" space
|
||||
// and the domain as the "trial" space, but there's no integration.
|
||||
void PAHcurlApplyGradient2D(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &B_,
|
||||
const Array<double> &G_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PAHcurlApplyGradient2D(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &B_,
|
||||
const Array<double> &G_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
auto B = Reshape(B_.Read(), c_dofs1D, c_dofs1D);
|
||||
auto G = Reshape(G_.Read(), o_dofs1D, c_dofs1D);
|
||||
@@ -4753,12 +4753,12 @@ void PAHcurlApplyGradient2D(const int c_dofs1D,
|
||||
}
|
||||
|
||||
// Specialization of PAHcurlApplyGradient2D to the case where B is identity
|
||||
void PAHcurlApplyGradient2DBId(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &G_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PAHcurlApplyGradient2DBId(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &G_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
auto G = Reshape(G_.Read(), o_dofs1D, c_dofs1D);
|
||||
|
||||
@@ -4822,7 +4822,7 @@ void PAHcurlApplyGradient2DBId(const int c_dofs1D,
|
||||
});
|
||||
}
|
||||
|
||||
void PAHcurlApplyGradientTranspose2D(
|
||||
static void PAHcurlApplyGradientTranspose2D(
|
||||
const int c_dofs1D, const int o_dofs1D, const int NE,
|
||||
const Array<double> &B_, const Array<double> &G_,
|
||||
const Vector &x_, Vector &y_)
|
||||
@@ -4898,7 +4898,7 @@ void PAHcurlApplyGradientTranspose2D(
|
||||
|
||||
// Specialization of PAHcurlApplyGradientTranspose2D to the case where
|
||||
// B is identity
|
||||
void PAHcurlApplyGradientTranspose2DBId(
|
||||
static void PAHcurlApplyGradientTranspose2DBId(
|
||||
const int c_dofs1D, const int o_dofs1D, const int NE,
|
||||
const Array<double> &G_,
|
||||
const Vector &x_, Vector &y_)
|
||||
@@ -4965,13 +4965,13 @@ void PAHcurlApplyGradientTranspose2DBId(
|
||||
});
|
||||
}
|
||||
|
||||
void PAHcurlApplyGradient3D(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &B_,
|
||||
const Array<double> &G_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PAHcurlApplyGradient3D(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &B_,
|
||||
const Array<double> &G_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
auto B = Reshape(B_.Read(), c_dofs1D, c_dofs1D);
|
||||
auto G = Reshape(G_.Read(), o_dofs1D, c_dofs1D);
|
||||
@@ -5154,12 +5154,12 @@ void PAHcurlApplyGradient3D(const int c_dofs1D,
|
||||
}
|
||||
|
||||
// Specialization of PAHcurlApplyGradient3D to the case where
|
||||
void PAHcurlApplyGradient3DBId(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &G_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PAHcurlApplyGradient3DBId(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &G_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
auto G = Reshape(G_.Read(), o_dofs1D, c_dofs1D);
|
||||
|
||||
@@ -5322,7 +5322,7 @@ void PAHcurlApplyGradient3DBId(const int c_dofs1D,
|
||||
});
|
||||
}
|
||||
|
||||
void PAHcurlApplyGradientTranspose3D(
|
||||
static void PAHcurlApplyGradientTranspose3D(
|
||||
const int c_dofs1D, const int o_dofs1D, const int NE,
|
||||
const Array<double> &B_, const Array<double> &G_,
|
||||
const Vector &x_, Vector &y_)
|
||||
@@ -5507,7 +5507,7 @@ void PAHcurlApplyGradientTranspose3D(
|
||||
}
|
||||
|
||||
// Specialization of PAHcurlApplyGradientTranspose3D to the case where
|
||||
void PAHcurlApplyGradientTranspose3DBId(
|
||||
static void PAHcurlApplyGradientTranspose3DBId(
|
||||
const int c_dofs1D, const int o_dofs1D, const int NE,
|
||||
const Array<double> &G_,
|
||||
const Vector &x_, Vector &y_)
|
||||
@@ -5789,14 +5789,14 @@ void GradientInterpolator::AddMultTransposePA(const Vector &x, Vector &y) const
|
||||
}
|
||||
}
|
||||
|
||||
void PAHcurlVecH1IdentityApply3D(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &Bclosed,
|
||||
const Array<double> &Bopen,
|
||||
const Vector &pa_data,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PAHcurlVecH1IdentityApply3D(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &Bclosed,
|
||||
const Array<double> &Bopen,
|
||||
const Vector &pa_data,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
auto Bc = Reshape(Bclosed.Read(), c_dofs1D, c_dofs1D);
|
||||
auto Bo = Reshape(Bopen.Read(), o_dofs1D, c_dofs1D);
|
||||
@@ -6002,14 +6002,14 @@ void PAHcurlVecH1IdentityApply3D(const int c_dofs1D,
|
||||
});
|
||||
}
|
||||
|
||||
void PAHcurlVecH1IdentityApplyTranspose3D(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &Bclosed,
|
||||
const Array<double> &Bopen,
|
||||
const Vector &pa_data,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PAHcurlVecH1IdentityApplyTranspose3D(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &Bclosed,
|
||||
const Array<double> &Bopen,
|
||||
const Vector &pa_data,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
auto Bc = Reshape(Bclosed.Read(), c_dofs1D, c_dofs1D);
|
||||
auto Bo = Reshape(Bopen.Read(), o_dofs1D, c_dofs1D);
|
||||
@@ -6228,14 +6228,14 @@ void PAHcurlVecH1IdentityApplyTranspose3D(const int c_dofs1D,
|
||||
});
|
||||
}
|
||||
|
||||
void PAHcurlVecH1IdentityApply2D(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &Bclosed,
|
||||
const Array<double> &Bopen,
|
||||
const Vector &pa_data,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PAHcurlVecH1IdentityApply2D(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &Bclosed,
|
||||
const Array<double> &Bopen,
|
||||
const Vector &pa_data,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
auto Bc = Reshape(Bclosed.Read(), c_dofs1D, c_dofs1D);
|
||||
auto Bo = Reshape(Bopen.Read(), o_dofs1D, c_dofs1D);
|
||||
@@ -6327,14 +6327,14 @@ void PAHcurlVecH1IdentityApply2D(const int c_dofs1D,
|
||||
});
|
||||
}
|
||||
|
||||
void PAHcurlVecH1IdentityApplyTranspose2D(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &Bclosed,
|
||||
const Array<double> &Bopen,
|
||||
const Vector &pa_data,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PAHcurlVecH1IdentityApplyTranspose2D(const int c_dofs1D,
|
||||
const int o_dofs1D,
|
||||
const int NE,
|
||||
const Array<double> &Bclosed,
|
||||
const Array<double> &Bopen,
|
||||
const Vector &pa_data,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
auto Bc = Reshape(Bclosed.Read(), c_dofs1D, c_dofs1D);
|
||||
auto Bo = Reshape(Bopen.Read(), o_dofs1D, c_dofs1D);
|
||||
|
||||
+116
-116
@@ -539,12 +539,12 @@ void PAHdivMassApply3D(const int D1D,
|
||||
|
||||
// PA H(div) div-div assemble 2D kernel
|
||||
// NOTE: this is identical to PACurlCurlSetup3D
|
||||
void PADivDivSetup2D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
Vector &coeff_,
|
||||
Vector &op)
|
||||
static void PADivDivSetup2D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
Vector &coeff_,
|
||||
Vector &op)
|
||||
{
|
||||
const int NQ = Q1D*Q1D;
|
||||
auto W = w.Read();
|
||||
@@ -565,12 +565,12 @@ void PADivDivSetup2D(const int Q1D,
|
||||
});
|
||||
}
|
||||
|
||||
void PADivDivSetup3D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
Vector &coeff_,
|
||||
Vector &op)
|
||||
static void PADivDivSetup3D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
Vector &coeff_,
|
||||
Vector &op)
|
||||
{
|
||||
const int NQ = Q1D*Q1D*Q1D;
|
||||
auto W = w.Read();
|
||||
@@ -599,16 +599,16 @@ void PADivDivSetup3D(const int Q1D,
|
||||
});
|
||||
}
|
||||
|
||||
void PADivDivApply2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &Bo_,
|
||||
const Array<double> &Gc_,
|
||||
const Array<double> &Bot_,
|
||||
const Array<double> &Gct_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PADivDivApply2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &Bo_,
|
||||
const Array<double> &Gc_,
|
||||
const Array<double> &Bot_,
|
||||
const Array<double> &Gct_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
constexpr static int VDIM = 2;
|
||||
constexpr static int MAX_D1D = HDIV_MAX_D1D;
|
||||
@@ -718,16 +718,16 @@ void PADivDivApply2D(const int D1D,
|
||||
}); // end of element loop
|
||||
}
|
||||
|
||||
void PADivDivApply3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &Bo_,
|
||||
const Array<double> &Gc_,
|
||||
const Array<double> &Bot_,
|
||||
const Array<double> &Gct_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PADivDivApply3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &Bo_,
|
||||
const Array<double> &Gc_,
|
||||
const Array<double> &Bot_,
|
||||
const Array<double> &Gct_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
|
||||
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
|
||||
@@ -967,13 +967,13 @@ void DivDivIntegrator::AddMultPA(const Vector &x, Vector &y) const
|
||||
}
|
||||
}
|
||||
|
||||
void PADivDivAssembleDiagonal2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &Bo_,
|
||||
const Array<double> &Gc_,
|
||||
const Vector &op_,
|
||||
Vector &diag_)
|
||||
static void PADivDivAssembleDiagonal2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &Bo_,
|
||||
const Array<double> &Gc_,
|
||||
const Vector &op_,
|
||||
Vector &diag_)
|
||||
{
|
||||
constexpr static int VDIM = 2;
|
||||
constexpr static int MAX_Q1D = HDIV_MAX_Q1D;
|
||||
@@ -1023,13 +1023,13 @@ void PADivDivAssembleDiagonal2D(const int D1D,
|
||||
});
|
||||
}
|
||||
|
||||
void PADivDivAssembleDiagonal3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &Bo_,
|
||||
const Array<double> &Gc_,
|
||||
const Vector &op_,
|
||||
Vector &diag_)
|
||||
static void PADivDivAssembleDiagonal3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &Bo_,
|
||||
const Array<double> &Gc_,
|
||||
const Vector &op_,
|
||||
Vector &diag_)
|
||||
{
|
||||
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
|
||||
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
|
||||
@@ -1104,11 +1104,11 @@ void DivDivIntegrator::AssembleDiagonalPA(Vector& diag)
|
||||
}
|
||||
|
||||
// PA H(div)-L2 (div u, p) assemble 2D kernel
|
||||
void PADivL2Setup2D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
Vector &coeff_,
|
||||
Vector &op)
|
||||
static void PADivL2Setup2D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
Vector &coeff_,
|
||||
Vector &op)
|
||||
{
|
||||
const int NQ = Q1D*Q1D;
|
||||
auto W = w.Read();
|
||||
@@ -1123,11 +1123,11 @@ void PADivL2Setup2D(const int Q1D,
|
||||
});
|
||||
}
|
||||
|
||||
void PADivL2Setup3D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
Vector &coeff_,
|
||||
Vector &op)
|
||||
static void PADivL2Setup3D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
Vector &coeff_,
|
||||
Vector &op)
|
||||
{
|
||||
const int NQ = Q1D*Q1D*Q1D;
|
||||
auto W = w.Read();
|
||||
@@ -1225,16 +1225,16 @@ VectorFEDivergenceIntegrator::AssemblePA(const FiniteElementSpace &trial_fes,
|
||||
|
||||
// Apply to x corresponding to DOF's in H(div) (trial), whose divergence is
|
||||
// integrated against L_2 test functions corresponding to y.
|
||||
void PAHdivL2Apply3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int L2D1D,
|
||||
const int NE,
|
||||
const Array<double> &Bo_,
|
||||
const Array<double> &Gc_,
|
||||
const Array<double> &L2Bot_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PAHdivL2Apply3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int L2D1D,
|
||||
const int NE,
|
||||
const Array<double> &Bo_,
|
||||
const Array<double> &Gc_,
|
||||
const Array<double> &L2Bot_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
|
||||
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
|
||||
@@ -1388,16 +1388,16 @@ void PAHdivL2Apply3D(const int D1D,
|
||||
|
||||
// Apply to x corresponding to DOF's in H(div) (trial), whose divergence is
|
||||
// integrated against L_2 test functions corresponding to y.
|
||||
void PAHdivL2Apply2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int L2D1D,
|
||||
const int NE,
|
||||
const Array<double> &Bo_,
|
||||
const Array<double> &Gc_,
|
||||
const Array<double> &L2Bot_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PAHdivL2Apply2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int L2D1D,
|
||||
const int NE,
|
||||
const Array<double> &Bo_,
|
||||
const Array<double> &Gc_,
|
||||
const Array<double> &L2Bot_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
constexpr static int VDIM = 2;
|
||||
constexpr static int MAX_D1D = HDIV_MAX_D1D;
|
||||
@@ -1494,16 +1494,16 @@ void PAHdivL2Apply2D(const int D1D,
|
||||
}); // end of element loop
|
||||
}
|
||||
|
||||
void PAHdivL2ApplyTranspose3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int L2D1D,
|
||||
const int NE,
|
||||
const Array<double> &L2Bo_,
|
||||
const Array<double> &Gct_,
|
||||
const Array<double> &Bot_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PAHdivL2ApplyTranspose3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int L2D1D,
|
||||
const int NE,
|
||||
const Array<double> &L2Bo_,
|
||||
const Array<double> &Gct_,
|
||||
const Array<double> &Bot_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
|
||||
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
|
||||
@@ -1656,16 +1656,16 @@ void PAHdivL2ApplyTranspose3D(const int D1D,
|
||||
}); // end of element loop
|
||||
}
|
||||
|
||||
void PAHdivL2ApplyTranspose2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int L2D1D,
|
||||
const int NE,
|
||||
const Array<double> &L2Bo_,
|
||||
const Array<double> &Gct_,
|
||||
const Array<double> &Bot_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
static void PAHdivL2ApplyTranspose2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int L2D1D,
|
||||
const int NE,
|
||||
const Array<double> &L2Bo_,
|
||||
const Array<double> &Gct_,
|
||||
const Array<double> &Bot_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_)
|
||||
{
|
||||
constexpr static int VDIM = 2;
|
||||
constexpr static int MAX_D1D = HDIV_MAX_D1D;
|
||||
@@ -1791,16 +1791,16 @@ void VectorFEDivergenceIntegrator::AddMultTransposePA(const Vector &x,
|
||||
}
|
||||
}
|
||||
|
||||
void PAHdivL2AssembleDiagonal_ADAt_3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int L2D1D,
|
||||
const int NE,
|
||||
const Array<double> &L2Bo_,
|
||||
const Array<double> &Gct_,
|
||||
const Array<double> &Bot_,
|
||||
const Vector &op_,
|
||||
const Vector &D_,
|
||||
Vector &diag_)
|
||||
static void PAHdivL2AssembleDiagonal_ADAt_3D(const int D1D,
|
||||
const int Q1D,
|
||||
const int L2D1D,
|
||||
const int NE,
|
||||
const Array<double> &L2Bo_,
|
||||
const Array<double> &Gct_,
|
||||
const Array<double> &Bot_,
|
||||
const Vector &op_,
|
||||
const Vector &D_,
|
||||
Vector &diag_)
|
||||
{
|
||||
MFEM_VERIFY(D1D <= HDIV_MAX_D1D, "Error: D1D > HDIV_MAX_D1D");
|
||||
MFEM_VERIFY(Q1D <= HDIV_MAX_Q1D, "Error: Q1D > HDIV_MAX_Q1D");
|
||||
@@ -1916,16 +1916,16 @@ void PAHdivL2AssembleDiagonal_ADAt_3D(const int D1D,
|
||||
}); // end of element loop
|
||||
}
|
||||
|
||||
void PAHdivL2AssembleDiagonal_ADAt_2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int L2D1D,
|
||||
const int NE,
|
||||
const Array<double> &L2Bo_,
|
||||
const Array<double> &Gct_,
|
||||
const Array<double> &Bot_,
|
||||
const Vector &op_,
|
||||
const Vector &D_,
|
||||
Vector &diag_)
|
||||
static void PAHdivL2AssembleDiagonal_ADAt_2D(const int D1D,
|
||||
const int Q1D,
|
||||
const int L2D1D,
|
||||
const int NE,
|
||||
const Array<double> &L2Bo_,
|
||||
const Array<double> &Gct_,
|
||||
const Array<double> &Bot_,
|
||||
const Vector &op_,
|
||||
const Vector &D_,
|
||||
Vector &diag_)
|
||||
{
|
||||
constexpr static int VDIM = 2;
|
||||
|
||||
|
||||
+21
-21
@@ -17,13 +17,13 @@ namespace mfem
|
||||
{
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void EAMassAssemble1D(const int NE,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void EAMassAssemble1D(const int NE,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -67,13 +67,13 @@ void EAMassAssemble1D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void EAMassAssemble2D(const int NE,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void EAMassAssemble2D(const int NE,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -139,13 +139,13 @@ void EAMassAssemble2D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void EAMassAssemble3D(const int NE,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void EAMassAssemble3D(const int NE,
|
||||
const Array<double> &basis,
|
||||
const Vector &padata,
|
||||
Vector &eadata,
|
||||
const bool add,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
|
||||
+56
-56
@@ -155,12 +155,12 @@ void MassIntegrator::AssemblePA(const FiniteElementSpace &fes)
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void PAMassAssembleDiagonal2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Vector &d,
|
||||
Vector &y,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PAMassAssembleDiagonal2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Vector &d,
|
||||
Vector &y,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -201,12 +201,12 @@ void PAMassAssembleDiagonal2D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
|
||||
void SmemPAMassAssembleDiagonal2D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Vector &d_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void SmemPAMassAssembleDiagonal2D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Vector &d_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -267,12 +267,12 @@ void SmemPAMassAssembleDiagonal2D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void PAMassAssembleDiagonal3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Vector &d,
|
||||
Vector &y,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PAMassAssembleDiagonal3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Vector &d,
|
||||
Vector &y,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -336,12 +336,12 @@ void PAMassAssembleDiagonal3D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void SmemPAMassAssembleDiagonal3D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Vector &d_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void SmemPAMassAssembleDiagonal3D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Vector &d_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -569,14 +569,14 @@ static void OccaPAMassApply3D(const int D1D,
|
||||
#endif // MFEM_USE_OCCA
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void PAMassApply2D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PAMassApply2D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -661,14 +661,14 @@ void PAMassApply2D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int T_NBZ = 0>
|
||||
void SmemPAMassApply2D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void SmemPAMassApply2D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
MFEM_CONTRACT_VAR(bt_);
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
@@ -784,14 +784,14 @@ void SmemPAMassApply2D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void PAMassApply3D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PAMassApply3D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -925,14 +925,14 @@ void PAMassApply3D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void SmemPAMassApply3D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void SmemPAMassApply3D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &bt_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
MFEM_CONTRACT_VAR(bt_);
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
|
||||
@@ -22,12 +22,12 @@ namespace mfem
|
||||
// PA Vector Diffusion Integrator
|
||||
|
||||
// PA Diffusion Assemble 2D kernel
|
||||
void PAVectorDiffusionSetup2D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const Vector &c,
|
||||
Vector &op)
|
||||
static void PAVectorDiffusionSetup2D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const Vector &c,
|
||||
Vector &op)
|
||||
{
|
||||
const int NQ = Q1D*Q1D;
|
||||
auto W = w.Read();
|
||||
@@ -59,12 +59,12 @@ void PAVectorDiffusionSetup2D(const int Q1D,
|
||||
}
|
||||
|
||||
// PA Diffusion Assemble 3D kernel
|
||||
void PAVectorDiffusionSetup3D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const Vector &c,
|
||||
Vector &op)
|
||||
static void PAVectorDiffusionSetup3D(const int Q1D,
|
||||
const int NE,
|
||||
const Array<double> &w,
|
||||
const Vector &j,
|
||||
const Vector &c,
|
||||
Vector &op)
|
||||
{
|
||||
const int NQ = Q1D*Q1D*Q1D;
|
||||
auto W = w.Read();
|
||||
@@ -251,7 +251,7 @@ void VectorDiffusionIntegrator::AssemblePA(const FiniteElementSpace &fes)
|
||||
}
|
||||
|
||||
// PA Diffusion Apply 2D kernel
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int T_VDIM = 0>
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int T_VDIM = 0> static
|
||||
void PAVectorDiffusionApply2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
@@ -374,7 +374,7 @@ void PAVectorDiffusionApply2D(const int NE,
|
||||
|
||||
// PA Diffusion Apply 3D kernel
|
||||
template<const int T_D1D = 0,
|
||||
const int T_Q1D = 0>
|
||||
const int T_Q1D = 0> static
|
||||
void PAVectorDiffusionApply3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
@@ -606,13 +606,13 @@ void VectorDiffusionIntegrator::AddMultPA(const Vector &x, Vector &y) const
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void PAVectorDiffusionDiagonal2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &d,
|
||||
Vector &y,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PAVectorDiffusionDiagonal2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &d,
|
||||
Vector &y,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -673,13 +673,13 @@ void PAVectorDiffusionDiagonal2D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void PAVectorDiffusionDiagonal3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &d,
|
||||
Vector &y,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PAVectorDiffusionDiagonal3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Vector &d,
|
||||
Vector &y,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
constexpr int DIM = 3;
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
|
||||
+30
-30
@@ -104,14 +104,14 @@ void VectorMassIntegrator::AssemblePA(const FiniteElementSpace &fes)
|
||||
|
||||
template<const int T_D1D = 0,
|
||||
const int T_Q1D = 0>
|
||||
void PAVectorMassApply2D(const int NE,
|
||||
const Array<double> &B_,
|
||||
const Array<double> &Bt_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PAVectorMassApply2D(const int NE,
|
||||
const Array<double> &B_,
|
||||
const Array<double> &Bt_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -201,14 +201,14 @@ void PAVectorMassApply2D(const int NE,
|
||||
|
||||
template<const int T_D1D = 0,
|
||||
const int T_Q1D = 0>
|
||||
void PAVectorMassApply3D(const int NE,
|
||||
const Array<double> &B_,
|
||||
const Array<double> &Bt_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PAVectorMassApply3D(const int NE,
|
||||
const Array<double> &B_,
|
||||
const Array<double> &Bt_,
|
||||
const Vector &op_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -379,13 +379,13 @@ void VectorMassIntegrator::AddMultPA(const Vector &x, Vector &y) const
|
||||
}
|
||||
|
||||
template<const int T_D1D = 0, const int T_Q1D = 0>
|
||||
void PAVectorMassAssembleDiagonal2D(const int NE,
|
||||
const Array<double> &B_,
|
||||
const Array<double> &Bt_,
|
||||
const Vector &op_,
|
||||
Vector &diag_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PAVectorMassAssembleDiagonal2D(const int NE,
|
||||
const Array<double> &B_,
|
||||
const Array<double> &Bt_,
|
||||
const Vector &op_,
|
||||
Vector &diag_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -431,13 +431,13 @@ void PAVectorMassAssembleDiagonal2D(const int NE,
|
||||
}
|
||||
|
||||
template<const int T_D1D = 0, const int T_Q1D = 0>
|
||||
void PAVectorMassAssembleDiagonal3D(const int NE,
|
||||
const Array<double> &B_,
|
||||
const Array<double> &Bt_,
|
||||
const Vector &op_,
|
||||
Vector &diag_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PAVectorMassAssembleDiagonal3D(const int NE,
|
||||
const Array<double> &B_,
|
||||
const Array<double> &Bt_,
|
||||
const Vector &op_,
|
||||
Vector &diag_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
|
||||
@@ -1,358 +0,0 @@
|
||||
// Copyright (c) 2010-2021, 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 "fem.hpp"
|
||||
|
||||
namespace mfem
|
||||
{
|
||||
|
||||
void DofTransformation::TransformPrimal(Vector &v) const
|
||||
{
|
||||
TransformPrimal(v.GetData());
|
||||
}
|
||||
|
||||
void DofTransformation::TransformPrimalCols(DenseMatrix &V) const
|
||||
{
|
||||
for (int c=0; c<V.Width(); c++)
|
||||
{
|
||||
TransformPrimal(V.GetColumn(c));
|
||||
}
|
||||
}
|
||||
|
||||
void DofTransformation::TransformDual(Vector &v) const
|
||||
{
|
||||
TransformDual(v.GetData());
|
||||
}
|
||||
|
||||
void DofTransformation::TransformDual(DenseMatrix &V) const
|
||||
{
|
||||
TransformDualCols(V);
|
||||
TransformDualRows(V);
|
||||
}
|
||||
|
||||
void DofTransformation::TransformDualRows(DenseMatrix &V) const
|
||||
{
|
||||
Vector row;
|
||||
for (int r=0; r<V.Height(); r++)
|
||||
{
|
||||
V.GetRow(r, row);
|
||||
TransformDual(row);
|
||||
V.SetRow(r, row);
|
||||
}
|
||||
}
|
||||
|
||||
void DofTransformation::TransformDualCols(DenseMatrix &V) const
|
||||
{
|
||||
for (int c=0; c<V.Width(); c++)
|
||||
{
|
||||
TransformDual(V.GetColumn(c));
|
||||
}
|
||||
}
|
||||
|
||||
void DofTransformation::InvTransformPrimal(Vector &v) const
|
||||
{
|
||||
InvTransformPrimal(v.GetData());
|
||||
}
|
||||
|
||||
void TransformPrimal(const DofTransformation *ran_dof_trans,
|
||||
const DofTransformation *dom_dof_trans,
|
||||
DenseMatrix &elmat)
|
||||
{
|
||||
if (ran_dof_trans && dom_dof_trans)
|
||||
{
|
||||
ran_dof_trans->TransformPrimalCols(elmat);
|
||||
dom_dof_trans->TransformDualRows(elmat);
|
||||
}
|
||||
else if (ran_dof_trans)
|
||||
{
|
||||
ran_dof_trans->TransformPrimalCols(elmat);
|
||||
}
|
||||
else if (dom_dof_trans)
|
||||
{
|
||||
dom_dof_trans->TransformDualRows(elmat);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If both transformations are NULL this function should not be called
|
||||
}
|
||||
}
|
||||
|
||||
void TransformDual(const DofTransformation *ran_dof_trans,
|
||||
const DofTransformation *dom_dof_trans,
|
||||
DenseMatrix &elmat)
|
||||
{
|
||||
if (ran_dof_trans && dom_dof_trans)
|
||||
{
|
||||
ran_dof_trans->TransformDualCols(elmat);
|
||||
dom_dof_trans->TransformDualRows(elmat);
|
||||
}
|
||||
else if (ran_dof_trans)
|
||||
{
|
||||
ran_dof_trans->TransformDualCols(elmat);
|
||||
}
|
||||
else if (dom_dof_trans)
|
||||
{
|
||||
dom_dof_trans->TransformDualRows(elmat);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If both transformations are NULL this function should not be called
|
||||
}
|
||||
}
|
||||
|
||||
void VDofTransformation::TransformPrimal(double *v) const
|
||||
{
|
||||
int size = doftrans_->Size();
|
||||
|
||||
if ((Ordering::Type)ordering_ == Ordering::byNODES || vdim_ == 1)
|
||||
{
|
||||
for (int i=0; i<vdim_; i++)
|
||||
{
|
||||
doftrans_->TransformPrimal(&v[i*size]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector vec(size);
|
||||
for (int i=0; i<vdim_; i++)
|
||||
{
|
||||
for (int j=0; j<size; j++)
|
||||
{
|
||||
vec(j) = v[j*vdim_+i];
|
||||
}
|
||||
doftrans_->TransformPrimal(vec);
|
||||
for (int j=0; j<size; j++)
|
||||
{
|
||||
v[j*vdim_+i] = vec(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VDofTransformation::InvTransformPrimal(double *v) const
|
||||
{
|
||||
int size = doftrans_->Height();
|
||||
|
||||
if ((Ordering::Type)ordering_ == Ordering::byNODES)
|
||||
{
|
||||
for (int i=0; i<vdim_; i++)
|
||||
{
|
||||
doftrans_->InvTransformPrimal(&v[i*size]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector vec(size);
|
||||
for (int i=0; i<vdim_; i++)
|
||||
{
|
||||
for (int j=0; j<size; j++)
|
||||
{
|
||||
vec(j) = v[j*vdim_+i];
|
||||
}
|
||||
doftrans_->InvTransformPrimal(vec);
|
||||
for (int j=0; j<size; j++)
|
||||
{
|
||||
v[j*vdim_+i] = vec(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VDofTransformation::TransformDual(double *v) const
|
||||
{
|
||||
int size = doftrans_->Size();
|
||||
|
||||
if ((Ordering::Type)ordering_ == Ordering::byNODES)
|
||||
{
|
||||
for (int i=0; i<vdim_; i++)
|
||||
{
|
||||
doftrans_->TransformDual(&v[i*size]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector vec(size);
|
||||
for (int i=0; i<vdim_; i++)
|
||||
{
|
||||
for (int j=0; j<size; j++)
|
||||
{
|
||||
vec(j) = v[j*vdim_+i];
|
||||
}
|
||||
doftrans_->TransformDual(vec);
|
||||
for (int j=0; j<size; j++)
|
||||
{
|
||||
v[j*vdim_+i] = vec(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const double ND_DofTransformation::T_data[24] =
|
||||
{
|
||||
1.0, 0.0, 0.0, 1.0,
|
||||
-1.0, -1.0, 0.0, 1.0,
|
||||
0.0, 1.0, -1.0, -1.0,
|
||||
1.0, 0.0, -1.0, -1.0,
|
||||
-1.0, -1.0, 1.0, 0.0,
|
||||
0.0, 1.0, 1.0, 0.0
|
||||
};
|
||||
|
||||
const DenseTensor ND_DofTransformation
|
||||
::T(const_cast<double*>(ND_DofTransformation::T_data), 2, 2, 6);
|
||||
|
||||
const double ND_DofTransformation::TInv_data[24] =
|
||||
{
|
||||
1.0, 0.0, 0.0, 1.0,
|
||||
-1.0, -1.0, 0.0, 1.0,
|
||||
-1.0, -1.0, 1.0, 0.0,
|
||||
1.0, 0.0, -1.0, -1.0,
|
||||
0.0, 1.0, -1.0, -1.0,
|
||||
0.0, 1.0, 1.0, 0.0
|
||||
};
|
||||
|
||||
const DenseTensor ND_DofTransformation
|
||||
::TInv(const_cast<double*>(TInv_data), 2, 2, 6);
|
||||
|
||||
ND_DofTransformation::ND_DofTransformation(int size, int p)
|
||||
: DofTransformation(size),
|
||||
order(p)
|
||||
{
|
||||
}
|
||||
|
||||
ND_TriDofTransformation::ND_TriDofTransformation(int p)
|
||||
: ND_DofTransformation(p*(p + 2), p)
|
||||
{
|
||||
}
|
||||
|
||||
void ND_TriDofTransformation::TransformPrimal(double *v) const
|
||||
{
|
||||
int nedofs = order; // number of DoFs per edge
|
||||
int nfdofs = order*(order-1); // number of DoFs per face
|
||||
|
||||
double data[2];
|
||||
Vector v2(data, 2);
|
||||
|
||||
// Transform face DoFs
|
||||
for (int f=0; f<1; f++)
|
||||
{
|
||||
for (int i=0; i<nfdofs/2; i++)
|
||||
{
|
||||
v2 = &v[3*nedofs + f*nfdofs + 2*i];
|
||||
T(Fo[f]).Mult(v2, &v[3*nedofs + f*nfdofs + 2*i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ND_TriDofTransformation::InvTransformPrimal(double *v) const
|
||||
{
|
||||
int nedofs = order; // number of DoFs per edge
|
||||
int nfdofs = order*(order-1); // number of DoFs per face
|
||||
|
||||
double data[2];
|
||||
Vector v2(data, 2);
|
||||
|
||||
// Transform face DoFs
|
||||
for (int f=0; f<1; f++)
|
||||
{
|
||||
for (int i=0; i<nfdofs/2; i++)
|
||||
{
|
||||
v2 = &v[3*nedofs + f*nfdofs + 2*i];
|
||||
TInv(Fo[f]).Mult(v2, &v[3*nedofs + f*nfdofs + 2*i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ND_TriDofTransformation::TransformDual(double *v) const
|
||||
{
|
||||
int nedofs = order; // number of DoFs per edge
|
||||
int nfdofs = order*(order-1); // number of DoFs per face
|
||||
|
||||
double data[2];
|
||||
Vector v2(data, 2);
|
||||
|
||||
// Transform face DoFs
|
||||
for (int f=0; f<1; f++)
|
||||
{
|
||||
for (int i=0; i<nfdofs/2; i++)
|
||||
{
|
||||
v2 = &v[3*nedofs + f*nfdofs + 2*i];
|
||||
TInv(Fo[f]).MultTranspose(v2, &v[3*nedofs + f*nfdofs + 2*i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ND_TetDofTransformation::ND_TetDofTransformation(int p)
|
||||
: ND_DofTransformation(p*(p + 2)*(p + 3)/2, p)
|
||||
{
|
||||
}
|
||||
|
||||
void ND_TetDofTransformation::TransformPrimal(double *v) const
|
||||
{
|
||||
int nedofs = order; // number of DoFs per edge
|
||||
int nfdofs = order*(order-1); // number of DoFs per face
|
||||
|
||||
double data[2];
|
||||
Vector v2(data, 2);
|
||||
|
||||
// Transform face DoFs
|
||||
for (int f=0; f<4; f++)
|
||||
{
|
||||
for (int i=0; i<nfdofs/2; i++)
|
||||
{
|
||||
v2 = &v[6*nedofs + f*nfdofs + 2*i];
|
||||
T(Fo[f]).Mult(v2, &v[6*nedofs + f*nfdofs + 2*i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ND_TetDofTransformation::InvTransformPrimal(double *v) const
|
||||
{
|
||||
int nedofs = order; // number of DoFs per edge
|
||||
int nfdofs = order*(order-1); // number of DoFs per face
|
||||
|
||||
double data[2];
|
||||
Vector v2(data, 2);
|
||||
|
||||
// Transform face DoFs
|
||||
for (int f=0; f<4; f++)
|
||||
{
|
||||
for (int i=0; i<nfdofs/2; i++)
|
||||
{
|
||||
v2 = &v[6*nedofs + f*nfdofs + 2*i];
|
||||
TInv(Fo[f]).Mult(v2, &v[6*nedofs + f*nfdofs + 2*i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ND_TetDofTransformation::TransformDual(double *v) const
|
||||
{
|
||||
int nedofs = order; // number of DoFs per edge
|
||||
int nfdofs = order*(order-1); // number of DoFs per face
|
||||
|
||||
double data[2];
|
||||
Vector v2(data, 2);
|
||||
|
||||
// Transform face DoFs
|
||||
for (int f=0; f<4; f++)
|
||||
{
|
||||
for (int i=0; i<nfdofs/2; i++)
|
||||
{
|
||||
v2 = &v[6*nedofs + f*nfdofs + 2*i];
|
||||
TInv(Fo[f]).MultTranspose(v2, &v[6*nedofs + f*nfdofs + 2*i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mfem
|
||||
@@ -1,277 +0,0 @@
|
||||
// Copyright (c) 2010-2021, 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.
|
||||
|
||||
#ifndef MFEM_DOFTRANSFORM
|
||||
#define MFEM_DOFTRANSFORM
|
||||
|
||||
#include "../config/config.hpp"
|
||||
#include "../linalg/linalg.hpp"
|
||||
#include "intrules.hpp"
|
||||
#include "fe.hpp"
|
||||
|
||||
namespace mfem
|
||||
{
|
||||
|
||||
/** The DofTransformation class is an abstract base class for a family of
|
||||
transformations that map local degrees of freedom (DoFs), contained within
|
||||
individual elements, to global degrees of freedom, stored within
|
||||
GridFunction objects. These transformations are necessary to ensure that
|
||||
basis functions in neighboring elements align correctly. Closely related but
|
||||
complementary transformations are required for the entries stored in
|
||||
LinearForm and BilinearForm objects. The DofTransformation class is designed
|
||||
to apply the action of both of these types of DoF transformations.
|
||||
|
||||
Let the "primal transformation" be given by the operator T. This means that
|
||||
given a local element vector v the data that must be placed into a
|
||||
GridFunction object is v_t = T * v.
|
||||
|
||||
We also need the inverse of the primal transformation T^{-1} so that we can
|
||||
recover the local element vector from data read out of a GridFunction
|
||||
e.g. v = T^{-1} * v_t.
|
||||
|
||||
We need to preserve the action of our linear forms applied to primal
|
||||
vectors. In other words, if f is the local vector computed by a linear
|
||||
form then f * v = f_t * v_t (where "*" represents an inner product of
|
||||
vectors). This requires that f_t = T^{-T} * f i.e. the "dual transform" is
|
||||
given by the transpose of the inverse of the primal transformation.
|
||||
|
||||
For bilinear forms we require that v^T * A * v = v_t^T * A_t * v_t. This
|
||||
implies that A_t = T^{-T} * A * T^{-1}. This can be accomplished by
|
||||
performing dual transformations of the rows and columns of the matrix A.
|
||||
|
||||
For discrete linear operators the range must be modified with the primal
|
||||
transformation rather than the dual transformation because the result is a
|
||||
primal vector rather than a dual vector. This leads to the transformation
|
||||
D_t = T * D * T^{-1}. This can be accomplished by using a primal
|
||||
transformation on the columns of D and a dual transformation on its rows.
|
||||
*/
|
||||
class DofTransformation
|
||||
{
|
||||
protected:
|
||||
int size_;
|
||||
|
||||
Array<int> Fo;
|
||||
|
||||
DofTransformation(int size)
|
||||
: size_(size) {}
|
||||
|
||||
public:
|
||||
|
||||
inline int Size() const { return size_; }
|
||||
inline int Height() const { return size_; }
|
||||
inline int NumRows() const { return size_; }
|
||||
inline int Width() const { return size_; }
|
||||
inline int NumCols() const { return size_; }
|
||||
|
||||
/** @brief Configure the transformation using face orientations for the
|
||||
current element. */
|
||||
/// The face_orientation array can be obtained from Mesh::GetElementFaces.
|
||||
inline void SetFaceOrientations(const Array<int> & face_orientation)
|
||||
{ Fo = face_orientation; }
|
||||
|
||||
inline const Array<int> & GetFaceOrientations() const { return Fo; }
|
||||
|
||||
/** Transform local DoFs to align with the global DoFs. For example, this
|
||||
transformation can be used to map the local vector computed by
|
||||
FiniteElement::Project() to the transformed vector stored within a
|
||||
GridFunction object. */
|
||||
virtual void TransformPrimal(double *v) const = 0;
|
||||
virtual void TransformPrimal(Vector &v) const;
|
||||
|
||||
/// Transform groups of DoFs stored as dense matrices
|
||||
virtual void TransformPrimalCols(DenseMatrix &V) const;
|
||||
|
||||
/** Inverse transform local DoFs. Used to transform DoFs from a global vector
|
||||
back to their element-local form. For example, this must be used to
|
||||
transform the vector obtained using GridFunction::GetSubVector before it
|
||||
can be used to compute a local interpolation.
|
||||
*/
|
||||
virtual void InvTransformPrimal(double *v) const = 0;
|
||||
virtual void InvTransformPrimal(Vector &v) const;
|
||||
|
||||
/** Transform dual DoFs as computed by a LinearFormIntegrator before summing
|
||||
into a LinearForm object. */
|
||||
virtual void TransformDual(double *v) const = 0;
|
||||
virtual void TransformDual(Vector &v) const;
|
||||
|
||||
/** Transform a matrix of dual DoFs entries as computed by a
|
||||
BilinearFormIntegrator before summing into a BilinearForm object. */
|
||||
virtual void TransformDual(DenseMatrix &V) const;
|
||||
|
||||
/// Transform groups of dual DoFs stored as dense matrices
|
||||
virtual void TransformDualRows(DenseMatrix &V) const;
|
||||
virtual void TransformDualCols(DenseMatrix &V) const;
|
||||
|
||||
virtual ~DofTransformation() {}
|
||||
};
|
||||
|
||||
/** Transform a matrix of DoFs entries from different finite element spaces as
|
||||
computed by a DiscreteInterpolator before copying into a
|
||||
DiscreteLinearOperator.
|
||||
*/
|
||||
void TransformPrimal(const DofTransformation *ran_dof_trans,
|
||||
const DofTransformation *dom_dof_trans,
|
||||
DenseMatrix &elmat);
|
||||
|
||||
/** Transform a matrix of dual DoFs entries from different finite element spaces
|
||||
as computed by a BilinearFormIntegrator before summing into a
|
||||
MixedBilinearForm object.
|
||||
*/
|
||||
void TransformDual(const DofTransformation *ran_dof_trans,
|
||||
const DofTransformation *dom_dof_trans,
|
||||
DenseMatrix &elmat);
|
||||
|
||||
/** The VDofTransformation class implements a nested transformation where an
|
||||
arbitrary DofTransformation is replicated with a vdim >= 1.
|
||||
*/
|
||||
class VDofTransformation : public DofTransformation
|
||||
{
|
||||
private:
|
||||
int vdim_;
|
||||
int ordering_;
|
||||
DofTransformation * doftrans_;
|
||||
|
||||
public:
|
||||
/** @brief Default constructor which requires that SetDofTransformation be
|
||||
called before use. */
|
||||
VDofTransformation(int vdim = 1, int ordering = 0)
|
||||
: DofTransformation(0),
|
||||
vdim_(vdim), ordering_(ordering),
|
||||
doftrans_(NULL) {}
|
||||
|
||||
/// Constructor with a known DofTransformation
|
||||
VDofTransformation(DofTransformation & doftrans, int vdim = 1,
|
||||
int ordering = 0)
|
||||
: DofTransformation(vdim * doftrans.Size()),
|
||||
vdim_(vdim), ordering_(ordering),
|
||||
doftrans_(&doftrans) {}
|
||||
|
||||
/// Set or change the vdim parameter
|
||||
inline void SetVDim(int vdim)
|
||||
{
|
||||
vdim_ = vdim;
|
||||
if (doftrans_)
|
||||
{
|
||||
size_ = vdim_ * doftrans_->Size();
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the current vdim value
|
||||
inline int GetVDim() const { return vdim_; }
|
||||
|
||||
/// Set or change the nested DofTransformation object
|
||||
inline void SetDofTransformation(DofTransformation & doftrans)
|
||||
{
|
||||
size_ = vdim_ * doftrans.Size();
|
||||
doftrans_ = &doftrans;
|
||||
}
|
||||
|
||||
/// Return the nested DofTransformation object
|
||||
inline DofTransformation * GetDofTransformation() const { return doftrans_; }
|
||||
|
||||
inline void SetFaceOrientation(const Array<int> & face_orientation)
|
||||
{ Fo = face_orientation; doftrans_->SetFaceOrientations(face_orientation); }
|
||||
|
||||
using DofTransformation::TransformPrimal;
|
||||
using DofTransformation::InvTransformPrimal;
|
||||
using DofTransformation::TransformDual;
|
||||
|
||||
void TransformPrimal(double *v) const;
|
||||
void InvTransformPrimal(double *v) const;
|
||||
void TransformDual(double *v) const;
|
||||
};
|
||||
|
||||
/** Abstract base class for high-order Nedelec spaces on elements with
|
||||
triangular faces.
|
||||
|
||||
The Nedelec DoFs on the interior of triangular faces come in pairs which
|
||||
share an interpolation point but have different vector directions. These
|
||||
directions depend on the orientation of the face and can therefore differ in
|
||||
neighboring elements. The mapping required to transform these DoFs can be
|
||||
implemented as series of 2x2 linear transformations. The raw data for these
|
||||
linear transformations is stored in the T_data and TInv_data arrays and can
|
||||
be accessed as DenseMatrices using the GetFaceTransform() and
|
||||
GetFaceInverseTransform() methods.
|
||||
*/
|
||||
class ND_DofTransformation : public DofTransformation
|
||||
{
|
||||
protected:
|
||||
static const double T_data[24];
|
||||
static const double TInv_data[24];
|
||||
static const DenseTensor T, TInv;
|
||||
int order;
|
||||
|
||||
ND_DofTransformation(int size, int order);
|
||||
|
||||
public:
|
||||
// Return the 2x2 transformation operator for the given face orientation
|
||||
static const DenseMatrix & GetFaceTransform(int ori) { return T(ori); }
|
||||
|
||||
// Return the 2x2 inverse transformation operator
|
||||
static const DenseMatrix & GetFaceInverseTransform(int ori)
|
||||
{ return TInv(ori); }
|
||||
};
|
||||
|
||||
/// DoF transformation implementation for the Nedelec basis on triangles
|
||||
class ND_TriDofTransformation : public ND_DofTransformation
|
||||
{
|
||||
public:
|
||||
ND_TriDofTransformation(int order);
|
||||
|
||||
using DofTransformation::TransformPrimal;
|
||||
using DofTransformation::InvTransformPrimal;
|
||||
using DofTransformation::TransformDual;
|
||||
|
||||
void TransformPrimal(double *v) const;
|
||||
|
||||
void InvTransformPrimal(double *v) const;
|
||||
|
||||
void TransformDual(double *v) const;
|
||||
};
|
||||
|
||||
/// DoF transformation implementation for the Nedelec basis on tetrahedra
|
||||
class ND_TetDofTransformation : public ND_DofTransformation
|
||||
{
|
||||
public:
|
||||
ND_TetDofTransformation(int order);
|
||||
|
||||
using DofTransformation::TransformPrimal;
|
||||
using DofTransformation::InvTransformPrimal;
|
||||
using DofTransformation::TransformDual;
|
||||
|
||||
void TransformPrimal(double *v) const;
|
||||
|
||||
void InvTransformPrimal(double *v) const;
|
||||
|
||||
void TransformDual(double *v) const;
|
||||
};
|
||||
|
||||
/// DoF transformation implementation for the Nedelec basis on wedge elements
|
||||
/** TODO: (Under development) */
|
||||
class ND_WedgeDofTransformation : public ND_DofTransformation
|
||||
{
|
||||
public:
|
||||
ND_WedgeDofTransformation(int order);
|
||||
|
||||
using DofTransformation::TransformPrimal;
|
||||
using DofTransformation::InvTransformPrimal;
|
||||
using DofTransformation::TransformDual;
|
||||
|
||||
void TransformPrimal(double *v) const;
|
||||
|
||||
void InvTransformPrimal(double *v) const;
|
||||
|
||||
void TransformDual(double *v) const;
|
||||
};
|
||||
|
||||
} // namespace mfem
|
||||
|
||||
#endif // MFEM_DOFTRANSFORM
|
||||
@@ -380,7 +380,6 @@ void IsoparametricTransformation::SetIdentityTransformation(
|
||||
case Geometry::TETRAHEDRON : FElem = &TetrahedronFE; break;
|
||||
case Geometry::CUBE : FElem = &HexahedronFE; break;
|
||||
case Geometry::PRISM : FElem = &WedgeFE; break;
|
||||
case Geometry::PYRAMID : FElem = &PyramidFE; break;
|
||||
default:
|
||||
MFEM_ABORT("unknown Geometry::Type!");
|
||||
}
|
||||
|
||||
+2
-3
@@ -329,7 +329,7 @@ void KellyErrorEstimator::ComputeEstimates()
|
||||
error_estimates(e) = sqrt(factor * error_estimates(e));
|
||||
}
|
||||
|
||||
total_error = error_estimates.Norml2();
|
||||
total_error = error_estimates.Sum();
|
||||
delete flux;
|
||||
return;
|
||||
}
|
||||
@@ -452,10 +452,9 @@ void KellyErrorEstimator::ComputeEstimates()
|
||||
auto pfes = dynamic_cast<ParFiniteElementSpace*>(xfes);
|
||||
MFEM_VERIFY(pfes, "xfes is not a ParFiniteElementSpace pointer");
|
||||
|
||||
double process_local_error = pow(error_estimates.Norml2(),2.0);
|
||||
double process_local_error = error_estimates.Sum();
|
||||
MPI_Allreduce(&process_local_error, &total_error, 1, MPI_DOUBLE,
|
||||
MPI_SUM, pfes->GetComm());
|
||||
total_error = sqrt(total_error);
|
||||
#endif // MFEM_USE_MPI
|
||||
}
|
||||
|
||||
|
||||
+18
-1204
File diff suppressed because it is too large
Load Diff
-219
@@ -1313,64 +1313,6 @@ public:
|
||||
DenseMatrix &dshape) const;
|
||||
};
|
||||
|
||||
/// A linear element defined on a triangular prism
|
||||
class LinearWedgeFiniteElement : public NodalFiniteElement
|
||||
{
|
||||
public:
|
||||
/// Construct the LinearWedgeFiniteElement
|
||||
LinearWedgeFiniteElement();
|
||||
|
||||
/** @brief virtual function which evaluates the values of all
|
||||
shape functions at a given point ip and stores
|
||||
them in the vector shape of dimension Dof (4) */
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
|
||||
/** @brief virtual function which evaluates the values of all
|
||||
partial derivatives of all shape functions at a given
|
||||
point ip and stores them in the matrix dshape (Dof x Dim) (4 x 3)
|
||||
so that each row contains the derivatives of one shape function */
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
||||
{ dofs = 0.0; dofs(vertex) = 1.0; }
|
||||
|
||||
/** @brief Get the dofs associated with the given @a face.
|
||||
@a *dofs is set to an internal array of the local dofc on the
|
||||
face, while *ndofs is set to the number of dofs on that face.
|
||||
*/
|
||||
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const;
|
||||
};
|
||||
|
||||
/// A linear element defined on a square pyramid
|
||||
class LinearPyramidFiniteElement : public NodalFiniteElement
|
||||
{
|
||||
public:
|
||||
/// Construct the LinearPyramidFiniteElement
|
||||
LinearPyramidFiniteElement();
|
||||
|
||||
/** @brief virtual function which evaluates the values of all
|
||||
shape functions at a given point ip and stores
|
||||
them in the vector shape of dimension Dof (4) */
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
|
||||
/** @brief virtual function which evaluates the values of all
|
||||
partial derivatives of all shape functions at a given
|
||||
point ip and stores them in the matrix dshape (Dof x Dim) (4 x 3)
|
||||
so that each row contains the derivatives of one shape function */
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
||||
{ dofs = 0.0; dofs(vertex) = 1.0; }
|
||||
|
||||
/** @brief Get the dofs associated with the given @a face.
|
||||
@a *dofs is set to an internal array of the local dofc on the
|
||||
face, while *ndofs is set to the number of dofs on that face.
|
||||
*/
|
||||
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const;
|
||||
};
|
||||
|
||||
/// A 2D constant element on a triangle
|
||||
class P0TriangleFiniteElement : public NodalFiniteElement
|
||||
{
|
||||
@@ -1748,32 +1690,6 @@ public:
|
||||
{ dofs(0) = 1.0; }
|
||||
};
|
||||
|
||||
/// A 3D constant element on a wedge
|
||||
class P0WdgFiniteElement : public NodalFiniteElement
|
||||
{
|
||||
public:
|
||||
/// Construct the P0WdgFiniteElement
|
||||
P0WdgFiniteElement ();
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
||||
{ dofs(0) = 1.0; }
|
||||
};
|
||||
|
||||
/// A 3D constant element on a pyramid
|
||||
class P0PyrFiniteElement : public NodalFiniteElement
|
||||
{
|
||||
public:
|
||||
/// Construct the P0PyrFiniteElement
|
||||
P0PyrFiniteElement ();
|
||||
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
|
||||
virtual void CalcDShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &dshape) const;
|
||||
virtual void ProjectDelta(int vertex, Vector &dofs) const
|
||||
{ dofs(0) = 1.0; }
|
||||
};
|
||||
|
||||
/** @brief Tensor products of 1D Lagrange1DFiniteElement
|
||||
(only degree 2 is functional) */
|
||||
class LagrangeHexFiniteElement : public NodalFiniteElement
|
||||
@@ -1912,10 +1828,6 @@ public:
|
||||
using FiniteElement::Project;
|
||||
virtual void Project (VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -1940,66 +1852,6 @@ public:
|
||||
using FiniteElement::Project;
|
||||
virtual void Project (VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const;
|
||||
};
|
||||
|
||||
|
||||
/// A 3D 1st order Nedelec element on a wedge
|
||||
class Nedelec1WdgFiniteElement : public VectorFiniteElement
|
||||
{
|
||||
private:
|
||||
static const double tk[9][3];
|
||||
|
||||
public:
|
||||
/// Construct the Nedelec1WdgFiniteElement
|
||||
Nedelec1WdgFiniteElement();
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
{ CalcVShape_ND(Trans, shape); }
|
||||
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const;
|
||||
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
||||
DenseMatrix &I) const;
|
||||
using FiniteElement::Project;
|
||||
virtual void Project (VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const;
|
||||
};
|
||||
|
||||
|
||||
/// A 3D 1st order Nedelec element on a pyramid
|
||||
class Nedelec1PyrFiniteElement : public VectorFiniteElement
|
||||
{
|
||||
private:
|
||||
static const double tk[8][3];
|
||||
|
||||
public:
|
||||
/// Construct the Nedelec1PyrFiniteElement
|
||||
Nedelec1PyrFiniteElement();
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
{ CalcVShape_ND(Trans, shape); }
|
||||
virtual void CalcCurlShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &curl_shape) const;
|
||||
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
||||
DenseMatrix &I) const;
|
||||
using FiniteElement::Project;
|
||||
virtual void Project (VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
|
||||
virtual void ProjectGrad(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &grad) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -2093,77 +1945,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/// A 3D 0th order Raviert-Thomas element on a wedge
|
||||
class RT0WdgFiniteElement : public VectorFiniteElement
|
||||
{
|
||||
private:
|
||||
static const double nk[5][3];
|
||||
|
||||
public:
|
||||
/// Construct the RT0WdgFiniteElement
|
||||
RT0WdgFiniteElement();
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
{ CalcVShape_RT(Trans, shape); }
|
||||
|
||||
virtual void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const;
|
||||
|
||||
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
||||
DenseMatrix &I) const;
|
||||
|
||||
using FiniteElement::Project;
|
||||
|
||||
virtual void Project (VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const;
|
||||
};
|
||||
|
||||
|
||||
/// A 3D 0th order Raviert-Thomas element on a pyramid
|
||||
class RT0PyrFiniteElement : public VectorFiniteElement
|
||||
{
|
||||
private:
|
||||
static const double nk[5][3];
|
||||
|
||||
// If true match RT0TetFiniteElement rather than RT_TetrahedronElement(0)
|
||||
bool rt0;
|
||||
|
||||
public:
|
||||
/// Construct the RT0PyrFiniteElement
|
||||
RT0PyrFiniteElement(bool rt0tets = true);
|
||||
|
||||
virtual void CalcVShape(const IntegrationPoint &ip,
|
||||
DenseMatrix &shape) const;
|
||||
|
||||
virtual void CalcVShape(ElementTransformation &Trans,
|
||||
DenseMatrix &shape) const
|
||||
{ CalcVShape_RT(Trans, shape); }
|
||||
|
||||
virtual void CalcDivShape(const IntegrationPoint &ip,
|
||||
Vector &divshape) const;
|
||||
|
||||
virtual void GetLocalInterpolation (ElementTransformation &Trans,
|
||||
DenseMatrix &I) const;
|
||||
|
||||
using FiniteElement::Project;
|
||||
|
||||
virtual void Project (VectorCoefficient &vc,
|
||||
ElementTransformation &Trans, Vector &dofs) const;
|
||||
|
||||
virtual void ProjectCurl(const FiniteElement &fe,
|
||||
ElementTransformation &Trans,
|
||||
DenseMatrix &curl) const;
|
||||
};
|
||||
|
||||
|
||||
class RotTriLinearHexFiniteElement : public NodalFiniteElement
|
||||
{
|
||||
public:
|
||||
|
||||
+15
-121
@@ -33,9 +33,6 @@ int FiniteElementCollection::HasFaceDofs(Geometry::Type geom, int p) const
|
||||
case Geometry::PRISM:
|
||||
return max(GetNumDof(Geometry::TRIANGLE, p),
|
||||
GetNumDof(Geometry::SQUARE, p));
|
||||
case Geometry::PYRAMID:
|
||||
return max(GetNumDof(Geometry::TRIANGLE, p),
|
||||
GetNumDof(Geometry::SQUARE, p));
|
||||
default:
|
||||
MFEM_ABORT("unknown geometry type");
|
||||
}
|
||||
@@ -577,7 +574,6 @@ LinearFECollection::FiniteElementForGeometry(Geometry::Type GeomType) const
|
||||
case Geometry::TETRAHEDRON: return &TetrahedronFE;
|
||||
case Geometry::CUBE: return &ParallelepipedFE;
|
||||
case Geometry::PRISM: return &WedgeFE;
|
||||
case Geometry::PYRAMID: return &PyramidFE;
|
||||
default:
|
||||
mfem_error ("LinearFECollection: unknown geometry type.");
|
||||
}
|
||||
@@ -595,7 +591,6 @@ int LinearFECollection::DofForGeometry(Geometry::Type GeomType) const
|
||||
case Geometry::TETRAHEDRON: return 0;
|
||||
case Geometry::CUBE: return 0;
|
||||
case Geometry::PRISM: return 0;
|
||||
case Geometry::PYRAMID: return 0;
|
||||
default:
|
||||
mfem_error ("LinearFECollection: unknown geometry type.");
|
||||
}
|
||||
@@ -1245,7 +1240,6 @@ Const3DFECollection::FiniteElementForGeometry(Geometry::Type GeomType) const
|
||||
case Geometry::TETRAHEDRON: return &TetrahedronFE;
|
||||
case Geometry::CUBE: return &ParallelepipedFE;
|
||||
case Geometry::PRISM: return &WedgeFE;
|
||||
case Geometry::PYRAMID: return &PyramidFE;
|
||||
default:
|
||||
mfem_error ("Const3DFECollection: unknown geometry type.");
|
||||
}
|
||||
@@ -1263,7 +1257,6 @@ int Const3DFECollection::DofForGeometry(Geometry::Type GeomType) const
|
||||
case Geometry::TETRAHEDRON: return 1;
|
||||
case Geometry::CUBE: return 1;
|
||||
case Geometry::PRISM: return 1;
|
||||
case Geometry::PYRAMID: return 1;
|
||||
default:
|
||||
mfem_error ("Const3DFECollection: unknown geometry type.");
|
||||
}
|
||||
@@ -1284,8 +1277,6 @@ LinearDiscont3DFECollection::FiniteElementForGeometry(
|
||||
switch (GeomType)
|
||||
{
|
||||
case Geometry::TETRAHEDRON: return &TetrahedronFE;
|
||||
case Geometry::PYRAMID: return &PyramidFE;
|
||||
case Geometry::PRISM: return &WedgeFE;
|
||||
case Geometry::CUBE: return &ParallelepipedFE;
|
||||
default:
|
||||
mfem_error ("LinearDiscont3DFECollection: unknown geometry type.");
|
||||
@@ -1302,8 +1293,6 @@ int LinearDiscont3DFECollection::DofForGeometry(Geometry::Type GeomType) const
|
||||
case Geometry::TRIANGLE: return 0;
|
||||
case Geometry::SQUARE: return 0;
|
||||
case Geometry::TETRAHEDRON: return 4;
|
||||
case Geometry::PYRAMID: return 5;
|
||||
case Geometry::PRISM: return 6;
|
||||
case Geometry::CUBE: return 8;
|
||||
default:
|
||||
mfem_error ("LinearDiscont3DFECollection: unknown geometry type.");
|
||||
@@ -1405,8 +1394,6 @@ ND1_3DFECollection::FiniteElementForGeometry(Geometry::Type GeomType) const
|
||||
{
|
||||
case Geometry::CUBE: return &HexahedronFE;
|
||||
case Geometry::TETRAHEDRON: return &TetrahedronFE;
|
||||
case Geometry::PRISM: return &WedgeFE;
|
||||
case Geometry::PYRAMID: return &PyramidFE;
|
||||
default:
|
||||
mfem_error ("ND1_3DFECollection: unknown geometry type.");
|
||||
}
|
||||
@@ -1423,8 +1410,6 @@ int ND1_3DFECollection::DofForGeometry(Geometry::Type GeomType) const
|
||||
case Geometry::SQUARE: return 0;
|
||||
case Geometry::TETRAHEDRON: return 0;
|
||||
case Geometry::CUBE: return 0;
|
||||
case Geometry::PRISM: return 0;
|
||||
case Geometry::PYRAMID: return 0;
|
||||
default:
|
||||
mfem_error ("ND1_3DFECollection: unknown geometry type.");
|
||||
}
|
||||
@@ -1454,8 +1439,6 @@ RT0_3DFECollection::FiniteElementForGeometry(Geometry::Type GeomType) const
|
||||
case Geometry::SQUARE: return &QuadrilateralFE;
|
||||
case Geometry::CUBE: return &HexahedronFE;
|
||||
case Geometry::TETRAHEDRON: return &TetrahedronFE;
|
||||
case Geometry::PRISM: return &WedgeFE;
|
||||
case Geometry::PYRAMID: return &PyramidFE;
|
||||
default:
|
||||
mfem_error ("RT0_3DFECollection: unknown geometry type.");
|
||||
}
|
||||
@@ -1472,8 +1455,6 @@ int RT0_3DFECollection::DofForGeometry(Geometry::Type GeomType) const
|
||||
case Geometry::SQUARE: return 1;
|
||||
case Geometry::TETRAHEDRON: return 0;
|
||||
case Geometry::CUBE: return 0;
|
||||
case Geometry::PRISM: return 0;
|
||||
case Geometry::PYRAMID: return 0;
|
||||
default:
|
||||
mfem_error ("RT0_3DFECollection: unknown geometry type.");
|
||||
}
|
||||
@@ -1749,7 +1730,6 @@ H1_FECollection::H1_FECollection(const int p, const int dim, const int btype)
|
||||
H1_dof[Geometry::TETRAHEDRON] = (TriDof*pm3)/3;
|
||||
H1_dof[Geometry::CUBE] = QuadDof*pm1;
|
||||
H1_dof[Geometry::PRISM] = TriDof*pm1;
|
||||
H1_dof[Geometry::PYRAMID] = 0;
|
||||
if (b_type == BasisType::Positive)
|
||||
{
|
||||
H1_Elements[Geometry::TETRAHEDRON] = new H1Pos_TetrahedronElement(p);
|
||||
@@ -1763,7 +1743,6 @@ H1_FECollection::H1_FECollection(const int p, const int dim, const int btype)
|
||||
H1_Elements[Geometry::CUBE] = new H1_HexahedronElement(p, btype);
|
||||
H1_Elements[Geometry::PRISM] = new H1_WedgeElement(p, btype);
|
||||
}
|
||||
H1_Elements[Geometry::PYRAMID] = new LinearPyramidFiniteElement;
|
||||
|
||||
const int &TetDof = H1_dof[Geometry::TETRAHEDRON];
|
||||
TetDofOrd[0] = new int[24*TetDof];
|
||||
@@ -1858,21 +1837,6 @@ H1_FECollection::H1_FECollection(const int p, const int dim, const int btype)
|
||||
}
|
||||
}
|
||||
|
||||
const FiniteElement *
|
||||
H1_FECollection::FiniteElementForGeometry(Geometry::Type GeomType) const
|
||||
{
|
||||
if (GeomType != Geometry::PYRAMID || this->GetOrder() == 1)
|
||||
{
|
||||
return H1_Elements[GeomType];
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_ABORT("H1 Pyramid basis functions are not yet supported "
|
||||
"for order > 1.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const int *H1_FECollection::DofOrderForOrientation(Geometry::Type GeomType,
|
||||
int Or) const
|
||||
{
|
||||
@@ -2112,12 +2076,9 @@ L2_FECollection::L2_FECollection(const int p, const int dim, const int btype,
|
||||
L2_Elements[Geometry::CUBE] = new L2_HexahedronElement(p, btype);
|
||||
L2_Elements[Geometry::PRISM] = new L2_WedgeElement(p, btype);
|
||||
}
|
||||
L2_Elements[Geometry::PYRAMID] = new P0PyrFiniteElement;
|
||||
|
||||
L2_Elements[Geometry::TETRAHEDRON]->SetMapType(map_type);
|
||||
L2_Elements[Geometry::CUBE]->SetMapType(map_type);
|
||||
L2_Elements[Geometry::PRISM]->SetMapType(map_type);
|
||||
L2_Elements[Geometry::PYRAMID]->SetMapType(map_type);
|
||||
// Trace element use the default Gauss-Legendre nodal points for positive basis
|
||||
if (b_type == BasisType::Positive)
|
||||
{
|
||||
@@ -2238,21 +2199,6 @@ L2_FECollection::L2_FECollection(const int p, const int dim, const int btype,
|
||||
}
|
||||
}
|
||||
|
||||
const FiniteElement *
|
||||
L2_FECollection::FiniteElementForGeometry(Geometry::Type GeomType) const
|
||||
{
|
||||
if (GeomType != Geometry::PYRAMID || this->GetOrder() == 0)
|
||||
{
|
||||
return L2_Elements[GeomType];
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_ABORT("L2 Pyramid basis functions are not yet supported "
|
||||
"for order > 0.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const int *L2_FECollection::DofOrderForOrientation(Geometry::Type GeomType,
|
||||
int Or) const
|
||||
{
|
||||
@@ -2344,12 +2290,6 @@ RT_FECollection::RT_FECollection(const int order, const int dim,
|
||||
|
||||
RT_Elements[Geometry::CUBE] = new RT_HexahedronElement(p, cb_type, ob_type);
|
||||
RT_dof[Geometry::CUBE] = 3*p*pp1*pp1;
|
||||
|
||||
RT_Elements[Geometry::PRISM] = new RT0WdgFiniteElement;
|
||||
RT_dof[Geometry::PRISM] = 0;
|
||||
|
||||
RT_Elements[Geometry::PYRAMID] = new RT0PyrFiniteElement(false);
|
||||
RT_dof[Geometry::PYRAMID] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2493,22 +2433,6 @@ void RT_FECollection::InitFaces(const int p, const int dim,
|
||||
}
|
||||
}
|
||||
|
||||
const FiniteElement *
|
||||
RT_FECollection::FiniteElementForGeometry(Geometry::Type GeomType) const
|
||||
{
|
||||
if ((GeomType != Geometry::PRISM && GeomType != Geometry::PYRAMID) ||
|
||||
this->GetOrder() == 1)
|
||||
{
|
||||
return RT_Elements[GeomType];
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_ABORT("RT Wedge and Pyramid basis functions are not yet supported "
|
||||
"for order > 0.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const int *RT_FECollection::DofOrderForOrientation(Geometry::Type GeomType,
|
||||
int Or) const
|
||||
{
|
||||
@@ -2732,31 +2656,18 @@ ND_FECollection::ND_FECollection(const int p, const int dim,
|
||||
{
|
||||
for (int i = 0; i + j <= pm2; i++)
|
||||
{
|
||||
int k0 = p*pm1 - (p - j)*(pm1 - j) + 2*i;
|
||||
int k1 = 2*pm2 - 2*i + ((2*p-3)-j)*j;
|
||||
int k2 = 2*pm2 - 2*j + ((2*p-3)-i)*i;
|
||||
int k3 = p*pm1 - 2 - 3*j - i - (i+j)*(i+j);
|
||||
int k4 = p*pm1 - 2 - 3*i - j - (i+j)*(i+j);
|
||||
int k5 = p*pm1 - (p - i)*(pm1 - i) + 2*j;
|
||||
|
||||
int k1 = p*pm1 - (p - j)*(pm1 - j) + 2*i;
|
||||
int k2 = p*pm1 - (p - i)*(pm1 - i) + 2*j;
|
||||
// (0,1,2)
|
||||
TriDofOrd[0][k0 ] = k0;
|
||||
TriDofOrd[0][k0+1] = k0 + 1;
|
||||
// (1,0,2)
|
||||
TriDofOrd[1][k0 ] = k1;
|
||||
TriDofOrd[1][k0+1] = k1 + 1;
|
||||
// (2,0,1)
|
||||
TriDofOrd[2][k0 ] = k2;
|
||||
TriDofOrd[2][k0+1] = k2 + 1;
|
||||
// (2,1,0)
|
||||
TriDofOrd[3][k0 ] = k3;
|
||||
TriDofOrd[3][k0+1] = k3 + 1;
|
||||
// (1,2,0)
|
||||
TriDofOrd[4][k0 ] = k4;
|
||||
TriDofOrd[4][k0+1] = k4 + 1;
|
||||
TriDofOrd[0][k1 ] = k1;
|
||||
TriDofOrd[0][k1+1] = k1 + 1;
|
||||
// (0,2,1)
|
||||
TriDofOrd[5][k0 ] = k5;
|
||||
TriDofOrd[5][k0+1] = k5 + 1;
|
||||
TriDofOrd[5][k1 ] = k2 + 1;
|
||||
TriDofOrd[5][k1+1] = k2;
|
||||
|
||||
// The other orientations can not be supported with the current
|
||||
// interface. The method Mesh::ReorientTetMesh will ensure that
|
||||
// only orientations 0 and 5 are generated.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2769,28 +2680,6 @@ ND_FECollection::ND_FECollection(const int p, const int dim,
|
||||
// TODO: cb_type and ob_type for tets
|
||||
ND_Elements[Geometry::TETRAHEDRON] = new ND_TetrahedronElement(p);
|
||||
ND_dof[Geometry::TETRAHEDRON] = p*pm1*pm2/2;
|
||||
|
||||
ND_Elements[Geometry::PRISM] = new Nedelec1WdgFiniteElement;
|
||||
ND_dof[Geometry::PRISM] = 0;
|
||||
|
||||
ND_Elements[Geometry::PYRAMID] = new Nedelec1PyrFiniteElement;
|
||||
ND_dof[Geometry::PYRAMID] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const FiniteElement *
|
||||
ND_FECollection::FiniteElementForGeometry(Geometry::Type GeomType) const
|
||||
{
|
||||
if ((GeomType != Geometry::PRISM && GeomType != Geometry::PYRAMID) ||
|
||||
this->GetOrder() == 1)
|
||||
{
|
||||
return ND_Elements[GeomType];
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_ABORT("ND Wedge and Pyramid basis functions are not yet supported "
|
||||
"for order > 1.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2803,6 +2692,11 @@ const int *ND_FECollection::DofOrderForOrientation(Geometry::Type GeomType,
|
||||
}
|
||||
else if (GeomType == Geometry::TRIANGLE)
|
||||
{
|
||||
if (Or != 0 && Or != 5)
|
||||
{
|
||||
MFEM_ABORT("triangle face orientation " << Or << " is not supported! "
|
||||
"Use Mesh::ReorientTetMesh to fix it.");
|
||||
}
|
||||
return TriDofOrd[Or%6];
|
||||
}
|
||||
else if (GeomType == Geometry::SQUARE)
|
||||
|
||||
+14
-16
@@ -228,7 +228,8 @@ public:
|
||||
const int btype = BasisType::GaussLobatto);
|
||||
|
||||
virtual const FiniteElement *FiniteElementForGeometry(
|
||||
Geometry::Type GeomType) const;
|
||||
Geometry::Type GeomType) const
|
||||
{ return H1_Elements[GeomType]; }
|
||||
virtual int DofForGeometry(Geometry::Type GeomType) const
|
||||
{ return H1_dof[GeomType]; }
|
||||
virtual const int *DofOrderForOrientation(Geometry::Type GeomType,
|
||||
@@ -301,7 +302,10 @@ public:
|
||||
const int map_type = FiniteElement::VALUE);
|
||||
|
||||
virtual const FiniteElement *FiniteElementForGeometry(
|
||||
Geometry::Type GeomType) const;
|
||||
Geometry::Type GeomType) const
|
||||
{
|
||||
return L2_Elements[GeomType];
|
||||
}
|
||||
virtual int DofForGeometry(Geometry::Type GeomType) const
|
||||
{
|
||||
if (L2_Elements[GeomType])
|
||||
@@ -367,7 +371,8 @@ public:
|
||||
const int ob_type = BasisType::GaussLegendre);
|
||||
|
||||
virtual const FiniteElement *FiniteElementForGeometry(
|
||||
Geometry::Type GeomType) const;
|
||||
Geometry::Type GeomType) const
|
||||
{ return RT_Elements[GeomType]; }
|
||||
virtual int DofForGeometry(Geometry::Type GeomType) const
|
||||
{ return RT_dof[GeomType]; }
|
||||
virtual const int *DofOrderForOrientation(Geometry::Type GeomType,
|
||||
@@ -425,7 +430,8 @@ public:
|
||||
const int ob_type = BasisType::GaussLegendre);
|
||||
|
||||
virtual const FiniteElement *
|
||||
FiniteElementForGeometry(Geometry::Type GeomType) const;
|
||||
FiniteElementForGeometry(Geometry::Type GeomType) const
|
||||
{ return ND_Elements[GeomType]; }
|
||||
|
||||
virtual int DofForGeometry(Geometry::Type GeomType) const
|
||||
{ return ND_dof[GeomType]; }
|
||||
@@ -523,10 +529,9 @@ private:
|
||||
const BiLinear2DFiniteElement QuadrilateralFE;
|
||||
const Linear3DFiniteElement TetrahedronFE;
|
||||
const TriLinear3DFiniteElement ParallelepipedFE;
|
||||
const LinearWedgeFiniteElement WedgeFE;
|
||||
const LinearPyramidFiniteElement PyramidFE;
|
||||
const H1_WedgeElement WedgeFE;
|
||||
public:
|
||||
LinearFECollection() : FiniteElementCollection(1) { }
|
||||
LinearFECollection() : FiniteElementCollection(1), WedgeFE(1) { }
|
||||
|
||||
virtual const FiniteElement *
|
||||
FiniteElementForGeometry(Geometry::Type GeomType) const;
|
||||
@@ -931,11 +936,10 @@ class Const3DFECollection : public FiniteElementCollection
|
||||
private:
|
||||
const P0TetFiniteElement TetrahedronFE;
|
||||
const P0HexFiniteElement ParallelepipedFE;
|
||||
const P0WdgFiniteElement WedgeFE;
|
||||
const P0PyrFiniteElement PyramidFE;
|
||||
const L2_WedgeElement WedgeFE;
|
||||
|
||||
public:
|
||||
Const3DFECollection() : FiniteElementCollection(0) { }
|
||||
Const3DFECollection() : FiniteElementCollection(0), WedgeFE(0) { }
|
||||
|
||||
virtual const FiniteElement *
|
||||
FiniteElementForGeometry(Geometry::Type GeomType) const;
|
||||
@@ -956,8 +960,6 @@ class LinearDiscont3DFECollection : public FiniteElementCollection
|
||||
{
|
||||
private:
|
||||
const Linear3DFiniteElement TetrahedronFE;
|
||||
const LinearPyramidFiniteElement PyramidFE;
|
||||
const LinearWedgeFiniteElement WedgeFE;
|
||||
const TriLinear3DFiniteElement ParallelepipedFE;
|
||||
|
||||
public:
|
||||
@@ -1034,8 +1036,6 @@ class ND1_3DFECollection : public FiniteElementCollection
|
||||
private:
|
||||
const Nedelec1HexFiniteElement HexahedronFE;
|
||||
const Nedelec1TetFiniteElement TetrahedronFE;
|
||||
const Nedelec1WdgFiniteElement WedgeFE;
|
||||
const Nedelec1PyrFiniteElement PyramidFE;
|
||||
|
||||
public:
|
||||
ND1_3DFECollection() : FiniteElementCollection(1) { }
|
||||
@@ -1061,8 +1061,6 @@ private:
|
||||
const P0QuadFiniteElement QuadrilateralFE;
|
||||
const RT0HexFiniteElement HexahedronFE;
|
||||
const RT0TetFiniteElement TetrahedronFE;
|
||||
const RT0WdgFiniteElement WedgeFE;
|
||||
const RT0PyrFiniteElement PyramidFE;
|
||||
public:
|
||||
RT0_3DFECollection() : FiniteElementCollection(1) { }
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "geom.hpp"
|
||||
#include "fe.hpp"
|
||||
#include "fe_coll.hpp"
|
||||
#include "doftrans.hpp"
|
||||
#include "eltrans.hpp"
|
||||
#include "coefficient.hpp"
|
||||
#include "complex_fem.hpp"
|
||||
|
||||
+50
-323
@@ -58,12 +58,9 @@ DofsToVDofs<Ordering::byVDIM>(int ndofs, int vdim, Array<int> &dofs)
|
||||
|
||||
FiniteElementSpace::FiniteElementSpace()
|
||||
: mesh(NULL), fec(NULL), vdim(0), ordering(Ordering::byNODES),
|
||||
ndofs(0), nvdofs(0), nedofs(0), nfdofs(0), nbdofs(0),
|
||||
bdofs(NULL),
|
||||
elem_dof(NULL), elem_fos(NULL), bdr_elem_dof(NULL), bdr_elem_fos(NULL),
|
||||
face_dof(NULL),
|
||||
ndofs(0), nvdofs(0), nedofs(0), nfdofs(0), nbdofs(0), bdofs(NULL),
|
||||
elem_dof(NULL), bdr_elem_dof(NULL), face_dof(NULL),
|
||||
NURBSext(NULL), own_ext(false),
|
||||
DoFTrans(0), VDoFTrans(vdim, ordering),
|
||||
cP(NULL), cR(NULL), cR_hp(NULL), cP_is_set(false),
|
||||
Th(Operator::ANY_TYPE),
|
||||
sequence(0), mesh_sequence(0), orders_changed(false), relaxed_hp(false)
|
||||
@@ -72,7 +69,6 @@ FiniteElementSpace::FiniteElementSpace()
|
||||
FiniteElementSpace::FiniteElementSpace(const FiniteElementSpace &orig,
|
||||
Mesh *mesh,
|
||||
const FiniteElementCollection *fec)
|
||||
: VDoFTrans(orig.vdim, orig.ordering)
|
||||
{
|
||||
mesh = mesh ? mesh : orig.mesh;
|
||||
fec = fec ? fec : orig.fec;
|
||||
@@ -263,36 +259,16 @@ void FiniteElementSpace::AdjustVDofs (Array<int> &vdofs)
|
||||
}
|
||||
}
|
||||
|
||||
DofTransformation *
|
||||
FiniteElementSpace::GetElementVDofs(int i, Array<int> &vdofs) const
|
||||
void FiniteElementSpace::GetElementVDofs(int i, Array<int> &vdofs) const
|
||||
{
|
||||
DofTransformation * doftrans = GetElementDofs(i, vdofs);
|
||||
GetElementDofs(i, vdofs);
|
||||
DofsToVDofs(vdofs);
|
||||
if (vdim == 1 || doftrans == NULL)
|
||||
{
|
||||
return doftrans;
|
||||
}
|
||||
else
|
||||
{
|
||||
VDoFTrans.SetDofTransformation(*doftrans);
|
||||
return &VDoFTrans;
|
||||
}
|
||||
}
|
||||
|
||||
DofTransformation *
|
||||
FiniteElementSpace::GetBdrElementVDofs(int i, Array<int> &vdofs) const
|
||||
void FiniteElementSpace::GetBdrElementVDofs(int i, Array<int> &vdofs) const
|
||||
{
|
||||
DofTransformation * doftrans = GetBdrElementDofs(i, vdofs);
|
||||
GetBdrElementDofs(i, vdofs);
|
||||
DofsToVDofs(vdofs);
|
||||
if (vdim == 1 || doftrans == NULL)
|
||||
{
|
||||
return doftrans;
|
||||
}
|
||||
else
|
||||
{
|
||||
VDoFTrans.SetDofTransformation(*doftrans);
|
||||
return &VDoFTrans;
|
||||
}
|
||||
}
|
||||
|
||||
void FiniteElementSpace::GetFaceVDofs(int i, Array<int> &vdofs) const
|
||||
@@ -331,39 +307,21 @@ void FiniteElementSpace::BuildElementToDofTable() const
|
||||
|
||||
// TODO: can we call GetElementDofs only once per element?
|
||||
Table *el_dof = new Table;
|
||||
Table *el_fos = (mesh->Dimension() > 2) ? (new Table) : NULL;
|
||||
Array<int> dofs;
|
||||
Array<int> F, Fo;
|
||||
el_dof -> MakeI (mesh -> GetNE());
|
||||
if (el_fos) { el_fos -> MakeI (mesh -> GetNE()); }
|
||||
for (int i = 0; i < mesh -> GetNE(); i++)
|
||||
{
|
||||
GetElementDofs (i, dofs);
|
||||
el_dof -> AddColumnsInRow (i, dofs.Size());
|
||||
|
||||
if (el_fos)
|
||||
{
|
||||
mesh->GetElementFaces(i, F, Fo);
|
||||
el_fos -> AddColumnsInRow (i, Fo.Size());
|
||||
}
|
||||
}
|
||||
el_dof -> MakeJ();
|
||||
if (el_fos) { el_fos -> MakeJ(); }
|
||||
for (int i = 0; i < mesh -> GetNE(); i++)
|
||||
{
|
||||
GetElementDofs (i, dofs);
|
||||
el_dof -> AddConnections (i, (int *)dofs, dofs.Size());
|
||||
|
||||
if (el_fos)
|
||||
{
|
||||
mesh->GetElementFaces(i, F, Fo);
|
||||
el_fos -> AddConnections (i, (int *)Fo, Fo.Size());
|
||||
}
|
||||
}
|
||||
el_dof -> ShiftUpI();
|
||||
if (el_fos) { el_fos -> ShiftUpI(); }
|
||||
elem_dof = el_dof;
|
||||
elem_fos = el_fos;
|
||||
}
|
||||
|
||||
void FiniteElementSpace::BuildBdrElementToDofTable() const
|
||||
@@ -417,9 +375,7 @@ void FiniteElementSpace::BuildFaceToDofTable() const
|
||||
void FiniteElementSpace::RebuildElementToDofTable()
|
||||
{
|
||||
delete elem_dof;
|
||||
delete elem_fos;
|
||||
elem_dof = NULL;
|
||||
elem_fos = NULL;
|
||||
BuildElementToDofTable();
|
||||
}
|
||||
|
||||
@@ -1359,10 +1315,8 @@ const FaceQuadratureInterpolator
|
||||
|
||||
SparseMatrix *FiniteElementSpace::RefinementMatrix_main(
|
||||
const int coarse_ndofs, const Table &coarse_elem_dof,
|
||||
const Table *coarse_elem_fos, const DenseTensor localP[]) const
|
||||
const DenseTensor localP[]) const
|
||||
{
|
||||
/// TODO: Implement DofTransformation support
|
||||
|
||||
MFEM_VERIFY(mesh->GetLastOperation() == Mesh::REFINE, "");
|
||||
|
||||
Array<int> dofs, coarse_dofs, coarse_vdofs;
|
||||
@@ -1445,8 +1399,7 @@ void FiniteElementSpace::GetLocalRefinementMatrices(
|
||||
}
|
||||
|
||||
SparseMatrix* FiniteElementSpace::RefinementMatrix(int old_ndofs,
|
||||
const Table* old_elem_dof,
|
||||
const Table* old_elem_fos)
|
||||
const Table* old_elem_dof)
|
||||
{
|
||||
MFEM_VERIFY(GetNE() >= old_elem_dof->Size(),
|
||||
"Previous mesh is not coarser.");
|
||||
@@ -1459,16 +1412,13 @@ SparseMatrix* FiniteElementSpace::RefinementMatrix(int old_ndofs,
|
||||
GetLocalRefinementMatrices(elem_geoms[i], localP[elem_geoms[i]]);
|
||||
}
|
||||
|
||||
return RefinementMatrix_main(old_ndofs, *old_elem_dof, old_elem_fos,
|
||||
localP);
|
||||
return RefinementMatrix_main(old_ndofs, *old_elem_dof, localP);
|
||||
}
|
||||
|
||||
FiniteElementSpace::RefinementOperator::RefinementOperator
|
||||
(const FiniteElementSpace* fespace, Table* old_elem_dof, Table* old_elem_fos,
|
||||
int old_ndofs)
|
||||
(const FiniteElementSpace* fespace, Table* old_elem_dof, int old_ndofs)
|
||||
: fespace(fespace)
|
||||
, old_elem_dof(old_elem_dof)
|
||||
, old_elem_fos(old_elem_fos)
|
||||
{
|
||||
MFEM_VERIFY(fespace->GetNE() >= old_elem_dof->Size(),
|
||||
"Previous mesh is not coarser.");
|
||||
@@ -1482,14 +1432,12 @@ FiniteElementSpace::RefinementOperator::RefinementOperator
|
||||
{
|
||||
fespace->GetLocalRefinementMatrices(elem_geoms[i], localP[elem_geoms[i]]);
|
||||
}
|
||||
|
||||
ConstructDoFTrans();
|
||||
}
|
||||
|
||||
FiniteElementSpace::RefinementOperator::RefinementOperator(
|
||||
const FiniteElementSpace *fespace, const FiniteElementSpace *coarse_fes)
|
||||
: Operator(fespace->GetVSize(), coarse_fes->GetVSize()),
|
||||
fespace(fespace), old_elem_dof(NULL), old_elem_fos(NULL)
|
||||
fespace(fespace), old_elem_dof(NULL)
|
||||
{
|
||||
Mesh::GeometryList elem_geoms(*fespace->GetMesh());
|
||||
|
||||
@@ -1501,50 +1449,11 @@ FiniteElementSpace::RefinementOperator::RefinementOperator(
|
||||
|
||||
// Make a copy of the coarse elem_dof Table.
|
||||
old_elem_dof = new Table(coarse_fes->GetElementToDofTable());
|
||||
|
||||
// Make a copy of the coarse elem_fos Table if it exists.
|
||||
if (coarse_fes->GetElementToFaceOrientationTable())
|
||||
{
|
||||
old_elem_fos = new Table(*coarse_fes->GetElementToFaceOrientationTable());
|
||||
}
|
||||
|
||||
ConstructDoFTrans();
|
||||
}
|
||||
|
||||
FiniteElementSpace::RefinementOperator::~RefinementOperator()
|
||||
{
|
||||
delete old_elem_dof;
|
||||
delete old_elem_fos;
|
||||
}
|
||||
|
||||
void FiniteElementSpace::RefinementOperator
|
||||
::ConstructDoFTrans()
|
||||
{
|
||||
old_DoFTrans.SetSize(Geometry::NUM_GEOMETRIES);
|
||||
for (int i=0; i<old_DoFTrans.Size(); i++)
|
||||
{
|
||||
old_DoFTrans[i] = NULL;
|
||||
}
|
||||
|
||||
const FiniteElementCollection *fec = fespace->FEColl();
|
||||
if (dynamic_cast<const ND_FECollection*>(fec))
|
||||
{
|
||||
const FiniteElement * nd_tri =
|
||||
fec->FiniteElementForGeometry(Geometry::TRIANGLE);
|
||||
if (nd_tri)
|
||||
{
|
||||
old_DoFTrans[Geometry::TRIANGLE] =
|
||||
new ND_TriDofTransformation(nd_tri->GetOrder());
|
||||
}
|
||||
|
||||
const FiniteElement * nd_tet =
|
||||
fec->FiniteElementForGeometry(Geometry::TETRAHEDRON);
|
||||
if (nd_tet)
|
||||
{
|
||||
old_DoFTrans[Geometry::TETRAHEDRON] =
|
||||
new ND_TetDofTransformation(nd_tet->GetOrder());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FiniteElementSpace::RefinementOperator
|
||||
@@ -1553,7 +1462,7 @@ void FiniteElementSpace::RefinementOperator
|
||||
Mesh* mesh = fespace->GetMesh();
|
||||
const CoarseFineTransformations &rtrans = mesh->GetRefinementTransforms();
|
||||
|
||||
Array<int> dofs, vdofs, old_dofs, old_vdofs, old_Fo;
|
||||
Array<int> dofs, vdofs, old_dofs, old_vdofs;
|
||||
|
||||
int vdim = fespace->GetVDim();
|
||||
int old_ndofs = width / vdim;
|
||||
@@ -1568,53 +1477,18 @@ void FiniteElementSpace::RefinementOperator
|
||||
|
||||
subY.SetSize(lP.Height());
|
||||
|
||||
DofTransformation *doftrans = fespace->GetElementDofs(k, dofs);
|
||||
fespace->GetElementDofs(k, dofs);
|
||||
old_elem_dof->GetRow(emb.parent, old_dofs);
|
||||
|
||||
if (!doftrans)
|
||||
for (int vd = 0; vd < vdim; vd++)
|
||||
{
|
||||
for (int vd = 0; vd < vdim; vd++)
|
||||
{
|
||||
dofs.Copy(vdofs);
|
||||
fespace->DofsToVDofs(vd, vdofs);
|
||||
old_dofs.Copy(old_vdofs);
|
||||
fespace->DofsToVDofs(vd, old_vdofs, old_ndofs);
|
||||
x.GetSubVector(old_vdofs, subX);
|
||||
lP.Mult(subX, subY);
|
||||
y.SetSubVector(vdofs, subY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
old_elem_fos->GetRow(emb.parent, old_Fo);
|
||||
old_DoFTrans[geom]->SetFaceOrientations(old_Fo);
|
||||
|
||||
DofTransformation *new_doftrans = NULL;
|
||||
VDofTransformation *vdoftrans =
|
||||
dynamic_cast<VDofTransformation*>(doftrans);
|
||||
if (vdoftrans)
|
||||
{
|
||||
new_doftrans = doftrans;
|
||||
doftrans = vdoftrans->GetDofTransformation();
|
||||
}
|
||||
|
||||
for (int vd = 0; vd < vdim; vd++)
|
||||
{
|
||||
dofs.Copy(vdofs);
|
||||
fespace->DofsToVDofs(vd, vdofs);
|
||||
old_dofs.Copy(old_vdofs);
|
||||
fespace->DofsToVDofs(vd, old_vdofs, old_ndofs);
|
||||
x.GetSubVector(old_vdofs, subX);
|
||||
old_DoFTrans[geom]->InvTransformPrimal(subX);
|
||||
lP.Mult(subX, subY);
|
||||
doftrans->TransformPrimal(subY);
|
||||
y.SetSubVector(vdofs, subY);
|
||||
}
|
||||
|
||||
if (vdoftrans)
|
||||
{
|
||||
doftrans = new_doftrans;
|
||||
}
|
||||
dofs.Copy(vdofs);
|
||||
fespace->DofsToVDofs(vd, vdofs);
|
||||
old_dofs.Copy(old_vdofs);
|
||||
fespace->DofsToVDofs(vd, old_vdofs, old_ndofs);
|
||||
x.GetSubVector(old_vdofs, subX);
|
||||
lP.Mult(subX, subY);
|
||||
y.SetSubVector(vdofs, subY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1630,12 +1504,12 @@ void FiniteElementSpace::RefinementOperator
|
||||
Array<char> processed(fespace->GetVSize());
|
||||
processed = 0;
|
||||
|
||||
Array<int> f_dofs, c_dofs, f_vdofs, c_vdofs, old_Fo;
|
||||
Array<int> f_dofs, c_dofs, f_vdofs, c_vdofs;
|
||||
|
||||
int vdim = fespace->GetVDim();
|
||||
int old_ndofs = width / vdim;
|
||||
|
||||
Vector subY, subX, subYt, subXt;
|
||||
Vector subY, subX;
|
||||
|
||||
for (int k = 0; k < mesh->GetNE(); k++)
|
||||
{
|
||||
@@ -1643,77 +1517,30 @@ void FiniteElementSpace::RefinementOperator
|
||||
const Geometry::Type geom = mesh->GetElementBaseGeometry(k);
|
||||
const DenseMatrix &lP = localP[geom](emb.matrix);
|
||||
|
||||
DofTransformation * doftrans = fespace->GetElementDofs(k, f_dofs);
|
||||
fespace->GetElementDofs(k, f_dofs);
|
||||
old_elem_dof->GetRow(emb.parent, c_dofs);
|
||||
|
||||
if (!doftrans)
|
||||
subY.SetSize(lP.Width());
|
||||
|
||||
for (int vd = 0; vd < vdim; vd++)
|
||||
{
|
||||
subY.SetSize(lP.Width());
|
||||
f_dofs.Copy(f_vdofs);
|
||||
fespace->DofsToVDofs(vd, f_vdofs);
|
||||
c_dofs.Copy(c_vdofs);
|
||||
fespace->DofsToVDofs(vd, c_vdofs, old_ndofs);
|
||||
|
||||
for (int vd = 0; vd < vdim; vd++)
|
||||
x.GetSubVector(f_vdofs, subX);
|
||||
|
||||
for (int p = 0; p < f_dofs.Size(); ++p)
|
||||
{
|
||||
f_dofs.Copy(f_vdofs);
|
||||
fespace->DofsToVDofs(vd, f_vdofs);
|
||||
c_dofs.Copy(c_vdofs);
|
||||
fespace->DofsToVDofs(vd, c_vdofs, old_ndofs);
|
||||
|
||||
x.GetSubVector(f_vdofs, subX);
|
||||
|
||||
for (int p = 0; p < f_dofs.Size(); ++p)
|
||||
if (processed[DecodeDof(f_dofs[p])])
|
||||
{
|
||||
if (processed[DecodeDof(f_dofs[p])])
|
||||
{
|
||||
subX[p] = 0.0;
|
||||
}
|
||||
subX[p] = 0.0;
|
||||
}
|
||||
|
||||
lP.MultTranspose(subX, subY);
|
||||
y.AddElementVector(c_vdofs, subY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
subYt.SetSize(lP.Width());
|
||||
|
||||
old_elem_fos->GetRow(emb.parent, old_Fo);
|
||||
old_DoFTrans[geom]->SetFaceOrientations(old_Fo);
|
||||
|
||||
DofTransformation *new_doftrans = NULL;
|
||||
VDofTransformation *vdoftrans =
|
||||
dynamic_cast<VDofTransformation*>(doftrans);
|
||||
if (vdoftrans)
|
||||
{
|
||||
new_doftrans = doftrans;
|
||||
doftrans = vdoftrans->GetDofTransformation();
|
||||
}
|
||||
|
||||
for (int vd = 0; vd < vdim; vd++)
|
||||
{
|
||||
f_dofs.Copy(f_vdofs);
|
||||
fespace->DofsToVDofs(vd, f_vdofs);
|
||||
c_dofs.Copy(c_vdofs);
|
||||
fespace->DofsToVDofs(vd, c_vdofs, old_ndofs);
|
||||
|
||||
x.GetSubVector(f_vdofs, subX);
|
||||
old_DoFTrans[geom]->InvTransformPrimal(subX);
|
||||
|
||||
for (int p = 0; p < f_dofs.Size(); ++p)
|
||||
{
|
||||
if (processed[DecodeDof(f_dofs[p])])
|
||||
{
|
||||
subX[p] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
lP.MultTranspose(subX, subY);
|
||||
doftrans->TransformPrimal(subY);
|
||||
y.AddElementVector(c_vdofs, subY);
|
||||
}
|
||||
|
||||
if (vdoftrans)
|
||||
{
|
||||
doftrans = new_doftrans;
|
||||
}
|
||||
lP.MultTranspose(subX, subY);
|
||||
y.AddElementVector(c_vdofs, subY);
|
||||
}
|
||||
|
||||
for (int p = 0; p < f_dofs.Size(); ++p)
|
||||
@@ -1723,7 +1550,6 @@ void FiniteElementSpace::RefinementOperator
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO: Implement DofTransformation support
|
||||
FiniteElementSpace::DerefinementOperator::DerefinementOperator(
|
||||
const FiniteElementSpace *f_fes, const FiniteElementSpace *c_fes,
|
||||
BilinearFormIntegrator *mass_integ)
|
||||
@@ -1881,11 +1707,8 @@ void FiniteElementSpace::GetLocalDerefinementMatrices(Geometry::Type geom,
|
||||
}
|
||||
|
||||
SparseMatrix* FiniteElementSpace::DerefinementMatrix(int old_ndofs,
|
||||
const Table* old_elem_dof,
|
||||
const Table* old_elem_fos)
|
||||
const Table* old_elem_dof)
|
||||
{
|
||||
/// TODO: Implement DofTransformation support
|
||||
|
||||
MFEM_VERIFY(Nonconforming(), "Not implemented for conforming meshes.");
|
||||
MFEM_VERIFY(old_ndofs, "Missing previous (finer) space.");
|
||||
MFEM_VERIFY(ndofs <= old_ndofs, "Previous space is not finer.");
|
||||
@@ -1991,7 +1814,6 @@ void FiniteElementSpace::Constructor(Mesh *mesh, NURBSExtension *NURBSext,
|
||||
this->ordering = (Ordering::Type) ordering;
|
||||
|
||||
elem_dof = NULL;
|
||||
elem_fos = NULL;
|
||||
face_dof = NULL;
|
||||
|
||||
sequence = 0;
|
||||
@@ -2019,8 +1841,6 @@ void FiniteElementSpace::Constructor(Mesh *mesh, NURBSExtension *NURBSext,
|
||||
UpdateNURBS();
|
||||
cP = cR = cR_hp = NULL;
|
||||
cP_is_set = false;
|
||||
|
||||
ConstructDoFTrans();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2028,41 +1848,9 @@ void FiniteElementSpace::Constructor(Mesh *mesh, NURBSExtension *NURBSext,
|
||||
own_ext = 0;
|
||||
Construct();
|
||||
}
|
||||
|
||||
BuildElementToDofTable();
|
||||
}
|
||||
|
||||
void FiniteElementSpace::ConstructDoFTrans()
|
||||
{
|
||||
DestroyDoFTrans();
|
||||
|
||||
VDoFTrans.SetVDim(vdim);
|
||||
DoFTrans.SetSize(Geometry::NUM_GEOMETRIES);
|
||||
for (int i=0; i<DoFTrans.Size(); i++)
|
||||
{
|
||||
DoFTrans[i] = NULL;
|
||||
}
|
||||
if (mesh->Dimension() < 3) { return; }
|
||||
if (dynamic_cast<const ND_FECollection*>(fec))
|
||||
{
|
||||
const FiniteElement * nd_tri =
|
||||
fec->FiniteElementForGeometry(Geometry::TRIANGLE);
|
||||
if (nd_tri)
|
||||
{
|
||||
DoFTrans[Geometry::TRIANGLE] =
|
||||
new ND_TriDofTransformation(nd_tri->GetOrder());
|
||||
}
|
||||
|
||||
const FiniteElement * nd_tet =
|
||||
fec->FiniteElementForGeometry(Geometry::TETRAHEDRON);
|
||||
if (nd_tet)
|
||||
{
|
||||
DoFTrans[Geometry::TETRAHEDRON] =
|
||||
new ND_TetDofTransformation(nd_tet->GetOrder());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NURBSExtension *FiniteElementSpace::StealNURBSext()
|
||||
{
|
||||
if (NURBSext && !own_ext)
|
||||
@@ -2158,9 +1946,7 @@ void FiniteElementSpace::Construct()
|
||||
"Variable order space requires a nonconforming mesh.");
|
||||
|
||||
elem_dof = NULL;
|
||||
elem_fos = NULL;
|
||||
bdr_elem_dof = NULL;
|
||||
bdr_elem_fos = NULL;
|
||||
face_dof = NULL;
|
||||
|
||||
ndofs = 0;
|
||||
@@ -2258,8 +2044,6 @@ void FiniteElementSpace::Construct()
|
||||
|
||||
ndofs = nvdofs + nedofs + nfdofs + nbdofs;
|
||||
|
||||
ConstructDoFTrans();
|
||||
|
||||
// record the current mesh sequence number to detect refinement etc.
|
||||
mesh_sequence = mesh->GetSequence();
|
||||
|
||||
@@ -2511,22 +2295,14 @@ int FiniteElementSpace::GetNVariants(int entity, int index) const
|
||||
static const char* msg_orders_changed =
|
||||
"Element orders changed, you need to Update() the space first.";
|
||||
|
||||
DofTransformation *
|
||||
FiniteElementSpace::GetElementDofs(int elem, Array<int> &dofs) const
|
||||
void FiniteElementSpace::GetElementDofs(int elem, Array<int> &dofs) const
|
||||
{
|
||||
MFEM_VERIFY(!orders_changed, msg_orders_changed);
|
||||
|
||||
if (elem_dof)
|
||||
{
|
||||
elem_dof->GetRow(elem, dofs);
|
||||
|
||||
if (DoFTrans[mesh->GetElementBaseGeometry(elem)])
|
||||
{
|
||||
Array<int> Fo;
|
||||
elem_fos -> GetRow (elem, Fo);
|
||||
DoFTrans[mesh->GetElementBaseGeometry(elem)]->SetFaceOrientations(Fo);
|
||||
}
|
||||
return DoFTrans[mesh->GetElementBaseGeometry(elem)];
|
||||
return;
|
||||
}
|
||||
|
||||
Array<int> V, E, Eo, F, Fo; // TODO: LocalArray
|
||||
@@ -2550,11 +2326,6 @@ FiniteElementSpace::GetElementDofs(int elem, Array<int> &dofs) const
|
||||
{
|
||||
nfd += fec->GetNumDof(mesh->GetFaceGeometry(F[i]), order);
|
||||
}
|
||||
if (DoFTrans[mesh->GetElementBaseGeometry(elem)])
|
||||
{
|
||||
DoFTrans[mesh->GetElementBaseGeometry(elem)]
|
||||
-> SetFaceOrientations(Fo);
|
||||
}
|
||||
}
|
||||
|
||||
dofs.SetSize(0);
|
||||
@@ -2612,7 +2383,6 @@ FiniteElementSpace::GetElementDofs(int elem, Array<int> &dofs) const
|
||||
dofs.Append(bbase + j);
|
||||
}
|
||||
}
|
||||
return DoFTrans[mesh->GetElementBaseGeometry(elem)];
|
||||
}
|
||||
|
||||
const FiniteElement *FiniteElementSpace::GetFE(int i) const
|
||||
@@ -2645,27 +2415,18 @@ const FiniteElement *FiniteElementSpace::GetFE(int i) const
|
||||
return FE;
|
||||
}
|
||||
|
||||
DofTransformation *
|
||||
FiniteElementSpace::GetBdrElementDofs(int bel, Array<int> &dofs) const
|
||||
void FiniteElementSpace::GetBdrElementDofs(int bel, Array<int> &dofs) const
|
||||
{
|
||||
MFEM_VERIFY(!orders_changed, msg_orders_changed);
|
||||
|
||||
if (bdr_elem_dof)
|
||||
{
|
||||
bdr_elem_dof->GetRow(bel, dofs);
|
||||
|
||||
if (DoFTrans[mesh->GetBdrElementBaseGeometry(bel)])
|
||||
{
|
||||
Array<int> Fo;
|
||||
bdr_elem_fos -> GetRow (bel, Fo);
|
||||
DoFTrans[mesh->GetBdrElementBaseGeometry(bel)]->
|
||||
SetFaceOrientations(Fo);
|
||||
}
|
||||
return DoFTrans[mesh->GetBdrElementBaseGeometry(bel)];
|
||||
return;
|
||||
}
|
||||
|
||||
Array<int> V, E, Eo, Fo; // TODO: LocalArray
|
||||
int F, oF;
|
||||
Array<int> V, E, Eo; // TODO: LocalArray
|
||||
int F, Fo;
|
||||
|
||||
int dim = mesh->Dimension();
|
||||
auto geom = mesh->GetBdrElementGeometry(bel);
|
||||
@@ -2684,17 +2445,7 @@ FiniteElementSpace::GetBdrElementDofs(int bel, Array<int> &dofs) const
|
||||
|
||||
if (nv) { mesh->GetBdrElementVertices(bel, V); }
|
||||
if (ne) { mesh->GetBdrElementEdges(bel, E, Eo); }
|
||||
if (nf)
|
||||
{
|
||||
mesh->GetBdrElementFace(bel, &F, &oF);
|
||||
|
||||
if (DoFTrans[mesh->GetBdrElementBaseGeometry(bel)])
|
||||
{
|
||||
Fo.Append(oF);
|
||||
DoFTrans[mesh->GetBdrElementBaseGeometry(bel)]->
|
||||
SetFaceOrientations(Fo);
|
||||
}
|
||||
}
|
||||
if (nf) { mesh->GetBdrElementFace(bel, &F, &Fo); }
|
||||
|
||||
dofs.SetSize(0);
|
||||
dofs.Reserve(nv*V.Size() + ne*E.Size() + nf);
|
||||
@@ -2727,15 +2478,13 @@ FiniteElementSpace::GetBdrElementDofs(int bel, Array<int> &dofs) const
|
||||
if (nf) // face DOFs
|
||||
{
|
||||
int fbase = (var_face_dofs.Size() > 0) ? FindFaceDof(F, nf) : F*nf;
|
||||
const int *ind = fec->GetDofOrdering(geom, order, oF);
|
||||
const int *ind = fec->GetDofOrdering(geom, order, Fo);
|
||||
|
||||
for (int j = 0; j < nf; j++)
|
||||
{
|
||||
dofs.Append(EncodeDof(nvdofs + nedofs + fbase, ind[j]));
|
||||
}
|
||||
}
|
||||
|
||||
return DoFTrans[mesh->GetBdrElementBaseGeometry(bel)];
|
||||
}
|
||||
|
||||
int FiniteElementSpace::GetFaceDofs(int face, Array<int> &dofs,
|
||||
@@ -3045,8 +2794,6 @@ void FiniteElementSpace::Destroy()
|
||||
}
|
||||
E2BFQ_array.SetSize(0);
|
||||
|
||||
DestroyDoFTrans();
|
||||
|
||||
dof_elem_array.DeleteAll();
|
||||
dof_ldof_array.DeleteAll();
|
||||
|
||||
@@ -3059,9 +2806,7 @@ void FiniteElementSpace::Destroy()
|
||||
else
|
||||
{
|
||||
delete elem_dof;
|
||||
delete elem_fos;
|
||||
delete bdr_elem_dof;
|
||||
delete bdr_elem_fos;
|
||||
delete face_dof;
|
||||
|
||||
delete [] bdofs;
|
||||
@@ -3069,15 +2814,6 @@ void FiniteElementSpace::Destroy()
|
||||
ceed::RemoveBasisAndRestriction(this);
|
||||
}
|
||||
|
||||
void FiniteElementSpace::DestroyDoFTrans()
|
||||
{
|
||||
for (int i = 0; i < DoFTrans.Size(); i++)
|
||||
{
|
||||
delete DoFTrans[i];
|
||||
}
|
||||
DoFTrans.SetSize(0);
|
||||
}
|
||||
|
||||
void FiniteElementSpace::GetTransferOperator(
|
||||
const FiniteElementSpace &coarse_fes, OperatorHandle &T) const
|
||||
{
|
||||
@@ -3095,8 +2831,6 @@ void FiniteElementSpace::GetTransferOperator(
|
||||
}
|
||||
T.Reset(RefinementMatrix_main(coarse_fes.GetNDofs(),
|
||||
coarse_fes.GetElementToDofTable(),
|
||||
coarse_fes.
|
||||
GetElementToFaceOrientationTable(),
|
||||
localP));
|
||||
}
|
||||
else
|
||||
@@ -3199,7 +2933,6 @@ void FiniteElementSpace::Update(bool want_transform)
|
||||
}
|
||||
|
||||
Table* old_elem_dof = NULL;
|
||||
Table* old_elem_fos = NULL;
|
||||
int old_ndofs;
|
||||
bool old_orders_changed = orders_changed;
|
||||
|
||||
@@ -3207,9 +2940,7 @@ void FiniteElementSpace::Update(bool want_transform)
|
||||
if (want_transform)
|
||||
{
|
||||
old_elem_dof = elem_dof;
|
||||
old_elem_fos = elem_fos;
|
||||
elem_dof = NULL;
|
||||
elem_fos = NULL;
|
||||
old_ndofs = ndofs;
|
||||
}
|
||||
|
||||
@@ -3235,18 +2966,15 @@ void FiniteElementSpace::Update(bool want_transform)
|
||||
{
|
||||
if (Th.Type() != Operator::MFEM_SPARSEMAT)
|
||||
{
|
||||
Th.Reset(new RefinementOperator(this, old_elem_dof,
|
||||
old_elem_fos, old_ndofs));
|
||||
Th.Reset(new RefinementOperator(this, old_elem_dof, old_ndofs));
|
||||
// The RefinementOperator takes ownership of 'old_elem_dof', so
|
||||
// we no longer own it:
|
||||
old_elem_dof = NULL;
|
||||
old_elem_fos = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate fully assembled matrix
|
||||
Th.Reset(RefinementMatrix(old_ndofs, old_elem_dof,
|
||||
old_elem_fos));
|
||||
Th.Reset(RefinementMatrix(old_ndofs, old_elem_dof));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3254,7 +2982,7 @@ void FiniteElementSpace::Update(bool want_transform)
|
||||
case Mesh::DEREFINE:
|
||||
{
|
||||
BuildConformingInterpolation();
|
||||
Th.Reset(DerefinementMatrix(old_ndofs, old_elem_dof, old_elem_fos));
|
||||
Th.Reset(DerefinementMatrix(old_ndofs, old_elem_dof));
|
||||
if (cP && cR)
|
||||
{
|
||||
Th.SetOperatorOwner(false);
|
||||
@@ -3269,7 +2997,6 @@ void FiniteElementSpace::Update(bool want_transform)
|
||||
}
|
||||
|
||||
delete old_elem_dof;
|
||||
delete old_elem_fos;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-30
@@ -16,7 +16,6 @@
|
||||
#include "../linalg/sparsemat.hpp"
|
||||
#include "../mesh/mesh.hpp"
|
||||
#include "fe_coll.hpp"
|
||||
#include "doftrans.hpp"
|
||||
#include "restriction.hpp"
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
@@ -129,9 +128,7 @@ protected:
|
||||
|
||||
// precalculated DOFs for each element, boundary element, and face
|
||||
mutable Table *elem_dof; // owned (except in NURBS FE space)
|
||||
mutable Table *elem_fos; // face orientations by element index
|
||||
mutable Table *bdr_elem_dof; // owned (except in NURBS FE space)
|
||||
mutable Table *bdr_elem_fos; // bdr face orientations by bdr element index
|
||||
mutable Table *face_dof; // owned; in var-order space contains variant 0 DOFs
|
||||
|
||||
Array<int> dof_elem_array, dof_ldof_array;
|
||||
@@ -140,9 +137,6 @@ protected:
|
||||
int own_ext;
|
||||
mutable Array<int> face_to_be; // NURBS FE space only
|
||||
|
||||
Array<DofTransformation*> DoFTrans;
|
||||
mutable VDofTransformation VDoFTrans;
|
||||
|
||||
/** Matrix representing the prolongation from the global conforming dofs to
|
||||
a set of intermediate partially conforming dofs, e.g. the dofs associated
|
||||
with a "cut" space on a non-conforming mesh. */
|
||||
@@ -195,9 +189,6 @@ protected:
|
||||
void Construct();
|
||||
void Destroy();
|
||||
|
||||
void ConstructDoFTrans();
|
||||
void DestroyDoFTrans();
|
||||
|
||||
void BuildElementToDofTable() const;
|
||||
void BuildBdrElementToDofTable() const;
|
||||
void BuildFaceToDofTable() const;
|
||||
@@ -292,19 +283,12 @@ protected:
|
||||
const FiniteElementSpace* fespace;
|
||||
DenseTensor localP[Geometry::NumGeom];
|
||||
Table* old_elem_dof; // Owned.
|
||||
Table* old_elem_fos; // Owned.
|
||||
|
||||
Array<DofTransformation*> old_DoFTrans;
|
||||
mutable VDofTransformation old_VDoFTrans;
|
||||
|
||||
void ConstructDoFTrans();
|
||||
|
||||
public:
|
||||
/** Construct the operator based on the elem_dof table of the original
|
||||
(coarse) space. The class takes ownership of the table. */
|
||||
RefinementOperator(const FiniteElementSpace* fespace,
|
||||
Table *old_elem_dof/*takes ownership*/,
|
||||
Table *old_elem_fos/*takes ownership*/, int old_ndofs);
|
||||
Table *old_elem_dof/*takes ownership*/, int old_ndofs);
|
||||
RefinementOperator(const FiniteElementSpace *fespace,
|
||||
const FiniteElementSpace *coarse_fes);
|
||||
virtual void Mult(const Vector &x, Vector &y) const;
|
||||
@@ -318,7 +302,6 @@ protected:
|
||||
const FiniteElementSpace *fine_fes; // Not owned.
|
||||
DenseTensor localR[Geometry::NumGeom];
|
||||
Table *coarse_elem_dof; // Owned.
|
||||
// Table *coarse_elem_fos; // Owned.
|
||||
Table coarse_to_fine;
|
||||
Array<int> coarse_to_ref_type;
|
||||
Array<Geometry::Type> ref_type_to_geom;
|
||||
@@ -340,7 +323,6 @@ protected:
|
||||
the same vector dimension, vdim. */
|
||||
SparseMatrix *RefinementMatrix_main(const int coarse_ndofs,
|
||||
const Table &coarse_elem_dof,
|
||||
const Table *coarse_elem_fos,
|
||||
const DenseTensor localP[]) const;
|
||||
|
||||
void GetLocalRefinementMatrices(Geometry::Type geom,
|
||||
@@ -351,12 +333,10 @@ protected:
|
||||
/** Calculate explicit GridFunction interpolation matrix (after mesh
|
||||
refinement). NOTE: consider using the RefinementOperator class instead
|
||||
of the fully assembled matrix, which can take a lot of memory. */
|
||||
SparseMatrix* RefinementMatrix(int old_ndofs, const Table* old_elem_dof,
|
||||
const Table* old_elem_fos);
|
||||
SparseMatrix* RefinementMatrix(int old_ndofs, const Table* old_elem_dof);
|
||||
|
||||
/// Calculate GridFunction restriction matrix after mesh derefinement.
|
||||
SparseMatrix* DerefinementMatrix(int old_ndofs, const Table* old_elem_dof,
|
||||
const Table* old_elem_fos);
|
||||
SparseMatrix* DerefinementMatrix(int old_ndofs, const Table* old_elem_dof);
|
||||
|
||||
/** @brief Return in @a localP the local refinement matrices that map
|
||||
between fespaces after mesh refinement. */
|
||||
@@ -634,11 +614,10 @@ public:
|
||||
int GetBdrAttribute(int i) const { return mesh->GetBdrAttribute(i); }
|
||||
|
||||
/// Returns indices of degrees of freedom of element 'elem'.
|
||||
virtual DofTransformation *GetElementDofs(int elem, Array<int> &dofs) const;
|
||||
virtual void GetElementDofs(int elem, Array<int> &dofs) const;
|
||||
|
||||
/// Returns indices of degrees of freedom for boundary element 'bel'.
|
||||
virtual DofTransformation *GetBdrElementDofs(int bel,
|
||||
Array<int> &dofs) const;
|
||||
virtual void GetBdrElementDofs(int bel, Array<int> &dofs) const;
|
||||
|
||||
/** @brief Returns the indices of the degrees of freedom for the specified
|
||||
face, including the DOFs for the edges and the vertices of the face. */
|
||||
@@ -687,10 +666,10 @@ public:
|
||||
static void AdjustVDofs(Array<int> &vdofs);
|
||||
|
||||
/// Returns indexes of degrees of freedom in array dofs for i'th element.
|
||||
DofTransformation *GetElementVDofs(int i, Array<int> &vdofs) const;
|
||||
void GetElementVDofs(int i, Array<int> &vdofs) const;
|
||||
|
||||
/// Returns indexes of degrees of freedom for i'th boundary element.
|
||||
DofTransformation *GetBdrElementVDofs(int i, Array<int> &vdofs) const;
|
||||
void GetBdrElementVDofs(int i, Array<int> &vdofs) const;
|
||||
|
||||
/// Returns indexes of degrees of freedom for i'th face element (2D and 3D).
|
||||
void GetFaceVDofs(int i, Array<int> &vdofs) const;
|
||||
@@ -716,8 +695,6 @@ public:
|
||||
is preserved. */
|
||||
void ReorderElementToDofTable();
|
||||
|
||||
const Table *GetElementToFaceOrientationTable() const { return elem_fos; }
|
||||
|
||||
/** @brief Return a reference to the internal Table that stores the lists of
|
||||
scalar dofs, for each mesh element, as returned by GetElementDofs(). */
|
||||
const Table &GetElementToDofTable() const { return *elem_dof; }
|
||||
|
||||
+7
-262
@@ -11,19 +11,15 @@
|
||||
|
||||
#include "fem.hpp"
|
||||
#include "../mesh/wedge.hpp"
|
||||
#include "../mesh/pyramid.hpp"
|
||||
|
||||
namespace mfem
|
||||
{
|
||||
|
||||
const char *Geometry::Name[NumGeom] =
|
||||
{
|
||||
"Point", "Segment", "Triangle", "Square", "Tetrahedron", "Cube", "Prism",
|
||||
"Pyramid"
|
||||
};
|
||||
{ "Point", "Segment", "Triangle", "Square", "Tetrahedron", "Cube", "Prism" };
|
||||
|
||||
const double Geometry::Volume[NumGeom] =
|
||||
{ 1.0, 1.0, 0.5, 1.0, 1./6, 1.0, 0.5, 1./3 };
|
||||
{ 1.0, 1.0, 0.5, 1.0, 1./6, 1.0, 0.5 };
|
||||
|
||||
Geometry::Geometry()
|
||||
{
|
||||
@@ -143,28 +139,6 @@ Geometry::Geometry()
|
||||
GeomVert[6]->IntPoint(5).y = 1.0;
|
||||
GeomVert[6]->IntPoint(5).z = 1.0;
|
||||
|
||||
// Vertices for Geometry::PYRAMID
|
||||
GeomVert[7] = new IntegrationRule(5);
|
||||
GeomVert[7]->IntPoint(0).x = 0.0;
|
||||
GeomVert[7]->IntPoint(0).y = 0.0;
|
||||
GeomVert[7]->IntPoint(0).z = 0.0;
|
||||
|
||||
GeomVert[7]->IntPoint(1).x = 1.0;
|
||||
GeomVert[7]->IntPoint(1).y = 0.0;
|
||||
GeomVert[7]->IntPoint(1).z = 0.0;
|
||||
|
||||
GeomVert[7]->IntPoint(2).x = 1.0;
|
||||
GeomVert[7]->IntPoint(2).y = 1.0;
|
||||
GeomVert[7]->IntPoint(2).z = 0.0;
|
||||
|
||||
GeomVert[7]->IntPoint(3).x = 0.0;
|
||||
GeomVert[7]->IntPoint(3).y = 1.0;
|
||||
GeomVert[7]->IntPoint(3).z = 0.0;
|
||||
|
||||
GeomVert[7]->IntPoint(4).x = 0.0;
|
||||
GeomVert[7]->IntPoint(4).y = 0.0;
|
||||
GeomVert[7]->IntPoint(4).z = 1.0;
|
||||
|
||||
GeomCenter[POINT].x = 0.0;
|
||||
GeomCenter[POINT].y = 0.0;
|
||||
GeomCenter[POINT].z = 0.0;
|
||||
@@ -193,10 +167,6 @@ Geometry::Geometry()
|
||||
GeomCenter[PRISM].y = 1.0 / 3.0;
|
||||
GeomCenter[PRISM].z = 0.5;
|
||||
|
||||
GeomCenter[PYRAMID].x = 0.375;
|
||||
GeomCenter[PYRAMID].y = 0.375;
|
||||
GeomCenter[PYRAMID].z = 0.25;
|
||||
|
||||
GeomToPerfGeomJac[POINT] = NULL;
|
||||
GeomToPerfGeomJac[SEGMENT] = new DenseMatrix(1);
|
||||
GeomToPerfGeomJac[TRIANGLE] = new DenseMatrix(2);
|
||||
@@ -204,7 +174,6 @@ Geometry::Geometry()
|
||||
GeomToPerfGeomJac[TETRAHEDRON] = new DenseMatrix(3);
|
||||
GeomToPerfGeomJac[CUBE] = new DenseMatrix(3);
|
||||
GeomToPerfGeomJac[PRISM] = new DenseMatrix(3);
|
||||
GeomToPerfGeomJac[PYRAMID] = new DenseMatrix(3);
|
||||
|
||||
PerfGeomToGeomJac[POINT] = NULL;
|
||||
PerfGeomToGeomJac[SEGMENT] = NULL;
|
||||
@@ -213,7 +182,6 @@ Geometry::Geometry()
|
||||
PerfGeomToGeomJac[TETRAHEDRON] = new DenseMatrix(3);
|
||||
PerfGeomToGeomJac[CUBE] = NULL;
|
||||
PerfGeomToGeomJac[PRISM] = new DenseMatrix(3);
|
||||
PerfGeomToGeomJac[PYRAMID] = new DenseMatrix(3);
|
||||
|
||||
GeomToPerfGeomJac[SEGMENT]->Diag(1.0, 1);
|
||||
{
|
||||
@@ -242,14 +210,6 @@ Geometry::Geometry()
|
||||
*GeomToPerfGeomJac[PRISM] = pri_T.Jacobian();
|
||||
CalcInverse(pri_T.Jacobian(), *PerfGeomToGeomJac[PRISM]);
|
||||
}
|
||||
{
|
||||
IsoparametricTransformation pyr_T;
|
||||
pyr_T.SetFE(&PyramidFE);
|
||||
GetPerfPointMat (PYRAMID, pyr_T.GetPointMat());
|
||||
pyr_T.SetIntPoint(&GeomCenter[PYRAMID]);
|
||||
*GeomToPerfGeomJac[PYRAMID] = pyr_T.Jacobian();
|
||||
CalcInverse(pyr_T.Jacobian(), *PerfGeomToGeomJac[PYRAMID]);
|
||||
}
|
||||
}
|
||||
|
||||
Geometry::~Geometry()
|
||||
@@ -273,7 +233,6 @@ const IntegrationRule * Geometry::GetVertices(int GeomType)
|
||||
case Geometry::TETRAHEDRON: return GeomVert[4];
|
||||
case Geometry::CUBE: return GeomVert[5];
|
||||
case Geometry::PRISM: return GeomVert[6];
|
||||
case Geometry::PYRAMID: return GeomVert[7];
|
||||
default:
|
||||
mfem_error ("Geometry::GetVertices(...)");
|
||||
}
|
||||
@@ -351,25 +310,6 @@ void Geometry::GetRandomPoint(int GeomType, IntegrationPoint &ip)
|
||||
ip.y = 1.0 - ip.y;
|
||||
}
|
||||
break;
|
||||
case Geometry::PYRAMID:
|
||||
ip.x = double(rand()) / RAND_MAX;
|
||||
ip.y = double(rand()) / RAND_MAX;
|
||||
ip.z = double(rand()) / RAND_MAX;
|
||||
if (ip.x + ip.z > 1.0 && ip.y < ip.x)
|
||||
{
|
||||
double x = ip.x;
|
||||
ip.x = ip.y;
|
||||
ip.y = 1.0 - ip.z;
|
||||
ip.z = 1.0 - x;
|
||||
}
|
||||
else if (ip.y + ip.z > 1.0)
|
||||
{
|
||||
double z = ip.z;
|
||||
ip.z = 1.0 - ip.y;
|
||||
ip.y = ip.x;
|
||||
ip.x = 1.0 - z;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MFEM_ABORT("Unknown type of reference element!");
|
||||
}
|
||||
@@ -431,10 +371,6 @@ bool Geometry::CheckPoint(int GeomType, const IntegrationPoint &ip)
|
||||
if (ip.x < 0.0 || ip.y < 0.0 || ip.x+ip.y > 1.0 ||
|
||||
ip.z < 0.0 || ip.z > 1.0) { return false; }
|
||||
break;
|
||||
case Geometry::PYRAMID:
|
||||
if (ip.x < 0.0 || ip.y < 0.0 || ip.x+ip.z > 1.0 || ip.y+ip.z > 1.0 ||
|
||||
ip.z < 0.0 || ip.z > 1.0) { return false; }
|
||||
break;
|
||||
default:
|
||||
MFEM_ABORT("Unknown type of reference element!");
|
||||
}
|
||||
@@ -505,17 +441,6 @@ bool Geometry::CheckPoint(int GeomType, const IntegrationPoint &ip, double eps)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case Geometry::PYRAMID:
|
||||
if (internal::FuzzyLT(ip.x, 0.0, eps)
|
||||
|| internal::FuzzyLT(ip.y, 0.0, eps)
|
||||
|| internal::FuzzyGT(ip.x+ip.z, 1.0, eps)
|
||||
|| internal::FuzzyGT(ip.y+ip.z, 1.0, eps)
|
||||
|| internal::FuzzyLT(ip.z, 0.0, eps)
|
||||
|| internal::FuzzyGT(ip.z, 1.0, eps) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MFEM_ABORT("Unknown type of reference element!");
|
||||
}
|
||||
@@ -630,16 +555,6 @@ bool Geometry::ProjectPoint(int GeomType, const IntegrationPoint &beg,
|
||||
double lbeg[5] = { beg.x, beg.y, beg.z, 1.0-beg.x-beg.y, 1.0-beg.z };
|
||||
return internal::IntersectSegment<5,3>(lbeg, lend, end);
|
||||
}
|
||||
case Geometry::PYRAMID:
|
||||
{
|
||||
double lend[6] = { end.x, end.y, end.z,
|
||||
1.0-end.x-end.z, 1.0-end.y-end.z, 1.0-end.z
|
||||
};
|
||||
double lbeg[6] = { beg.x, beg.y, beg.z,
|
||||
1.0-beg.x-beg.z, 1.0-beg.y-beg.z, 1.0-beg.z
|
||||
};
|
||||
return internal::IntersectSegment<6,3>(lbeg, lend, end);
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("Unknown type of reference element!");
|
||||
}
|
||||
@@ -737,43 +652,6 @@ bool Geometry::ProjectPoint(int GeomType, IntegrationPoint &ip)
|
||||
return in_tri && in_z;
|
||||
}
|
||||
|
||||
case PYRAMID:
|
||||
{
|
||||
if (ip.x < 0.0)
|
||||
{
|
||||
ip.x = 0.0;
|
||||
internal::ProjectTriangle(ip.y, ip.z);
|
||||
return false;
|
||||
}
|
||||
if (ip.y < 0.0)
|
||||
{
|
||||
ip.y = 0.0;
|
||||
internal::ProjectTriangle(ip.x, ip.z);
|
||||
return false;
|
||||
}
|
||||
if (ip.z < 0.0)
|
||||
{
|
||||
ip.z = 0.0;
|
||||
if (ip.x > 1.0) { ip.x = 1.0; }
|
||||
if (ip.y > 1.0) { ip.y = 1.0; }
|
||||
return false;
|
||||
}
|
||||
if (ip.x >= ip.y)
|
||||
{
|
||||
bool in_y = true;
|
||||
bool in_tri = internal::ProjectTriangle(ip.x, ip.z);
|
||||
if (ip.y > ip.z) { in_y = false; ip.y = ip.z; }
|
||||
return in_tri && in_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool in_x = true;
|
||||
bool in_tri = internal::ProjectTriangle(ip.y, ip.z);
|
||||
if (ip.x > ip.z) { in_x = false; ip.x = ip.z; }
|
||||
return in_tri && in_x;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
MFEM_ABORT("Reference element type is not supported!");
|
||||
}
|
||||
@@ -848,17 +726,6 @@ void Geometry::GetPerfPointMat(int GeomType, DenseMatrix &pm)
|
||||
}
|
||||
break;
|
||||
|
||||
case Geometry::PYRAMID:
|
||||
{
|
||||
pm.SetSize (3, 5);
|
||||
pm(0,0) = 0.0; pm(1,0) = 0.0; pm(2,0) = 0.0;
|
||||
pm(0,1) = 1.0; pm(1,1) = 0.0; pm(2,1) = 0.0;
|
||||
pm(0,2) = 1.0; pm(1,2) = 1.0; pm(2,2) = 0.0;
|
||||
pm(0,3) = 0.0; pm(1,3) = 1.0; pm(2,3) = 0.0;
|
||||
pm(0,4) = 0.5; pm(1,4) = 0.5; pm(2,4) = 0.7071067811865475;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
mfem_error ("Geometry::GetPerfPointMat (...)");
|
||||
}
|
||||
@@ -877,13 +744,13 @@ void Geometry::JacToPerfJac(int GeomType, const DenseMatrix &J,
|
||||
}
|
||||
}
|
||||
|
||||
const int Geometry::NumBdrArray[NumGeom] = { 0, 2, 3, 4, 4, 6, 5, 5 };
|
||||
const int Geometry::Dimension[NumGeom] = { 0, 1, 2, 2, 3, 3, 3, 3 };
|
||||
const int Geometry::NumBdrArray[NumGeom] = { 0, 2, 3, 4, 4, 6, 5 };
|
||||
const int Geometry::Dimension[NumGeom] = { 0, 1, 2, 2, 3, 3, 3 };
|
||||
const int Geometry::DimStart[MaxDim+2] =
|
||||
{ POINT, SEGMENT, TRIANGLE, TETRAHEDRON, NUM_GEOMETRIES };
|
||||
const int Geometry::NumVerts[NumGeom] = { 1, 2, 3, 4, 4, 8, 6, 5 };
|
||||
const int Geometry::NumEdges[NumGeom] = { 0, 1, 3, 4, 6, 12, 9, 8 };
|
||||
const int Geometry::NumFaces[NumGeom] = { 0, 0, 1, 1, 4, 6, 5, 5 };
|
||||
const int Geometry::NumVerts[NumGeom] = { 1, 2, 3, 4, 4, 8, 6 };
|
||||
const int Geometry::NumEdges[NumGeom] = { 0, 1, 3, 4, 6, 12, 9 };
|
||||
const int Geometry::NumFaces[NumGeom] = { 0, 0, 1, 1, 4, 6, 5 };
|
||||
|
||||
const int Geometry::
|
||||
Constants<Geometry::POINT>::Orient[1][1] = {{0}};
|
||||
@@ -1030,30 +897,6 @@ Constants<Geometry::PRISM>::VertToVert::J[9][2] =
|
||||
{5, 4} // 4,5:4
|
||||
};
|
||||
|
||||
const int Geometry::
|
||||
Constants<Geometry::PYRAMID>::Edges[8][2] =
|
||||
{{0, 1}, {1, 2}, {3, 2}, {0, 3}, {0, 4}, {1, 4}, {2, 4}, {3, 4}};
|
||||
const int Geometry::
|
||||
Constants<Geometry::PYRAMID>::FaceTypes[5] =
|
||||
{
|
||||
Geometry::SQUARE,
|
||||
Geometry::TRIANGLE, Geometry::TRIANGLE,
|
||||
Geometry::TRIANGLE, Geometry::TRIANGLE
|
||||
};
|
||||
const int Geometry::
|
||||
Constants<Geometry::PYRAMID>::FaceVert[5][4] =
|
||||
{{3, 2, 1, 0}, {0, 1, 4, -1}, {1, 2, 4, -1}, {2, 3, 4, -1}, {3, 0, 4, -1}};
|
||||
const int Geometry::
|
||||
Constants<Geometry::PYRAMID>::VertToVert::I[5] = {0, 3, 5, 7, 8};
|
||||
const int Geometry::
|
||||
Constants<Geometry::PYRAMID>::VertToVert::J[8][2] =
|
||||
{
|
||||
{1, 0}, {3, 3}, {4, 4}, // 0,1:0 0,3:3 0,4:4
|
||||
{2, 1}, {4, 5}, // 1,2:1 1,4:5
|
||||
{3,-3}, {4, 6}, // 2,3:-3 2,4:6
|
||||
{4, 7} // 3,4:7
|
||||
};
|
||||
|
||||
|
||||
GeometryRefiner::GeometryRefiner()
|
||||
{
|
||||
@@ -1419,104 +1262,6 @@ RefinedGeometry * GeometryRefiner::Refine(Geometry::Type Geom,
|
||||
return RG;
|
||||
}
|
||||
|
||||
case Geometry::PYRAMID:
|
||||
{
|
||||
const int n = Times;
|
||||
RG = new RefinedGeometry ((n+1)*(n+2)*(2*n+3)/6,
|
||||
5*n*(2*n-1)*(2*n+1)/3, 0);
|
||||
RG->Times = Times;
|
||||
RG->ETimes = ETimes;
|
||||
RG->Type = type;
|
||||
// enumerate and define the vertices
|
||||
m = 0;
|
||||
for (k = 0; k <= n; k++)
|
||||
{
|
||||
const double *cpij =
|
||||
poly1d.GetPoints(Times - k, BasisType::GetNodalBasis(type));
|
||||
for (j = 0; j <= n - k; j++)
|
||||
for (i = 0; i <= n - k; i++)
|
||||
{
|
||||
IntegrationPoint &ip = RG->RefPts.IntPoint(m);
|
||||
if (type == 0)
|
||||
{
|
||||
ip.x = (n > k) ? (double(i) / (n - k)) : 0.0;
|
||||
ip.y = (n > k) ? (double(j) / (n - k)) : 0.0;
|
||||
ip.z = double(k) / n;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip.x = cpij[i] * (1.0 - cp[k]);
|
||||
ip.y = cpij[j] * (1.0 - cp[k]);
|
||||
ip.z = cp[k];
|
||||
}
|
||||
m++;
|
||||
}
|
||||
}
|
||||
if (m != (n+1)*(n+2)*(2*n+3)/6)
|
||||
{
|
||||
mfem_error("GeometryRefiner::Refine() for PYRAMID #1");
|
||||
}
|
||||
// elements
|
||||
Array<int> &G = RG->RefGeoms;
|
||||
m = 0;
|
||||
for (k = 0; k < n; k++)
|
||||
{
|
||||
int lk = k * (k * (2 * k - 6 * n - 9) + 6 * n * (n + 3) + 13) / 6;
|
||||
int lkp1 = (k + 1) *
|
||||
(k * (2 * k - 6 * n -5) + 6 * n * (n + 2) + 6) / 6;
|
||||
for (j = 0; j < n - k; j++)
|
||||
{
|
||||
for (i = 0; i < n - k; i++)
|
||||
{
|
||||
G[m++] = lk + j * (n - k + 1) + i;
|
||||
G[m++] = lk + j * (n - k + 1) + i + 1;
|
||||
G[m++] = lk + (j + 1) * (n - k + 1) + i + 1;
|
||||
G[m++] = lk + (j + 1) * (n - k + 1) + i;
|
||||
G[m++] = lkp1 + j * (n - k) + i;
|
||||
}
|
||||
}
|
||||
for (j = 0; j < n - k - 1; j++)
|
||||
{
|
||||
for (i = 0; i < n - k - 1; i++)
|
||||
{
|
||||
G[m++] = lkp1 + j * (n - k) + i;
|
||||
G[m++] = lkp1 + (j + 1) * (n - k) + i;
|
||||
G[m++] = lkp1 + (j + 1) * (n - k) + i + 1;
|
||||
G[m++] = lkp1 + j * (n - k) + i + 1;
|
||||
G[m++] = lk + (j + 1) * (n - k + 1) + i + 1;
|
||||
}
|
||||
}
|
||||
for (j = 0; j < n - k; j++)
|
||||
{
|
||||
for (i = 0; i < n - k - 1; i++)
|
||||
{
|
||||
G[m++] = lk + j * (n - k + 1) + i + 1;
|
||||
G[m++] = lk + (j + 1) * (n - k + 1) + i + 1;
|
||||
G[m++] = lkp1 + j * (n - k) + i;
|
||||
G[m++] = lkp1 + j * (n - k) + i + 1;
|
||||
G[m++] = -1;
|
||||
}
|
||||
}
|
||||
for (j = 0; j < n - k - 1; j++)
|
||||
{
|
||||
for (i = 0; i < n - k; i++)
|
||||
{
|
||||
G[m++] = lk + (j + 1) * (n - k + 1) + i;
|
||||
G[m++] = lk + (j + 1) * (n - k + 1) + i + 1;
|
||||
G[m++] = lkp1 + (j + 1) * (n - k) + i;
|
||||
G[m++] = lkp1 + j * (n - k) + i;
|
||||
G[m++] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m != 5*n*(2*n-1)*(2*n+1)/3)
|
||||
{
|
||||
mfem_error("GeometryRefiner::Refine() for PYRAMID #2");
|
||||
}
|
||||
RGeom[Geometry::PYRAMID].Append(RG);
|
||||
return RG;
|
||||
}
|
||||
|
||||
case Geometry::PRISM:
|
||||
{
|
||||
const int n = Times;
|
||||
|
||||
+2
-22
@@ -27,7 +27,6 @@ namespace mfem
|
||||
Geometry::TETRAHEDRON - w/ vert. (0,0,0),(1,0,0),(0,1,0),(0,0,1)
|
||||
Geometry::CUBE - the unit cube
|
||||
Geometry::PRISM - w/ vert. (0,0,0),(1,0,0),(0,1,0),(0,0,1),(1,0,1),(0,1,1)
|
||||
Geometry::PYRAMID - w/ vert. (0,0,0),(1,0,0),(1,1,0),(0,1,0),(0,0,1)
|
||||
*/
|
||||
class Geometry
|
||||
{
|
||||
@@ -35,7 +34,7 @@ public:
|
||||
enum Type
|
||||
{
|
||||
INVALID = -1,
|
||||
POINT = 0, SEGMENT, TRIANGLE, SQUARE, TETRAHEDRON, CUBE, PRISM, PYRAMID,
|
||||
POINT = 0, SEGMENT, TRIANGLE, SQUARE, TETRAHEDRON, CUBE, PRISM,
|
||||
NUM_GEOMETRIES
|
||||
};
|
||||
|
||||
@@ -252,26 +251,7 @@ template <> struct Geometry::Constants<Geometry::PRISM>
|
||||
};
|
||||
};
|
||||
|
||||
template <> struct Geometry::Constants<Geometry::PYRAMID>
|
||||
{
|
||||
static const int Dimension = 3;
|
||||
static const int NumVert = 5;
|
||||
static const int NumEdges = 8;
|
||||
static const int Edges[NumEdges][2];
|
||||
static const int NumFaces = 5;
|
||||
static const int FaceTypes[NumFaces];
|
||||
static const int MaxFaceVert = 4;
|
||||
static const int FaceVert[NumFaces][MaxFaceVert];
|
||||
// Upper-triangular part of the local vertex-to-vertex graph.
|
||||
struct VertToVert
|
||||
{
|
||||
static const int I[NumVert];
|
||||
static const int J[NumEdges][2]; // {end,edge_idx}
|
||||
};
|
||||
};
|
||||
|
||||
// Defined in fe.cpp to ensure construction after 'mfem::TriangleFE' and
|
||||
// `mfem::TetrahedronFE`.
|
||||
// Defined in fe.cpp to ensure construction after 'mfem::WedgeFE'.
|
||||
extern Geometry Geometries;
|
||||
|
||||
|
||||
|
||||
+54
-166
@@ -255,8 +255,6 @@ void GridFunction::SumFluxAndCount(BilinearFormIntegrator &blfi,
|
||||
GridFunction &u = *this;
|
||||
|
||||
ElementTransformation *Transf;
|
||||
DofTransformation *udoftrans;
|
||||
DofTransformation *fdoftrans;
|
||||
|
||||
FiniteElementSpace *ufes = u.FESpace();
|
||||
FiniteElementSpace *ffes = flux.FESpace();
|
||||
@@ -276,23 +274,15 @@ void GridFunction::SumFluxAndCount(BilinearFormIntegrator &blfi,
|
||||
continue;
|
||||
}
|
||||
|
||||
udoftrans = ufes->GetElementVDofs(i, udofs);
|
||||
fdoftrans = ffes->GetElementVDofs(i, fdofs);
|
||||
ufes->GetElementVDofs(i, udofs);
|
||||
ffes->GetElementVDofs(i, fdofs);
|
||||
|
||||
u.GetSubVector(udofs, ul);
|
||||
if (udoftrans)
|
||||
{
|
||||
udoftrans->InvTransformPrimal(ul);
|
||||
}
|
||||
|
||||
Transf = ufes->GetElementTransformation(i);
|
||||
blfi.ComputeElementFlux(*ufes->GetFE(i), *Transf, ul,
|
||||
*ffes->GetFE(i), fl, wcoef);
|
||||
|
||||
if (fdoftrans)
|
||||
{
|
||||
fdoftrans->TransformPrimal(fl);
|
||||
}
|
||||
flux.AddElementVector(fdofs, fl);
|
||||
|
||||
FiniteElementSpace::AdjustVDofs(fdofs);
|
||||
@@ -374,7 +364,7 @@ void GridFunction::GetNodalValues(int i, Array<double> &nval, int vdim) const
|
||||
|
||||
int k;
|
||||
|
||||
DofTransformation * doftrans = fes->GetElementVDofs(i, vdofs);
|
||||
fes->GetElementVDofs(i, vdofs);
|
||||
const FiniteElement *FElem = fes->GetFE(i);
|
||||
const IntegrationRule *ElemVert =
|
||||
Geometries.GetVertices(FElem->GetGeomType());
|
||||
@@ -384,10 +374,6 @@ void GridFunction::GetNodalValues(int i, Array<double> &nval, int vdim) const
|
||||
vdim--;
|
||||
Vector loc_data;
|
||||
GetSubVector(vdofs, loc_data);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(loc_data);
|
||||
}
|
||||
|
||||
if (FElem->GetRangeType() == FiniteElement::SCALAR)
|
||||
{
|
||||
@@ -417,7 +403,7 @@ double GridFunction::GetValue(int i, const IntegrationPoint &ip, int vdim)
|
||||
const
|
||||
{
|
||||
Array<int> dofs;
|
||||
DofTransformation * doftrans = fes->GetElementDofs(i, dofs);
|
||||
fes->GetElementDofs(i, dofs);
|
||||
fes->DofsToVDofs(vdim-1, dofs);
|
||||
Vector DofVal(dofs.Size()), LocVec;
|
||||
const FiniteElement *fe = fes->GetFE(i);
|
||||
@@ -432,10 +418,6 @@ const
|
||||
fe->CalcPhysShape(*Tr, DofVal);
|
||||
}
|
||||
GetSubVector(dofs, LocVec);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(LocVec);
|
||||
}
|
||||
|
||||
return (DofVal * LocVec);
|
||||
}
|
||||
@@ -446,13 +428,9 @@ void GridFunction::GetVectorValue(int i, const IntegrationPoint &ip,
|
||||
const FiniteElement *FElem = fes->GetFE(i);
|
||||
int dof = FElem->GetDof();
|
||||
Array<int> vdofs;
|
||||
DofTransformation * doftrans = fes->GetElementVDofs(i, vdofs);
|
||||
fes->GetElementVDofs(i, vdofs);
|
||||
Vector loc_data;
|
||||
GetSubVector(vdofs, loc_data);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(loc_data);
|
||||
}
|
||||
if (FElem->GetRangeType() == FiniteElement::SCALAR)
|
||||
{
|
||||
Vector shape(dof);
|
||||
@@ -492,35 +470,30 @@ const
|
||||
Array<int> dofs;
|
||||
int n = ir.GetNPoints();
|
||||
vals.SetSize(n);
|
||||
DofTransformation * doftrans = fes->GetElementDofs(i, dofs);
|
||||
fes->GetElementDofs(i, dofs);
|
||||
fes->DofsToVDofs(vdim-1, dofs);
|
||||
const FiniteElement *FElem = fes->GetFE(i);
|
||||
int dof = FElem->GetDof();
|
||||
Vector DofVal(dof), loc_data(dof);
|
||||
GetSubVector(dofs, loc_data);
|
||||
if (doftrans)
|
||||
if (FElem->GetMapType() == FiniteElement::VALUE)
|
||||
{
|
||||
doftrans->InvTransformPrimal(loc_data);
|
||||
for (int k = 0; k < n; k++)
|
||||
{
|
||||
FElem->CalcShape(ir.IntPoint(k), DofVal);
|
||||
vals(k) = DofVal * loc_data;
|
||||
}
|
||||
}
|
||||
for (int k = 0; k < n; k++)
|
||||
if (FElem->GetMapType() == FiniteElement::VALUE)
|
||||
else
|
||||
{
|
||||
ElementTransformation *Tr = fes->GetElementTransformation(i);
|
||||
for (int k = 0; k < n; k++)
|
||||
{
|
||||
for (int k = 0; k < n; k++)
|
||||
{
|
||||
FElem->CalcShape(ir.IntPoint(k), DofVal);
|
||||
vals(k) = DofVal * loc_data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ElementTransformation *Tr = fes->GetElementTransformation(i);
|
||||
for (int k = 0; k < n; k++)
|
||||
{
|
||||
Tr->SetIntPoint(&ir.IntPoint(k));
|
||||
FElem->CalcPhysShape(*Tr, DofVal);
|
||||
vals(k) = DofVal * loc_data;
|
||||
}
|
||||
Tr->SetIntPoint(&ir.IntPoint(k));
|
||||
FElem->CalcPhysShape(*Tr, DofVal);
|
||||
vals(k) = DofVal * loc_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GridFunction::GetValues(int i, const IntegrationRule &ir, Vector &vals,
|
||||
@@ -888,12 +861,11 @@ void GridFunction::GetVectorValue(ElementTransformation &T,
|
||||
|
||||
Array<int> vdofs;
|
||||
const FiniteElement *fe = NULL;
|
||||
DofTransformation * doftrans = NULL;
|
||||
|
||||
switch (T.ElementType)
|
||||
{
|
||||
case ElementTransformation::ELEMENT:
|
||||
doftrans = fes->GetElementVDofs(T.ElementNo, vdofs);
|
||||
fes->GetElementVDofs(T.ElementNo, vdofs);
|
||||
fe = fes->GetFE(T.ElementNo);
|
||||
break;
|
||||
case ElementTransformation::EDGE:
|
||||
@@ -984,10 +956,6 @@ void GridFunction::GetVectorValue(ElementTransformation &T,
|
||||
int dof = fe->GetDof();
|
||||
Vector loc_data;
|
||||
GetSubVector(vdofs, loc_data);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(loc_data);
|
||||
}
|
||||
if (fe->GetRangeType() == FiniteElement::SCALAR)
|
||||
{
|
||||
Vector shape(dof);
|
||||
@@ -1030,14 +998,10 @@ void GridFunction::GetVectorValues(ElementTransformation &T,
|
||||
int dof = FElem->GetDof();
|
||||
|
||||
Array<int> vdofs;
|
||||
DofTransformation * doftrans = fes->GetElementVDofs(T.ElementNo, vdofs);
|
||||
fes->GetElementVDofs(T.ElementNo, vdofs);
|
||||
|
||||
Vector loc_data;
|
||||
GetSubVector(vdofs, loc_data);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(loc_data);
|
||||
}
|
||||
|
||||
int nip = ir.GetNPoints();
|
||||
|
||||
if (FElem->GetRangeType() == FiniteElement::SCALAR)
|
||||
@@ -1125,8 +1089,6 @@ void GridFunction::GetValuesFrom(const GridFunction &orig_func)
|
||||
// Without averaging ...
|
||||
|
||||
const FiniteElementSpace *orig_fes = orig_func.FESpace();
|
||||
DofTransformation * doftrans;
|
||||
DofTransformation * orig_doftrans;
|
||||
Array<int> vdofs, orig_vdofs;
|
||||
Vector shape, loc_values, orig_loc_values;
|
||||
int i, j, d, ne, dof, odof, vdim;
|
||||
@@ -1135,13 +1097,9 @@ void GridFunction::GetValuesFrom(const GridFunction &orig_func)
|
||||
vdim = fes->GetVDim();
|
||||
for (i = 0; i < ne; i++)
|
||||
{
|
||||
doftrans = fes->GetElementVDofs(i, vdofs);
|
||||
orig_doftrans = orig_fes->GetElementVDofs(i, orig_vdofs);
|
||||
fes->GetElementVDofs(i, vdofs);
|
||||
orig_fes->GetElementVDofs(i, orig_vdofs);
|
||||
orig_func.GetSubVector(orig_vdofs, orig_loc_values);
|
||||
if (orig_doftrans)
|
||||
{
|
||||
orig_doftrans->InvTransformPrimal(orig_loc_values);
|
||||
}
|
||||
const FiniteElement *fe = fes->GetFE(i);
|
||||
const FiniteElement *orig_fe = orig_fes->GetFE(i);
|
||||
dof = fe->GetDof();
|
||||
@@ -1159,10 +1117,6 @@ void GridFunction::GetValuesFrom(const GridFunction &orig_func)
|
||||
shape * ((const double *)orig_loc_values + d * odof) ;
|
||||
}
|
||||
}
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->TransformPrimal(loc_values);
|
||||
}
|
||||
SetSubVector(vdofs, loc_values);
|
||||
}
|
||||
}
|
||||
@@ -1172,10 +1126,8 @@ void GridFunction::GetBdrValuesFrom(const GridFunction &orig_func)
|
||||
// Without averaging ...
|
||||
|
||||
const FiniteElementSpace *orig_fes = orig_func.FESpace();
|
||||
// DofTransformation * doftrans;
|
||||
// DofTransformation * orig_doftrans;
|
||||
Array<int> vdofs, orig_vdofs;
|
||||
Vector shape, loc_values, loc_values_t, orig_loc_values, orig_loc_values_t;
|
||||
Vector shape, loc_values, orig_loc_values;
|
||||
int i, j, d, nbe, dof, odof, vdim;
|
||||
|
||||
nbe = fes->GetNBE();
|
||||
@@ -1213,33 +1165,37 @@ void GridFunction::GetVectorFieldValues(
|
||||
Array<int> vdofs;
|
||||
ElementTransformation *transf;
|
||||
|
||||
int d, k, n, sdim, dof;
|
||||
int d, j, k, n, sdim, dof, ind;
|
||||
|
||||
n = ir.GetNPoints();
|
||||
DofTransformation * doftrans = fes->GetElementVDofs(i, vdofs);
|
||||
fes->GetElementVDofs(i, vdofs);
|
||||
const FiniteElement *fe = fes->GetFE(i);
|
||||
dof = fe->GetDof();
|
||||
sdim = fes->GetMesh()->SpaceDimension();
|
||||
// int *dofs = &vdofs[comp*dof];
|
||||
int *dofs = &vdofs[comp*dof];
|
||||
transf = fes->GetElementTransformation(i);
|
||||
transf->Transform(ir, tr);
|
||||
vals.SetSize(n, sdim);
|
||||
DenseMatrix vshape(dof, sdim);
|
||||
Vector loc_data, val(sdim);
|
||||
GetSubVector(vdofs, loc_data);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(loc_data);
|
||||
}
|
||||
double a;
|
||||
for (k = 0; k < n; k++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir.IntPoint(k);
|
||||
transf->SetIntPoint(&ip);
|
||||
fe->CalcVShape(*transf, vshape);
|
||||
vshape.MultTranspose(loc_data, val);
|
||||
for (d = 0; d < sdim; d++)
|
||||
{
|
||||
vals(k,d) = val(d);
|
||||
a = 0.0;
|
||||
for (j = 0; j < dof; j++)
|
||||
if ( (ind=dofs[j]) >= 0 )
|
||||
{
|
||||
a += vshape(j, d) * data[ind];
|
||||
}
|
||||
else
|
||||
{
|
||||
a -= vshape(j, d) * data[-1-ind];
|
||||
}
|
||||
vals(k, d) = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1409,13 +1365,9 @@ void GridFunction::GetVectorGradientHat(
|
||||
const FiniteElement *FElem = fes->GetFE(elNo);
|
||||
int dim = FElem->GetDim(), dof = FElem->GetDof();
|
||||
Array<int> vdofs;
|
||||
DofTransformation * doftrans = fes->GetElementVDofs(elNo, vdofs);
|
||||
fes->GetElementVDofs(elNo, vdofs);
|
||||
Vector loc_data;
|
||||
GetSubVector(vdofs, loc_data);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(loc_data);
|
||||
}
|
||||
// assuming scalar FE
|
||||
int vdim = fes->GetVDim();
|
||||
DenseMatrix dshape(dof, dim);
|
||||
@@ -1454,13 +1406,9 @@ double GridFunction::GetDivergence(ElementTransformation &T) const
|
||||
{
|
||||
// Assuming RT-type space
|
||||
Array<int> dofs;
|
||||
DofTransformation * doftrans = fes->GetElementDofs(elNo, dofs);
|
||||
fes->GetElementDofs(elNo, dofs);
|
||||
Vector loc_data, divshape(fe->GetDof());
|
||||
GetSubVector(dofs, loc_data);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(loc_data);
|
||||
}
|
||||
fe->CalcDivShape(T.GetIntPoint(), divshape);
|
||||
return (loc_data * divshape) / T.Weight();
|
||||
}
|
||||
@@ -1551,13 +1499,9 @@ void GridFunction::GetCurl(ElementTransformation &T, Vector &curl) const
|
||||
{
|
||||
// Assuming ND-type space
|
||||
Array<int> dofs;
|
||||
DofTransformation * doftrans = fes->GetElementDofs(elNo, dofs);
|
||||
fes->GetElementDofs(elNo, dofs);
|
||||
Vector loc_data;
|
||||
GetSubVector(dofs, loc_data);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(loc_data);
|
||||
}
|
||||
DenseMatrix curl_shape(fe->GetDof(), fe->GetDim() == 3 ? 3 : 1);
|
||||
fe->CalcCurlShape(T.GetIntPoint(), curl_shape);
|
||||
curl.SetSize(curl_shape.Width());
|
||||
@@ -1699,12 +1643,8 @@ void GridFunction::GetGradients(ElementTransformation &tr,
|
||||
DenseMatrix dshape(fe->GetDof(), fe->GetDim());
|
||||
Vector lval, gh(fe->GetDim()), gcol;
|
||||
Array<int> dofs;
|
||||
DofTransformation * doftrans = fes->GetElementDofs(elNo, dofs);
|
||||
fes->GetElementDofs(elNo, dofs);
|
||||
GetSubVector(dofs, lval);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(lval);
|
||||
}
|
||||
grad.SetSize(fe->GetDim(), ir.GetNPoints());
|
||||
for (int i = 0; i < ir.GetNPoints(); i++)
|
||||
{
|
||||
@@ -1784,8 +1724,6 @@ void GridFunction::GetElementAverages(GridFunction &avgs) const
|
||||
{
|
||||
MassIntegrator Mi;
|
||||
DenseMatrix loc_mass;
|
||||
DofTransformation * te_doftrans;
|
||||
DofTransformation * tr_doftrans;
|
||||
Array<int> te_dofs, tr_dofs;
|
||||
Vector loc_avgs, loc_this;
|
||||
Vector int_psi(avgs.Size());
|
||||
@@ -1796,19 +1734,11 @@ void GridFunction::GetElementAverages(GridFunction &avgs) const
|
||||
{
|
||||
Mi.AssembleElementMatrix2(*fes->GetFE(i), *avgs.FESpace()->GetFE(i),
|
||||
*fes->GetElementTransformation(i), loc_mass);
|
||||
tr_doftrans = fes->GetElementDofs(i, tr_dofs);
|
||||
te_doftrans = avgs.FESpace()->GetElementDofs(i, te_dofs);
|
||||
fes->GetElementDofs(i, tr_dofs);
|
||||
avgs.FESpace()->GetElementDofs(i, te_dofs);
|
||||
GetSubVector(tr_dofs, loc_this);
|
||||
if (tr_doftrans)
|
||||
{
|
||||
tr_doftrans->InvTransformPrimal(loc_this);
|
||||
}
|
||||
loc_avgs.SetSize(te_dofs.Size());
|
||||
loc_mass.Mult(loc_this, loc_avgs);
|
||||
if (te_doftrans)
|
||||
{
|
||||
te_doftrans->TransformPrimal(loc_avgs);
|
||||
}
|
||||
avgs.AddElementVector(te_dofs, loc_avgs);
|
||||
loc_this = 1.0; // assume the local basis for 'this' sums to 1
|
||||
loc_mass.Mult(loc_this, loc_avgs);
|
||||
@@ -1823,12 +1753,8 @@ void GridFunction::GetElementAverages(GridFunction &avgs) const
|
||||
void GridFunction::GetElementDofValues(int el, Vector &dof_vals) const
|
||||
{
|
||||
Array<int> dof_idx;
|
||||
DofTransformation * doftrans = fes->GetElementVDofs(el, dof_idx);
|
||||
fes->GetElementVDofs(el, dof_idx);
|
||||
GetSubVector(dof_idx, dof_vals);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(dof_vals);
|
||||
}
|
||||
}
|
||||
|
||||
void GridFunction::ProjectGridFunction(const GridFunction &src)
|
||||
@@ -1864,21 +1790,13 @@ void GridFunction::ProjectGridFunction(const GridFunction &src)
|
||||
cached_geom = geom;
|
||||
}
|
||||
|
||||
DofTransformation * src_doftrans = src.fes->GetElementVDofs(i, src_vdofs);
|
||||
src.fes->GetElementVDofs(i, src_vdofs);
|
||||
src.GetSubVector(src_vdofs, src_lvec);
|
||||
if (src_doftrans)
|
||||
{
|
||||
src_doftrans->InvTransformPrimal(src_lvec);
|
||||
}
|
||||
for (int vd = 0; vd < vdim; vd++)
|
||||
{
|
||||
P.Mult(&src_lvec[vd*P.Width()], &dest_lvec[vd*P.Height()]);
|
||||
}
|
||||
DofTransformation * doftrans = fes->GetElementVDofs(i, dest_vdofs);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->TransformPrimal(dest_lvec);
|
||||
}
|
||||
fes->GetElementVDofs(i, dest_vdofs);
|
||||
SetSubVector(dest_vdofs, dest_lvec);
|
||||
}
|
||||
}
|
||||
@@ -1887,15 +1805,10 @@ void GridFunction::ImposeBounds(int i, const Vector &weights,
|
||||
const Vector &lo_, const Vector &hi_)
|
||||
{
|
||||
Array<int> vdofs;
|
||||
DofTransformation * doftrans = fes->GetElementVDofs(i, vdofs);
|
||||
fes->GetElementVDofs(i, vdofs);
|
||||
int size = vdofs.Size();
|
||||
Vector vals, new_vals(size);
|
||||
|
||||
GetSubVector(vdofs, vals);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(vals);
|
||||
}
|
||||
|
||||
MFEM_ASSERT(weights.Size() == size, "Different # of weights and dofs.");
|
||||
MFEM_ASSERT(lo_.Size() == size, "Different # of lower bounds and dofs.");
|
||||
@@ -1912,10 +1825,6 @@ void GridFunction::ImposeBounds(int i, const Vector &weights,
|
||||
slbqp.SetPrintLevel(0); // print messages only if not converged
|
||||
slbqp.Mult(vals, new_vals);
|
||||
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->TransformPrimal(new_vals);
|
||||
}
|
||||
SetSubVector(vdofs, new_vals);
|
||||
}
|
||||
|
||||
@@ -1923,14 +1832,10 @@ void GridFunction::ImposeBounds(int i, const Vector &weights,
|
||||
double min_, double max_)
|
||||
{
|
||||
Array<int> vdofs;
|
||||
DofTransformation * doftrans = fes->GetElementVDofs(i, vdofs);
|
||||
fes->GetElementVDofs(i, vdofs);
|
||||
int size = vdofs.Size();
|
||||
Vector vals, new_vals(size);
|
||||
GetSubVector(vdofs, vals);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(vals);
|
||||
}
|
||||
|
||||
double max_val = vals.Max();
|
||||
double min_val = vals.Min();
|
||||
@@ -1938,10 +1843,6 @@ void GridFunction::ImposeBounds(int i, const Vector &weights,
|
||||
if (max_val <= min_)
|
||||
{
|
||||
new_vals = min_;
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->TransformPrimal(new_vals);
|
||||
}
|
||||
SetSubVector(vdofs, new_vals);
|
||||
return;
|
||||
}
|
||||
@@ -2377,7 +2278,6 @@ void GridFunction::ProjectDeltaCoefficient(DeltaCoefficient &delta_coeff,
|
||||
void GridFunction::ProjectCoefficient(Coefficient &coeff)
|
||||
{
|
||||
DeltaCoefficient *delta_c = dynamic_cast<DeltaCoefficient *>(&coeff);
|
||||
DofTransformation * doftrans = NULL;
|
||||
|
||||
if (delta_c == NULL)
|
||||
{
|
||||
@@ -2386,13 +2286,9 @@ void GridFunction::ProjectCoefficient(Coefficient &coeff)
|
||||
|
||||
for (int i = 0; i < fes->GetNE(); i++)
|
||||
{
|
||||
doftrans = fes->GetElementVDofs(i, vdofs);
|
||||
fes->GetElementVDofs(i, vdofs);
|
||||
vals.SetSize(vdofs.Size());
|
||||
fes->GetFE(i)->Project(coeff, *fes->GetElementTransformation(i), vals);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->TransformPrimal(vals);
|
||||
}
|
||||
SetSubVector(vdofs, vals);
|
||||
}
|
||||
}
|
||||
@@ -2438,17 +2334,11 @@ void GridFunction::ProjectCoefficient(VectorCoefficient &vcoeff)
|
||||
Array<int> vdofs;
|
||||
Vector vals;
|
||||
|
||||
DofTransformation * doftrans = NULL;
|
||||
|
||||
for (i = 0; i < fes->GetNE(); i++)
|
||||
{
|
||||
doftrans = fes->GetElementVDofs(i, vdofs);
|
||||
fes->GetElementVDofs(i, vdofs);
|
||||
vals.SetSize(vdofs.Size());
|
||||
fes->GetFE(i)->Project(vcoeff, *fes->GetElementTransformation(i), vals);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->TransformPrimal(vals);
|
||||
}
|
||||
SetSubVector(vdofs, vals);
|
||||
}
|
||||
}
|
||||
@@ -2511,7 +2401,6 @@ void GridFunction::ProjectCoefficient(Coefficient *coeff[])
|
||||
double val;
|
||||
const FiniteElement *fe;
|
||||
ElementTransformation *transf;
|
||||
// DofTransformation * doftrans;
|
||||
Array<int> vdofs;
|
||||
|
||||
vdim = fes->GetVDim();
|
||||
@@ -2521,7 +2410,6 @@ void GridFunction::ProjectCoefficient(Coefficient *coeff[])
|
||||
fdof = fe->GetDof();
|
||||
transf = fes->GetElementTransformation(i);
|
||||
const IntegrationRule &ir = fe->GetNodes();
|
||||
// doftrans = fes->GetElementVDofs(i, vdofs);
|
||||
fes->GetElementVDofs(i, vdofs);
|
||||
for (j = 0; j < fdof; j++)
|
||||
{
|
||||
|
||||
@@ -910,9 +910,6 @@ IntegrationRules::IntegrationRules(int Ref, int type_):
|
||||
TetrahedronIntRules.SetSize(32, h_mt);
|
||||
TetrahedronIntRules = NULL;
|
||||
|
||||
PyramidIntRules.SetSize(32, h_mt);
|
||||
PyramidIntRules = NULL;
|
||||
|
||||
PrismIntRules.SetSize(32, h_mt);
|
||||
PrismIntRules = NULL;
|
||||
|
||||
@@ -933,7 +930,6 @@ const IntegrationRule &IntegrationRules::Get(int GeomType, int Order)
|
||||
case Geometry::TETRAHEDRON: ir_array = &TetrahedronIntRules; break;
|
||||
case Geometry::CUBE: ir_array = &CubeIntRules; break;
|
||||
case Geometry::PRISM: ir_array = &PrismIntRules; break;
|
||||
case Geometry::PYRAMID: ir_array = &PyramidIntRules; break;
|
||||
default:
|
||||
mfem_error("IntegrationRules::Get(...) : Unknown geometry type!");
|
||||
ir_array = NULL;
|
||||
@@ -980,7 +976,6 @@ void IntegrationRules::Set(int GeomType, int Order, IntegrationRule &IntRule)
|
||||
case Geometry::TETRAHEDRON: ir_array = &TetrahedronIntRules; break;
|
||||
case Geometry::CUBE: ir_array = &CubeIntRules; break;
|
||||
case Geometry::PRISM: ir_array = &PrismIntRules; break;
|
||||
case Geometry::PYRAMID: ir_array = &PyramidIntRules; break;
|
||||
default:
|
||||
mfem_error("IntegrationRules::Set(...) : Unknown geometry type!");
|
||||
ir_array = NULL;
|
||||
@@ -1024,7 +1019,6 @@ IntegrationRules::~IntegrationRules()
|
||||
DeleteIntRuleArray(TetrahedronIntRules);
|
||||
DeleteIntRuleArray(CubeIntRules);
|
||||
DeleteIntRuleArray(PrismIntRules);
|
||||
DeleteIntRuleArray(PyramidIntRules);
|
||||
}
|
||||
|
||||
|
||||
@@ -1047,8 +1041,6 @@ IntegrationRule *IntegrationRules::GenerateIntegrationRule(int GeomType,
|
||||
return CubeIntegrationRule(Order);
|
||||
case Geometry::PRISM:
|
||||
return PrismIntegrationRule(Order);
|
||||
case Geometry::PYRAMID:
|
||||
return PyramidIntegrationRule(Order);
|
||||
default:
|
||||
mfem_error("IntegrationRules::Set(...) : Unknown geometry type!");
|
||||
return NULL;
|
||||
@@ -1656,30 +1648,6 @@ IntegrationRule *IntegrationRules::TetrahedronIntegrationRule(int Order)
|
||||
}
|
||||
}
|
||||
|
||||
// Integration rules for reference pyramid
|
||||
IntegrationRule *IntegrationRules::PyramidIntegrationRule(int Order)
|
||||
{
|
||||
// This is a simple integration rule adapted from an integration
|
||||
// rule for a cube which seems to be adequate for now. When we
|
||||
// implement high order finite elements for pyramids we should
|
||||
// revisit this and see if we can improve upon it.
|
||||
const IntegrationRule &irc = Get(Geometry::CUBE, Order);
|
||||
int npts = irc.GetNPoints();
|
||||
AllocIntRule(PyramidIntRules, Order);
|
||||
PyramidIntRules[Order] = new IntegrationRule(npts);
|
||||
|
||||
for (int k=0; k<npts; k++)
|
||||
{
|
||||
const IntegrationPoint & ipc = irc.IntPoint(k);
|
||||
IntegrationPoint & ipp = PyramidIntRules[Order]->IntPoint(k);
|
||||
ipp.x = ipc.x * (1.0 - ipc.z);
|
||||
ipp.y = ipc.y * (1.0 - ipc.z);
|
||||
ipp.z = ipc.z;
|
||||
ipp.weight = ipc.weight / 3.0;
|
||||
}
|
||||
return PyramidIntRules[Order];
|
||||
}
|
||||
|
||||
// Integration rules for reference prism
|
||||
IntegrationRule *IntegrationRules::PrismIntegrationRule(int Order)
|
||||
{
|
||||
|
||||
@@ -323,7 +323,6 @@ private:
|
||||
Array<IntegrationRule *> TriangleIntRules;
|
||||
Array<IntegrationRule *> SquareIntRules;
|
||||
Array<IntegrationRule *> TetrahedronIntRules;
|
||||
Array<IntegrationRule *> PyramidIntRules;
|
||||
Array<IntegrationRule *> PrismIntRules;
|
||||
Array<IntegrationRule *> CubeIntRules;
|
||||
|
||||
@@ -352,7 +351,6 @@ private:
|
||||
IntegrationRule *TriangleIntegrationRule(int Order);
|
||||
IntegrationRule *SquareIntegrationRule(int Order);
|
||||
IntegrationRule *TetrahedronIntegrationRule(int Order);
|
||||
IntegrationRule *PyramidIntegrationRule(int Order);
|
||||
IntegrationRule *PrismIntegrationRule(int Order);
|
||||
IntegrationRule *CubeIntegrationRule(int Order);
|
||||
|
||||
|
||||
+2
-11
@@ -103,7 +103,6 @@ void LinearForm::Assemble()
|
||||
{
|
||||
Array<int> vdofs;
|
||||
ElementTransformation *eltrans;
|
||||
DofTransformation *doftrans;
|
||||
Vector elemvect;
|
||||
|
||||
int i;
|
||||
@@ -135,14 +134,10 @@ void LinearForm::Assemble()
|
||||
if ( domain_integs_marker[k] == NULL ||
|
||||
(*(domain_integs_marker[k]))[elem_attr-1] == 1 )
|
||||
{
|
||||
doftrans = fes -> GetElementVDofs (i, vdofs);
|
||||
fes -> GetElementVDofs (i, vdofs);
|
||||
eltrans = fes -> GetElementTransformation (i);
|
||||
domain_integs[k]->AssembleRHSElementVect(*fes->GetFE(i),
|
||||
*eltrans, elemvect);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->TransformDual(elemvect);
|
||||
}
|
||||
AddElementVector (vdofs, elemvect);
|
||||
}
|
||||
}
|
||||
@@ -179,7 +174,7 @@ void LinearForm::Assemble()
|
||||
{
|
||||
const int bdr_attr = mesh->GetBdrAttribute(i);
|
||||
if (bdr_attr_marker[bdr_attr-1] == 0) { continue; }
|
||||
doftrans = fes -> GetBdrElementVDofs (i, vdofs);
|
||||
fes -> GetBdrElementVDofs (i, vdofs);
|
||||
eltrans = fes -> GetBdrElementTransformation (i);
|
||||
for (int k=0; k < boundary_integs.Size(); k++)
|
||||
{
|
||||
@@ -189,10 +184,6 @@ void LinearForm::Assemble()
|
||||
boundary_integs[k]->AssembleRHSElementVect(*fes->GetBE(i),
|
||||
*eltrans, elemvect);
|
||||
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->TransformDual(elemvect);
|
||||
}
|
||||
AddElementVector (vdofs, elemvect);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,15 +116,15 @@ void VectorConvectionNLFIntegrator::AssemblePA(const FiniteElementSpace &fes)
|
||||
|
||||
// PA Convection NL 2D kernel
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void PAConvectionNLApply2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Vector &q_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PAConvectionNLApply2D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Vector &q_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -252,15 +252,15 @@ void PAConvectionNLApply2D(const int NE,
|
||||
|
||||
// PA Convection NL 3D kernel
|
||||
template<int T_D1D = 0, int T_Q1D = 0>
|
||||
void PAConvectionNLApply3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Vector &q_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void PAConvectionNLApply3D(const int NE,
|
||||
const Array<double> &b,
|
||||
const Array<double> &g,
|
||||
const Array<double> &bt,
|
||||
const Vector &q_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
constexpr int VDIM = 3;
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
@@ -558,14 +558,14 @@ void PAConvectionNLApply3D(const int NE,
|
||||
}
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int T_MAX_D1D =0, int T_MAX_Q1D =0>
|
||||
void SmemPAConvectionNLApply3D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void SmemPAConvectionNLApply3D(const int NE,
|
||||
const Array<double> &b_,
|
||||
const Array<double> &g_,
|
||||
const Vector &d_,
|
||||
const Vector &x_,
|
||||
Vector &y_,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
constexpr int VDIM = 3;
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
|
||||
@@ -321,7 +321,6 @@ const
|
||||
{
|
||||
X.SetSpace(pfes);
|
||||
Y.SetSpace(pfes);
|
||||
Ytmp.SetSize(pfes->GetTrueVSize());
|
||||
}
|
||||
|
||||
X.Distribute(&x);
|
||||
@@ -336,8 +335,7 @@ const
|
||||
" implemented");
|
||||
mat->Mult(X, Y);
|
||||
}
|
||||
pfes->GetProlongationMatrix()->MultTranspose(Y, Ytmp);
|
||||
y.Add(a,Ytmp);
|
||||
pfes->Dof_TrueDof_Matrix()->MultTranspose(a, Y, 1.0, y);
|
||||
}
|
||||
|
||||
void ParBilinearForm::FormLinearSystem(
|
||||
|
||||
@@ -33,7 +33,6 @@ protected:
|
||||
|
||||
/// Auxiliary objects used in TrueAddMult().
|
||||
mutable ParGridFunction X, Y;
|
||||
mutable Vector Ytmp;
|
||||
|
||||
OperatorHandle p_mat, p_mat_e;
|
||||
|
||||
|
||||
+53
-319
@@ -128,9 +128,6 @@ void ParFiniteElementSpace::ParInit(ParMesh *pm)
|
||||
{
|
||||
ApplyLDofSigns(*elem_dof);
|
||||
}
|
||||
|
||||
// Check for shared trianglular faces with interior Nedelec DoFs
|
||||
CheckNDSTriaDofs();
|
||||
}
|
||||
|
||||
void ParFiniteElementSpace::Construct()
|
||||
@@ -467,53 +464,32 @@ void ParFiniteElementSpace::ApplyLDofSigns(Table &el_dof) const
|
||||
ApplyLDofSigns(all_dofs);
|
||||
}
|
||||
|
||||
DofTransformation *
|
||||
ParFiniteElementSpace::GetElementDofs(int i, Array<int> &dofs) const
|
||||
void ParFiniteElementSpace::GetElementDofs(int i, Array<int> &dofs) const
|
||||
{
|
||||
if (elem_dof)
|
||||
{
|
||||
elem_dof->GetRow(i, dofs);
|
||||
|
||||
if (DoFTrans[mesh->GetElementBaseGeometry(i)])
|
||||
{
|
||||
Array<int> Fo;
|
||||
elem_fos->GetRow(i, Fo);
|
||||
DoFTrans[mesh->GetElementBaseGeometry(i)]->SetFaceOrientations(Fo);
|
||||
return DoFTrans[mesh->GetElementBaseGeometry(i)];
|
||||
}
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
DofTransformation * doftrans = FiniteElementSpace::GetElementDofs(i, dofs);
|
||||
FiniteElementSpace::GetElementDofs(i, dofs);
|
||||
if (Conforming())
|
||||
{
|
||||
ApplyLDofSigns(dofs);
|
||||
}
|
||||
return doftrans;
|
||||
}
|
||||
|
||||
DofTransformation *
|
||||
ParFiniteElementSpace::GetBdrElementDofs(int i, Array<int> &dofs) const
|
||||
void ParFiniteElementSpace::GetBdrElementDofs(int i, Array<int> &dofs) const
|
||||
{
|
||||
if (bdr_elem_dof)
|
||||
{
|
||||
bdr_elem_dof->GetRow(i, dofs);
|
||||
|
||||
if (DoFTrans[mesh->GetBdrElementBaseGeometry(i)])
|
||||
{
|
||||
Array<int> Fo;
|
||||
bdr_elem_fos -> GetRow (i, Fo);
|
||||
DoFTrans[mesh->GetBdrElementBaseGeometry(i)]->SetFaceOrientations(Fo);
|
||||
return DoFTrans[mesh->GetBdrElementBaseGeometry(i)];
|
||||
}
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
DofTransformation * doftrans =
|
||||
FiniteElementSpace::GetBdrElementDofs(i, dofs);
|
||||
FiniteElementSpace::GetBdrElementDofs(i, dofs);
|
||||
if (Conforming())
|
||||
{
|
||||
ApplyLDofSigns(dofs);
|
||||
}
|
||||
return doftrans;
|
||||
}
|
||||
|
||||
int ParFiniteElementSpace::GetFaceDofs(int i, Array<int> &dofs,
|
||||
@@ -681,267 +657,60 @@ void ParFiniteElementSpace::GenerateGlobalOffsets() const
|
||||
}
|
||||
}
|
||||
|
||||
void ParFiniteElementSpace::CheckNDSTriaDofs()
|
||||
{
|
||||
// Check for Nedelec basis
|
||||
bool nd_basis = dynamic_cast<const ND_FECollection*>(fec);
|
||||
if (!nd_basis)
|
||||
{
|
||||
nd_strias = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for interior face dofs on triangles (the use of TETRAHEDRON
|
||||
// is not an error)
|
||||
bool nd_fdof = fec->HasFaceDofs(Geometry::TETRAHEDRON,
|
||||
GetMaxElementOrder());
|
||||
if (!nd_fdof)
|
||||
{
|
||||
nd_strias = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for shared triangle faces
|
||||
bool strias = false;
|
||||
{
|
||||
int ngrps = pmesh->GetNGroups();
|
||||
for (int g = 1; g < ngrps; g++)
|
||||
{
|
||||
strias |= pmesh->GroupNTriangles(g);
|
||||
}
|
||||
}
|
||||
|
||||
// Combine results
|
||||
int loc_nd_strias = strias ? 1 : 0;
|
||||
int glb_nd_strias = 0;
|
||||
MPI_Allreduce(&loc_nd_strias, &glb_nd_strias, 1,
|
||||
MPI_INTEGER, MPI_SUM, MyComm);
|
||||
nd_strias = glb_nd_strias > 0;
|
||||
}
|
||||
|
||||
void ParFiniteElementSpace::Build_Dof_TrueDof_Matrix() const // matrix P
|
||||
{
|
||||
MFEM_ASSERT(Conforming(), "wrong code path");
|
||||
|
||||
if (P) { return; }
|
||||
|
||||
if (!nd_strias)
|
||||
int ldof = GetVSize();
|
||||
int ltdof = TrueVSize();
|
||||
|
||||
HYPRE_Int *i_diag = Memory<HYPRE_Int>(ldof+1);
|
||||
HYPRE_Int *j_diag = Memory<HYPRE_Int>(ltdof);
|
||||
int diag_counter;
|
||||
|
||||
HYPRE_Int *i_offd = Memory<HYPRE_Int>(ldof+1);
|
||||
HYPRE_Int *j_offd = Memory<HYPRE_Int>(ldof-ltdof);
|
||||
int offd_counter;
|
||||
|
||||
HYPRE_BigInt *cmap = Memory<HYPRE_BigInt>(ldof-ltdof);
|
||||
|
||||
HYPRE_BigInt *col_starts = GetTrueDofOffsets();
|
||||
HYPRE_BigInt *row_starts = GetDofOffsets();
|
||||
|
||||
Array<Pair<HYPRE_BigInt, int> > cmap_j_offd(ldof-ltdof);
|
||||
|
||||
i_diag[0] = i_offd[0] = 0;
|
||||
diag_counter = offd_counter = 0;
|
||||
for (int i = 0; i < ldof; i++)
|
||||
{
|
||||
// Safe to assume 1-1 correspondence between shared dofs
|
||||
int ldof = GetVSize();
|
||||
int ltdof = TrueVSize();
|
||||
|
||||
HYPRE_Int *i_diag = Memory<HYPRE_Int>(ldof+1);
|
||||
HYPRE_Int *j_diag = Memory<HYPRE_Int>(ltdof);
|
||||
int diag_counter;
|
||||
|
||||
HYPRE_Int *i_offd = Memory<HYPRE_Int>(ldof+1);
|
||||
HYPRE_Int *j_offd = Memory<HYPRE_Int>(ldof-ltdof);
|
||||
int offd_counter;
|
||||
|
||||
HYPRE_BigInt *cmap = Memory<HYPRE_BigInt>(ldof-ltdof);
|
||||
|
||||
HYPRE_BigInt *col_starts = GetTrueDofOffsets();
|
||||
HYPRE_BigInt *row_starts = GetDofOffsets();
|
||||
|
||||
Array<Pair<HYPRE_BigInt, int> > cmap_j_offd(ldof-ltdof);
|
||||
|
||||
i_diag[0] = i_offd[0] = 0;
|
||||
diag_counter = offd_counter = 0;
|
||||
for (int i = 0; i < ldof; i++)
|
||||
int ltdof = GetLocalTDofNumber(i);
|
||||
if (ltdof >= 0)
|
||||
{
|
||||
int ltdof = GetLocalTDofNumber(i);
|
||||
if (ltdof >= 0)
|
||||
{
|
||||
j_diag[diag_counter++] = ltdof;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmap_j_offd[offd_counter].one = GetGlobalTDofNumber(i);
|
||||
cmap_j_offd[offd_counter].two = offd_counter;
|
||||
offd_counter++;
|
||||
}
|
||||
i_diag[i+1] = diag_counter;
|
||||
i_offd[i+1] = offd_counter;
|
||||
j_diag[diag_counter++] = ltdof;
|
||||
}
|
||||
|
||||
SortPairs<HYPRE_BigInt, int>(cmap_j_offd, offd_counter);
|
||||
|
||||
for (int i = 0; i < offd_counter; i++)
|
||||
else
|
||||
{
|
||||
cmap[i] = cmap_j_offd[i].one;
|
||||
j_offd[cmap_j_offd[i].two] = i;
|
||||
cmap_j_offd[offd_counter].one = GetGlobalTDofNumber(i);
|
||||
cmap_j_offd[offd_counter].two = offd_counter;
|
||||
offd_counter++;
|
||||
}
|
||||
|
||||
P = new HypreParMatrix(MyComm, MyRank, NRanks, row_starts, col_starts,
|
||||
i_diag, j_diag, i_offd, j_offd,
|
||||
cmap, offd_counter);
|
||||
i_diag[i+1] = diag_counter;
|
||||
i_offd[i+1] = offd_counter;
|
||||
}
|
||||
else
|
||||
|
||||
SortPairs<HYPRE_BigInt, int>(cmap_j_offd, offd_counter);
|
||||
|
||||
for (int i = 0; i < offd_counter; i++)
|
||||
{
|
||||
// Some shared dofs will be linear combinations of others
|
||||
int ldof = GetVSize();
|
||||
int ltdof = TrueVSize();
|
||||
|
||||
HYPRE_Int gdof = -1;
|
||||
HYPRE_Int gtdof = -1;
|
||||
|
||||
MPI_Allreduce(&ldof, &gdof, 1, HYPRE_MPI_INT, MPI_SUM, MyComm);
|
||||
MPI_Allreduce(<dof, >dof, 1, HYPRE_MPI_INT, MPI_SUM, MyComm);
|
||||
|
||||
// Ensure face orientations have been communicated
|
||||
pmesh->ExchangeFaceNbrData();
|
||||
|
||||
// Locate and count non-zeros in off-diagonal portion of P
|
||||
int nnz_offd = 0;
|
||||
Array<int> ldsize(ldof); ldsize = 0;
|
||||
Array<int> ltori(ldof); ltori = 0; // Local triangle orientations
|
||||
{
|
||||
int ngrps = pmesh->GetNGroups();
|
||||
int nedofs = fec->DofForGeometry(Geometry::SEGMENT);
|
||||
Array<int> sdofs;
|
||||
for (int g = 1; g < ngrps; g++)
|
||||
{
|
||||
if (pmesh->gtopo.IAmMaster(g))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (int ei=0; ei<pmesh->GroupNEdges(g); ei++)
|
||||
{
|
||||
this->GetSharedEdgeDofs(g, ei, sdofs);
|
||||
for (int i=0; i<sdofs.Size(); i++)
|
||||
{
|
||||
int ind = (sdofs[i]>=0) ? sdofs[i] : (-sdofs[i]-1);
|
||||
if (ldsize[ind] == 0) { nnz_offd++; }
|
||||
ldsize[ind] = 1;
|
||||
}
|
||||
}
|
||||
for (int fi=0; fi<pmesh->GroupNTriangles(g); fi++)
|
||||
{
|
||||
int face, ori, info1, info2;
|
||||
pmesh->GroupTriangle(g, fi, face, ori);
|
||||
pmesh->GetFaceInfos(face, &info1, &info2);
|
||||
this->GetSharedTriangleDofs(g, fi, sdofs);
|
||||
for (int i=0; i<3*nedofs; i++)
|
||||
{
|
||||
int ind = (sdofs[i]>=0) ? sdofs[i] : (-sdofs[i]-1);
|
||||
if (ldsize[ind] == 0) { nnz_offd++; }
|
||||
ldsize[ind] = 1;
|
||||
}
|
||||
for (int i=3*nedofs; i<sdofs.Size(); i++)
|
||||
{
|
||||
if (ldsize[sdofs[i]] == 0) { nnz_offd += 2; }
|
||||
ldsize[sdofs[i]] = 2;
|
||||
ltori[sdofs[i]] = info2 % 64;
|
||||
}
|
||||
}
|
||||
for (int fi=0; fi<pmesh->GroupNQuadrilaterals(g); fi++)
|
||||
{
|
||||
this->GetSharedQuadrilateralDofs(g, fi, sdofs);
|
||||
for (int i=0; i<sdofs.Size(); i++)
|
||||
{
|
||||
int ind = (sdofs[i]>=0) ? sdofs[i] : (-sdofs[i]-1);
|
||||
if (ldsize[ind] == 0) { nnz_offd++; }
|
||||
ldsize[ind] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HYPRE_Int *i_diag = new HYPRE_Int[ldof+1];
|
||||
HYPRE_Int *j_diag = new HYPRE_Int[ltdof];
|
||||
double *d_diag = new double[ltdof];
|
||||
int diag_counter;
|
||||
|
||||
HYPRE_Int *i_offd = new HYPRE_Int[ldof+1];
|
||||
HYPRE_Int *j_offd = new HYPRE_Int[nnz_offd];
|
||||
double *d_offd = new double[nnz_offd];
|
||||
int offd_counter;
|
||||
|
||||
HYPRE_BigInt *cmap = new HYPRE_BigInt[ldof-ltdof];
|
||||
|
||||
HYPRE_BigInt *col_starts = GetTrueDofOffsets();
|
||||
HYPRE_BigInt *row_starts = GetDofOffsets();
|
||||
|
||||
Array<Pair<HYPRE_BigInt, int> > cmap_j_offd(ldof-ltdof);
|
||||
|
||||
i_diag[0] = i_offd[0] = 0;
|
||||
diag_counter = offd_counter = 0;
|
||||
int offd_col_counter = 0;
|
||||
for (int i = 0; i < ldof; i++)
|
||||
{
|
||||
int ltdof = GetLocalTDofNumber(i);
|
||||
if (ltdof >= 0)
|
||||
{
|
||||
j_diag[diag_counter] = ltdof;
|
||||
d_diag[diag_counter++] = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ldsize[i] == 1)
|
||||
{
|
||||
cmap_j_offd[offd_col_counter].one = GetGlobalTDofNumber(i);
|
||||
cmap_j_offd[offd_col_counter].two = offd_counter;
|
||||
offd_counter++;
|
||||
offd_col_counter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmap_j_offd[offd_col_counter].one = GetGlobalTDofNumber(i);
|
||||
cmap_j_offd[offd_col_counter].two = offd_counter;
|
||||
offd_counter += 2;
|
||||
offd_col_counter++;
|
||||
i_diag[i+1] = diag_counter;
|
||||
i_offd[i+1] = offd_counter;
|
||||
i++;
|
||||
cmap_j_offd[offd_col_counter].one = GetGlobalTDofNumber(i);
|
||||
cmap_j_offd[offd_col_counter].two = offd_counter;
|
||||
offd_counter += 2;
|
||||
offd_col_counter++;
|
||||
}
|
||||
}
|
||||
i_diag[i+1] = diag_counter;
|
||||
i_offd[i+1] = offd_counter;
|
||||
}
|
||||
|
||||
SortPairs<HYPRE_BigInt, int>(cmap_j_offd, offd_col_counter);
|
||||
|
||||
for (int i = 0; i < nnz_offd; i++)
|
||||
{
|
||||
j_offd[i] = -1;
|
||||
d_offd[i] = 0.0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < offd_col_counter; i++)
|
||||
{
|
||||
cmap[i] = cmap_j_offd[i].one;
|
||||
j_offd[cmap_j_offd[i].two] = i;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ldof; i++)
|
||||
{
|
||||
if (i_offd[i+1] == i_offd[i] + 1)
|
||||
{
|
||||
d_offd[i_offd[i]] = 1.0;
|
||||
}
|
||||
else if (i_offd[i+1] == i_offd[i] + 2)
|
||||
{
|
||||
const double * T = ND_DofTransformation
|
||||
::GetFaceTransform(ltori[i]).GetData();
|
||||
j_offd[i_offd[i] + 1] = j_offd[i_offd[i]] + 1;
|
||||
d_offd[i_offd[i]] = T[0]; d_offd[i_offd[i] + 1] = T[2];
|
||||
i++;
|
||||
j_offd[i_offd[i] + 1] = j_offd[i_offd[i]];
|
||||
j_offd[i_offd[i]] = j_offd[i_offd[i] + 1] - 1;
|
||||
d_offd[i_offd[i]] = T[1]; d_offd[i_offd[i] + 1] = T[3];
|
||||
}
|
||||
}
|
||||
|
||||
P = new HypreParMatrix(MyComm, gdof, gtdof, row_starts, col_starts,
|
||||
i_diag, j_diag, d_diag, i_offd, j_offd, d_offd,
|
||||
offd_col_counter, cmap);
|
||||
cmap[i] = cmap_j_offd[i].one;
|
||||
j_offd[cmap_j_offd[i].two] = i;
|
||||
}
|
||||
|
||||
P = new HypreParMatrix(MyComm, MyRank, NRanks, row_starts, col_starts,
|
||||
i_diag, j_diag, i_offd, j_offd, cmap, offd_counter);
|
||||
|
||||
SparseMatrix Pdiag;
|
||||
P->GetDiag(Pdiag);
|
||||
R = Transpose(Pdiag);
|
||||
@@ -1144,8 +913,6 @@ const Operator *ParFiniteElementSpace::GetProlongationMatrix() const
|
||||
{
|
||||
if (Pconf) { return Pconf; }
|
||||
|
||||
if (nd_strias) { return Dof_TrueDof_Matrix(); }
|
||||
|
||||
if (NRanks == 1)
|
||||
{
|
||||
Pconf = new IdentityOperator(GetTrueVSize());
|
||||
@@ -1449,29 +1216,10 @@ void ParFiniteElementSpace::ExchangeFaceNbrData()
|
||||
delete [] requests;
|
||||
}
|
||||
|
||||
DofTransformation *ParFiniteElementSpace::GetFaceNbrElementVDofs(
|
||||
void ParFiniteElementSpace::GetFaceNbrElementVDofs(
|
||||
int i, Array<int> &vdofs) const
|
||||
{
|
||||
face_nbr_element_dof.GetRow(i, vdofs);
|
||||
|
||||
DofTransformation *doftrans = NULL;
|
||||
Geometry::Type geom = GetFaceNbrFE(i)->GetGeomType();
|
||||
if (DoFTrans[geom])
|
||||
{
|
||||
Array<int> F, Fo;
|
||||
pmesh->GetFaceNbrElementFaces(pmesh->GetNE() + i, F, Fo);
|
||||
doftrans = DoFTrans[geom];
|
||||
doftrans->SetFaceOrientations(Fo);
|
||||
}
|
||||
if (vdim == 1 || doftrans == NULL)
|
||||
{
|
||||
return doftrans;
|
||||
}
|
||||
else
|
||||
{
|
||||
VDoFTrans.SetDofTransformation(*doftrans);
|
||||
return &VDoFTrans;
|
||||
}
|
||||
}
|
||||
|
||||
void ParFiniteElementSpace::GetFaceNbrFaceVDofs(int i, Array<int> &vdofs) const
|
||||
@@ -1530,17 +1278,12 @@ const FiniteElement *ParFiniteElementSpace::GetFaceNbrFaceFE(int i) const
|
||||
|
||||
void ParFiniteElementSpace::Lose_Dof_TrueDof_Matrix()
|
||||
{
|
||||
P -> StealData();
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
hypre_ParCSRMatrix *csrP = (hypre_ParCSRMatrix*)(*P);
|
||||
hypre_ParCSRMatrixOwnsRowStarts(csrP) = 1;
|
||||
hypre_ParCSRMatrixOwnsColStarts(csrP) = 1;
|
||||
P -> StealData();
|
||||
dof_offsets.LoseData();
|
||||
tdof_offsets.LoseData();
|
||||
#else
|
||||
dof_offsets.DeleteAll();
|
||||
tdof_offsets.DeleteAll();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ParFiniteElementSpace::ConstructTrueDofs()
|
||||
@@ -2783,8 +2526,7 @@ static int_type* make_j_array(int_type* I, int nrows)
|
||||
|
||||
HypreParMatrix*
|
||||
ParFiniteElementSpace::RebalanceMatrix(int old_ndofs,
|
||||
const Table* old_elem_dof,
|
||||
const Table* old_elem_fos)
|
||||
const Table* old_elem_dof)
|
||||
{
|
||||
MFEM_VERIFY(Nonconforming(), "Only supported for nonconforming meshes.");
|
||||
MFEM_VERIFY(old_dof_offsets.Size(), "ParFiniteElementSpace::Update needs to "
|
||||
@@ -2909,8 +2651,7 @@ struct DerefDofMessage
|
||||
|
||||
HypreParMatrix*
|
||||
ParFiniteElementSpace::ParallelDerefinementMatrix(int old_ndofs,
|
||||
const Table* old_elem_dof,
|
||||
const Table *old_elem_fos)
|
||||
const Table* old_elem_dof)
|
||||
{
|
||||
int nrk = HYPRE_AssumedPartitionCheck() ? 2 : NRanks;
|
||||
|
||||
@@ -3266,16 +3007,13 @@ void ParFiniteElementSpace::Update(bool want_transform)
|
||||
}
|
||||
|
||||
Table* old_elem_dof = NULL;
|
||||
Table* old_elem_fos = NULL;
|
||||
int old_ndofs;
|
||||
|
||||
// save old DOF table
|
||||
if (want_transform)
|
||||
{
|
||||
old_elem_dof = elem_dof;
|
||||
old_elem_fos = elem_fos;
|
||||
elem_dof = NULL;
|
||||
elem_fos = NULL;
|
||||
old_ndofs = ndofs;
|
||||
Swap(dof_offsets, old_dof_offsets);
|
||||
}
|
||||
@@ -3297,25 +3035,22 @@ void ParFiniteElementSpace::Update(bool want_transform)
|
||||
{
|
||||
if (Th.Type() != Operator::MFEM_SPARSEMAT)
|
||||
{
|
||||
Th.Reset(new RefinementOperator(this, old_elem_dof,
|
||||
old_elem_fos, old_ndofs));
|
||||
Th.Reset(new RefinementOperator(this, old_elem_dof, old_ndofs));
|
||||
// The RefinementOperator takes ownership of 'old_elem_dofs', so
|
||||
// we no longer own it:
|
||||
old_elem_dof = NULL;
|
||||
old_elem_fos = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate fully assembled matrix
|
||||
Th.Reset(RefinementMatrix(old_ndofs, old_elem_dof, old_elem_fos));
|
||||
Th.Reset(RefinementMatrix(old_ndofs, old_elem_dof));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Mesh::DEREFINE:
|
||||
{
|
||||
Th.Reset(ParallelDerefinementMatrix(old_ndofs, old_elem_dof,
|
||||
old_elem_fos));
|
||||
Th.Reset(ParallelDerefinementMatrix(old_ndofs, old_elem_dof));
|
||||
if (Nonconforming())
|
||||
{
|
||||
Th.SetOperatorOwner(false);
|
||||
@@ -3327,7 +3062,7 @@ void ParFiniteElementSpace::Update(bool want_transform)
|
||||
|
||||
case Mesh::REBALANCE:
|
||||
{
|
||||
Th.Reset(RebalanceMatrix(old_ndofs, old_elem_dof, old_elem_fos));
|
||||
Th.Reset(RebalanceMatrix(old_ndofs, old_elem_dof));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3336,7 +3071,6 @@ void ParFiniteElementSpace::Update(bool want_transform)
|
||||
}
|
||||
|
||||
delete old_elem_dof;
|
||||
delete old_elem_fos;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-17
@@ -87,12 +87,6 @@ private:
|
||||
this is a TransposeOperator wrapping R. */
|
||||
mutable Operator *R_transpose;
|
||||
|
||||
/// Flag indicating the existence of shared triangles with interior ND dofs
|
||||
bool nd_strias;
|
||||
|
||||
/// Resets nd_strias flag at constuction or after rebalancing
|
||||
void CheckNDSTriaDofs();
|
||||
|
||||
ParNURBSExtension *pNURBSext() const
|
||||
{ return dynamic_cast<ParNURBSExtension *>(NURBSext); }
|
||||
|
||||
@@ -180,16 +174,14 @@ private:
|
||||
The result is a parallel permutation matrix that can be used to update
|
||||
all grid functions defined on this space. */
|
||||
HypreParMatrix* RebalanceMatrix(int old_ndofs,
|
||||
const Table* old_elem_dof,
|
||||
const Table* old_elem_fos);
|
||||
const Table* old_elem_dof);
|
||||
|
||||
/** Calculate a GridFunction restriction matrix after mesh derefinement.
|
||||
The matrix is constructed so that the new grid function interpolates
|
||||
the original function, i.e., the original function is evaluated at the
|
||||
nodes of the coarse function. */
|
||||
HypreParMatrix* ParallelDerefinementMatrix(int old_ndofs,
|
||||
const Table *old_elem_dof,
|
||||
const Table *old_elem_fos);
|
||||
const Table *old_elem_dof);
|
||||
|
||||
/// Updates the internal mesh pointer. @warning @a new_mesh must be
|
||||
/// <b>topologically identical</b> to the existing mesh. Used if the address
|
||||
@@ -210,8 +202,6 @@ public:
|
||||
int num_face_nbr_dofs;
|
||||
// Face-neighbor-element to face-neighbor dof
|
||||
Table face_nbr_element_dof;
|
||||
// Face-neighbor-element face orientations
|
||||
Table face_nbr_element_fos;
|
||||
// Face-neighbor to ldof in the face-neighbor numbering
|
||||
Table face_nbr_ldof;
|
||||
// The global ldof indices of the face-neighbor dofs
|
||||
@@ -289,10 +279,10 @@ public:
|
||||
virtual int GetTrueVSize() const { return ltdof_size; }
|
||||
|
||||
/// Returns indexes of degrees of freedom in array dofs for i'th element.
|
||||
virtual DofTransformation *GetElementDofs(int i, Array<int> &dofs) const;
|
||||
virtual void GetElementDofs(int i, Array<int> &dofs) const;
|
||||
|
||||
/// Returns indexes of degrees of freedom for i'th boundary element.
|
||||
virtual DofTransformation *GetBdrElementDofs(int i, Array<int> &dofs) const;
|
||||
virtual void GetBdrElementDofs(int i, Array<int> &dofs) const;
|
||||
|
||||
/** Returns the indexes of the degrees of freedom for i'th face
|
||||
including the dofs for the edges and the vertices of the face. */
|
||||
@@ -392,7 +382,7 @@ public:
|
||||
// Face-neighbor functions
|
||||
void ExchangeFaceNbrData();
|
||||
int GetFaceNbrVSize() const { return num_face_nbr_dofs; }
|
||||
DofTransformation *GetFaceNbrElementVDofs(int i, Array<int> &vdofs) const;
|
||||
void GetFaceNbrElementVDofs(int i, Array<int> &vdofs) const;
|
||||
void GetFaceNbrFaceVDofs(int i, Array<int> &vdofs) const;
|
||||
const FiniteElement *GetFaceNbrFE(int i) const;
|
||||
const FiniteElement *GetFaceNbrFaceFE(int i) const;
|
||||
@@ -407,8 +397,6 @@ public:
|
||||
bool Conforming() const { return pmesh->pncmesh == NULL && !nonconf_P; }
|
||||
bool Nonconforming() const { return pmesh->pncmesh != NULL || nonconf_P; }
|
||||
|
||||
bool SharedNDTriangleDofs() const { return nd_strias; }
|
||||
|
||||
// Transfer parallel true-dof data from coarse_fes, defined on a coarse mesh,
|
||||
// to this FE space, defined on a refined mesh. See full documentation in the
|
||||
// base class, FiniteElementSpace::GetTrueTransferOperator.
|
||||
|
||||
+2
-12
@@ -325,14 +325,9 @@ void ParGridFunction::GetVectorValue(int i, const IntegrationPoint &ip,
|
||||
if (nbr_el_no >= 0)
|
||||
{
|
||||
Array<int> dofs;
|
||||
DofTransformation * doftrans = pfes->GetFaceNbrElementVDofs(nbr_el_no,
|
||||
dofs);
|
||||
pfes->GetFaceNbrElementVDofs(nbr_el_no, dofs);
|
||||
Vector loc_data;
|
||||
face_nbr_data.GetSubVector(dofs, loc_data);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(loc_data);
|
||||
}
|
||||
const FiniteElement *FElem = pfes->GetFaceNbrFE(nbr_el_no);
|
||||
int dof = FElem->GetDof();
|
||||
if (FElem->GetRangeType() == FiniteElement::SCALAR)
|
||||
@@ -442,17 +437,12 @@ void ParGridFunction::GetVectorValue(ElementTransformation &T,
|
||||
}
|
||||
|
||||
Array<int> vdofs;
|
||||
DofTransformation * doftrans = pfes->GetFaceNbrElementVDofs(nbr_el_no,
|
||||
vdofs);
|
||||
pfes->GetFaceNbrElementVDofs(nbr_el_no, vdofs);
|
||||
const FiniteElement *fe = pfes->GetFaceNbrFE(nbr_el_no);
|
||||
|
||||
int dof = fe->GetDof();
|
||||
Vector loc_data;
|
||||
face_nbr_data.GetSubVector(vdofs, loc_data);
|
||||
if (doftrans)
|
||||
{
|
||||
doftrans->InvTransformPrimal(loc_data);
|
||||
}
|
||||
if (fe->GetRangeType() == FiniteElement::SCALAR)
|
||||
{
|
||||
Vector shape(dof);
|
||||
|
||||
+17
-17
@@ -27,14 +27,14 @@ namespace quadrature_interpolator
|
||||
{
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int MAX_D1D = 0, int MAX_Q1D = 0>
|
||||
void Det2D(const int NE,
|
||||
const double *b,
|
||||
const double *g,
|
||||
const double *x,
|
||||
double *y,
|
||||
const int vdim = 1,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void Det2D(const int NE,
|
||||
const double *b,
|
||||
const double *g,
|
||||
const double *x,
|
||||
double *y,
|
||||
const int vdim = 1,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
constexpr int DIM = 2;
|
||||
static constexpr int NBZ = 1;
|
||||
@@ -79,15 +79,15 @@ void Det2D(const int NE,
|
||||
|
||||
template<int T_D1D = 0, int T_Q1D = 0, int MAX_D1D = 0, int MAX_Q1D = 0,
|
||||
bool SMEM = true>
|
||||
void Det3D(const int NE,
|
||||
const double *b,
|
||||
const double *g,
|
||||
const double *x,
|
||||
double *y,
|
||||
const int vdim = 1,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0,
|
||||
Vector *d_buff = nullptr) // used only with SMEM = false
|
||||
static void Det3D(const int NE,
|
||||
const double *b,
|
||||
const double *g,
|
||||
const double *x,
|
||||
double *y,
|
||||
const int vdim = 1,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0,
|
||||
Vector *d_buff = nullptr) // used only with SMEM = false
|
||||
{
|
||||
constexpr int DIM = 3;
|
||||
static constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
|
||||
|
||||
+14
-14
@@ -31,13 +31,13 @@ namespace quadrature_interpolator
|
||||
template<QVectorLayout Q_LAYOUT,
|
||||
int T_VDIM = 0, int T_D1D = 0, int T_Q1D = 0,
|
||||
int T_NBZ = 1, int MAX_D1D = 0, int MAX_Q1D = 0>
|
||||
void Values2D(const int NE,
|
||||
const double *b_,
|
||||
const double *x_,
|
||||
double *y_,
|
||||
const int vdim = 0,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void Values2D(const int NE,
|
||||
const double *b_,
|
||||
const double *x_,
|
||||
double *y_,
|
||||
const int vdim = 0,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
static constexpr int NBZ = T_NBZ ? T_NBZ : 1;
|
||||
|
||||
@@ -95,13 +95,13 @@ void Values2D(const int NE,
|
||||
template<QVectorLayout Q_LAYOUT,
|
||||
int T_VDIM = 0, int T_D1D = 0, int T_Q1D = 0,
|
||||
int MAX_D1D = 0, int MAX_Q1D = 0>
|
||||
void Values3D(const int NE,
|
||||
const double *b_,
|
||||
const double *x_,
|
||||
double *y_,
|
||||
const int vdim = 0,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void Values3D(const int NE,
|
||||
const double *b_,
|
||||
const double *x_,
|
||||
double *y_,
|
||||
const int vdim = 0,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
|
||||
+18
-18
@@ -31,15 +31,15 @@ namespace quadrature_interpolator
|
||||
template<QVectorLayout Q_LAYOUT, bool GRAD_PHYS,
|
||||
int T_VDIM = 0, int T_D1D = 0, int T_Q1D = 0,
|
||||
int T_NBZ = 1, int MAX_D1D = 0, int MAX_Q1D = 0>
|
||||
void Derivatives2D(const int NE,
|
||||
const double *b_,
|
||||
const double *g_,
|
||||
const double *j_,
|
||||
const double *x_,
|
||||
double *y_,
|
||||
const int vdim = 0,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void Derivatives2D(const int NE,
|
||||
const double *b_,
|
||||
const double *g_,
|
||||
const double *j_,
|
||||
const double *x_,
|
||||
double *y_,
|
||||
const int vdim = 0,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
@@ -139,15 +139,15 @@ void Derivatives2D(const int NE,
|
||||
template<QVectorLayout Q_LAYOUT, bool GRAD_PHYS,
|
||||
int T_VDIM = 0, int T_D1D = 0, int T_Q1D = 0,
|
||||
int MAX_D1D = 0, int MAX_Q1D = 0>
|
||||
void Derivatives3D(const int NE,
|
||||
const double *b_,
|
||||
const double *g_,
|
||||
const double *j_,
|
||||
const double *x_,
|
||||
double *y_,
|
||||
const int vdim = 0,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
static void Derivatives3D(const int NE,
|
||||
const double *b_,
|
||||
const double *g_,
|
||||
const double *j_,
|
||||
const double *x_,
|
||||
double *y_,
|
||||
const int vdim = 0,
|
||||
const int d1d = 0,
|
||||
const int q1d = 0)
|
||||
{
|
||||
const int D1D = T_D1D ? T_D1D : d1d;
|
||||
const int Q1D = T_Q1D ? T_Q1D : q1d;
|
||||
|
||||
+20
-20
@@ -61,16 +61,16 @@ namespace quadrature_interpolator
|
||||
// * assumes 'e_vec' is using ElementDofOrdering::NATIVE,
|
||||
// * assumes 'maps.mode == FULL'.
|
||||
template<const int T_VDIM, const int T_ND, const int T_NQ>
|
||||
void Eval2D(const int NE,
|
||||
const int vdim,
|
||||
const QVectorLayout q_layout,
|
||||
const GeometricFactors *geom,
|
||||
const DofToQuad &maps,
|
||||
const Vector &e_vec,
|
||||
Vector &q_val,
|
||||
Vector &q_der,
|
||||
Vector &q_det,
|
||||
const int eval_flags)
|
||||
static void Eval2D(const int NE,
|
||||
const int vdim,
|
||||
const QVectorLayout q_layout,
|
||||
const GeometricFactors *geom,
|
||||
const DofToQuad &maps,
|
||||
const Vector &e_vec,
|
||||
Vector &q_val,
|
||||
Vector &q_der,
|
||||
Vector &q_det,
|
||||
const int eval_flags)
|
||||
{
|
||||
using QI = QuadratureInterpolator;
|
||||
|
||||
@@ -209,16 +209,16 @@ void Eval2D(const int NE,
|
||||
// * assumes 'e_vec' is using ElementDofOrdering::NATIVE,
|
||||
// * assumes 'maps.mode == FULL'.
|
||||
template<const int T_VDIM, const int T_ND, const int T_NQ>
|
||||
void Eval3D(const int NE,
|
||||
const int vdim,
|
||||
const QVectorLayout q_layout,
|
||||
const GeometricFactors *geom,
|
||||
const DofToQuad &maps,
|
||||
const Vector &e_vec,
|
||||
Vector &q_val,
|
||||
Vector &q_der,
|
||||
Vector &q_det,
|
||||
const int eval_flags)
|
||||
static void Eval3D(const int NE,
|
||||
const int vdim,
|
||||
const QVectorLayout q_layout,
|
||||
const GeometricFactors *geom,
|
||||
const DofToQuad &maps,
|
||||
const Vector &e_vec,
|
||||
Vector &q_val,
|
||||
Vector &q_der,
|
||||
Vector &q_det,
|
||||
const int eval_flags)
|
||||
{
|
||||
using QI = QuadratureInterpolator;
|
||||
|
||||
|
||||
+1
-1
@@ -1306,7 +1306,7 @@ namespace internal
|
||||
// MFEM_FORALL-based copy kernel -- used by protected methods below.
|
||||
// Needed as a workaround for the nvcc restriction that methods with MFEM_FORALL
|
||||
// in them must to be public.
|
||||
inline void device_copy(double *d_dest, const double *d_src, int size)
|
||||
static inline void device_copy(double *d_dest, const double *d_src, int size)
|
||||
{
|
||||
MFEM_FORALL(i, size, d_dest[i] = d_src[i];);
|
||||
}
|
||||
|
||||
+1
-1
@@ -234,7 +234,7 @@ void TMOPRefinerEstimator::SetTriIntRules()
|
||||
|
||||
// Reftype = 0 // original element
|
||||
const int Nvert = 3, NEsplit = 1;
|
||||
Mesh meshsplit(2, Nvert, NEsplit, 0,2);
|
||||
Mesh meshsplit(2, Nvert, NEsplit, 0 ,2);
|
||||
const double tri_v[3][2] =
|
||||
{
|
||||
{0, 0}, {1, 0}, {0, 1}
|
||||
|
||||
+1
-2
@@ -175,8 +175,7 @@ const Operator &InterpolationGridTransfer::ForwardOperator()
|
||||
localP[elem_geoms[i]]);
|
||||
}
|
||||
F.Reset(ran_fes.RefinementMatrix_main(
|
||||
dom_fes.GetNDofs(), dom_fes.GetElementToDofTable(),
|
||||
dom_fes.GetElementToFaceOrientationTable(), localP));
|
||||
dom_fes.GetNDofs(), dom_fes.GetElementToDofTable(), localP));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -21,16 +21,12 @@
|
||||
#define MFEM_PERF_FUNCTION CALI_CXX_MARK_FUNCTION
|
||||
#define MFEM_PERF_BEGIN(s) CALI_MARK_BEGIN(s)
|
||||
#define MFEM_PERF_END(s) CALI_MARK_END(s)
|
||||
#define MFEM_PERF_SCOPE(name) \
|
||||
cali::Annotation::Guard cali_autogenerated_guard_name(cali::Annotation("function").begin(std::string(name).c_str()))
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define MFEM_PERF_FUNCTION
|
||||
#define MFEM_PERF_BEGIN(s)
|
||||
#define MFEM_PERF_END(s)
|
||||
#define MFEM_PERF_SCOPE(name)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+1
-7
@@ -164,13 +164,7 @@ __device__ void abort_msg(T & msg)
|
||||
#endif
|
||||
|
||||
// Abort inside a device kernel
|
||||
#if defined(__CUDA_ARCH__) && defined(_WIN32)
|
||||
#define MFEM_ABORT_KERNEL(msg) \
|
||||
{ \
|
||||
printf(msg); \
|
||||
__debugbreak(); \
|
||||
}
|
||||
#elif defined(__CUDA_ARCH__)
|
||||
#if defined(__CUDA_ARCH__)
|
||||
#define MFEM_ABORT_KERNEL(msg) \
|
||||
{ \
|
||||
printf(msg); \
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#define MFEM_FORALL_HPP
|
||||
|
||||
#include "../config/config.hpp"
|
||||
#include "annotation.hpp"
|
||||
#include "error.hpp"
|
||||
#include "backends.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
@@ -79,13 +79,7 @@ int isockstream::establish()
|
||||
int on=1;
|
||||
setsockopt(port, SOL_SOCKET, SO_REUSEADDR, (char *)(&on), sizeof(on));
|
||||
|
||||
if (bind(
|
||||
#ifdef _WIN32
|
||||
(SOCKET)port
|
||||
#else
|
||||
port
|
||||
#endif
|
||||
,(const sockaddr*)&sa,(socklen_t)sizeof(struct sockaddr_in)) < 0)
|
||||
if (bind(port,(const sockaddr*)&sa,(socklen_t)sizeof(struct sockaddr_in)) < 0)
|
||||
{
|
||||
mfem::err << "isockstream::establish(): bind() failed!" << endl;
|
||||
close(port);
|
||||
|
||||
@@ -118,11 +118,6 @@ int STable3D::Index (int r, int c, int f) const
|
||||
{
|
||||
STable3DNode *node;
|
||||
|
||||
if (r >= Size)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
Sort3 (r, c, f);
|
||||
|
||||
for (node = Rows[r]; node != NULL; node = node->Prev)
|
||||
|
||||
+2996
-3325
File diff suppressed because it is too large
Load Diff
@@ -787,16 +787,10 @@ HypreParMatrix * ComplexHypreParMatrix::GetSystemMatrix() const
|
||||
2 * num_cols_offd, cmap,
|
||||
true);
|
||||
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
// Give the new matrix ownership of row_starts and col_starts
|
||||
hypre_ParCSRMatrix *hA = (hypre_ParCSRMatrix*)(*A);
|
||||
|
||||
hypre_ParCSRMatrixSetRowStartsOwner(hA,1);
|
||||
hypre_ParCSRMatrixSetColStartsOwner(hA,1);
|
||||
#else
|
||||
mfem_hypre_TFree_host(row_starts);
|
||||
mfem_hypre_TFree_host(col_starts);
|
||||
#endif
|
||||
|
||||
return A;
|
||||
}
|
||||
|
||||
@@ -763,13 +763,6 @@ public:
|
||||
tdata.New(i*j*k);
|
||||
}
|
||||
|
||||
DenseTensor(double *d, int i, int j, int k)
|
||||
: Mk(NULL, i, j)
|
||||
{
|
||||
nk = k;
|
||||
tdata.Wrap(d, i*j*k, false);
|
||||
}
|
||||
|
||||
DenseTensor(int i, int j, int k, MemoryType mt)
|
||||
: Mk(NULL, i, j)
|
||||
{
|
||||
|
||||
+1
-63
@@ -88,9 +88,7 @@ HypreParVector::HypreParVector(MPI_Comm comm, HYPRE_BigInt glob_size,
|
||||
{
|
||||
x = hypre_ParVectorCreate(comm,glob_size,col);
|
||||
hypre_ParVectorInitialize(x);
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
hypre_ParVectorSetPartitioningOwner(x,0);
|
||||
#endif
|
||||
// The data will be destroyed by hypre (this is the default)
|
||||
hypre_ParVectorSetDataOwner(x,1);
|
||||
hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),1);
|
||||
@@ -107,9 +105,7 @@ HypreParVector::HypreParVector(MPI_Comm comm, HYPRE_BigInt glob_size,
|
||||
hypre_ParVectorSetDataOwner(x,1); // owns the seq vector
|
||||
hypre_Vector *x_loc = hypre_ParVectorLocalVector(x);
|
||||
hypre_SeqVectorSetDataOwner(x_loc,0);
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
hypre_ParVectorSetPartitioningOwner(x,0);
|
||||
#endif
|
||||
double tmp = 0.0;
|
||||
hypre_VectorData(x_loc) = &tmp;
|
||||
#ifdef HYPRE_USING_CUDA
|
||||
@@ -132,9 +128,7 @@ HypreParVector::HypreParVector(const HypreParVector &y) : Vector()
|
||||
x = hypre_ParVectorCreate(y.x -> comm, y.x -> global_size,
|
||||
y.x -> partitioning);
|
||||
hypre_ParVectorInitialize(x);
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
hypre_ParVectorSetPartitioningOwner(x,0);
|
||||
#endif
|
||||
hypre_ParVectorSetDataOwner(x,1);
|
||||
hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),1);
|
||||
_SetDataAndSize_();
|
||||
@@ -168,9 +162,7 @@ HypreParVector::HypreParVector(ParFiniteElementSpace *pfes)
|
||||
x = hypre_ParVectorCreate(pfes->GetComm(), pfes->GlobalTrueVSize(),
|
||||
pfes->GetTrueDofOffsets());
|
||||
hypre_ParVectorInitialize(x);
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
hypre_ParVectorSetPartitioningOwner(x,0);
|
||||
#endif
|
||||
// The data will be destroyed by hypre (this is the default)
|
||||
hypre_ParVectorSetDataOwner(x,1);
|
||||
hypre_SeqVectorSetDataOwner(hypre_ParVectorLocalVector(x),1);
|
||||
@@ -691,10 +683,8 @@ HypreParMatrix::HypreParMatrix(MPI_Comm comm, HYPRE_BigInt glob_size,
|
||||
A = hypre_ParCSRMatrixCreate(comm, glob_size, glob_size, row_starts,
|
||||
row_starts, 0, diag->NumNonZeroElems(), 0);
|
||||
hypre_ParCSRMatrixSetDataOwner(A,1);
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
hypre_ParCSRMatrixSetRowStartsOwner(A,0);
|
||||
hypre_ParCSRMatrixSetColStartsOwner(A,0);
|
||||
#endif
|
||||
|
||||
hypre_CSRMatrixSetDataOwner(A->diag,0);
|
||||
diagOwner = CopyCSR(diag, mem_diag, A->diag, false);
|
||||
@@ -736,10 +726,8 @@ HypreParMatrix::HypreParMatrix(MPI_Comm comm,
|
||||
row_starts, col_starts,
|
||||
0, diag->NumNonZeroElems(), 0);
|
||||
hypre_ParCSRMatrixSetDataOwner(A,1);
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
hypre_ParCSRMatrixSetRowStartsOwner(A,0);
|
||||
hypre_ParCSRMatrixSetColStartsOwner(A,0);
|
||||
#endif
|
||||
|
||||
hypre_CSRMatrixSetDataOwner(A->diag,0);
|
||||
diagOwner = CopyCSR(diag, mem_diag, A->diag, false);
|
||||
@@ -782,10 +770,8 @@ HypreParMatrix::HypreParMatrix(MPI_Comm comm,
|
||||
offd->Width(), diag->NumNonZeroElems(),
|
||||
offd->NumNonZeroElems());
|
||||
hypre_ParCSRMatrixSetDataOwner(A,1);
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
hypre_ParCSRMatrixSetRowStartsOwner(A,0);
|
||||
hypre_ParCSRMatrixSetColStartsOwner(A,0);
|
||||
#endif
|
||||
|
||||
hypre_CSRMatrixSetDataOwner(A->diag,0);
|
||||
diagOwner = CopyCSR(diag, mem_diag, A->diag, own_diag_offd);
|
||||
@@ -831,10 +817,8 @@ HypreParMatrix::HypreParMatrix(
|
||||
A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
|
||||
row_starts, col_starts, offd_num_cols, 0, 0);
|
||||
hypre_ParCSRMatrixSetDataOwner(A,1);
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
hypre_ParCSRMatrixSetRowStartsOwner(A,0);
|
||||
hypre_ParCSRMatrixSetColStartsOwner(A,0);
|
||||
#endif
|
||||
|
||||
HYPRE_Int local_num_rows = hypre_CSRMatrixNumRows(A->diag);
|
||||
|
||||
@@ -947,10 +931,8 @@ HypreParMatrix::HypreParMatrix(MPI_Comm comm,
|
||||
A = hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
|
||||
row_starts, col_starts, 0, nnz, 0);
|
||||
hypre_ParCSRMatrixSetDataOwner(A,1);
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
hypre_ParCSRMatrixSetRowStartsOwner(A,0);
|
||||
hypre_ParCSRMatrixSetColStartsOwner(A,0);
|
||||
#endif
|
||||
|
||||
hypre_CSRMatrixSetDataOwner(A->diag,0);
|
||||
diagOwner = CopyBoolCSR(diag, mem_diag, A->diag);
|
||||
@@ -1007,10 +989,8 @@ HypreParMatrix::HypreParMatrix(MPI_Comm comm, int id, int np,
|
||||
}
|
||||
|
||||
hypre_ParCSRMatrixSetDataOwner(A,1);
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
hypre_ParCSRMatrixSetRowStartsOwner(A,0);
|
||||
hypre_ParCSRMatrixSetColStartsOwner(A,0);
|
||||
#endif
|
||||
|
||||
mem_diag.data.New(diag_nnz);
|
||||
for (HYPRE_Int i = 0; i < diag_nnz; i++)
|
||||
@@ -1197,13 +1177,6 @@ HypreParMatrix::HypreParMatrix(MPI_Comm comm, int nrows,
|
||||
{
|
||||
hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
|
||||
}
|
||||
#if MFEM_HYPRE_VERSION > 22200
|
||||
mfem_hypre_TFree_host(row_starts);
|
||||
if (rows != cols)
|
||||
{
|
||||
mfem_hypre_TFree_host(col_starts);
|
||||
}
|
||||
#endif
|
||||
hypre_MatvecCommPkgCreate(A);
|
||||
|
||||
height = GetNumRows();
|
||||
@@ -1290,7 +1263,6 @@ void HypreParMatrix::SetOwnerFlags(signed char diag, signed char offd,
|
||||
|
||||
void HypreParMatrix::CopyRowStarts()
|
||||
{
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
if (!A || hypre_ParCSRMatrixOwnsRowStarts(A) ||
|
||||
(hypre_ParCSRMatrixRowStarts(A) == hypre_ParCSRMatrixColStarts(A) &&
|
||||
hypre_ParCSRMatrixOwnsColStarts(A)))
|
||||
@@ -1325,12 +1297,10 @@ void HypreParMatrix::CopyRowStarts()
|
||||
hypre_ParCSRMatrixColStarts(A) = new_row_starts;
|
||||
hypre_ParCSRMatrixOwnsColStarts(A) = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void HypreParMatrix::CopyColStarts()
|
||||
{
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
if (!A || hypre_ParCSRMatrixOwnsColStarts(A) ||
|
||||
(hypre_ParCSRMatrixRowStarts(A) == hypre_ParCSRMatrixColStarts(A) &&
|
||||
hypre_ParCSRMatrixOwnsRowStarts(A)))
|
||||
@@ -1369,7 +1339,6 @@ void HypreParMatrix::CopyColStarts()
|
||||
{
|
||||
hypre_ParCSRMatrixOwnsColStarts(A) = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void HypreParMatrix::GetDiag(Vector &diag) const
|
||||
@@ -1822,14 +1791,9 @@ HypreParMatrix* HypreParMatrix::LeftDiagMult(const SparseMatrix &D,
|
||||
DA_diag, DA_offd, new_col_map_offd,
|
||||
own_diag_offd);
|
||||
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
// Give ownership of row_starts, col_starts, and col_map_offd to DA
|
||||
hypre_ParCSRMatrixSetRowStartsOwner(DA->A, 1);
|
||||
hypre_ParCSRMatrixSetColStartsOwner(DA->A, 1);
|
||||
#else
|
||||
mfem_hypre_TFree_host(new_row_starts);
|
||||
mfem_hypre_TFree_host(new_col_starts);
|
||||
#endif
|
||||
DA->colMapOwner = 1;
|
||||
|
||||
return DA;
|
||||
@@ -1984,22 +1948,18 @@ void HypreParMatrix::Threshold(double threshold)
|
||||
row_starts = hypre_ParCSRMatrixRowStarts(A);
|
||||
col_starts = hypre_ParCSRMatrixColStarts(A);
|
||||
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
bool old_owns_row = hypre_ParCSRMatrixOwnsRowStarts(A);
|
||||
bool old_owns_col = hypre_ParCSRMatrixOwnsColStarts(A);
|
||||
#endif
|
||||
HYPRE_BigInt global_num_rows = hypre_ParCSRMatrixGlobalNumRows(A);
|
||||
HYPRE_BigInt global_num_cols = hypre_ParCSRMatrixGlobalNumCols(A);
|
||||
parcsr_A_ptr = hypre_ParCSRMatrixCreate(comm, global_num_rows,
|
||||
global_num_cols,
|
||||
row_starts, col_starts,
|
||||
0, 0, 0);
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
hypre_ParCSRMatrixOwnsRowStarts(parcsr_A_ptr) = old_owns_row;
|
||||
hypre_ParCSRMatrixOwnsColStarts(parcsr_A_ptr) = old_owns_col;
|
||||
hypre_ParCSRMatrixOwnsRowStarts(A) = 0;
|
||||
hypre_ParCSRMatrixOwnsColStarts(A) = 0;
|
||||
#endif
|
||||
|
||||
csr_A = hypre_MergeDiagAndOffd(A);
|
||||
|
||||
@@ -2034,12 +1994,7 @@ void HypreParMatrix::Threshold(double threshold)
|
||||
|
||||
hypre_ParCSRMatrixSetNumNonzeros(A);
|
||||
/* Make sure that the first entry in each row is the diagonal one. */
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
if (row_starts == col_starts)
|
||||
#else
|
||||
if ((row_starts[0] == col_starts[0]) &&
|
||||
(row_starts[1] == col_starts[1]))
|
||||
#endif
|
||||
{
|
||||
hypre_CSRMatrixReorder(hypre_ParCSRMatrixDiag(A));
|
||||
}
|
||||
@@ -2548,14 +2503,11 @@ HypreParMatrix * RAP(const HypreParMatrix *A, const HypreParMatrix *P)
|
||||
// hypre_ParCSRMatrixRAPKT
|
||||
}
|
||||
#else
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
HYPRE_Int P_owns_its_col_starts =
|
||||
hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
|
||||
#endif
|
||||
|
||||
hypre_BoomerAMGBuildCoarseOperator(*P,*A,*P,&rap);
|
||||
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
/* Warning: hypre_BoomerAMGBuildCoarseOperator steals the col_starts
|
||||
from P (even if it does not own them)! */
|
||||
hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
|
||||
@@ -2564,7 +2516,6 @@ HypreParMatrix * RAP(const HypreParMatrix *A, const HypreParMatrix *P)
|
||||
{
|
||||
hypre_ParCSRMatrixSetColStartsOwner(*P, 1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
hypre_ParCSRMatrixSetNumNonzeros(rap);
|
||||
@@ -2585,16 +2536,13 @@ HypreParMatrix * RAP(const HypreParMatrix * Rt, const HypreParMatrix *A,
|
||||
hypre_ParCSRMatrixDestroy(Q);
|
||||
}
|
||||
#else
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
HYPRE_Int P_owns_its_col_starts =
|
||||
hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*P));
|
||||
HYPRE_Int Rt_owns_its_col_starts =
|
||||
hypre_ParCSRMatrixOwnsColStarts((hypre_ParCSRMatrix*)(*Rt));
|
||||
#endif
|
||||
|
||||
hypre_BoomerAMGBuildCoarseOperator(*Rt,*A,*P,&rap);
|
||||
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
/* Warning: hypre_BoomerAMGBuildCoarseOperator steals the col_starts
|
||||
from Rt and P (even if they do not own them)! */
|
||||
hypre_ParCSRMatrixSetRowStartsOwner(rap,0);
|
||||
@@ -2607,7 +2555,6 @@ HypreParMatrix * RAP(const HypreParMatrix * Rt, const HypreParMatrix *A,
|
||||
{
|
||||
hypre_ParCSRMatrixSetColStartsOwner(*Rt, 1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
hypre_ParCSRMatrixSetNumNonzeros(rap);
|
||||
@@ -3197,12 +3144,8 @@ void HypreSmoother::SetOperator(const Operator &op)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
min_eig_est = 0;
|
||||
hypre_ParCSRMaxEigEstimate(*A, poly_scale, &max_eig_est);
|
||||
#else
|
||||
hypre_ParCSRMaxEigEstimate(*A, poly_scale, &max_eig_est, &min_eig_est);
|
||||
#endif
|
||||
}
|
||||
Z = new HypreParVector(*A);
|
||||
}
|
||||
@@ -3216,12 +3159,8 @@ void HypreSmoother::SetOperator(const Operator &op)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
min_eig_est = 0;
|
||||
hypre_ParCSRMaxEigEstimate(*A, poly_scale, &max_eig_est);
|
||||
#else
|
||||
hypre_ParCSRMaxEigEstimate(*A, poly_scale, &max_eig_est, &min_eig_est);
|
||||
#endif
|
||||
}
|
||||
|
||||
// The Taubin and FIR polynomials are defined on [0, 2]
|
||||
@@ -5058,11 +4997,11 @@ HypreADS::HypreADS(const HypreParMatrix &A, ParFiniteElementSpace *face_fespace)
|
||||
void HypreADS::Init(ParFiniteElementSpace *face_fespace)
|
||||
{
|
||||
int cycle_type = 11;
|
||||
int rlx_type = 2;
|
||||
int rlx_sweeps = 1;
|
||||
double rlx_weight = 1.0;
|
||||
double rlx_omega = 1.0;
|
||||
#ifndef HYPRE_USING_CUDA
|
||||
int rlx_type = 2;
|
||||
int amg_coarsen_type = 10;
|
||||
int amg_agg_levels = 1;
|
||||
int amg_rlx_type = 8;
|
||||
@@ -5070,7 +5009,6 @@ void HypreADS::Init(ParFiniteElementSpace *face_fespace)
|
||||
int amg_interp_type = 6;
|
||||
int amg_Pmax = 4;
|
||||
#else
|
||||
int rlx_type = 1;
|
||||
int amg_coarsen_type = 8;
|
||||
int amg_agg_levels = 0;
|
||||
int amg_rlx_type = 18;
|
||||
|
||||
@@ -508,10 +508,8 @@ void hypre_ParCSRMatrixEliminateAAe(hypre_ParCSRMatrix *A,
|
||||
hypre_ParCSRMatrixColStarts(A),
|
||||
0, 0, 0);
|
||||
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
hypre_ParCSRMatrixSetRowStartsOwner(*Ae, 0);
|
||||
hypre_ParCSRMatrixSetColStartsOwner(*Ae, 0);
|
||||
#endif
|
||||
|
||||
hypre_CSRMatrix *Ae_diag = hypre_ParCSRMatrixDiag(*Ae);
|
||||
hypre_CSRMatrix *Ae_offd = hypre_ParCSRMatrixOffd(*Ae);
|
||||
@@ -1004,17 +1002,10 @@ void hypre_ParCSRMatrixSplit(hypre_ParCSRMatrix *A,
|
||||
|
||||
hypre_ParCSRMatrixOwnsData(blocks[i]) = 1;
|
||||
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
/* only the first block will own the row/col_starts */
|
||||
hypre_ParCSRMatrixOwnsRowStarts(blocks[i]) = !i;
|
||||
hypre_ParCSRMatrixOwnsColStarts(blocks[i]) = !i;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MFEM_HYPRE_VERSION > 22200
|
||||
mfem_hypre_TFree_host(row_starts);
|
||||
mfem_hypre_TFree_host(col_starts);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Based on hypre_CSRMatrixMatvec in hypre's csr_matvec.c */
|
||||
@@ -1925,12 +1916,9 @@ hypre_ParCSRMatrixAdd(hypre_ParCSRMatrix *A,
|
||||
|
||||
/* C owns diag, offd, and cmap. */
|
||||
hypre_ParCSRMatrixSetDataOwner(C, 1);
|
||||
|
||||
#if MFEM_HYPRE_VERSION <= 22200
|
||||
/* C does not own row and column starts. */
|
||||
hypre_ParCSRMatrixSetRowStartsOwner(C, 0);
|
||||
hypre_ParCSRMatrixSetColStartsOwner(C, 0);
|
||||
#endif
|
||||
|
||||
return C;
|
||||
}
|
||||
|
||||
+1169
File diff suppressed because it is too large
Load Diff
+244
@@ -0,0 +1,244 @@
|
||||
#ifndef MFEM_IMEX
|
||||
#define MFEM_IMEX
|
||||
|
||||
#include "../config/config.hpp"
|
||||
#include "operator.hpp"
|
||||
#include "ode.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace mfem
|
||||
{
|
||||
|
||||
/** Class for spatial discretizations of a PDE resulting in the time-dependent,
|
||||
nonlinear set of ODEs with implicit-explicit additive partition
|
||||
M*du/dt = N_E(u,t) + N_I(u,t).
|
||||
MFEM typically treats time integration as
|
||||
du/dt = F^{-1} G(u),
|
||||
Here F represents what MFEM calls the “implicit” part, and G represents the
|
||||
“explicit” part; in simpler terms, F is typically just a mass matrix.
|
||||
|
||||
For BDF schemes, the ImplicitSolve function is a bit different, and it is
|
||||
more natural to apply M and M^{-1} separate from the Mult functions, so we
|
||||
include MassMult and MassInv as functions to be provided, and do not include
|
||||
such actions in the Mult functions. */
|
||||
class IMEXTimeDependentOperator : public TimeDependentOperator
|
||||
{
|
||||
protected:
|
||||
mutable Vector temp; // Auxillary vector
|
||||
|
||||
public:
|
||||
// Sets linearly implicit to false by default
|
||||
IMEXTimeDependentOperator(int n, double t=0.0, Type type=EXPLICIT)
|
||||
: TimeDependentOperator(n, t, type) { };
|
||||
~IMEXTimeDependentOperator() { };
|
||||
|
||||
/** Apply action of implicit part of operator y <- N_I(x,y). For fully
|
||||
implicit schemes, this just corresponds to applying the time-dependent
|
||||
(nonlinear) operator.
|
||||
PREVIOUSLY CALLED ExplicitMult */
|
||||
virtual void ImplicitMult(const Vector &x, Vector &y) const = 0;
|
||||
|
||||
/** Apply action of explicit part of operator y <- N_E(x,y) */
|
||||
virtual void ExplicitMult(const Vector &x, Vector &y) const { y = 0.0; };
|
||||
|
||||
/** Solve k = f(x+dt*k) for stage k, where f() is the implicit part of
|
||||
the operator. Used in Runge-Kutta methods. */
|
||||
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &k)
|
||||
{ mfem::mfem_error("IMEXTimeDependentOperator::ImplicitSolve() is not overridden!"); };
|
||||
|
||||
/** Solve M*x - dtf(x, t) = b for solution x, where f() is the implicit
|
||||
part of the operator. Used in BDF methods. */
|
||||
virtual void ImplicitSolve2(const double dt, const Vector &b, Vector &x)
|
||||
{ mfem::mfem_error("IMEXTimeDependentOperator::ImplicitSolve2() is not overridden!"); };
|
||||
|
||||
/** Apply action mass matrix, y = M*x.
|
||||
If not re-implemented, this method simply generates an error.
|
||||
PREVIOUSLY CALLED ImplictMult */
|
||||
virtual void MassMult(const Vector &x, Vector &y) const = 0;
|
||||
|
||||
/** Apply action of inverse of mass matrix, y = M^{-1}*x.
|
||||
If not re-implemented, this method simply generates an error.
|
||||
NOTE : only necessary for PolyIMEX methods. */
|
||||
virtual void MassInv(const Vector &x, Vector &y) const = 0;
|
||||
};
|
||||
|
||||
/** Class holding RK Butcher tableau, and associated data required by
|
||||
implicit and explicit splitting. */
|
||||
class IMEXRKData
|
||||
{
|
||||
public:
|
||||
// Implicit Runge Kutta type. Enumeration (s, \sigma, p):
|
||||
// - s = number of implicit stages
|
||||
// - \sigma = number of explicit stages
|
||||
// - p = order
|
||||
// In this notation, when s = \sigma, we satisfy (2.3)/(2.4) in
|
||||
// Ascher et al., and do not need to compute the final explicit
|
||||
// stage. This is represented in the stiffly_accurate boolean.
|
||||
enum Type {
|
||||
IMEX111 = 111,
|
||||
IMEX121 = 121,
|
||||
IMEX122 = 122,
|
||||
IMEX222 = 222,
|
||||
IMEX232 = 232,
|
||||
IMEX233 = 233,
|
||||
IMEX443 = 443,
|
||||
// ARK ESDIRK-ERK schemes: enumeration (s,p), for total number of
|
||||
// stages s.
|
||||
ARK43 = -43
|
||||
};
|
||||
|
||||
IMEXRKData() : s(-1) { };
|
||||
IMEXRKData(Type ID_) : ID(ID_) { SetData(); };
|
||||
~IMEXRKData() { };
|
||||
|
||||
/// Set explicit RK data
|
||||
void SetExplicitData(DenseMatrix Ae_, Vector be_, Vector ce_);
|
||||
/// Set implicit RK data
|
||||
void SetImplicitData(DenseMatrix Ai_, Vector bi_, Vector ci_, bool esdirk_=false);
|
||||
void SetID(Type ID_) { ID=ID_; SetData(); };
|
||||
|
||||
bool esdirk;
|
||||
bool stiffly_accurate;
|
||||
bool use_final_exp_stage;
|
||||
int s;
|
||||
|
||||
DenseMatrix Ai; // Implicit Butcher matrix
|
||||
Vector bi; // Implicit Butcher tableau weights
|
||||
DenseMatrix Ae; // Explicit Butcher matrix
|
||||
Vector be; // Explicit Butcher tableau weights
|
||||
Vector c0; // Butcher tableau nodes (same for implicit and explicit!)
|
||||
|
||||
private:
|
||||
Type ID;
|
||||
void SetData();
|
||||
void InitData();
|
||||
};
|
||||
|
||||
/** Class for two-part additive IMEX RK method, where explicit and implicit
|
||||
stage vectors are stored. Assume same abscissae, {c}, for both schemes.
|
||||
Butcher Data must be provided either in a custom IMEXRKData object, or
|
||||
using the IMEXRKData::Type for predefined tableaux. */
|
||||
class IMEXRK : public ODESolver
|
||||
{
|
||||
protected:
|
||||
IMEXRKData tableaux;
|
||||
std::vector< Vector *> exp_stages;
|
||||
std::vector< Vector *> imp_stages;
|
||||
IMEXTimeDependentOperator *imex; // Spatial discretization.
|
||||
|
||||
public:
|
||||
IMEXRK(IMEXRKData tableaux_) : ODESolver(), tableaux(tableaux_) { };
|
||||
IMEXRK(IMEXRKData::Type type_) : ODESolver(), tableaux(type_) { };
|
||||
~IMEXRK();
|
||||
void Init(IMEXTimeDependentOperator &_imex);
|
||||
void Step(Vector &x, double &t, double &dt) override;
|
||||
};
|
||||
|
||||
/** Class holding BDF integrator data. Setting alpha < 0 (the default
|
||||
constructor) defines alpha = 2/(q-1), corresponding to classical BDF
|
||||
of order q. */
|
||||
class BDFData
|
||||
{
|
||||
public:
|
||||
|
||||
enum Type {
|
||||
BDF1 = 01, BDF2 = 02, BDF3 = 03, BDF4 = 04,
|
||||
IMEX_BDF1 = 11, IMEX_BDF2 = 12, IMEX_BDF3 = 13,
|
||||
IMEX_BDF4 = 14
|
||||
};
|
||||
|
||||
BDFData() { };
|
||||
BDFData(Type ID_, double alpha_=-1) : ID(ID_), alpha(alpha_) { SetData(); };
|
||||
~BDFData() { };
|
||||
|
||||
int GetID() { return static_cast<int>(ID); };
|
||||
void SetID(Type ID_, double alpha_=-1)
|
||||
{
|
||||
ID=ID_;
|
||||
alpha = alpha_;
|
||||
SetData();
|
||||
};
|
||||
void Print()
|
||||
{
|
||||
std::cout << "q = " << q << "\n";
|
||||
std::cout << "alpha = " << alpha << "\n";
|
||||
std::cout << "A:\n";
|
||||
A.PrintMatlab();
|
||||
std::cout << "Be:\n";
|
||||
Be.PrintMatlab();
|
||||
std::cout << "Bi:\n";
|
||||
Bi.Print();
|
||||
std::cout << "z:\n";
|
||||
z0.Print();
|
||||
};
|
||||
|
||||
double alpha;
|
||||
int q; // Number of previous values stored
|
||||
bool shifted_nodes; // false = clssical BDF, true = Polynomial BDF w/ shifted nodes
|
||||
DenseMatrix A; // Previous solution coefficients
|
||||
Vector Bi; // Implicit coefficients
|
||||
DenseMatrix Be; // Explicit coefficients
|
||||
Vector z0;
|
||||
|
||||
|
||||
private:
|
||||
Type ID;
|
||||
void SetData();
|
||||
void InitData();
|
||||
};
|
||||
|
||||
/** Class for IMEX-BDF methods, including classical IMEX-BDF and IMEX-
|
||||
Polynomial-BDF (IMEX-PBDF). IMEX-PBDF methods have an additional
|
||||
alpha parameter, where larger alpha leads to smaller stability
|
||||
regions and a smaller leading accuracy constant, while smaller
|
||||
alpha leads to larger stabiltiy regions and a larger accuracy
|
||||
constant. For classical methods, there are two implementations:
|
||||
- ClassicalStep() stores previous solutions and the explicit
|
||||
part of the operator evaluated on the solution, and
|
||||
- ClassicalStepNoStore() does not store the explicit
|
||||
component, but must re-evaluate q times during each time
|
||||
step.
|
||||
This option can be set via the recompute_exp input. The type of
|
||||
scheme must be set through the BDFData structure or BDFData::Type.
|
||||
There is also an option to use pointwise Lagrange interpolating
|
||||
polynomials to provide an initial guess for the ImplicitSolve. This
|
||||
is set via InterpolateGuess(). This option is only implemented for
|
||||
PBDF. */
|
||||
class IMEXBDF : public ODESolver
|
||||
{
|
||||
private:
|
||||
BDFData data;
|
||||
bool recompute_exp;
|
||||
bool interpolate;
|
||||
int initialized;
|
||||
double dt_prev;
|
||||
std::vector< Vector*> sols;
|
||||
std::vector< Vector*> exp_sols;
|
||||
IMEXTimeDependentOperator *imex; // Spatial discretization
|
||||
IMEXRK *RKsolver;
|
||||
std::vector<double> exp_nodes;
|
||||
|
||||
void AlphaStep(Vector &x, double &t, double &dt);
|
||||
void ClassicalStep(Vector &x, double &t, double &dt);
|
||||
void ClassicalStepNoStore(Vector &x, double &t, double &dt);
|
||||
|
||||
public:
|
||||
IMEXBDF(BDFData data_, bool recompute_exp_=false) :
|
||||
ODESolver(), data(data_), recompute_exp(recompute_exp_),
|
||||
interpolate(false) { };
|
||||
IMEXBDF(BDFData::Type scheme, bool recompute_exp_=false) :
|
||||
ODESolver(), recompute_exp(recompute_exp_), interpolate(false)
|
||||
{ data.SetID(scheme); };
|
||||
IMEXBDF(BDFData::Type scheme, double alpha) :
|
||||
ODESolver(), interpolate(false), recompute_exp(false)
|
||||
{ data.SetID(scheme, alpha); };
|
||||
~IMEXBDF();
|
||||
|
||||
void Init(IMEXTimeDependentOperator &_imex);
|
||||
void Step(Vector &x, double &t, double &dt);
|
||||
void InterpolateGuess() {interpolate = true; };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+1
-1
@@ -378,7 +378,7 @@ void Swap(T &a, T &b)
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
constexpr double Epsilon = std::numeric_limits<double>::epsilon();
|
||||
const double Epsilon = std::numeric_limits<double>::epsilon();
|
||||
|
||||
/// Utility function used in CalcSingularvalue<3>.
|
||||
MFEM_HOST_DEVICE static inline
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "invariants.hpp"
|
||||
#include "constraints.hpp"
|
||||
#include "auxiliary.hpp"
|
||||
#include "imex.hpp"
|
||||
|
||||
#ifdef MFEM_USE_AMGX
|
||||
#include "amgxsolver.hpp"
|
||||
|
||||
+1
-1
@@ -1677,7 +1677,7 @@ int KINSolver::GradientMult(N_Vector v, N_Vector Jv, N_Vector u,
|
||||
|
||||
// Wrapper for evaluating linear systems J u = b
|
||||
int KINSolver::LinSysSetup(N_Vector u, N_Vector, SUNMatrix J,
|
||||
void *, N_Vector, N_Vector )
|
||||
void *, N_Vector , N_Vector )
|
||||
{
|
||||
const SundialsNVector mfem_u(u);
|
||||
KINSolver *self = static_cast<KINSolver*>(GET_CONTENT(J));
|
||||
|
||||
@@ -119,7 +119,7 @@ $(if $(word 2,$(SRC)),$(error Spaces in SRC = "$(SRC)" are not supported))
|
||||
MFEM_GIT_STRING = $(shell [ -d $(MFEM_DIR)/.git ] && git -C $(MFEM_DIR) \
|
||||
describe --all --long --abbrev=40 --dirty --always 2> /dev/null)
|
||||
|
||||
EXAMPLE_SUBDIRS = amgx caliper ginkgo hiop petsc pumi sundials superlu
|
||||
EXAMPLE_SUBDIRS = amgx ginkgo hiop petsc pumi sundials superlu
|
||||
EXAMPLE_DIRS := examples $(addprefix examples/,$(EXAMPLE_SUBDIRS))
|
||||
EXAMPLE_TEST_DIRS := examples
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ set(SRCS
|
||||
ncmesh.cpp
|
||||
nurbs.cpp
|
||||
point.cpp
|
||||
pyramid.cpp
|
||||
quadrilateral.cpp
|
||||
segment.cpp
|
||||
tetrahedron.cpp
|
||||
@@ -39,7 +38,6 @@ set(HDRS
|
||||
ncmesh.hpp
|
||||
nurbs.hpp
|
||||
point.hpp
|
||||
pyramid.hpp
|
||||
quadrilateral.hpp
|
||||
segment.hpp
|
||||
tetrahedron.hpp
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ public:
|
||||
|
||||
/// Constants for the classes derived from Element.
|
||||
enum Type { POINT, SEGMENT, TRIANGLE, QUADRILATERAL,
|
||||
TETRAHEDRON, HEXAHEDRON, WEDGE, PYRAMID
|
||||
TETRAHEDRON, HEXAHEDRON, WEDGE
|
||||
};
|
||||
|
||||
/// Default element constructor.
|
||||
|
||||
+36
-335
@@ -335,7 +335,6 @@ FiniteElement *Mesh::GetTransformationFEforElementType(Element::Type ElemType)
|
||||
case Element::TETRAHEDRON : return &TetrahedronFE;
|
||||
case Element::HEXAHEDRON : return &HexahedronFE;
|
||||
case Element::WEDGE : return &WedgeFE;
|
||||
case Element::PYRAMID : return &PyramidFE;
|
||||
default:
|
||||
MFEM_ABORT("Unknown element type \"" << ElemType << "\"");
|
||||
break;
|
||||
@@ -736,31 +735,6 @@ void Mesh::GetLocalTriToWdgTransformation(
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::GetLocalTriToPyrTransformation(
|
||||
IsoparametricTransformation &Transf, int i)
|
||||
{
|
||||
DenseMatrix &locpm = Transf.GetPointMat();
|
||||
|
||||
Transf.SetFE(&TriangleFE);
|
||||
// (i/64) is the local face no. in the pyr
|
||||
MFEM_VERIFY(i >= 64, "Local face index " << i/64
|
||||
<< " is not a triangular face of a pyramid.");
|
||||
const int *pv = pyr_t::FaceVert[i/64];
|
||||
// (i%64) is the orientation of the pyramid face
|
||||
// w.r.t. the face element
|
||||
const int *to = tri_t::Orient[i%64];
|
||||
const IntegrationRule *PyrVert =
|
||||
Geometries.GetVertices(Geometry::PYRAMID);
|
||||
locpm.SetSize(3, 3);
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
const IntegrationPoint &vert = PyrVert->IntPoint(pv[to[j]]);
|
||||
locpm(0, j) = vert.x;
|
||||
locpm(1, j) = vert.y;
|
||||
locpm(2, j) = vert.z;
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::GetLocalQuadToHexTransformation(
|
||||
IsoparametricTransformation &Transf, int i)
|
||||
{
|
||||
@@ -807,29 +781,6 @@ void Mesh::GetLocalQuadToWdgTransformation(
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::GetLocalQuadToPyrTransformation(
|
||||
IsoparametricTransformation &Transf, int i)
|
||||
{
|
||||
DenseMatrix &locpm = Transf.GetPointMat();
|
||||
|
||||
Transf.SetFE(&QuadrilateralFE);
|
||||
// (i/64) is the local face no. in the pyr
|
||||
MFEM_VERIFY(i < 64, "Local face index " << i/64
|
||||
<< " is not a quadrilateral face of a pyramid.");
|
||||
const int *pv = pyr_t::FaceVert[i/64];
|
||||
// (i%64) is the orientation of the quad
|
||||
const int *qo = quad_t::Orient[i%64];
|
||||
const IntegrationRule *PyrVert = Geometries.GetVertices(Geometry::PYRAMID);
|
||||
locpm.SetSize(3, 4);
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
const IntegrationPoint &vert = PyrVert->IntPoint(pv[qo[j]]);
|
||||
locpm(0, j) = vert.x;
|
||||
locpm(1, j) = vert.y;
|
||||
locpm(2, j) = vert.z;
|
||||
}
|
||||
}
|
||||
|
||||
const GeometricFactors* Mesh::GetGeometricFactors(const IntegrationRule& ir,
|
||||
const int flags,
|
||||
MemoryType d_mt)
|
||||
@@ -911,19 +862,10 @@ void Mesh::GetLocalFaceTransformation(
|
||||
{
|
||||
GetLocalTriToTetTransformation(Transf, info);
|
||||
}
|
||||
else if (elem_type == Element::WEDGE)
|
||||
{
|
||||
GetLocalTriToWdgTransformation(Transf, info);
|
||||
}
|
||||
else if (elem_type == Element::PYRAMID)
|
||||
{
|
||||
GetLocalTriToPyrTransformation(Transf, info);
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_ABORT("Mesh::GetLocalFaceTransformation not defined for "
|
||||
"face type " << face_type
|
||||
<< " and element type " << elem_type << "\n");
|
||||
MFEM_ASSERT(elem_type == Element::WEDGE, "");
|
||||
GetLocalTriToWdgTransformation(Transf, info);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -932,19 +874,10 @@ void Mesh::GetLocalFaceTransformation(
|
||||
{
|
||||
GetLocalQuadToHexTransformation(Transf, info);
|
||||
}
|
||||
else if (elem_type == Element::WEDGE)
|
||||
{
|
||||
GetLocalQuadToWdgTransformation(Transf, info);
|
||||
}
|
||||
else if (elem_type == Element::PYRAMID)
|
||||
{
|
||||
GetLocalQuadToPyrTransformation(Transf, info);
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_ABORT("Mesh::GetLocalFaceTransformation not defined for "
|
||||
"face type " << face_type
|
||||
<< " and element type " << elem_type << "\n");
|
||||
MFEM_ASSERT(elem_type == Element::WEDGE, "");
|
||||
GetLocalQuadToWdgTransformation(Transf, info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1437,20 +1370,6 @@ int Mesh::AddWedge(const int *vi, int attr)
|
||||
return NumOfElements++;
|
||||
}
|
||||
|
||||
int Mesh::AddPyramid(int v1, int v2, int v3, int v4, int v5, int attr)
|
||||
{
|
||||
CheckEnlarge(elements, NumOfElements);
|
||||
elements[NumOfElements] = new Pyramid(v1, v2, v3, v4, v5, attr);
|
||||
return NumOfElements++;
|
||||
}
|
||||
|
||||
int Mesh::AddPyramid(const int *vi, int attr)
|
||||
{
|
||||
CheckEnlarge(elements, NumOfElements);
|
||||
elements[NumOfElements] = new Pyramid(vi, attr);
|
||||
return NumOfElements++;
|
||||
}
|
||||
|
||||
int Mesh::AddHex(int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8,
|
||||
int attr)
|
||||
{
|
||||
@@ -1504,25 +1423,6 @@ void Mesh::AddHexAsWedges(const int *vi, int attr)
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::AddHexAsPyramids(const int *vi, int attr)
|
||||
{
|
||||
static const int hex_to_pyr[6][5] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 8 }, { 0, 4, 5, 1, 8 }, { 1, 5, 6, 2, 8 },
|
||||
{ 2, 6, 7, 3, 8 }, { 3, 7, 4, 0, 8 }, { 7, 6, 5, 4, 8 }
|
||||
};
|
||||
int ti[5];
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
for (int j = 0; j < 5; j++)
|
||||
{
|
||||
ti[j] = vi[hex_to_pyr[i][j]];
|
||||
}
|
||||
AddPyramid(ti, attr);
|
||||
}
|
||||
}
|
||||
|
||||
int Mesh::AddElement(Element *elem)
|
||||
{
|
||||
CheckEnlarge(elements, NumOfElements);
|
||||
@@ -2792,16 +2692,11 @@ void Mesh::Make3D(int nx, int ny, int nz, Element::Type type,
|
||||
NElem *= 2;
|
||||
NBdrElem += 2*nx*ny;
|
||||
}
|
||||
else if (type == Element::PYRAMID)
|
||||
{
|
||||
NElem *= 6;
|
||||
NVert += nx * ny * nz;
|
||||
}
|
||||
|
||||
InitMesh(3, 3, NVert, NElem, NBdrElem);
|
||||
|
||||
double coord[3];
|
||||
int ind[9];
|
||||
int ind[8];
|
||||
|
||||
// Sets vertices and the corresponding coordinates
|
||||
for (z = 0; z <= nz; z++)
|
||||
@@ -2817,25 +2712,8 @@ void Mesh::Make3D(int nx, int ny, int nz, Element::Type type,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type == Element::PYRAMID)
|
||||
{
|
||||
for (z = 0; z < nz; z++)
|
||||
{
|
||||
coord[2] = (((double) z + 0.5) / nz) * sz;
|
||||
for (y = 0; y < ny; y++)
|
||||
{
|
||||
coord[1] = (((double) y + 0.5 ) / ny) * sy;
|
||||
for (x = 0; x < nx; x++)
|
||||
{
|
||||
coord[0] = (((double) x + 0.5 ) / nx) * sx;
|
||||
AddVertex(coord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define VTX(XC, YC, ZC) ((XC)+((YC)+(ZC)*(ny+1))*(nx+1))
|
||||
#define VTXP(XC, YC, ZC) ((nx+1)*(ny+1)*(nz+1)+(XC)+((YC)+(ZC)*ny)*nx)
|
||||
|
||||
// Sets elements and the corresponding indices of vertices
|
||||
if (sfc_ordering && type == Element::HEXAHEDRON)
|
||||
@@ -2850,14 +2728,14 @@ void Mesh::Make3D(int nx, int ny, int nz, Element::Type type,
|
||||
y = sfc[3*k + 1];
|
||||
z = sfc[3*k + 2];
|
||||
|
||||
ind[0] = VTX(x, y, z );
|
||||
ind[1] = VTX(x+1, y, z );
|
||||
ind[0] = VTX(x , y , z );
|
||||
ind[1] = VTX(x+1, y , z );
|
||||
ind[2] = VTX(x+1, y+1, z );
|
||||
ind[3] = VTX(x, y+1, z );
|
||||
ind[4] = VTX(x, y, z+1);
|
||||
ind[5] = VTX(x+1, y, z+1);
|
||||
ind[3] = VTX(x , y+1, z );
|
||||
ind[4] = VTX(x , y , z+1);
|
||||
ind[5] = VTX(x+1, y , z+1);
|
||||
ind[6] = VTX(x+1, y+1, z+1);
|
||||
ind[7] = VTX(x, y+1, z+1);
|
||||
ind[7] = VTX(x , y+1, z+1);
|
||||
|
||||
AddHex(ind, 1);
|
||||
}
|
||||
@@ -2870,12 +2748,12 @@ void Mesh::Make3D(int nx, int ny, int nz, Element::Type type,
|
||||
{
|
||||
for (x = 0; x < nx; x++)
|
||||
{
|
||||
ind[0] = VTX(x, y, z );
|
||||
ind[1] = VTX(x+1, y, z );
|
||||
ind[0] = VTX(x , y , z );
|
||||
ind[1] = VTX(x+1, y , z );
|
||||
ind[2] = VTX(x+1, y+1, z );
|
||||
ind[3] = VTX(x, y+1, z );
|
||||
ind[4] = VTX(x, y, z+1);
|
||||
ind[5] = VTX(x+1, y, z+1);
|
||||
ind[3] = VTX(x , y+1, z );
|
||||
ind[4] = VTX(x , y , z+1);
|
||||
ind[5] = VTX(x+1, y , z+1);
|
||||
ind[6] = VTX(x+1, y+1, z+1);
|
||||
ind[7] = VTX( x, y+1, z+1);
|
||||
if (type == Element::TETRAHEDRON)
|
||||
@@ -2886,11 +2764,6 @@ void Mesh::Make3D(int nx, int ny, int nz, Element::Type type,
|
||||
{
|
||||
AddHexAsWedges(ind, 1);
|
||||
}
|
||||
else if (type == Element::PYRAMID)
|
||||
{
|
||||
ind[8] = VTXP( x, y, z);
|
||||
AddHexAsPyramids(ind, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddHex(ind, 1);
|
||||
@@ -2906,10 +2779,10 @@ void Mesh::Make3D(int nx, int ny, int nz, Element::Type type,
|
||||
{
|
||||
for (x = 0; x < nx; x++)
|
||||
{
|
||||
ind[0] = VTX(x, y, 0);
|
||||
ind[1] = VTX(x, y+1, 0);
|
||||
ind[0] = VTX(x , y , 0);
|
||||
ind[1] = VTX(x , y+1, 0);
|
||||
ind[2] = VTX(x+1, y+1, 0);
|
||||
ind[3] = VTX(x+1, y, 0);
|
||||
ind[3] = VTX(x+1, y , 0);
|
||||
if (type == Element::TETRAHEDRON)
|
||||
{
|
||||
AddBdrQuadAsTriangles(ind, 1);
|
||||
@@ -2929,10 +2802,10 @@ void Mesh::Make3D(int nx, int ny, int nz, Element::Type type,
|
||||
{
|
||||
for (x = 0; x < nx; x++)
|
||||
{
|
||||
ind[0] = VTX(x, y, nz);
|
||||
ind[1] = VTX(x+1, y, nz);
|
||||
ind[0] = VTX(x , y , nz);
|
||||
ind[1] = VTX(x+1, y , nz);
|
||||
ind[2] = VTX(x+1, y+1, nz);
|
||||
ind[3] = VTX(x, y+1, nz);
|
||||
ind[3] = VTX(x , y+1, nz);
|
||||
if (type == Element::TETRAHEDRON)
|
||||
{
|
||||
AddBdrQuadAsTriangles(ind, 6);
|
||||
@@ -2952,10 +2825,10 @@ void Mesh::Make3D(int nx, int ny, int nz, Element::Type type,
|
||||
{
|
||||
for (y = 0; y < ny; y++)
|
||||
{
|
||||
ind[0] = VTX(0, y, z );
|
||||
ind[1] = VTX(0, y, z+1);
|
||||
ind[2] = VTX(0, y+1, z+1);
|
||||
ind[3] = VTX(0, y+1, z );
|
||||
ind[0] = VTX(0 , y , z );
|
||||
ind[1] = VTX(0 , y , z+1);
|
||||
ind[2] = VTX(0 , y+1, z+1);
|
||||
ind[3] = VTX(0 , y+1, z );
|
||||
if (type == Element::TETRAHEDRON)
|
||||
{
|
||||
AddBdrQuadAsTriangles(ind, 5);
|
||||
@@ -2971,10 +2844,10 @@ void Mesh::Make3D(int nx, int ny, int nz, Element::Type type,
|
||||
{
|
||||
for (y = 0; y < ny; y++)
|
||||
{
|
||||
ind[0] = VTX(nx, y, z );
|
||||
ind[0] = VTX(nx, y , z );
|
||||
ind[1] = VTX(nx, y+1, z );
|
||||
ind[2] = VTX(nx, y+1, z+1);
|
||||
ind[3] = VTX(nx, y, z+1);
|
||||
ind[3] = VTX(nx, y , z+1);
|
||||
if (type == Element::TETRAHEDRON)
|
||||
{
|
||||
AddBdrQuadAsTriangles(ind, 3);
|
||||
@@ -2990,10 +2863,10 @@ void Mesh::Make3D(int nx, int ny, int nz, Element::Type type,
|
||||
{
|
||||
for (z = 0; z < nz; z++)
|
||||
{
|
||||
ind[0] = VTX(x, 0, z );
|
||||
ind[0] = VTX(x , 0, z );
|
||||
ind[1] = VTX(x+1, 0, z );
|
||||
ind[2] = VTX(x+1, 0, z+1);
|
||||
ind[3] = VTX(x, 0, z+1);
|
||||
ind[3] = VTX(x , 0, z+1);
|
||||
if (type == Element::TETRAHEDRON)
|
||||
{
|
||||
AddBdrQuadAsTriangles(ind, 2);
|
||||
@@ -3009,8 +2882,8 @@ void Mesh::Make3D(int nx, int ny, int nz, Element::Type type,
|
||||
{
|
||||
for (z = 0; z < nz; z++)
|
||||
{
|
||||
ind[0] = VTX(x, ny, z );
|
||||
ind[1] = VTX(x, ny, z+1);
|
||||
ind[0] = VTX(x , ny, z );
|
||||
ind[1] = VTX(x , ny, z+1);
|
||||
ind[2] = VTX(x+1, ny, z+1);
|
||||
ind[3] = VTX(x+1, ny, z );
|
||||
if (type == Element::TETRAHEDRON)
|
||||
@@ -3555,7 +3428,6 @@ Element *Mesh::NewElement(int geom)
|
||||
#endif
|
||||
case Geometry::CUBE: return (new Hexahedron);
|
||||
case Geometry::PRISM: return (new Wedge);
|
||||
case Geometry::PYRAMID: return (new Pyramid);
|
||||
default:
|
||||
MFEM_ABORT("invalid Geometry::Type, geom = " << geom);
|
||||
}
|
||||
@@ -3648,15 +3520,6 @@ void Mesh::SetMeshGen()
|
||||
meshgen |= 4;
|
||||
break;
|
||||
|
||||
case Element::PYRAMID:
|
||||
mesh_geoms |= (1 << Geometry::PYRAMID);
|
||||
mesh_geoms |= (1 << Geometry::SQUARE);
|
||||
mesh_geoms |= (1 << Geometry::TRIANGLE);
|
||||
mesh_geoms |= (1 << Geometry::SEGMENT);
|
||||
mesh_geoms |= (1 << Geometry::POINT);
|
||||
meshgen |= 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
MFEM_ABORT("invalid element type: " << type);
|
||||
break;
|
||||
@@ -4111,12 +3974,6 @@ void Mesh::MakeRefined_(Mesh &orig_mesh, const Array<int> ref_factors,
|
||||
}
|
||||
}
|
||||
|
||||
if (Dim > 2)
|
||||
{
|
||||
GetElementToFaceTable(false);
|
||||
GenerateFaces();
|
||||
}
|
||||
|
||||
// Add refined boundary elements
|
||||
for (int el = 0; el < orig_mesh.GetNBE(); el++)
|
||||
{
|
||||
@@ -5197,19 +5054,6 @@ int Mesh::CheckElementOrientation(bool fix_it)
|
||||
}
|
||||
break;
|
||||
|
||||
case Element::PYRAMID:
|
||||
// only check the Jacobian at the center of the element
|
||||
GetElementJacobian(i, J);
|
||||
if (J.Det() < 0.0)
|
||||
{
|
||||
wo++;
|
||||
if (fix_it)
|
||||
{
|
||||
// how?
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Element::HEXAHEDRON:
|
||||
// only check the Jacobian at the center of the element
|
||||
GetElementJacobian(i, J);
|
||||
@@ -6292,22 +6136,6 @@ void Mesh::GenerateFaces()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Element::PYRAMID:
|
||||
{
|
||||
for (int j = 0; j < 1; j++)
|
||||
{
|
||||
const int *fv = pyr_t::FaceVert[j];
|
||||
AddQuadFaceElement(j, ef[j], i,
|
||||
v[fv[0]], v[fv[1]], v[fv[2]], v[fv[3]]);
|
||||
}
|
||||
for (int j = 1; j < 5; j++)
|
||||
{
|
||||
const int *fv = pyr_t::FaceVert[j];
|
||||
AddTriangleFaceElement(j, ef[j], i,
|
||||
v[fv[0]], v[fv[1]], v[fv[2]]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Element::HEXAHEDRON:
|
||||
{
|
||||
for (int j = 0; j < 6; j++)
|
||||
@@ -6400,20 +6228,6 @@ STable3D *Mesh::GetFacesTable()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Element::PYRAMID:
|
||||
{
|
||||
for (int j = 0; j < 1; j++)
|
||||
{
|
||||
const int *fv = pyr_t::FaceVert[j];
|
||||
faces_tbl->Push4(v[fv[0]], v[fv[1]], v[fv[2]], v[fv[3]]);
|
||||
}
|
||||
for (int j = 1; j < 5; j++)
|
||||
{
|
||||
const int *fv = pyr_t::FaceVert[j];
|
||||
faces_tbl->Push(v[fv[0]], v[fv[1]], v[fv[2]]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Element::WEDGE:
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
@@ -6488,22 +6302,6 @@ STable3D *Mesh::GetElementToFaceTable(int ret_ftbl)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Element::PYRAMID:
|
||||
{
|
||||
for (int j = 0; j < 1; j++)
|
||||
{
|
||||
const int *fv = pyr_t::FaceVert[j];
|
||||
el_to_face->Push(
|
||||
i, faces_tbl->Push4(v[fv[0]], v[fv[1]], v[fv[2]], v[fv[3]]));
|
||||
}
|
||||
for (int j = 1; j < 5; j++)
|
||||
{
|
||||
const int *fv = pyr_t::FaceVert[j];
|
||||
el_to_face->Push(
|
||||
i, faces_tbl->Push(v[fv[0]], v[fv[1]], v[fv[2]]));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Element::HEXAHEDRON:
|
||||
{
|
||||
// find the face by the vertices with the smallest 3 numbers
|
||||
@@ -7840,22 +7638,8 @@ void Mesh::UniformRefinement3D_base(Array<int> *f2qf_ptr, DSTable *v_to_v_p,
|
||||
}
|
||||
}
|
||||
|
||||
int pyr_counter = 0;
|
||||
if (HasGeometry(Geometry::PYRAMID))
|
||||
{
|
||||
for (int i = 0; i < elements.Size(); i++)
|
||||
{
|
||||
if (elements[i]->GetType() == Element::PYRAMID)
|
||||
{
|
||||
pyr_counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Map from edge-index to vertex-index, needed for ReorientTetMesh() for
|
||||
// parallel meshes.
|
||||
// Note: with the removal of ReorientTetMesh() this may no longer
|
||||
// be needed. Unfortunately, it's hard to be sure.
|
||||
Array<int> e2v;
|
||||
if (HasGeometry(Geometry::TETRAHEDRON))
|
||||
{
|
||||
@@ -7911,7 +7695,7 @@ void Mesh::UniformRefinement3D_base(Array<int> *f2qf_ptr, DSTable *v_to_v_p,
|
||||
Array<Element*> new_boundary;
|
||||
|
||||
vertices.SetSize(oelem + hex_counter);
|
||||
new_elements.SetSize(8 * NumOfElements + 2 * pyr_counter);
|
||||
new_elements.SetSize(8 * NumOfElements);
|
||||
CoarseFineTr.embeddings.SetSize(new_elements.Size());
|
||||
|
||||
hex_counter = 0;
|
||||
@@ -8177,73 +7961,6 @@ void Mesh::UniformRefinement3D_base(Array<int> *f2qf_ptr, DSTable *v_to_v_p,
|
||||
}
|
||||
break;
|
||||
|
||||
case Element::PYRAMID:
|
||||
{
|
||||
const int *f = el_to_face->GetRow(i);
|
||||
// pyr_counter++;
|
||||
|
||||
for (int fi = 0; fi < 1; fi++)
|
||||
{
|
||||
for (int k = 0; k < 4; k++)
|
||||
{
|
||||
vv[k] = v[pyr_t::FaceVert[fi][k]];
|
||||
}
|
||||
AverageVertices(vv, 4, oface + f2qf[f[fi]]);
|
||||
}
|
||||
|
||||
for (int ei = 0; ei < 8; ei++)
|
||||
{
|
||||
for (int k = 0; k < 2; k++)
|
||||
{
|
||||
vv[k] = v[pyr_t::Edges[ei][k]];
|
||||
}
|
||||
AverageVertices(vv, 2, oedge+e[ei]);
|
||||
}
|
||||
|
||||
const int qf0 = f2qf[f[0]];
|
||||
|
||||
new_elements[j++] =
|
||||
new Pyramid(v[0], oedge+e[0], oface+qf0,
|
||||
oedge+e[3], oedge+e[4], attr);
|
||||
|
||||
new_elements[j++] =
|
||||
new Pyramid(oedge+e[0], v[1], oedge+e[1],
|
||||
oface+qf0, oedge+e[5], attr);
|
||||
|
||||
new_elements[j++] =
|
||||
new Pyramid(oface+qf0, oedge+e[1], v[2],
|
||||
oedge+e[2], oedge+e[6], attr);
|
||||
|
||||
new_elements[j++] =
|
||||
new Pyramid(oedge+e[3], oface+qf0, oedge+e[2],
|
||||
v[3], oedge+e[7], attr);
|
||||
|
||||
new_elements[j++] =
|
||||
new Pyramid(oedge+e[4], oedge+e[5], oedge+e[6],
|
||||
oedge+e[7], v[4], attr);
|
||||
|
||||
new_elements[j++] =
|
||||
new Pyramid(oedge+e[7], oedge+e[6], oedge+e[5],
|
||||
oedge+e[4], oface+qf0, attr);
|
||||
|
||||
new_elements[j++] =
|
||||
new Tetrahedron(oedge+e[0], oedge+e[4], oedge+e[5],
|
||||
oface+qf0, attr);
|
||||
|
||||
new_elements[j++] =
|
||||
new Tetrahedron(oedge+e[1], oedge+e[5], oedge+e[6],
|
||||
oface+qf0, attr);
|
||||
|
||||
new_elements[j++] =
|
||||
new Tetrahedron(oedge+e[2], oedge+e[6], oedge+e[7],
|
||||
oface+qf0, attr);
|
||||
|
||||
new_elements[j++] =
|
||||
new Tetrahedron(oedge+e[3], oedge+e[7], oedge+e[4],
|
||||
oface+qf0, attr);
|
||||
}
|
||||
break;
|
||||
|
||||
case Element::HEXAHEDRON:
|
||||
{
|
||||
const int *f = el_to_face->GetRow(i);
|
||||
@@ -8375,7 +8092,7 @@ void Mesh::UniformRefinement3D_base(Array<int> *f2qf_ptr, DSTable *v_to_v_p,
|
||||
}
|
||||
mfem::Swap(boundary, new_boundary);
|
||||
|
||||
static const double A = 0.0, B = 0.5, C = 1.0, D = -1.0;
|
||||
static const double A = 0.0, B = 0.5, C = 1.0;
|
||||
static double tet_children[3*4*16] =
|
||||
{
|
||||
A,A,A, B,A,A, A,B,A, A,A,B,
|
||||
@@ -8401,19 +8118,6 @@ void Mesh::UniformRefinement3D_base(Array<int> *f2qf_ptr, DSTable *v_to_v_p,
|
||||
A,A,B, A,B,B, B,A,B, B,B,A,
|
||||
A,A,B, B,A,B, B,A,A, B,B,A
|
||||
};
|
||||
static double pyr_children[3*5*10] =
|
||||
{
|
||||
A,A,A, B,A,A, B,B,A, A,B,A, A,A,B,
|
||||
B,A,A, C,A,A, C,B,A, B,B,A, B,A,B,
|
||||
B,B,A, C,B,A, C,C,A, B,C,A, B,B,B,
|
||||
A,B,A, B,B,A, B,C,A, A,C,A, A,B,B,
|
||||
A,A,B, B,A,B, B,B,B, A,B,B, A,A,C,
|
||||
A,B,B, B,B,B, B,A,B, A,A,B, B,B,A,
|
||||
B,A,A, A,A,B, B,A,B, B,B,A, D,D,D,
|
||||
C,B,A, B,A,B, B,B,B, B,B,A, D,D,D,
|
||||
B,C,A, B,B,B, A,B,B, B,B,A, D,D,D,
|
||||
A,B,A, A,B,B, A,A,B, B,B,A, D,D,D
|
||||
};
|
||||
static double pri_children[3*6*8] =
|
||||
{
|
||||
A,A,A, B,A,A, A,B,A, A,A,B, B,A,B, A,B,B,
|
||||
@@ -8439,8 +8143,6 @@ void Mesh::UniformRefinement3D_base(Array<int> *f2qf_ptr, DSTable *v_to_v_p,
|
||||
|
||||
CoarseFineTr.point_matrices[Geometry::TETRAHEDRON]
|
||||
.UseExternalData(tet_children, 3, 4, 16);
|
||||
CoarseFineTr.point_matrices[Geometry::PYRAMID]
|
||||
.UseExternalData(pyr_children, 3, 5, 10);
|
||||
CoarseFineTr.point_matrices[Geometry::PRISM]
|
||||
.UseExternalData(pri_children, 3, 6, 8);
|
||||
CoarseFineTr.point_matrices[Geometry::CUBE]
|
||||
@@ -8457,7 +8159,7 @@ void Mesh::UniformRefinement3D_base(Array<int> *f2qf_ptr, DSTable *v_to_v_p,
|
||||
}
|
||||
|
||||
NumOfVertices = vertices.Size();
|
||||
NumOfElements = 8 * NumOfElements + 2 * pyr_counter;
|
||||
NumOfElements = 8 * NumOfElements;
|
||||
NumOfBdrElements = 4 * NumOfBdrElements;
|
||||
|
||||
GetElementToFaceTable();
|
||||
@@ -9041,7 +8743,7 @@ void Mesh::GeneralRefinement(const Array<Refinement> &refinements,
|
||||
else if (nonconforming < 0)
|
||||
{
|
||||
// determine if nonconforming refinement is suitable
|
||||
if ((meshgen & 2) || (meshgen & 4) || (meshgen & 8))
|
||||
if ((meshgen & 2) || (meshgen & 4))
|
||||
{
|
||||
nonconforming = 1; // tensor product elements and wedges
|
||||
}
|
||||
@@ -9825,7 +9527,6 @@ void Mesh::Printer(std::ostream &out, std::string section_delimiter) const
|
||||
"# TETRAHEDRON = 4\n"
|
||||
"# CUBE = 5\n"
|
||||
"# PRISM = 6\n"
|
||||
"# PYRAMID = 7\n"
|
||||
"#\n";
|
||||
|
||||
out << "\ndimension\n" << Dim;
|
||||
|
||||
+1
-19
@@ -177,7 +177,6 @@ protected:
|
||||
int own_nodes;
|
||||
|
||||
static const int vtk_quadratic_tet[10];
|
||||
static const int vtk_quadratic_pyramid[13];
|
||||
static const int vtk_quadratic_wedge[18];
|
||||
static const int vtk_quadratic_hex[27];
|
||||
|
||||
@@ -196,7 +195,6 @@ public:
|
||||
typedef Geometry::Constants<Geometry::TETRAHEDRON> tet_t;
|
||||
typedef Geometry::Constants<Geometry::CUBE> hex_t;
|
||||
typedef Geometry::Constants<Geometry::PRISM> pri_t;
|
||||
typedef Geometry::Constants<Geometry::PYRAMID> pyr_t;
|
||||
|
||||
enum Operation { NONE, REFINE, DEREFINE, REBALANCE };
|
||||
|
||||
@@ -375,17 +373,11 @@ protected:
|
||||
void GetLocalTriToWdgTransformation (IsoparametricTransformation &loc,
|
||||
int i);
|
||||
/// Used in GetFaceElementTransformations (...)
|
||||
void GetLocalTriToPyrTransformation (IsoparametricTransformation &loc,
|
||||
int i);
|
||||
/// Used in GetFaceElementTransformations (...)
|
||||
void GetLocalQuadToHexTransformation (IsoparametricTransformation &loc,
|
||||
int i);
|
||||
/// Used in GetFaceElementTransformations (...)
|
||||
void GetLocalQuadToWdgTransformation (IsoparametricTransformation &loc,
|
||||
int i);
|
||||
/// Used in GetFaceElementTransformations (...)
|
||||
void GetLocalQuadToPyrTransformation (IsoparametricTransformation &loc,
|
||||
int i);
|
||||
|
||||
/** Used in GetFaceElementTransformations to account for the fact that a
|
||||
slave face occupies only a portion of its master face. */
|
||||
@@ -665,15 +657,11 @@ public:
|
||||
int AddWedge(int v1, int v2, int v3, int v4, int v5, int v6, int attr = 1);
|
||||
int AddWedge(const int *vi, int attr = 1);
|
||||
|
||||
int AddPyramid(int v1, int v2, int v3, int v4, int v5, int attr = 1);
|
||||
int AddPyramid(const int *vi, int attr = 1);
|
||||
|
||||
int AddHex(int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8,
|
||||
int attr = 1);
|
||||
int AddHex(const int *vi, int attr = 1);
|
||||
void AddHexAsTets(const int *vi, int attr = 1);
|
||||
void AddHexAsWedges(const int *vi, int attr = 1);
|
||||
void AddHexAsPyramids(const int *vi, int attr = 1);
|
||||
|
||||
/// The parameter @a elem should be allocated using the NewElement() method
|
||||
int AddElement(Element *elem);
|
||||
@@ -841,16 +829,10 @@ public:
|
||||
|
||||
/** @brief Get the mesh generator/type.
|
||||
|
||||
The purpose of this is to be able to quickly tell what type of elements
|
||||
one has in the mesh. Examination of this bitmask along with knowledge
|
||||
of the mesh dimension can be used to identify which element types are
|
||||
present.
|
||||
|
||||
@return A bitmask:
|
||||
- bit 0 - simplices are present in the mesh (triangles, tets),
|
||||
- bit 1 - tensor product elements are present in the mesh (quads, hexes),
|
||||
- bit 2 - the mesh has wedge elements.
|
||||
- bit 3 - the mesh has pyramid elements.
|
||||
|
||||
In parallel, the result takes into account elements on all processors.
|
||||
*/
|
||||
@@ -1245,7 +1227,7 @@ public:
|
||||
satisfy: v0 < min(v1, v2).
|
||||
|
||||
@note Refinement does not work after a call to this method! */
|
||||
MFEM_DEPRECATED virtual void ReorientTetMesh();
|
||||
virtual void ReorientTetMesh();
|
||||
|
||||
int *CartesianPartitioning(int nxyz[]);
|
||||
int *GeneratePartitioning(int nparts, int part_method = 1);
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "mesh_operators.hpp"
|
||||
#include "nurbs.hpp"
|
||||
#include "wedge.hpp"
|
||||
#include "pyramid.hpp"
|
||||
|
||||
#ifdef MFEM_USE_MESQUITE
|
||||
#include "mesquite.hpp"
|
||||
|
||||
+3
-18
@@ -352,11 +352,6 @@ void Mesh::ReadTrueGridMesh(std::istream &input)
|
||||
const int Mesh::vtk_quadratic_tet[10] =
|
||||
{ 0, 1, 2, 3, 4, 7, 5, 6, 8, 9 };
|
||||
|
||||
// see Pyramid::edges & Mesh::GenerateFaces
|
||||
// https://www.vtk.org/doc/nightly/html/classvtkBiQuadraticQuadraticWedge.html
|
||||
const int Mesh::vtk_quadratic_pyramid[13] =
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
|
||||
// see Wedge::edges & Mesh::GenerateFaces
|
||||
// https://www.vtk.org/doc/nightly/html/classvtkBiQuadraticQuadraticWedge.html
|
||||
const int Mesh::vtk_quadratic_wedge[18] =
|
||||
@@ -519,7 +514,8 @@ void Mesh::CreateVTKMesh(const Vector &points, const Array<int> &cell_data,
|
||||
}
|
||||
}
|
||||
}
|
||||
// Generate faces and edges so that we can define FE space on the mesh
|
||||
// Generate faces and edges so that we can define
|
||||
// FE space on the mesh
|
||||
FinalizeTopology();
|
||||
|
||||
FiniteElementCollection *fec;
|
||||
@@ -550,8 +546,6 @@ void Mesh::CreateVTKMesh(const Vector &points, const Array<int> &cell_data,
|
||||
vtk_mfem = vtk_quadratic_hex; break;
|
||||
case Geometry::PRISM:
|
||||
vtk_mfem = vtk_quadratic_wedge; break;
|
||||
case Geometry::PYRAMID:
|
||||
vtk_mfem = vtk_quadratic_pyramid; break;
|
||||
default:
|
||||
vtk_mfem = NULL; // suppress a warning
|
||||
break;
|
||||
@@ -1400,10 +1394,6 @@ void Mesh::ReadInlineMesh(std::istream &input, bool generate_edges)
|
||||
{
|
||||
type = Element::WEDGE;
|
||||
}
|
||||
else if (eltype == "pyramid")
|
||||
{
|
||||
type = Element::PYRAMID;
|
||||
}
|
||||
else if (eltype == "tet")
|
||||
{
|
||||
type = Element::TETRAHEDRON;
|
||||
@@ -1458,7 +1448,7 @@ void Mesh::ReadInlineMesh(std::istream &input, bool generate_edges)
|
||||
Make2D(nx, ny, type, sx, sy, generate_edges, true);
|
||||
}
|
||||
else if (type == Element::TETRAHEDRON || type == Element::WEDGE ||
|
||||
type == Element::HEXAHEDRON || type == Element::PYRAMID)
|
||||
type == Element::HEXAHEDRON)
|
||||
{
|
||||
MFEM_VERIFY(nx > 0 && ny > 0 && nz > 0 &&
|
||||
sx > 0.0 && sy > 0.0 && sz > 0.0,
|
||||
@@ -2455,10 +2445,6 @@ void Mesh::ReadGmshMesh(std::istream &input, int &curved, int &read_gf)
|
||||
// initialize mesh_geoms so we can create Nodes FE space below
|
||||
this->SetMeshGen();
|
||||
|
||||
// Generate faces and edges so that we can define
|
||||
// FE space on the mesh
|
||||
this->FinalizeTopology();
|
||||
|
||||
// Construct GridFunction for uniformly spaced high order coords
|
||||
FiniteElementCollection* nfec;
|
||||
FiniteElementSpace* nfes;
|
||||
@@ -2680,7 +2666,6 @@ void Mesh::ReadGmshMesh(std::istream &input, int &curved, int &read_gf)
|
||||
// Convert nodes to discontinuous GridFunction (if they aren't already)
|
||||
if (mesh_order == 1)
|
||||
{
|
||||
this->FinalizeTopology();
|
||||
this->SetMeshGen();
|
||||
this->SetCurvature(1, true, spaceDim, Ordering::byVDIM);
|
||||
}
|
||||
|
||||
+1
-1
@@ -612,7 +612,7 @@ int NCMesh::NewSegment(int n0, int n1, int attr, int vattr1, int vattr2)
|
||||
// get (degenerate) faces and assign face attributes
|
||||
int v0 = el.node[0], v1 = el.node[1];
|
||||
faces.Get(v0, v0, v0, v0)->attribute = vattr1;
|
||||
faces.Get(v1, v1, v1,v1)->attribute = vattr2;
|
||||
faces.Get(v1, v1, v1 ,v1)->attribute = vattr2;
|
||||
|
||||
return new_id;
|
||||
}
|
||||
|
||||
+4
-243
@@ -34,7 +34,6 @@ ParMesh::ParMesh(const ParMesh &pmesh, bool copy_nodes)
|
||||
group_sedge(pmesh.group_sedge),
|
||||
group_stria(pmesh.group_stria),
|
||||
group_squad(pmesh.group_squad),
|
||||
face_nbr_el_to_face(NULL),
|
||||
glob_elem_offset(-1),
|
||||
glob_offset_sequence(-1),
|
||||
gtopo(pmesh.gtopo)
|
||||
@@ -106,8 +105,7 @@ ParMesh& ParMesh::operator=(ParMesh &&mesh)
|
||||
|
||||
ParMesh::ParMesh(MPI_Comm comm, Mesh &mesh, int *partitioning_,
|
||||
int part_method)
|
||||
: face_nbr_el_to_face(NULL)
|
||||
, glob_elem_offset(-1)
|
||||
: glob_elem_offset(-1)
|
||||
, glob_offset_sequence(-1)
|
||||
, gtopo(comm)
|
||||
{
|
||||
@@ -854,7 +852,6 @@ ParMesh::ParMesh(const ParNCMesh &pncmesh)
|
||||
: MyComm(pncmesh.MyComm)
|
||||
, NRanks(pncmesh.NRanks)
|
||||
, MyRank(pncmesh.MyRank)
|
||||
, face_nbr_el_to_face(NULL)
|
||||
, glob_elem_offset(-1)
|
||||
, glob_offset_sequence(-1)
|
||||
, gtopo(MyComm)
|
||||
@@ -921,8 +918,7 @@ void ParMesh::FinalizeParTopo()
|
||||
}
|
||||
|
||||
ParMesh::ParMesh(MPI_Comm comm, istream &input, bool refine)
|
||||
: face_nbr_el_to_face(NULL)
|
||||
, glob_elem_offset(-1)
|
||||
: glob_elem_offset(-1)
|
||||
, glob_offset_sequence(-1)
|
||||
, gtopo(comm)
|
||||
{
|
||||
@@ -1133,7 +1129,6 @@ void ParMesh::MakeRefined_(ParMesh &orig_mesh, int ref_factor, int ref_type)
|
||||
MyComm = orig_mesh.GetComm();
|
||||
NRanks = orig_mesh.GetNRanks();
|
||||
MyRank = orig_mesh.GetMyRank();
|
||||
face_nbr_el_to_face = NULL;
|
||||
glob_elem_offset = -1;
|
||||
glob_offset_sequence = -1;
|
||||
gtopo = orig_mesh.gtopo;
|
||||
@@ -2078,11 +2073,6 @@ void ParMesh::ExchangeFaceNbrData()
|
||||
|
||||
ExchangeFaceNbrData(gr_sface, s2l_face);
|
||||
|
||||
if (Dim == 3)
|
||||
{
|
||||
GetFaceNbrElementToFaceTable();
|
||||
}
|
||||
|
||||
if (del_tables) { delete gr_sface; }
|
||||
|
||||
if ( have_face_nbr_data ) { return; }
|
||||
@@ -2151,8 +2141,6 @@ void ParMesh::ExchangeFaceNbrData(Table *gr_sface, int *s2l_face)
|
||||
el_marker = -1;
|
||||
vertex_marker = -1;
|
||||
|
||||
Array<int> fcs, cor;
|
||||
|
||||
Table send_face_nbr_elemdata, send_face_nbr_facedata;
|
||||
|
||||
send_face_nbr_elements.MakeI(num_face_nbrs);
|
||||
@@ -2182,9 +2170,7 @@ void ParMesh::ExchangeFaceNbrData(Table *gr_sface, int *s2l_face)
|
||||
send_face_nbr_vertices.AddAColumnInRow(fn);
|
||||
}
|
||||
|
||||
const int nf = elements[el]->GetNFaces();
|
||||
|
||||
send_face_nbr_elemdata.AddColumnsInRow(fn, nv + nf + 2);
|
||||
send_face_nbr_elemdata.AddColumnsInRow(fn, nv + 2);
|
||||
}
|
||||
}
|
||||
send_face_nbr_facedata.AddColumnsInRow(fn, 2*num_sfaces);
|
||||
@@ -2236,13 +2222,6 @@ void ParMesh::ExchangeFaceNbrData(Table *gr_sface, int *s2l_face)
|
||||
send_face_nbr_elemdata.AddConnection(
|
||||
fn, GetElementBaseGeometry(el));
|
||||
send_face_nbr_elemdata.AddConnections(fn, v, nv);
|
||||
|
||||
if (Dim == 3)
|
||||
{
|
||||
const int nf = elements[el]->GetNFaces();
|
||||
GetElementFaces(el, fcs, cor);
|
||||
send_face_nbr_elemdata.AddConnections(fn, cor, nf);
|
||||
}
|
||||
}
|
||||
send_face_nbr_facedata.AddConnection(fn, el);
|
||||
int info = faces_info[lface].Elem1Inf;
|
||||
@@ -2288,13 +2267,12 @@ void ParMesh::ExchangeFaceNbrData(Table *gr_sface, int *s2l_face)
|
||||
for (int el = 0; el < num_elems; el++)
|
||||
{
|
||||
const int nv = elements[elems[el]]->GetNVertices();
|
||||
const int nf = (Dim == 3) ? elements[elems[el]]->GetNFaces() : 0;
|
||||
elemdata += 2; // skip the attribute and the geometry type
|
||||
for (int j = 0; j < nv; j++)
|
||||
{
|
||||
elemdata[j] = vertex_marker[elemdata[j]];
|
||||
}
|
||||
elemdata += nv + nf;
|
||||
elemdata += nv;
|
||||
|
||||
el_marker[elems[el]] = el;
|
||||
}
|
||||
@@ -2345,8 +2323,6 @@ void ParMesh::ExchangeFaceNbrData(Table *gr_sface, int *s2l_face)
|
||||
|
||||
// convert the element data into face_nbr_elements
|
||||
face_nbr_elements.SetSize(face_nbr_elements_offset[num_face_nbrs]);
|
||||
face_nbr_el_ori.Clear();
|
||||
face_nbr_el_ori.SetSize(face_nbr_elements_offset[num_face_nbrs], 6);
|
||||
while (true)
|
||||
{
|
||||
int fn;
|
||||
@@ -2374,20 +2350,9 @@ void ParMesh::ExchangeFaceNbrData(Table *gr_sface, int *s2l_face)
|
||||
}
|
||||
el->SetVertices(recv_elemdata);
|
||||
recv_elemdata += nv;
|
||||
if (Dim == 3)
|
||||
{
|
||||
int nf = el->GetNFaces();
|
||||
int * fn_ori = face_nbr_el_ori.GetRow(elem_off);
|
||||
for (int j = 0; j < nf; j++)
|
||||
{
|
||||
fn_ori[j] = recv_elemdata[j];
|
||||
}
|
||||
recv_elemdata += nf;
|
||||
}
|
||||
face_nbr_elements[elem_off++] = el;
|
||||
}
|
||||
}
|
||||
face_nbr_el_ori.Finalize();
|
||||
|
||||
MPI_Waitall(num_face_nbrs, send_requests, statuses);
|
||||
|
||||
@@ -2546,179 +2511,6 @@ void ParMesh::ExchangeFaceNbrNodes()
|
||||
}
|
||||
}
|
||||
|
||||
STable3D *ParMesh::GetSharedFacesTable()
|
||||
{
|
||||
STable3D *sfaces_tbl = new STable3D(face_nbr_vertices.Size());
|
||||
for (int i = 0; i < face_nbr_elements.Size(); i++)
|
||||
{
|
||||
const int *v = face_nbr_elements[i]->GetVertices();
|
||||
switch (face_nbr_elements[i]->GetType())
|
||||
{
|
||||
case Element::TETRAHEDRON:
|
||||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
const int *fv = tet_t::FaceVert[j];
|
||||
sfaces_tbl->Push(v[fv[0]], v[fv[1]], v[fv[2]]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Element::WEDGE:
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
const int *fv = pri_t::FaceVert[j];
|
||||
sfaces_tbl->Push(v[fv[0]], v[fv[1]], v[fv[2]]);
|
||||
}
|
||||
for (int j = 2; j < 5; j++)
|
||||
{
|
||||
const int *fv = pri_t::FaceVert[j];
|
||||
sfaces_tbl->Push4(v[fv[0]], v[fv[1]], v[fv[2]], v[fv[3]]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Element::HEXAHEDRON:
|
||||
{
|
||||
// find the face by the vertices with the smallest 3 numbers
|
||||
// z = 0, y = 0, x = 1, y = 1, x = 0, z = 1
|
||||
for (int j = 0; j < 6; j++)
|
||||
{
|
||||
const int *fv = hex_t::FaceVert[j];
|
||||
sfaces_tbl->Push4(v[fv[0]], v[fv[1]], v[fv[2]], v[fv[3]]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("Unexpected type of Element.");
|
||||
}
|
||||
}
|
||||
return sfaces_tbl;
|
||||
}
|
||||
|
||||
STable3D *ParMesh::GetFaceNbrElementToFaceTable(int ret_ftbl)
|
||||
{
|
||||
int i, *v;
|
||||
STable3D * faces_tbl = GetFacesTable();
|
||||
STable3D * sfaces_tbl = GetSharedFacesTable();
|
||||
|
||||
if (face_nbr_el_to_face != NULL)
|
||||
{
|
||||
delete face_nbr_el_to_face;
|
||||
}
|
||||
face_nbr_el_to_face = new Table(face_nbr_elements.Size(), 6);
|
||||
for (i = 0; i < face_nbr_elements.Size(); i++)
|
||||
{
|
||||
v = face_nbr_elements[i]->GetVertices();
|
||||
switch (face_nbr_elements[i]->GetType())
|
||||
{
|
||||
case Element::TETRAHEDRON:
|
||||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
const int *fv = tet_t::FaceVert[j];
|
||||
int lf = faces_tbl->Index(v[fv[0]], v[fv[1]], v[fv[2]]);
|
||||
if (lf < 0)
|
||||
{
|
||||
lf = sfaces_tbl->Index(v[fv[0]], v[fv[1]], v[fv[2]]);
|
||||
if (lf >= 0)
|
||||
{
|
||||
lf += NumOfFaces;
|
||||
}
|
||||
}
|
||||
face_nbr_el_to_face->Push(i, lf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Element::WEDGE:
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
const int *fv = pri_t::FaceVert[j];
|
||||
face_nbr_el_to_face->Push(
|
||||
i, faces_tbl->Index(v[fv[0]], v[fv[1]], v[fv[2]]));
|
||||
}
|
||||
for (int j = 2; j < 5; j++)
|
||||
{
|
||||
const int *fv = pri_t::FaceVert[j];
|
||||
int k = 0;
|
||||
int max = v[fv[0]];
|
||||
|
||||
if (max < v[fv[1]]) { max = v[fv[1]], k = 1; }
|
||||
if (max < v[fv[2]]) { max = v[fv[2]], k = 2; }
|
||||
if (max < v[fv[3]]) { k = 3; }
|
||||
|
||||
switch (k)
|
||||
{
|
||||
case 0:
|
||||
face_nbr_el_to_face->Push(
|
||||
i, faces_tbl->Index(v[fv[1]],v[fv[2]],v[fv[3]]));
|
||||
break;
|
||||
case 1:
|
||||
face_nbr_el_to_face->Push(
|
||||
i, faces_tbl->Index(v[fv[0]],v[fv[2]],v[fv[3]]));
|
||||
break;
|
||||
case 2:
|
||||
face_nbr_el_to_face->Push(
|
||||
i, faces_tbl->Index(v[fv[0]],v[fv[1]],v[fv[3]]));
|
||||
break;
|
||||
case 3:
|
||||
face_nbr_el_to_face->Push(
|
||||
i, faces_tbl->Index(v[fv[0]],v[fv[1]],v[fv[2]]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Element::HEXAHEDRON:
|
||||
{
|
||||
// find the face by the vertices with the smallest 3 numbers
|
||||
// z = 0, y = 0, x = 1, y = 1, x = 0, z = 1
|
||||
for (int j = 0; j < 6; j++)
|
||||
{
|
||||
const int *fv = hex_t::FaceVert[j];
|
||||
int k = 0;
|
||||
int max = v[fv[0]];
|
||||
|
||||
if (max < v[fv[1]]) { max = v[fv[1]], k = 1; }
|
||||
if (max < v[fv[2]]) { max = v[fv[2]], k = 2; }
|
||||
if (max < v[fv[3]]) { k = 3; }
|
||||
|
||||
switch (k)
|
||||
{
|
||||
case 0:
|
||||
face_nbr_el_to_face->Push(
|
||||
i, faces_tbl->Index(v[fv[1]],v[fv[2]],v[fv[3]]));
|
||||
break;
|
||||
case 1:
|
||||
face_nbr_el_to_face->Push(
|
||||
i, faces_tbl->Index(v[fv[0]],v[fv[2]],v[fv[3]]));
|
||||
break;
|
||||
case 2:
|
||||
face_nbr_el_to_face->Push(
|
||||
i, faces_tbl->Index(v[fv[0]],v[fv[1]],v[fv[3]]));
|
||||
break;
|
||||
case 3:
|
||||
face_nbr_el_to_face->Push(
|
||||
i, faces_tbl->Index(v[fv[0]],v[fv[1]],v[fv[2]]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("Unexpected type of Element.");
|
||||
}
|
||||
}
|
||||
face_nbr_el_to_face->Finalize();
|
||||
|
||||
if (ret_ftbl)
|
||||
{
|
||||
return faces_tbl;
|
||||
}
|
||||
delete faces_tbl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ParMesh::GetFaceNbrRank(int fn) const
|
||||
{
|
||||
if (Conforming())
|
||||
@@ -2736,37 +2528,6 @@ int ParMesh::GetFaceNbrRank(int fn) const
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ParMesh::GetFaceNbrElementFaces(int i, Array<int> &fcs, Array<int> &cor) const
|
||||
{
|
||||
int n, j;
|
||||
int el_nbr = i - GetNE();
|
||||
if (face_nbr_el_to_face)
|
||||
{
|
||||
face_nbr_el_to_face->GetRow(el_nbr, fcs);
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_ABORT("ParMesh::GetFaceNbrElementFaces(...) : "
|
||||
"face_nbr_el_to_face not generated.");
|
||||
}
|
||||
if (el_nbr < face_nbr_el_ori.Size())
|
||||
{
|
||||
const int * row = face_nbr_el_ori.GetRow(el_nbr);
|
||||
n = fcs.Size();
|
||||
cor.SetSize(n);
|
||||
for (j=0; j<n; j++)
|
||||
{
|
||||
cor[j] = row[j];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_ABORT("ParMesh::GetFaceNbrElementFaces(...) : "
|
||||
"face_nbr_el_to_face not generated.");
|
||||
}
|
||||
}
|
||||
|
||||
Table *ParMesh::GetFaceToAllElementTable() const
|
||||
{
|
||||
const Array<int> *s2l_face;
|
||||
|
||||
+3
-15
@@ -75,9 +75,6 @@ protected:
|
||||
// sface ids: all triangles first, then all quads
|
||||
Array<int> sface_lface;
|
||||
|
||||
Table *face_nbr_el_to_face;
|
||||
Table face_nbr_el_ori; // orientations for each face (from nbr processor)
|
||||
|
||||
IsoparametricTransformation FaceNbrTransformation;
|
||||
|
||||
// glob_elem_offset + local element number defines a global element numbering
|
||||
@@ -106,8 +103,6 @@ protected:
|
||||
bool DecodeFaceSplittings(HashTable<Hashed2> &v_to_v, const int *v,
|
||||
const Array<unsigned> &codes, int &pos);
|
||||
|
||||
STable3D *GetFaceNbrElementToFaceTable(int ret_ftbl = 0);
|
||||
|
||||
void GetFaceNbrElementTransformation(
|
||||
int i, IsoparametricTransformation *ElTr);
|
||||
|
||||
@@ -201,9 +196,6 @@ protected:
|
||||
void BuildSharedVertMapping(int nvert, const Table* vert_element,
|
||||
const Array<int> &vert_global_local);
|
||||
|
||||
// Similar to Mesh::GetFacesTable()
|
||||
STable3D *GetSharedFacesTable();
|
||||
|
||||
/// Ensure that bdr_attributes and attributes agree across processors
|
||||
void DistributeAttributes(Array<int> &attr);
|
||||
|
||||
@@ -224,9 +216,8 @@ protected:
|
||||
|
||||
public:
|
||||
/// Default constructor. Create an empty @a ParMesh.
|
||||
ParMesh() : MyComm(0), NRanks(0), MyRank(-1), face_nbr_el_to_face(NULL),
|
||||
glob_elem_offset(-1), glob_offset_sequence(-1),
|
||||
have_face_nbr_data(false), pncmesh(NULL) { }
|
||||
ParMesh() : MyComm(0), NRanks(0), MyRank(-1), glob_elem_offset(-1),
|
||||
glob_offset_sequence(-1), have_face_nbr_data(false), pncmesh(NULL) { }
|
||||
|
||||
/// Create a parallel mesh by partitioning a serial Mesh.
|
||||
/** The mesh is partitioned automatically or using external partitioning
|
||||
@@ -350,9 +341,6 @@ public:
|
||||
int GetFaceNbrGroup(int fn) const { return face_nbr_group[fn]; }
|
||||
int GetFaceNbrRank(int fn) const;
|
||||
|
||||
/** Similar to Mesh::GetElementFaces */
|
||||
void GetFaceNbrElementFaces(int i, Array<int> &fcs, Array<int> &cor) const;
|
||||
|
||||
/** Similar to Mesh::GetFaceToElementTable with added face-neighbor elements
|
||||
with indices offset by the local number of elements. */
|
||||
Table *GetFaceToAllElementTable() const;
|
||||
@@ -382,7 +370,7 @@ public:
|
||||
int GetSharedFace(int sface) const;
|
||||
|
||||
/// See the remarks for the serial version in mesh.hpp
|
||||
MFEM_DEPRECATED virtual void ReorientTetMesh();
|
||||
virtual void ReorientTetMesh();
|
||||
|
||||
/// Utility function: sum integers from all processors (Allreduce).
|
||||
virtual long ReduceInt(int value) const;
|
||||
|
||||
+2
-1
@@ -84,7 +84,8 @@ public:
|
||||
the PUMI and MFEM meshes. E.g.,
|
||||
PUMI_tet{v0,v1,v2,v3} ---> MFEM_tet{v1,v0,v3,v2}
|
||||
* Note that change in the orientation can be caused by
|
||||
fixing wrong boundary element orientations */
|
||||
a) fixing wrong boundary element orientations
|
||||
b) a call to ReorientTetMesh() which is required for Nedelec */
|
||||
int RotationPUMItoMFEM(apf::Mesh2* apf_mesh,
|
||||
apf::MeshEntity* tet,
|
||||
int elemId);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user