Newer
Older
// Gmsh - Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <gmsh@geuz.org>.
#include <math.h>
#include "MElement.h"
#include "GEntity.h"
#include "Numeric.h"
#include "GaussLegendre1D.h"
#include "Context.h"
#include "qualityMeasures.h"
#include "meshGFaceDelaunayInsertion.h"
#include "meshGRegionDelaunayInsertion.h"
{
x[0] = v0->x(); y[0] = v0->y(); z[0] = v0->z();
x[1] = v1->x(); y[1] = v1->y(); z[1] = v1->z();
if(faceIndex >= 0){
n[0] = n[1] = getFace(faceIndex).normal();
}
else{
MEdge e(v0, v1);
n[0] = n[1] = e.normal();
}
}
void MElement::_getFaceRep(MVertex *v0, MVertex *v1, MVertex *v2,
{
x[0] = v0->x(); x[1] = v1->x(); x[2] = v2->x();
y[0] = v0->y(); y[1] = v1->y(); y[2] = v2->y();
z[0] = v0->z(); z[1] = v1->z(); z[2] = v2->z();
SVector3 t1(x[1] - x[0], y[1] - y[0], z[1] - z[0]);
SVector3 t2(x[2] - x[0], y[2] - y[0], z[2] - z[0]);
SVector3 normal = crossprod(t1, t2);
normal.normalize();
for(int i = 0; i < 3; i++) n[i] = normal;
}
char MElement::getVisibility()
{
if(CTX.hide_unselected && _visible < 2) return false;
return _visible;
}
double MElement::minEdge()
{
double m = 1.e25;
for(int i = 0; i < getNumEdges(); i++){
}
return m;
}
double MElement::maxEdge()
{
double m = 0.;
for(int i = 0; i < getNumEdges(); i++){
}
return m;
}
double MElement::rhoShapeMeasure()
{
double min = minEdge();
double max = maxEdge();
if(max)
return min / max;
else
return 0.;
}
void MElement::getIntegrationPoints(int pOrder, int *npts, IntPt **pts) const
{
Msg::Error("No integration points defined for this type of element");
}
SPoint3 MTriangle::circumcenter()
{
#if defined(HAVE_GMSH_EMBEDDED)
#else
double p1[3] = {_v[0]->x(),_v[0]->y(),_v[0]->z()};
double p2[3] = {_v[1]->x(),_v[1]->y(),_v[1]->z()};
double p3[3] = {_v[2]->x(),_v[2]->y(),_v[2]->z()};
double res[3];
circumCenterXYZ(p1,p2,p3,res);
return SPoint3(res[0],res[1],res[2]);
#endif
}
SPoint3 MTetrahedron::circumcenter()
{
#if defined(HAVE_GMSH_EMBEDDED)
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#else
MTet4 t(this,0);
double res[3];
t.circumcenter(res);
return SPoint3(res[0],res[1],res[2]);
#endif
}
double MTriangle::distoShapeMeasure()
{
#if defined(HAVE_GMSH_EMBEDDED)
return 1.;
#else
return qmDistorsionOfMapping(this);
#endif
}
double MTetrahedron::distoShapeMeasure()
{
#if defined(HAVE_GMSH_EMBEDDED)
return 1.;
#else
return qmDistorsionOfMapping(this);
#endif
}
double MTriangle::gammaShapeMeasure()
{
double MTetrahedron::gammaShapeMeasure()
{
}
double MTetrahedron::etaShapeMeasure()
{
double mat[3][3];
getMat(mat);
return det3x3(mat) / 6.;
}
b[0] = xyz[0] - getVertex(0)->x();
b[1] = xyz[1] - getVertex(0)->y();
b[2] = xyz[2] - getVertex(0)->z();
sys3x3(mat, b, uvw, &det);
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
}
int MHexahedron::getVolumeSign()
{
double mat[3][3];
mat[0][0] = _v[1]->x() - _v[0]->x();
mat[0][1] = _v[3]->x() - _v[0]->x();
mat[0][2] = _v[4]->x() - _v[0]->x();
mat[1][0] = _v[1]->y() - _v[0]->y();
mat[1][1] = _v[3]->y() - _v[0]->y();
mat[1][2] = _v[4]->y() - _v[0]->y();
mat[2][0] = _v[1]->z() - _v[0]->z();
mat[2][1] = _v[3]->z() - _v[0]->z();
mat[2][2] = _v[4]->z() - _v[0]->z();
return sign(det3x3(mat));
}
int MPrism::getVolumeSign()
{
double mat[3][3];
mat[0][0] = _v[1]->x() - _v[0]->x();
mat[0][1] = _v[2]->x() - _v[0]->x();
mat[0][2] = _v[3]->x() - _v[0]->x();
mat[1][0] = _v[1]->y() - _v[0]->y();
mat[1][1] = _v[2]->y() - _v[0]->y();
mat[1][2] = _v[3]->y() - _v[0]->y();
mat[2][0] = _v[1]->z() - _v[0]->z();
mat[2][1] = _v[2]->z() - _v[0]->z();
mat[2][2] = _v[3]->z() - _v[0]->z();
return sign(det3x3(mat));
}
int MPyramid::getVolumeSign()
{
double mat[3][3];
mat[0][0] = _v[1]->x() - _v[0]->x();
mat[0][1] = _v[3]->x() - _v[0]->x();
mat[0][2] = _v[4]->x() - _v[0]->x();
mat[1][0] = _v[1]->y() - _v[0]->y();
mat[1][1] = _v[3]->y() - _v[0]->y();
mat[1][2] = _v[4]->y() - _v[0]->y();
mat[2][0] = _v[1]->z() - _v[0]->z();
mat[2][1] = _v[3]->z() - _v[0]->z();
mat[2][2] = _v[4]->z() - _v[0]->z();
return sign(det3x3(mat));
}
int n = getNumVertices();
for(int i = 0; i < n; i++) {
MVertex *v = getVertex(i);
p[0] += v->x();
p[1] += v->y();
p[2] += v->z();
p[0] /= (double)n;
p[1] /= (double)n;
p[2] /= (double)n;
return p;
std::string MElement::getInfoString()
{
char tmp[256];
sprintf(tmp, "Element %d", getNum());
return std::string(tmp);
}
double MElement::getJacobian(double u, double v, double w, double jac[3][3])
{
jac[0][0] = jac[0][1] = jac[0][2] = 0.;
jac[1][0] = jac[1][1] = jac[1][2] = 0.;
jac[2][0] = jac[2][1] = jac[2][2] = 0.;
double s[3];
switch(getDim()){
case 3 :
for(int i = 0; i < getNumVertices(); i++) {
getGradShapeFunction(i, u, v, w, s);
MVertex *p = getVertex(i);
jac[0][0] += p->x() * s[0]; jac[0][1] += p->y() * s[0]; jac[0][2] += p->z() * s[0];
jac[1][0] += p->x() * s[1]; jac[1][1] += p->y() * s[1]; jac[1][2] += p->z() * s[1];
jac[2][0] += p->x() * s[2]; jac[2][1] += p->y() * s[2]; jac[2][2] += p->z() * s[2];
}
return fabs(jac[0][0] * jac[1][1] * jac[2][2] + jac[0][2] * jac[1][0] * jac[2][1] +
jac[0][1] * jac[1][2] * jac[2][0] - jac[0][2] * jac[1][1] * jac[2][0] -
jac[0][0] * jac[1][2] * jac[2][1] - jac[0][1] * jac[1][0] * jac[2][2]);
case 2 :
for(int i = 0; i < getNumVertices(); i++) {
getGradShapeFunction(i, u, v, w, s);
MVertex *p = getVertex(i);
jac[0][0] += p->x() * s[0]; jac[0][1] += p->y() * s[0]; jac[0][2] += p->z() * s[0];
jac[1][0] += p->x() * s[1]; jac[1][1] += p->y() * s[1]; jac[1][2] += p->z() * s[1];
}
{
double a[3], b[3], c[3];
a[0] = jac[0][0];
a[1] = jac[0][1];
a[2] = jac[0][2];
b[0] = jac[1][0];
b[1] = jac[1][1];
b[2] = jac[1][2];
return sqrt(SQU(jac[0][0] * jac[1][1] - jac[0][1] * jac[1][0]) +
SQU(jac[0][2] * jac[1][0] - jac[0][0] * jac[1][2]) +
SQU(jac[0][1] * jac[1][2] - jac[0][2] * jac[1][1]));
case 1:
for(int i = 0; i < getNumVertices(); i++) {
getGradShapeFunction(i, u, v, w, s);
MVertex *p = getVertex(i);
jac[0][0] += p->x() * s[0]; jac[0][1] += p->y() * s[0]; jac[0][2] += p->z() * s[0];
}
{
double a[3], b[3], c[3];
a[0] = getVertex(1)->x() - getVertex(0)->x();
a[1] = getVertex(1)->y() - getVertex(0)->y();
a[2] = getVertex(1)->z() - getVertex(0)->z();
(fabs(a[1]) >= fabs(a[0]) && fabs(a[1]) >= fabs(a[2]))) {
b[0] = a[1]; b[1] = -a[0]; b[2] = 0.;
}
prodve(a, b, c);
jac[1][0] = b[0]; jac[1][1] = b[1]; jac[1][2] = b[2];
jac[2][0] = c[0]; jac[2][1] = c[1]; jac[2][2] = c[2];
}
return sqrt(SQU(jac[0][0]) + SQU(jac[0][1]) + SQU(jac[0][2]));
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
default:
return 1.;
}
}
void MElement::xyz2uvw(double xyz[3], double uvw[3])
{
// general Newton routine for the nonlinear case (more efficient
// routines are implemented for simplices, where the basis functions
// are linear)
uvw[0] = uvw[1] = uvw[2] = 0.;
int iter = 1, maxiter = 20;
double error = 1., tol = 1.e-6;
while (error > tol && iter < maxiter){
double jac[3][3];
if(!getJacobian(uvw[0], uvw[1], uvw[2], jac)) break;
double xn = 0., yn = 0., zn = 0.;
for (int i = 0; i < getNumVertices(); i++) {
double s;
getShapeFunction(i, uvw[0], uvw[1], uvw[2], s);
MVertex *v = getVertex(i);
xn += v->x() * s;
yn += v->y() * s;
zn += v->z() * s;
}
double inv[3][3];
inv3x3(jac, inv);
double un = uvw[0] +
inv[0][0] * (xyz[0] - xn) + inv[1][0] * (xyz[1] - yn) + inv[2][0] * (xyz[2] - zn);
double vn = uvw[1] +
inv[0][1] * (xyz[0] - xn) + inv[1][1] * (xyz[1] - yn) + inv[2][1] * (xyz[2] - zn) ;
double wn = uvw[2] +
inv[0][2] * (xyz[0] - xn) + inv[1][2] * (xyz[1] - yn) + inv[2][2] * (xyz[2] - zn) ;
error = sqrt(SQU(un - uvw[0]) + SQU(vn - uvw[1]) + SQU(wn - uvw[2]));
uvw[0] = un;
uvw[1] = vn;
uvw[2] = wn;
iter++ ;
}
}
double MElement::interpolate(double val[], double u, double v, double w, int stride)
{
double sum = 0;
int j = 0;
for(int i = 0; i < getNumVertices(); i++){
double s;
getShapeFunction(i, u, v, w, s);
sum += val[j] * s;
j += stride;
}
return sum;
}
void MElement::interpolateGrad(double val[], double u, double v, double w, double f[3],
{
double dfdu[3] = {0., 0., 0.};
int j = 0;
for(int i = 0; i < getNumVertices(); i++){
double s[3];
getGradShapeFunction(i, u, v, w, s);
dfdu[0] += val[j] * s[0];
dfdu[1] += val[j] * s[1];
dfdu[2] += val[j] * s[2];
j += stride;
}
if(invjac){
matvec(invjac, dfdu, f);
}
else{
double jac[3][3], inv[3][3];
getJacobian(u, v, w, jac);
inv3x3(jac, inv);
matvec(inv, dfdu, f);
}
}
void MElement::interpolateCurl(double val[], double u, double v, double w, double f[3],
{
double fx[3], fy[3], fz[3], jac[3][3], inv[3][3];
getJacobian(u, v, w, jac);
inv3x3(jac, inv);
interpolateGrad(&val[0], u, v, w, fx, stride, inv);
interpolateGrad(&val[1], u, v, w, fy, stride, inv);
interpolateGrad(&val[2], u, v, w, fz, stride, inv);
f[0] = fz[1] - fy[2];
f[1] = -(fz[0] - fx[2]);
f[2] = fy[0] - fx[1];
}
double MElement::interpolateDiv(double val[], double u, double v, double w, int stride)
{
double fx[3], fy[3], fz[3], jac[3][3], inv[3][3];
getJacobian(u, v, w, jac);
inv3x3(jac, inv);
interpolateGrad(&val[0], u, v, w, fx, stride, inv);
interpolateGrad(&val[1], u, v, w, fy, stride, inv);
interpolateGrad(&val[2], u, v, w, fz, stride, inv);
return fx[0] + fy[1] + fz[2];
}

Koen Hillewaert
committed
// Expensive, generic version
void MElement::pnt(double u, double v, double w, SPoint3 &p)
{
double x(0), y(0), z(0);
for (int i = 0; i < getNumVertices(); i++) {

Koen Hillewaert
committed
double s;

Koen Hillewaert
committed
MVertex* v = getVertex(i);
x += v->x() * s;
y += v->y() * s;
z += v->z() * s;
}

Koen Hillewaert
committed
}
void MElement::writeMSH(FILE *fp, double version, bool binary, int num,
// if necessary, change the ordering of the vertices to get positive
// volume
setVolumePositive();
if(!binary){
fprintf(fp, "%d %d", num ? num : _num, type);
if(version < 2.0)
fprintf(fp, " 3 %d %d %d", abs(physical), elementary, _partition);
int tags[4] = {num ? num : _num, abs(physical), elementary, _partition};
if(!binary){
for(int i = 0; i < n; i++)
fprintf(fp, " %d", verts[i]);
fprintf(fp, "\n");
}
else{
fwrite(verts, sizeof(int), n, fp);
}
void MElement::writePOS(FILE *fp, bool printElementary, bool printElementNumber,
bool printDisto, double scalingFactor, int elementary)
if(!str) return;
int n = getNumVertices();
fprintf(fp, "%s(", str);
for(int i = 0; i < n; i++){
if(i) fprintf(fp, ",");
fprintf(fp, "%g,%g,%g", getVertex(i)->x() * scalingFactor,
getVertex(i)->y() * scalingFactor, getVertex(i)->z() * scalingFactor);
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
bool first = true;
if(printElementary){
for(int i = 0; i < n; i++){
if(first) first = false; else fprintf(fp, ",");
fprintf(fp, "%d", elementary);
}
}
if(printElementNumber){
for(int i = 0; i < n; i++){
if(first) first = false; else fprintf(fp, ",");
fprintf(fp, "%d", getNum());
}
}
if(printGamma){
double gamma = gammaShapeMeasure();
for(int i = 0; i < n; i++){
if(first) first = false; else fprintf(fp, ",");
fprintf(fp, "%g", gamma);
}
}
if(printEta){
double eta = etaShapeMeasure();
for(int i = 0; i < n; i++){
if(first) first = false; else fprintf(fp, ",");
fprintf(fp, "%g", eta);
}
}
if(printRho){
double rho = rhoShapeMeasure();
for(int i = 0; i < n; i++){
if(first) first = false; else fprintf(fp, ",");
if(printDisto){
double disto = distoShapeMeasure();
for(int i = 0; i < n; i++){
if(first) first = false; else fprintf(fp, ",");
fprintf(fp, "%g", disto);
}
}
void MElement::writeSTL(FILE *fp, bool binary, double scalingFactor)
if(getNumEdges() != 3 && getNumEdges() != 4) return;
int qid[3] = {0, 2, 3};
SVector3 n = getFace(0).normal();
if(!binary){
fprintf(fp, "facet normal %g %g %g\n", n[0], n[1], n[2]);
getVertex(j)->x() * scalingFactor,
getVertex(j)->y() * scalingFactor,
getVertex(j)->z() * scalingFactor);
fprintf(fp, " endloop\n");
fprintf(fp, "endfacet\n");
if(getNumVertices() == 4){
fprintf(fp, "facet normal %g %g %g\n", n[0], n[1], n[2]);
fprintf(fp, " outer loop\n");
for(int j = 0; j < 3; j++)
fprintf(fp, " vertex %g %g %g\n",
getVertex(qid[j])->x() * scalingFactor,
getVertex(qid[j])->y() * scalingFactor,
getVertex(qid[j])->z() * scalingFactor);
fprintf(fp, " endloop\n");
fprintf(fp, "endfacet\n");
}
}
else{
char data[50];
float *coords = (float*)data;
coords[0] = n[0];
coords[1] = n[1];
coords[2] = n[2];
for(int j = 0; j < 3; j++){
coords[3 + 3 * j] = getVertex(j)->x() * scalingFactor;
coords[3 + 3 * j + 1] = getVertex(j)->y() * scalingFactor;
coords[3 + 3 * j + 2] = getVertex(j)->z() * scalingFactor;
}
fwrite(data, sizeof(char), 50, fp);
if(getNumVertices() == 4){
for(int j = 0; j < 3; j++){
coords[3 + 3 * j] = getVertex(qid[j])->x() * scalingFactor;
coords[3 + 3 * j + 1] = getVertex(qid[j])->y() * scalingFactor;
coords[3 + 3 * j + 2] = getVertex(qid[j])->z() * scalingFactor;
}
}
void MElement::writeVRML(FILE *fp)
{
for(int i = 0; i < getNumVertices(); i++)
void MElement::writeVTK(FILE *fp, bool binary)
{
int type = getTypeForUNV();
if(!type) return;
setVolumePositive();
int n = getNumVertices();
if(binary){
verts[0] = n;
for(int i = 0; i < n; i++)
verts[i + 1] = getVertexVTK(i)->getIndex() - 1;
fwrite(verts, sizeof(int), n + 1, fp);
}
else{
fprintf(fp, "%d", n);
for(int i = 0; i < n; i++)
fprintf(fp, " %d", getVertexVTK(i)->getIndex() - 1);
fprintf(fp, "\n");
}
}
void MElement::writeUNV(FILE *fp, int num, int elementary, int physical)
if(!type) return;
setVolumePositive();
int n = getNumVertices();
int physical_property = elementary;
num ? num : _num, type, physical_property, material_property, color, n);
if(type == 21 || type == 24) // linear beam or parabolic beam
fprintf(fp, "%10d%10d%10d\n", 0, 0, 0);
void MElement::writeMESH(FILE *fp, int elementary)
{
for(int i = 0; i < getNumVertices(); i++)
if(!str) return;
setVolumePositive();
int n = getNumVertices();
const char *cont[4] = {"E", "F", "G", "H"};
int ncont = 0;
if(format == 0){ // free field format
fprintf(fp, "%s,%d,%d", str, _num, elementary);
for(int i = 0; i < n; i++){
fprintf(fp, ",%d", getVertexBDF(i)->getIndex());
fprintf(fp, ",+%s%d\n+%s%d", cont[ncont], _num, cont[ncont], _num);
ncont++;
if(n == 2) // CBAR
fprintf(fp, ",0.,0.,0.");
fprintf(fp, "\n");
}
else{ // small or large field format
fprintf(fp, "%-8s%-8d%-8d", str, _num, elementary);
for(int i = 0; i < n; i++){
fprintf(fp, "%-8d", getVertexBDF(i)->getIndex());
fprintf(fp, "+%s%-6d\n+%s%-6d", cont[ncont], _num, cont[ncont], _num);
ncont++;
if(n == 2) // CBAR
fprintf(fp, "%-8s%-8s%-8s", "0.", "0.", "0.");
fprintf(fp, "\n");
int MElement::getInfoMSH(const int typeMSH, const char **const name)
{
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
switch(typeMSH){
case MSH_PNT : if(name) *name = "Point"; return 1;
case MSH_LIN_2 : if(name) *name = "Line 2"; return 2;
case MSH_LIN_3 : if(name) *name = "Line 3"; return 2 + 1;
case MSH_LIN_4 : if(name) *name = "Line 4"; return 2 + 2;
case MSH_LIN_5 : if(name) *name = "Line 5"; return 2 + 3;
case MSH_LIN_6 : if(name) *name = "Line 6"; return 2 + 4;
case MSH_TRI_3 : if(name) *name = "Triangle 3"; return 3;
case MSH_TRI_6 : if(name) *name = "Triangle 6"; return 3 + 3;
case MSH_TRI_9 : if(name) *name = "Triangle 9"; return 3 + 6;
case MSH_TRI_10 : if(name) *name = "Triangle 10"; return 3 + 6 + 1;
case MSH_TRI_12 : if(name) *name = "Triangle 12"; return 3 + 9;
case MSH_TRI_15 : if(name) *name = "Triangle 15"; return 3 + 9 + 3;
case MSH_TRI_15I: if(name) *name = "Triangle 15I"; return 3 + 12;
case MSH_TRI_21 : if(name) *name = "Triangle 21"; return 3 + 12 + 6;
case MSH_QUA_4 : if(name) *name = "Quadrilateral 4"; return 4;
case MSH_QUA_8 : if(name) *name = "Quadrilateral 8"; return 4 + 4;
case MSH_QUA_9 : if(name) *name = "Quadrilateral 9"; return 4 + 4 + 1;
case MSH_TET_4 : if(name) *name = "Tetrahedron 4"; return 4;
case MSH_TET_10 : if(name) *name = "Tetrahedron 10"; return 4 + 6;
case MSH_TET_20 : if(name) *name = "Tetrahedron 20"; return 4 + 12 + 4;
case MSH_TET_34 : if(name) *name = "Tetrahedron 34"; return 4 + 18 + 12 + 0;
case MSH_TET_35 : if(name) *name = "Tetrahedron 35"; return 4 + 18 + 12 + 1;
case MSH_TET_52 : if(name) *name = "Tetrahedron 52"; return 4 + 24 + 24 + 0;
case MSH_TET_56 : if(name) *name = "Tetrahedron 56"; return 4 + 24 + 24 + 4;
case MSH_HEX_8 : if(name) *name = "Hexahedron 8"; return 8;
case MSH_HEX_20 : if(name) *name = "Hexahedron 20"; return 8 + 12;
case MSH_HEX_27 : if(name) *name = "Hexahedron 27"; return 8 + 12 + 6 + 1;
case MSH_PRI_6 : if(name) *name = "Prism 6"; return 6;
case MSH_PRI_15 : if(name) *name = "Prism 15"; return 6 + 9;
case MSH_PRI_18 : if(name) *name = "Prism 18"; return 6 + 9 + 3;
case MSH_PYR_5 : if(name) *name = "Pyramid 5"; return 5;
case MSH_PYR_13 : if(name) *name = "Pyramid 13"; return 5 + 8;
case MSH_PYR_14 : if(name) *name = "Pyramid 14"; return 5 + 8 + 1;
default:
Msg::Error("Unknown type of element %d", typeMSH);
void MLine::pnt(double u,double v,double w,SPoint3& p)
{
double f1, f2;
getShapeFunction(0, u, v, w, f1);
getShapeFunction(1, u, v, w, f2);

Koen Hillewaert
committed
double x = f1 * _v[0]->x() + f2 * _v[1]->x();
double y = f1 * _v[0]->y() + f2 * _v[1]->y();
double z = f1 * _v[0]->z() + f2 * _v[1]->z();

Koen Hillewaert
committed
}
void MLine3::pnt(double u, double v, double w, SPoint3 &p)
{

Koen Hillewaert
committed
double sf[3];
gmshFunctionSpaces::find(MSH_LIN_3).f(u, v, w, sf);
double x = sf[0] * _v[0]->x() + sf[1] * _v[1]->x() + sf[2] * _vs[0]->x();
double y = sf[0] * _v[0]->y() + sf[1] * _v[1]->y() + sf[2] * _vs[0]->y();
double z = sf[0] * _v[0]->z() + sf[1] * _v[1]->z() + sf[2] * _vs[0]->z();
p = SPoint3(x,y,z);
}
void MLine3::getShapeFunction(int num,double uu, double vv,double ww,double& s)
{

Koen Hillewaert
committed
if (num > 2) s = 0.;
double sf[3];
gmshFunctionSpaces::find(MSH_LIN_3).f(uu, vv, ww, sf);
s = sf[num];
}
void MLine3::getGradShapeFunction(int num,double uu,double vv,double ww,double s[3])
{
if (num > 2) for (int i = 0; i < 3; i++) s[i] = 0.;

Koen Hillewaert
committed
double sf[3][3];
gmshFunctionSpaces::find(MSH_LIN_3).df(uu, vv, ww, sf);

Koen Hillewaert
committed
}
void MLineN::pnt(double uu, double vv, double ww, SPoint3 &p)
{

Koen Hillewaert
committed
double sf[6];
switch (getPolynomialOrder()) {
case 1: gmshFunctionSpaces::find(MSH_LIN_2).f(uu, vv, ww, sf); break;
case 2: gmshFunctionSpaces::find(MSH_LIN_3).f(uu, vv, ww, sf); break;
case 3: gmshFunctionSpaces::find(MSH_LIN_4).f(uu, vv, ww, sf); break;
case 4: gmshFunctionSpaces::find(MSH_LIN_5).f(uu, vv, ww, sf); break;
case 5: gmshFunctionSpaces::find(MSH_LIN_6).f(uu, vv, ww, sf); break;
default:
Msg::Error("Order %d line point interpolation not implemented",
getPolynomialOrder());
break;

Koen Hillewaert
committed
}
double x = 0; for (int i = 0; i < 2; i++) x += sf[i] * _v[i]->x();
double y = 0; for (int i = 0; i < 2; i++) y += sf[i] * _v[i]->y();
double z = 0; for (int i = 0; i < 2; i++) z += sf[i] * _v[i]->z();

Koen Hillewaert
committed
for (int i = 0; i < _vs.size(); i++) x += sf[i+2] * _vs[i]->x();
for (int i = 0; i < _vs.size(); i++) y += sf[i+2] * _vs[i]->y();
for (int i = 0; i < _vs.size(); i++) z += sf[i+2] * _vs[i]->z();

Koen Hillewaert
committed

Koen Hillewaert
committed
}
void MLineN::getShapeFunction(int num, double uu, double vv, double ww, double &s)
{

Koen Hillewaert
committed
double sf[6];
switch (getPolynomialOrder()) {
case 1: gmshFunctionSpaces::find(MSH_LIN_2).f(uu, vv, ww, sf); break;
case 2: gmshFunctionSpaces::find(MSH_LIN_3).f(uu, vv, ww, sf); break;
case 3: gmshFunctionSpaces::find(MSH_LIN_4).f(uu, vv, ww, sf); break;
case 4: gmshFunctionSpaces::find(MSH_LIN_5).f(uu, vv, ww, sf); break;
case 5: gmshFunctionSpaces::find(MSH_LIN_6).f(uu, vv, ww, sf); break;
default:
Msg::Error("Order %d line shape function not provided",
getPolynomialOrder());
break;

Koen Hillewaert
committed
}
s = sf[num];
}
void MLineN::getGradShapeFunction(int num, double uu, double vv, double ww, double s[3])
{

Koen Hillewaert
committed
double sf[6][3];
switch (getPolynomialOrder()) {
case 1: gmshFunctionSpaces::find(MSH_LIN_2).df(uu, vv, ww, sf); break;
case 2: gmshFunctionSpaces::find(MSH_LIN_3).df(uu, vv, ww, sf); break;
case 3: gmshFunctionSpaces::find(MSH_LIN_4).df(uu, vv, ww, sf); break;
case 4: gmshFunctionSpaces::find(MSH_LIN_5).df(uu, vv, ww, sf); break;
case 5: gmshFunctionSpaces::find(MSH_LIN_6).df(uu, vv, ww, sf); break;
default:
Msg::Error("Order %d line shape function gradient not implemented",
getPolynomialOrder());
break;

Koen Hillewaert
committed
}

Koen Hillewaert
committed
}
void MTriangle::getShapeFunction(int num, double uu, double vv, double ww, double &s)
{
int nf = getNumFaceVertices();
double fv[256];
if (!nf){
switch(getPolynomialOrder()){
case 1: gmshFunctionSpaces::find(MSH_TRI_3).f(uu, vv, fv); break;
case 2: gmshFunctionSpaces::find(MSH_TRI_6).f(uu, vv, fv); break;
case 3: gmshFunctionSpaces::find(MSH_TRI_9).f(uu, vv, fv); break;
case 4: gmshFunctionSpaces::find(MSH_TRI_12).f(uu, vv, fv); break;
case 5: gmshFunctionSpaces::find(MSH_TRI_15I).f(uu, vv, fv); break;
default:
Msg::Error("Order %d triangle shape function not implemented",
getPolynomialOrder());
break;
}
}
else{
switch(getPolynomialOrder()){
case 1: gmshFunctionSpaces::find(MSH_TRI_3).f(uu, vv, fv); break;
case 2: gmshFunctionSpaces::find(MSH_TRI_6).f(uu, vv, fv); break;
case 3: gmshFunctionSpaces::find(MSH_TRI_10).f(uu, vv, fv); break;
case 4: gmshFunctionSpaces::find(MSH_TRI_15).f(uu, vv, fv); break;
case 5: gmshFunctionSpaces::find(MSH_TRI_21).f(uu, vv, fv); break;
default:
Msg::Error("Order %d triangle shape function not implemented",
getPolynomialOrder());
break;
}
}
s = fv[num];
}
void MTriangle::getGradShapeFunction(int num, double uu, double vv, double ww, double s[3])
{
if (!nf){
switch(getPolynomialOrder()){
case 1: gmshFunctionSpaces::find(MSH_TRI_3).df(uu, vv, ww, grads); break;
case 2: gmshFunctionSpaces::find(MSH_TRI_6).df(uu, vv, ww, grads); break;
case 3: gmshFunctionSpaces::find(MSH_TRI_9).df(uu, vv, ww, grads); break;
case 4: gmshFunctionSpaces::find(MSH_TRI_12).df(uu, vv, ww, grads); break;
case 5: gmshFunctionSpaces::find(MSH_TRI_15I).df(uu, vv, ww, grads); break;
default:
Msg::Error("Order %d triangle shape function gradient not implemented",
getPolynomialOrder());
break;
}
}
else{
switch(getPolynomialOrder()){
case 1: gmshFunctionSpaces::find(MSH_TRI_3).df(uu, vv, ww, grads); break;
case 2: gmshFunctionSpaces::find(MSH_TRI_6).df(uu, vv, ww, grads); break;
case 3: gmshFunctionSpaces::find(MSH_TRI_10).df(uu, vv, ww, grads); break;
case 4: gmshFunctionSpaces::find(MSH_TRI_15).df(uu, vv, ww, grads); break;
case 5: gmshFunctionSpaces::find(MSH_TRI_21).df(uu, vv, ww, grads); break;
default:
Msg::Error("Order %d triangle shape function gradient not implemented",
getPolynomialOrder());
break;
for (int i = 0; i < 2; i++) s[i] = grads[num][i];
void MTriangle::jac(int ord, MVertex *vs[], double uu, double vv, double ww,
double j[2][3])
double grads[256][2];
int nf = getNumFaceVertices();
if (!nf){
switch(ord){
case 1: gmshFunctionSpaces::find(MSH_TRI_3).df(uu, vv, ww, grads); break;
case 2: gmshFunctionSpaces::find(MSH_TRI_6).df(uu, vv, ww, grads); break;
case 3: gmshFunctionSpaces::find(MSH_TRI_9).df(uu, vv, ww, grads); break;
case 4: gmshFunctionSpaces::find(MSH_TRI_12).df(uu, vv, ww, grads); break;
case 5: gmshFunctionSpaces::find(MSH_TRI_15I).df(uu, vv, ww, grads); break;
default: Msg::Error("Order %d triangle jac not implemented", ord); break;
case 1: gmshFunctionSpaces::find(MSH_TRI_3).df(uu, vv, ww, grads); break;
case 2: gmshFunctionSpaces::find(MSH_TRI_6).df(uu, vv, ww, grads); break;
case 3: gmshFunctionSpaces::find(MSH_TRI_10).df(uu, vv, ww, grads); break;
case 4: gmshFunctionSpaces::find(MSH_TRI_15).df(uu, vv, ww, grads); break;
case 5: gmshFunctionSpaces::find(MSH_TRI_21).df(uu, vv, ww, grads); break;
default: Msg::Error("Order %d triangle jac not implemented", ord); break;
j[0][0] = 0 ; for(int i = 0; i < 3; i++) j[0][0] += grads [i][0] * _v[i]->x();
j[1][0] = 0 ; for(int i = 0; i < 3; i++) j[1][0] += grads [i][1] * _v[i]->x();
j[0][1] = 0 ; for(int i = 0; i < 3; i++) j[0][1] += grads [i][0] * _v[i]->y();
j[1][1] = 0 ; for(int i = 0; i < 3; i++) j[1][1] += grads [i][1] * _v[i]->y();
j[0][2] = 0 ; for(int i = 0; i < 3; i++) j[0][2] += grads [i][0] * _v[i]->z();
j[1][2] = 0 ; for(int i = 0; i < 3; i++) j[1][2] += grads [i][1] * _v[i]->z();
if (ord == 1) return;
for(int i = 3; i < 3 * ord + nf; i++) j[0][0] += grads[i][0] * vs[i - 3]->x();
for(int i = 3; i < 3 * ord + nf; i++) j[1][0] += grads[i][1] * vs[i - 3]->x();
for(int i = 3; i < 3 * ord + nf; i++) j[0][1] += grads[i][0] * vs[i - 3]->y();
for(int i = 3; i < 3 * ord + nf; i++) j[1][1] += grads[i][1] * vs[i - 3]->y();
for(int i = 3; i < 3 * ord + nf; i++) j[0][2] += grads[i][0] * vs[i - 3]->z();
for(int i = 3; i < 3 * ord + nf; i++) j[1][2] += grads[i][1] * vs[i - 3]->z();
void MTriangle::pnt(int ord, MVertex *vs[], double uu, double vv, double ww,
SPoint3 &p)
int nf = getNumFaceVertices();
if (!nf){
switch(ord){
case 1: gmshFunctionSpaces::find(MSH_TRI_3).f(uu, vv, sf); break;
case 2: gmshFunctionSpaces::find(MSH_TRI_6).f(uu, vv, sf); break;
case 3: gmshFunctionSpaces::find(MSH_TRI_9).f(uu, vv, sf); break;
case 4: gmshFunctionSpaces::find(MSH_TRI_12).f(uu, vv, sf); break;
case 5: gmshFunctionSpaces::find(MSH_TRI_15I).f(uu, vv, sf); break;
default: Msg::Error("Order %d triangle pnt not implemented", ord); break;
case 1: gmshFunctionSpaces::find(MSH_TRI_3).f(uu, vv, sf); break;
case 2: gmshFunctionSpaces::find(MSH_TRI_6).f(uu, vv, sf); break;
case 3: gmshFunctionSpaces::find(MSH_TRI_10).f(uu, vv, sf); break;
case 4: gmshFunctionSpaces::find(MSH_TRI_15).f(uu, vv, sf); break;
case 5: gmshFunctionSpaces::find(MSH_TRI_21).f(uu, vv, sf); break;
default: Msg::Error("Order %d triangle pnt not implemented", ord); break;
double x = 0 ; for(int i = 0; i < 3; i++) x += sf[i] * _v[i]->x();
double y = 0 ; for(int i = 0; i < 3; i++) y += sf[i] * _v[i]->y();
double z = 0 ; for(int i = 0; i < 3; i++) z += sf[i] * _v[i]->z();
for(int i = 3; i < 3 * ord + nf; i++) x += sf[i] * vs[i - 3]->x();
for(int i = 3; i < 3 * ord + nf; i++) y += sf[i] * vs[i - 3]->y();
for(int i = 3; i < 3 * ord + nf; i++) z += sf[i] * vs[i - 3]->z();
void MTetrahedron::jac(int ord, MVertex *vs[], double uu, double vv, double ww,
double j[3][3])
{
double grads[256][3];
switch(ord){
case 1: gmshFunctionSpaces::find(MSH_TET_4) .df(uu, vv, ww, grads); break;
case 2: gmshFunctionSpaces::find(MSH_TET_10).df(uu, vv, ww, grads); break;
case 3: gmshFunctionSpaces::find(MSH_TET_20).df(uu, vv, ww, grads); break;
case 4: gmshFunctionSpaces::find(MSH_TET_35).df(uu, vv, ww, grads); break;