Skip to content
Snippets Groups Projects
Commit 24672d61 authored by Amaury Johnen's avatar Amaury Johnen
Browse files

face closure of HO prisms

parent a558f142
No related branches found
No related tags found
No related merge requests found
...@@ -181,6 +181,20 @@ class MPrism : public MElement { ...@@ -181,6 +181,20 @@ class MPrism : public MElement {
}; };
return f[face][vert]; return f[face][vert];
} }
static int faceClosureEdge2edge(const int face, const int edge)
{
// Warning: numbering of element edge starts here at 1.
// - 0 means no edge (triangular face)
// - negative means going backward
static const int f[5][4] = {
{2, -4, -1, 0},
{7, 9, -8, 0},
{1, 5, -7, -3},
{3, 8, -6, -2},
{4, 6, -9, -5}
};
return f[face][edge];
}
}; };
/* /*
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "nodalBasis.h" #include "nodalBasis.h"
#include "BasisFactory.h" #include "BasisFactory.h"
#include "pointsGenerators.h" #include "pointsGenerators.h"
#include "MPrism.h"
namespace ClosureGen { namespace ClosureGen {
inline double pow2(double x) inline double pow2(double x)
...@@ -409,20 +410,119 @@ namespace ClosureGen { ...@@ -409,20 +410,119 @@ namespace ClosureGen {
} }
} }
void fillInteriorFaceNodes(nodalBasis::closure &closure, int idx, int order,
int isTriangle, int start)
{
int nNodes = isTriangle ? (order-2)*(order-1)/2 : (order-1)*(order-1);
for (int i = 0; i < nNodes; ++i, ++idx, ++start) {
closure[idx] = start;
}
}
void reorderFaceClosure(int iSign, int iRotate, nodalBasis::closure &closure,
int idx, int order, int isTriangle)
{
if (order <= 0) return;
nodalBasis::closure old = closure;
int start = idx;
const int nCorner = isTriangle ? 3 : 4;
for (int i = 0; i < nCorner; ++i, ++idx) {
closure[idx] = old[start + (nCorner + i * iSign + iRotate) % nCorner];
}
const int &nEdge = nCorner;
for (int i = 0; i < nEdge; ++i) {
int iOldEdge = (nEdge + i * iSign + iRotate + (iSign==-1? -1 : 0)) % nEdge;
int startOldEdge = start + nCorner + iOldEdge * (order-1);
if (iSign > 0) {
for (int j = startOldEdge; j < startOldEdge+order-1; ++j, ++idx)
closure[idx] = old[j];
}
else if (iSign < 0) {
for (int j = startOldEdge+order-2; j >= startOldEdge; --j, ++idx)
closure[idx] = old[j];
}
}
if (isTriangle && order > 3)
reorderFaceClosure(iSign, iRotate, closure, idx, order-3, isTriangle);
else if (!isTriangle && order > 2)
reorderFaceClosure(iSign, iRotate, closure, idx, order-2, isTriangle);
}
void getFaceClosurePrism(int iFace, int iSign, int iRotate, void getFaceClosurePrism(int iFace, int iSign, int iRotate,
nodalBasis::closure &closure, int order) nodalBasis::closure &closure, int order)
{ {
//if (order > 2) // printf("HHHHHHHHHHHere %d %d %d %d\n", iFace, iSign, iRotate, order);
// Msg::Error("FaceClosure not implemented for prisms of order %d",order);
bool isTriangle = iFace<2;
int nNodes = isTriangle ? (order+1)*(order+2)/2 : (order+1)*(order+1);
closure.clear(); closure.clear();
bool isTriangle = iFace<2;
if (isTriangle && iRotate > 2) return; if (isTriangle && iRotate > 2) return;
closure.type = ElementType::getTag(isTriangle ? TYPE_TRI : TYPE_QUA, order);
int nNodes = isTriangle ? (order+1)*(order+2)/2 : (order+1)*(order+1);
closure.resize(nNodes); closure.resize(nNodes);
if (order==0) { if (order == 0) {
closure[0] = 0; closure[0] = 0;
return; return;
} }
int *edge2nodes[9];
int n = 6;
for (int i = 0; i < 9; ++i) {
edge2nodes[i] = new int[order-1];
for (int k = 0; k < order-1; ++k, ++n)
edge2nodes[i][k] = n;
}
const int nCorner = isTriangle ? 3 : 4;
for (int i = 0; i < nCorner; ++i) {
closure[i] = MPrism::faces_prism(iFace, i);
}
if (order > 1) {
int idx = nCorner;
const int &nEdge = nCorner;
for (int i = 0; i < nEdge; ++i) {
int edge = MPrism::faceClosureEdge2edge(iFace, i);
if (edge > 0) {
edge = edge-1;
for (int k = 0; k < order-1; ++k, ++idx) {
closure[idx] = edge2nodes[edge][k];
}
}
else if (edge < 0) {
edge = -edge-1;
for (int k = order-2; k >= 0; --k, ++idx) {
closure[idx] = edge2nodes[edge][k];
}
}
}
for (int i = 0; i < 9; ++i) delete edge2nodes[i];
// Numbering of nodes inside the face start at
int start = 6 + 9*(order-1) + std::min(iFace, 2) * (order-2)*(order-1)/2 +
std::max(iFace-2, 0) * (order-1)*(order-1);
fillInteriorFaceNodes(closure, idx, order, isTriangle, start);
}
// printf("Closure 1\n");
// for (unsigned i = 0; i < closure.size(); ++i) {
// printf("%d ", closure[i]);
// }
// printf("\n");
reorderFaceClosure(iSign, iRotate, closure, 0, order, isTriangle);
return;
printf("Reoriented\n");
for (unsigned i = 0; i < closure.size(); ++i) {
printf("%d ", closure[i]);
}
printf("\n");
closure.clear();
closure.resize(nNodes);
//if (order > 2)
// Msg::Error("FaceClosure not implemented for prisms of order %d",order);
int order1node[5][4] = {{0, 2, 1, -1}, {3, 4, 5, -1}, {0, 1, 4, 3}, {0, 3, 5, 2}, int order1node[5][4] = {{0, 2, 1, -1}, {3, 4, 5, -1}, {0, 1, 4, 3}, {0, 3, 5, 2},
{1, 2, 5, 4}}; {1, 2, 5, 4}};
int order2node[5][5] = {{7, 9, 6, -1, -1}, {12, 14, 13, -1, -1}, {6, 10, 12, 8, 15}, int order2node[5][5] = {{7, 9, 6, -1, -1}, {12, 14, 13, -1, -1}, {6, 10, 12, 8, 15},
...@@ -431,6 +531,7 @@ namespace ClosureGen { ...@@ -431,6 +531,7 @@ namespace ClosureGen {
// {8, 13, 11, 7}, {9, 11, 14, 10}}; // {8, 13, 11, 7}, {9, 11, 14, 10}};
int nVertex = isTriangle ? 3 : 4; int nVertex = isTriangle ? 3 : 4;
closure.type = ElementType::getTag(isTriangle ? TYPE_TRI : TYPE_QUA, order); closure.type = ElementType::getTag(isTriangle ? TYPE_TRI : TYPE_QUA, order);
for (int i = 0; i < nVertex; ++i){ for (int i = 0; i < nVertex; ++i){
int k = (nVertex + (iSign * i) + iRotate) % nVertex; //- iSign * iRotate int k = (nVertex + (iSign * i) + iRotate) % nVertex; //- iSign * iRotate
closure[i] = order1node[iFace][k]; closure[i] = order1node[iFace][k];
...@@ -444,12 +545,18 @@ namespace ClosureGen { ...@@ -444,12 +545,18 @@ namespace ClosureGen {
if (!isTriangle) if (!isTriangle)
closure[nNodes-1] = order2node[iFace][4]; // center closure[nNodes-1] = order2node[iFace][4]; // center
} }
printf("Closure 2\n");
for (unsigned i = 0; i < closure.size(); ++i) {
printf("%d ", closure[i]);
}
printf("\n");
} }
void generateFaceClosurePrism(nodalBasis::clCont &closure, int order) void generateFaceClosurePrism(nodalBasis::clCont &closure, int order)
{ {
if (order > 2) // if (order > 2) //fordebug
Msg::Error("FaceClosure not implemented for prisms of order %d",order); // Msg::Fatal("FaceClosure not implemented for prisms of order %d",order);
closure.clear(); closure.clear();
for (int iRotate = 0; iRotate < 4; iRotate++){ for (int iRotate = 0; iRotate < 4; iRotate++){
for (int iSign = 1; iSign >= -1; iSign -= 2){ for (int iSign = 1; iSign >= -1; iSign -= 2){
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment