Forked from
gmsh / gmsh
9485 commits behind the upstream repository.
-
Nicolas Marsic authored
HUGE BUG FIX: correcting rev19884 introduced a new bug -- TriEdgeBasis functions associated to FACES were missing a -1 !! It seems like everything works now :-)!
Nicolas Marsic authoredHUGE BUG FIX: correcting rev19884 introduced a new bug -- TriEdgeBasis functions associated to FACES were missing a -1 !! It seems like everything works now :-)!
TriEdgeBasis.cpp 5.52 KiB
#include "Legendre.h"
#include "GmshDefines.h"
#include "ReferenceSpaceManager.h"
#include "TriEdgeBasis.h"
using namespace std;
TriEdgeBasis::TriEdgeBasis(size_t order){
// Set Basis Type //
this->order = order;
type = TYPE_TRI;
dim = 2;
nVertex = 0;
nEdge = 3 * (order + 1);
nFace = ((order - 1) * order + order - 1);
nCell = 0;
nFunction = nVertex + nEdge + nFace + nCell;
// Reference Space //
const size_t nOrientation = ReferenceSpaceManager::getNOrientation(type);
const vector<vector<vector<size_t> > >&
edgeIdx = ReferenceSpaceManager::getEdgeNodeIndex(type);
const vector<vector<vector<size_t> > >&
faceIdx = ReferenceSpaceManager::getFaceNodeIndex(type);
// Alloc Some Space //
const int orderPlus = order + 1;
const int orderMinus = order - 1;
Polynomial* legendre = new Polynomial[orderPlus];
Polynomial* intLegendre = new Polynomial[orderPlus];
// Legendre Polynomial //
Legendre::legendre(legendre, order);
Legendre::intScaled(intLegendre, orderPlus);
// Lagrange //
const Polynomial lagrange[3] =
{
Polynomial(Polynomial(1, 0, 0, 0) -
Polynomial(1, 1, 0, 0) -
Polynomial(1, 0, 1, 0)),
Polynomial(Polynomial(1, 1, 0, 0)),
Polynomial(Polynomial(1, 0, 1, 0))
};
// One //
Polynomial one(1, 0, 0, 0);
// Basis //
basis = new vector<Polynomial>**[nOrientation];
for(size_t s = 0; s < nOrientation; s++)
basis[s] = new vector<Polynomial>*[nFunction];
// Edge Based //
for(size_t s = 0; s < nOrientation; s++){
size_t i = 0;
for(int e = 0; e < 3; e++){
for(int l = 0; l < orderPlus; l++){
// Nedelec
if(l == 0){
vector<Polynomial> tmp1 = lagrange[edgeIdx[s][e][1]].gradient();
vector<Polynomial> tmp2 = lagrange[edgeIdx[s][e][0]].gradient();
tmp1[0].mul(lagrange[edgeIdx[s][e][0]]);
tmp1[1].mul(lagrange[edgeIdx[s][e][0]]);
tmp1[2].mul(lagrange[edgeIdx[s][e][0]]);
tmp2[0].mul(lagrange[edgeIdx[s][e][1]]);
tmp2[1].mul(lagrange[edgeIdx[s][e][1]]);
tmp2[2].mul(lagrange[edgeIdx[s][e][1]]);
tmp2[0].sub(tmp1[0]);
tmp2[1].sub(tmp1[1]);
tmp2[2].sub(tmp1[2]);
basis[s][i] = new vector<Polynomial>(tmp2);
}
// High Order
else{
basis[s][i] =
new vector<Polynomial>
((intLegendre[l].compose(lagrange[edgeIdx[s][e][0]] -
lagrange[edgeIdx[s][e][1]]
,
lagrange[edgeIdx[s][e][1]] +
lagrange[edgeIdx[s][e][0]])).gradient());
}
i++;
}
}
}
// Face Based //
// NB: We use (*(*faceIdx[s])[f])[]
// where f = 0, because triangles
// have only ONE face: the face '0'
for(size_t s = 0; s < nOrientation; s++){
size_t i = nEdge;
for(size_t l1 = 1; l1 < order; l1++){
for(int l2 = 0; l2 + (int)l1 - 1 < orderMinus; l2++){
// Preliminary Type 1
Polynomial u =
intLegendre[l1].compose(lagrange[faceIdx[s][0][1]] -
lagrange[faceIdx[s][0][0]]
,
lagrange[faceIdx[s][0][0]] +
lagrange[faceIdx[s][0][1]]);
Polynomial v =
lagrange[faceIdx[s][0][2]] *
legendre[l2].compose(lagrange[faceIdx[s][0][2]] * 2 - one);
// Preliminary Type 2
vector<Polynomial> gradU = u.gradient();
vector<Polynomial> gradV = v.gradient();
vector<Polynomial> vGradU(gradU);
vGradU[0].mul(v);
vGradU[1].mul(v);
vGradU[2].mul(v);
vector<Polynomial> uGradV(gradV);
uGradV[0].mul(u);
uGradV[1].mul(u);
uGradV[2].mul(u);
vector<Polynomial> subGradUV(vGradU);
subGradUV[0].sub(uGradV[0]);
subGradUV[1].sub(uGradV[1]);
subGradUV[2].sub(uGradV[2]);
// Preliminary Type 3
vector<Polynomial> gradL1 = lagrange[faceIdx[s][0][0]].gradient();
vector<Polynomial> gradL2 = lagrange[faceIdx[s][0][1]].gradient();
vector<Polynomial> l2GradL1(gradL1);
l2GradL1[0].mul(lagrange[faceIdx[s][0][1]]);
l2GradL1[1].mul(lagrange[faceIdx[s][0][1]]);
l2GradL1[2].mul(lagrange[faceIdx[s][0][1]]);
vector<Polynomial> l1GradL2(gradL2);
l1GradL2[0].mul(lagrange[faceIdx[s][0][0]]);
l1GradL2[1].mul(lagrange[faceIdx[s][0][0]]);
l1GradL2[2].mul(lagrange[faceIdx[s][0][0]]);
vector<Polynomial> subGradL1L2V(l2GradL1);
subGradL1L2V[0].sub(l1GradL2[0]);
subGradL1L2V[1].sub(l1GradL2[1]);
subGradL1L2V[2].sub(l1GradL2[2]);
subGradL1L2V[0].mul(v);
subGradL1L2V[1].mul(v);
subGradL1L2V[2].mul(v);
// Type 1
basis[s][i] = new vector<Polynomial>((u * v).gradient());
i++;
// Type 2
basis[s][i] = new vector<Polynomial>(subGradUV);
i++;
// Type 3
if(l1 == 1){
basis[s][i] = new vector<Polynomial>(subGradL1L2V);
i++;
}
}
}
}
// Clear //
delete[] legendre;
delete[] intLegendre;
}
TriEdgeBasis::~TriEdgeBasis(void){
const size_t nOrientation = ReferenceSpaceManager::getNOrientation(type);
// Basis //
for(size_t i = 0; i < nOrientation; i++){
for(size_t j = 0; j < nFunction; j++)
delete basis[i][j];
delete[] basis[i];
}
delete[] basis;
}