Skip to content
Snippets Groups Projects
Commit 7c3cf4b7 authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

This commit was manufactured by cvs2svn to create tag 'gmsh_1_63'.

parent 4cacb132
Branches
Tags
No related merge requests found
// $Id: 3D_Bricks.cpp,v 1.18 2006-01-28 18:44:19 geuzaine Exp $
//
// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to <gmsh@geuz.org>.
#include "Gmsh.h"
#include "Numeric.h"
#include "Mesh.h"
void AddSimplexInGrid(Mesh * m, Simplex * s, int boule_boite)
{
double XminBox = 0., XmaxBox = 0., YminBox = 0., YmaxBox = 0., ZmaxBox = 0., ZminBox = 0.;
int Ix1, Ix2, Iy1, Iy2, Iz1, Iz2;
int i, j, k, index;
Brick Br, *pBrick;
if(!m->Grid.init) {
m->Grid.Bricks =
List_Create(m->Grid.Nx * m->Grid.Ny * m->Grid.Nz, 10, sizeof(Brick));
for(i = 0; i < m->Grid.Nx * m->Grid.Ny * m->Grid.Nz; i++) {
Br.pT = List_Create(2, 2, sizeof(Simplex *));
Br.N = i + 1;
List_Add(m->Grid.Bricks, &Br);
}
m->Grid.init = 1;
}
if(boule_boite == BOITE) {
XminBox = XmaxBox = s->V[0]->Pos.X;
YminBox = YmaxBox = s->V[0]->Pos.Y;
ZminBox = ZmaxBox = s->V[0]->Pos.Z;
for(i = 1; i < 4; i++) {
XminBox = DMIN(XminBox, s->V[i]->Pos.X);
XmaxBox = DMAX(XmaxBox, s->V[i]->Pos.X);
YminBox = DMIN(YminBox, s->V[i]->Pos.Y);
YmaxBox = DMAX(YmaxBox, s->V[i]->Pos.Y);
ZminBox = DMIN(ZminBox, s->V[i]->Pos.Z);
ZmaxBox = DMAX(ZmaxBox, s->V[i]->Pos.Z);
}
}
else if(boule_boite == BOULE) {
XminBox = s->Center.X - s->Radius;
XmaxBox = s->Center.X + s->Radius;
YminBox = s->Center.Y - s->Radius;
YmaxBox = s->Center.Y + s->Radius;
ZminBox = s->Center.Z - s->Radius;
ZmaxBox = s->Center.Z + s->Radius;
}
Ix1 = (int)((double)m->Grid.Nx * (XminBox - m->Grid.min.X) /
(m->Grid.max.X - m->Grid.min.X));
Ix2 = (int)((double)m->Grid.Nx * (XmaxBox - m->Grid.min.X) /
(m->Grid.max.X - m->Grid.min.X));
Iy1 = (int)((double)m->Grid.Ny * (YminBox - m->Grid.min.Y) /
(m->Grid.max.Y - m->Grid.min.Y));
Iy2 = (int)((double)m->Grid.Ny * (YmaxBox - m->Grid.min.Y) /
(m->Grid.max.Y - m->Grid.min.Y));
Iz1 = (int)((double)m->Grid.Nz * (ZminBox - m->Grid.min.Z) /
(m->Grid.max.Z - m->Grid.min.Z));
Iz2 = (int)((double)m->Grid.Nz * (ZmaxBox - m->Grid.min.Z) /
(m->Grid.max.Z - m->Grid.min.Z));
Ix1 = IMAX(Ix1, 0);
Ix2 = IMIN(Ix2, m->Grid.Nx - 1);
Iy1 = IMAX(Iy1, 0);
Iy2 = IMIN(Iy2, m->Grid.Ny - 1);
Iz1 = IMAX(Iz1, 0);
Iz2 = IMIN(Iz2, m->Grid.Nz - 1);
for(i = Ix1; i <= Ix2; i++) {
for(j = Iy1; j <= Iy2; j++) {
for(k = Iz1; k <= Iz2; k++) {
index = i + j * m->Grid.Nx + k * m->Grid.Nx * m->Grid.Ny;
pBrick = (Brick *) List_Pointer(m->Grid.Bricks, index);
List_Add(pBrick->pT, &s);
}
}
}
}
// $Id: 3D_Mesh_Old.cpp,v 1.16 2006-01-28 18:44:19 geuzaine Exp $
//
// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to <gmsh@geuz.org>.
/*
Isotropic Delaunay 3D
tant que l'arbre des tetraedres de qualites inacceptables
n'est pas vide {
prendre le plus mauvais tetraedre;
creer un nouveau point;
eliminer les tetraedres dont le cercle circonscrit contient le point;
reconstruire le volume convexe;
}
*/
#include "Gmsh.h"
#include "Numeric.h"
#include "Mesh.h"
#include "3D_Mesh.h"
#include "Create.h"
#include "Context.h"
extern Mesh *THEM, *LOCAL;
extern Context_T CTX;
extern int FACE_DIMENSION;
static Tree_T *Tsd, *Sim_Sur_Le_Bord, *POINTS_TREE;
static List_T *Simplexes_Destroyed, *Simplexes_New, *Suppress;
static List_T *LLL, *POINTS;
static Simplex *THES;
static Vertex *THEV;
static Tree_T *SimXFac;
static double volume, LC3D;
static int ZONEELIMINEE, Methode = 0;
Simplex MyNewBoundary;
int Alerte_Point_Scabreux;
void DebugSimplexe(Simplex * s)
{
int i;
fprintf(stderr, "Simplexe %p = %d %d %d %d \n",
s, s->V[0]->Num, s->V[1]->Num, s->V[2]->Num, s->V[3]->Num);
for(i = 0; i < 4; i++) {
if(s->S[i] != &MyNewBoundary)
printf(" face : %d %d %d -> Simplexe %p\n",
s->F[i].V[0]->Num, s->F[i].V[1]->Num, s->F[i].V[2]->Num,
s->S[i]);
else
printf(" face : %d %d %d -> Simplexe Boundary\n",
s->F[i].V[0]->Num, s->F[i].V[1]->Num, s->F[i].V[2]->Num);
}
}
void VSIM(void *a, void *b)
{
Simplex *S;
S = *(Simplex **) a;
if(S->V[3])
volume += fabs(S->Volume_Simplexe());
}
void add_points(void *a, void *b)
{
Tree_Insert(POINTS_TREE, a);
}
void add_points_2(void *a, void *b)
{
List_Add(POINTS, a);
}
double Interpole_lcTetraedre(Simplex * s, Vertex * v)
{
double mat[3][3], rhs[3], sol[3], det;
s->matsimpl(mat);
rhs[0] = v->Pos.X - s->V[0]->Pos.X;
rhs[1] = v->Pos.Y - s->V[0]->Pos.Y;
rhs[2] = v->Pos.Z - s->V[0]->Pos.Z;
sys3x3(mat, rhs, sol, &det);
if(det == 0.0 ||
(1. - sol[0] - sol[1] - sol[2]) > 1. ||
(1. - sol[0] - sol[1] - sol[2]) < 0. ||
sol[0] > 1. ||
sol[1] > 1. ||
sol[2] > 1. || sol[0] < 0. || sol[1] < 0. || sol[2] < 0.) {
return DMAX(s->V[0]->lc,
DMAX(s->V[1]->lc, DMAX(s->V[2]->lc, s->V[3]->lc)));
//sol[0] = sol[1] = sol[2] = 0.25;
}
return (s->V[0]->lc * (1. - sol[0] - sol[1] - sol[2]) +
sol[0] * s->V[1]->lc + sol[1] * s->V[2]->lc + sol[2] * s->V[3]->lc);
}
Vertex *NewVertex(Simplex * s)
{
Vertex *v;
v =
Create_Vertex(++THEM->MaxPointNum, s->Center.X, s->Center.Y, s->Center.Z,
1., 0.0);
v->lc = Interpole_lcTetraedre(s, v);
return (v);
}
int Pt_In_Circum(Simplex * s, Vertex * v)
{
double d1, d2, eps;
/* Determine si un point est dans le cercle circonscrit a un simplexe */
d1 = s->Radius;
d2 = sqrt(DSQR(v->Pos.X - s->Center.X) +
DSQR(v->Pos.Y - s->Center.Y) + DSQR(v->Pos.Z - s->Center.Z));
eps = fabs(d1 - d2) / (d1 + d2);
if(eps < 1.e-12) {
return (0); // return 1 ? 0 ?
}
if(d2 < d1)
return (1);
return (0);
}
void Action_First_Simplexes(void *a, void *b)
{
Simplex **q;
if(!THES) {
q = (Simplex **) a;
if(Pt_In_Circum(*q, THEV)) {
THES = *q;
}
}
}
void LiS(void *a, void *b)
{
int j, N;
SxF SXF, *pSXF;
Simplex **pS, *S;
pS = (Simplex **) a;
S = *pS;
N = (S->V[3]) ? 4 : 3;
for(j = 0; j < N; j++) {
SXF.F = S->F[j];
if((pSXF = (SxF *) Tree_PQuery(SimXFac, &SXF))) {
/* Creation du lien */
S->S[j] = pSXF->S;
pSXF->S->S[pSXF->NumFaceSimpl] = S;
}
else {
SXF.S = S;
SXF.NumFaceSimpl = j;
Tree_Add(SimXFac, &SXF);
}
}
}
void RzS(void *a, void *b)
{
int j, N;
Simplex **pS, *S;
pS = (Simplex **) a;
S = *pS;
N = (S->V[3]) ? 4 : 3;
for(j = 0; j < N; j++) {
if((S->S[j]) == NULL) {
S->S[j] = &MyNewBoundary;
}
}
}
/* Cree les liens entre les simplexes, c.a.d recherche les voisins */
void Link_Simplexes(List_T * Sim, Tree_T * Tim)
{
Simplex *S;
int i;
SimXFac = Tree_Create(sizeof(SxF), compareSxF);
if(Sim) {
for(i = 0; i < List_Nbr(Sim); i++) {
List_Read(Sim, i, &S);
LiS(&S, NULL);
}
for(i = 0; i < List_Nbr(Sim); i++) {
List_Read(Sim, i, &S);
RzS(&S, NULL);
}
}
else {
Tree_Action(Tim, LiS);
Tree_Action(Tim, RzS);
}
Tree_Delete(SimXFac);
}
void Box_6_Tetraedron(List_T * P, Mesh * m)
{
#define FACT 1.1
#define LOIN 0.2
int i, j;
static int pts[8][3] = { {0, 0, 0},
{1, 0, 0},
{1, 1, 0},
{0, 1, 0},
{0, 0, 1},
{1, 0, 1},
{1, 1, 1},
{0, 1, 1}
};
static int tet[6][4] = { {1, 5, 2, 4},
{2, 5, 6, 4},
{4, 5, 6, 8},
{6, 4, 8, 7},
{6, 4, 7, 3},
{2, 3, 4, 6}
};
double Xm, Ym, Zm, XM, YM, ZM, Xc, Yc, Zc;
Simplex *S, *ps;
Vertex *V, *v, *pv;
List_T *smp;
smp = List_Create(8, 1, sizeof(Simplex *));
V = (Vertex *) Malloc(8 * sizeof(Vertex));
for(i = 0; i < List_Nbr(P); i++) {
List_Read(P, i, &v);
if(!i) {
Xm = XM = v->Pos.X;
Ym = YM = v->Pos.Y;
Zm = ZM = v->Pos.Z;
}
else {
Xm = DMIN(Xm, v->Pos.X);
XM = DMAX(XM, v->Pos.X);
Ym = DMIN(Ym, v->Pos.Y);
YM = DMAX(YM, v->Pos.Y);
Zm = DMIN(Zm, v->Pos.Z);
ZM = DMAX(ZM, v->Pos.Z);
}
}
if(Xm == XM)
XM = Xm + 1.;
if(Ym == YM)
YM = Ym + 1.;
if(Zm == ZM)
ZM = Zm + 1.;
Xc = XM - Xm;
Yc = YM - Ym;
Zc = ZM - Zm;
/* initialisation de la grille */
m->Grid.init = 0;
m->Grid.min.X = Xm - LOIN * FACT * Xc;
m->Grid.min.Y = Ym - LOIN * FACT * Yc;
m->Grid.min.Z = Zm - LOIN * FACT * Zc;
m->Grid.max.X = XM + LOIN * FACT * Xc;
m->Grid.max.Y = YM + LOIN * FACT * Yc;
m->Grid.max.Z = ZM + LOIN * FACT * Zc;
m->Grid.Nx = m->Grid.Ny = m->Grid.Nz = 20;
/* Longueur Caracteristique */
LC3D = sqrt(Xc * Xc + Yc * Yc + Zc * Zc);
/* Points de la boite de 1 a 8
Z 8____________7
| /| /|
| / | / |
| / | / |
5|/___|________/6 |
| 4|________|___|3
| / | /
| / Y | /
| / | /
|/____________|/___ X
1 2
*/
for(i = 0; i < 8; i++) {
if(pts[i][0])
V[i].Pos.X = Xm - LOIN * Xc;
else
V[i].Pos.X = XM + LOIN * Xc;
if(pts[i][1])
V[i].Pos.Y = Ym - LOIN * Yc;
else
V[i].Pos.Y = YM + LOIN * Yc;
if(pts[i][2])
V[i].Pos.Z = Zm - LOIN * Zc;
else
V[i].Pos.Z = ZM + LOIN * Zc;
V[i].Num = -(++THEM->MaxPointNum);
pv = &V[i];
pv->lc = 1.0;
pv->Mov = NULL;
Tree_Replace(m->Vertices, &pv);
}
/* 6 Tetraedres forment le maillage de la boite */
for(i = 0; i < 6; i++) {
S = Create_Simplex(&V[tet[i][0] - 1], &V[tet[i][1] - 1],
&V[tet[i][2] - 1], &V[tet[i][3] - 1]);
List_Add(smp, &S);
}
Link_Simplexes(smp, NULL);
for(i = 0; i < List_Nbr(smp); i++) {
List_Read(smp, i, &ps);
for(j = 0; j < 4; j++)
if(ps->S[j] == NULL)
ps->S[j] = &MyNewBoundary;
Tree_Replace(m->Simplexes, &ps);
}
}
void Fill_Sim_Des(void *a, void *b)
{
Simplex **S;
S = (Simplex **) a;
if(Pt_In_Circum(*S, THEV))
List_Add(Simplexes_Destroyed, a);
}
void TStoLS(void *a, void *b)
{
List_Add(Simplexes_Destroyed, a);
}
void TAtoLA(void *a, void *b)
{
List_Add(Simplexes_New, a);
}
void CrSi(void *a, void *b)
{
SxF *S;
Simplex *s;
S = (SxF *) a;
if(S->NumFaceSimpl == 1) {
s = Create_Simplex(THEV, S->F.V[0], S->F.V[1], S->F.V[2]);
s->iEnt = ZONEELIMINEE;
THEM->Metric->setSimplexQuality(s);
List_Add(Simplexes_New, &s);
}
else if(S->NumFaceSimpl != 2) {
Msg(WARNING, "Huh! Panic in CrSi");
}
}
void NewSimplexes(Mesh * m, List_T * Sim, List_T * news)
{
int i, j;
Tree_T *SimXFac;
Simplex *S;
SxF SXF, *pSXF;
SimXFac = Tree_Create(sizeof(SxF), compareSxF);
for(i = 0; i < List_Nbr(Sim); i++) {
List_Read(Sim, i, &S);
if(!i)
ZONEELIMINEE = S->iEnt;
else {
if(S->iEnt != ZONEELIMINEE) {
Msg(WARNING, "Huh! The elimination failed %d %d",
S->iEnt, ZONEELIMINEE);
}
}
for(j = 0; j < 4; j++) {
SXF.F = S->F[j];
if((pSXF = (SxF *) Tree_PQuery(SimXFac, &SXF))) {
(pSXF->NumFaceSimpl)++;
}
else {
SXF.NumFaceSimpl = 1;
Tree_Add(SimXFac, &SXF);
}
}
}
/* Les faces non communes sont obligatoirement a la frontiere ...
-> Nouveaux simplexes */
Tree_Action(SimXFac, CrSi);
Tree_Delete(SimXFac);
}
/* Methode recursive : Rempli Tsd les simplexes detruits
Invariant : Le simplexe est a eliminer
Le simplexe n'est pas encore considere */
int recur_bowyer(Simplex * s)
{
int i;
Tree_Insert(Tsd, &s);
for(i = 0; i < 4; i++) {
if(s->S[i] && s->S[i] != &MyNewBoundary && !Tree_Query(Tsd, &s->S[i])) {
if(Pt_In_Circum(s->S[i], THEV) && (s->iEnt == s->S[i]->iEnt)) {
recur_bowyer(s->S[i]);
}
else {
if(s->iEnt != s->S[i]->iEnt) {
//Msg(WARNING, "Point scabreux %d", s->S[i]->Num);
Alerte_Point_Scabreux = 1;
}
Tree_Insert(Sim_Sur_Le_Bord, &s->S[i]);
}
}
}
return 1;
}
bool Bowyer_Watson(Mesh * m, Vertex * v, Simplex * S, int force)
{
int i;
Simplex *s;
double volumeold, volumenew;
THEV = v;
double x =
(S->V[0]->Pos.X + S->V[1]->Pos.X + S->V[2]->Pos.X + S->V[3]->Pos.X) / 4.;
double y =
(S->V[0]->Pos.Y + S->V[1]->Pos.Y + S->V[2]->Pos.Y + S->V[3]->Pos.Y) / 4.;
double z =
(S->V[0]->Pos.Z + S->V[1]->Pos.Z + S->V[2]->Pos.Z + S->V[3]->Pos.Z) / 4.;
if(force)
THEM->Metric->Identity();
else
THEM->Metric->setMetric(x, y, z);
Tsd = Tree_Create(sizeof(Simplex *), compareSimplex);
Sim_Sur_Le_Bord = Tree_Create(sizeof(Simplex *), compareSimplex);
List_Reset(Simplexes_Destroyed);
List_Reset(Simplexes_New);
if(Methode) {
Tree_Action(m->Simplexes, Fill_Sim_Des);
}
else {
recur_bowyer(S);
}
Tree_Action(Tsd, TStoLS);
NewSimplexes(m, Simplexes_Destroyed, Simplexes_New);
/* calcul des volumes des simplexes crees */
if(Alerte_Point_Scabreux || !CTX.mesh.speed_max) {
volume = 0.0;
for(i = 0; i < List_Nbr(Simplexes_Destroyed); i++) {
VSIM(List_Pointer(Simplexes_Destroyed, i), NULL);
}
volumeold = volume;
volume = 0.0;
for(i = 0; i < List_Nbr(Simplexes_New); i++) {
VSIM(List_Pointer(Simplexes_New, i), NULL);
}
volumenew = volume;
}
else {
volumeold = 1.0;
volumenew = 1.0;
}
/* critere du volume */
if((fabs(volumeold - volumenew) / (volumeold + volumenew)) > 1.e-8) {
if(Tree_Suppress(m->Simplexes, &S)) {
S->Quality = 0.0;
Tree_Add(m->Simplexes, &S);
}
if(force) {
List_Reset(Simplexes_Destroyed);
List_Reset(Simplexes_New);
Tree_Delete(Sim_Sur_Le_Bord);
Tree_Delete(Tsd);
//printf(" Aie Aie Aie volume changed %g -> %g\n",volumeold,volumenew);
return false;
}
}
else {
Tree_Add(m->Vertices, &THEV);
for(i = 0; i < List_Nbr(Simplexes_New); i++) {
Tree_Add(m->Simplexes, List_Pointer(Simplexes_New, i));
}
/* Suppression des simplexes elimines */
for(i = 0; i < List_Nbr(Simplexes_Destroyed); i++) {
List_Read(Simplexes_Destroyed, i, &s);
if(!Tree_Suppress(m->Simplexes, &s))
Msg(GERROR, "Impossible to delete simplex");
Free_Simplex(&s, 0);
}
/* Creation des liens entre nouveaux simplexes */
Tree_Action(Sim_Sur_Le_Bord, TAtoLA);
Link_Simplexes(Simplexes_New, m->Simplexes);
}
Tree_Delete(Sim_Sur_Le_Bord);
Tree_Delete(Tsd);
return true;
}
void Convex_Hull_Mesh(List_T * Points, Mesh * m)
{
int i, j, N, n;
int Nbr_OK = 0, Nbr_NOTOK = 0;
N = List_Nbr(Points);
n = IMAX(N / 20, 1);
Box_6_Tetraedron(Points, m);
// List_Sort (Points, comparePosition);
for(i = 0; i < N; i++) {
THES = NULL;
List_Read(Points, i, &THEV);
if(Simplexes_New)
for(j = 0; j < List_Nbr(Simplexes_New); j++) {
Action_First_Simplexes(List_Pointer(Simplexes_New, j), NULL);
}
if(!THES) {
Tree_Action(m->Simplexes, Action_First_Simplexes);
Nbr_OK++;
}
else {
Nbr_NOTOK++;
}
if(i % n == n - 1) {
volume = 0.0;
Tree_Action(m->Simplexes, VSIM);
Msg(STATUS3, "Nod=%d/%d Elm=%d", i + 1, N, Tree_Nbr(m->Simplexes));
Msg(STATUS1, "Vol=%g", volume);
}
if(!THES) {
Msg(WARNING, "Vertex (%g,%g,%g) in no simplex", THEV->Pos.X,
THEV->Pos.Y, THEV->Pos.Z);
THEV->Pos.X +=
CTX.mesh.rand_factor * LC3D * (1. -
(double)rand() / (double)RAND_MAX);
THEV->Pos.Y +=
CTX.mesh.rand_factor * LC3D * (1. -
(double)rand() / (double)RAND_MAX);
THEV->Pos.Z +=
CTX.mesh.rand_factor * LC3D * (1. -
(double)rand() / (double)RAND_MAX);
Tree_Action(m->Simplexes, Action_First_Simplexes);
}
bool ca_marche = Bowyer_Watson(m, THEV, THES, 1);
int count = 0;
while(!ca_marche) {
count++;
double dx =
CTX.mesh.rand_factor * LC3D * (1. -
(double)rand() / (double)RAND_MAX);
double dy =
CTX.mesh.rand_factor * LC3D * (1. -
(double)rand() / (double)RAND_MAX);
double dz =
CTX.mesh.rand_factor * LC3D * (1. -
(double)rand() / (double)RAND_MAX);
THEV->Pos.X += dx;
THEV->Pos.Y += dy;
THEV->Pos.Z += dz;
THES = NULL;
Tree_Action(m->Simplexes, Action_First_Simplexes);
ca_marche = Bowyer_Watson(m, THEV, THES, 1);
THEV->Pos.X -= dx;
THEV->Pos.Y -= dy;
THEV->Pos.Z -= dz;
if(count > 5) {
N++;
List_Add(POINTS, &THEV);
Msg(WARNING, "Unable to add point %d (will try it later)", THEV->Num);
break;
}
}
}
}
void suppress_vertex(void *data, void *dum)
{
Vertex **pv;
pv = (Vertex **) data;
if((*pv)->Num < 0)
List_Add(Suppress, pv);
}
void suppress_simplex(void *data, void *dum)
{
Simplex **pv;
pv = (Simplex **) data;
if((*pv)->iEnt == 0)
List_Add(Suppress, pv);
}
void add_in_bgm(void *a, void *b)
{
Simplex **s, *S;
s = (Simplex **) a;
S = *s;
List_Add(LLL, S);
}
void Bgm_With_Points(Mesh * bgm)
{
int i;
Simplex *s;
bgm->BGM.bgm = List_Create(Tree_Nbr(bgm->Simplexes), 10, sizeof(Simplex));
LLL = bgm->BGM.bgm;
Tree_Action(bgm->Simplexes, add_in_bgm);
for(i = 0; i < List_Nbr(LLL); i++) {
s = (Simplex *) List_Pointer(LLL, i);
AddSimplexInGrid(bgm, s, BOITE);
}
}
void Create_BgMesh(int Type, double lc, Mesh * m)
{
m->BGM.Typ = Type;
switch (Type) {
case CONSTANT:
m->BGM.lc = lc;
break;
case ONFILE:
break;
case WITHPOINTS:
m->BGM.bgm = NULL;
break;
}
}
void Maillage_Volume(void *data, void *dum)
{
Volume *v, **pv;
Mesh M;
Surface S, *s;
Simplex *simp;
Vertex *newv;
int n, N;
double uvw[3];
int i;
FACE_DIMENSION = 2;
pv = (Volume **) data;
v = *pv;
if(v->Dirty) {
Msg(INFO, "Not meshing dirty Volume %d", v->Num);
return;
}
if(Extrude_Mesh(v)) {
}
else if(MeshTransfiniteVolume(v)) {
}
else if(v->Typ == 99999) {
Simplexes_New = List_Create(10, 10, sizeof(Simplex *));
Simplexes_Destroyed = List_Create(10, 10, sizeof(Simplex *));
LOCAL = &M;
Create_BgMesh(THEM->BGM.Typ, .2, LOCAL);
s = &S;
POINTS_TREE = Tree_Create(sizeof(Vertex *), comparePosition);
POINTS = List_Create(100, 100, sizeof(Vertex *));
LOCAL->Simplexes = v->Simplexes;
LOCAL->Vertices = v->Vertices;
for(i = 0; i < List_Nbr(v->Surfaces); i++) {
List_Read(v->Surfaces, i, &s);
Tree_Action(s->Vertices, add_points);
}
Tree_Action(POINTS_TREE, add_points_2);
Tree_Delete(POINTS_TREE);
N = List_Nbr(POINTS);
n = N / 30 + 1;
if(!N)
return;
/* Creation d'un maillage initial respectant la frontiere */
Msg(STATUS2, "Mesh 3D... (initial)");
Convex_Hull_Mesh(POINTS, LOCAL);
if(!Coherence(v, LOCAL))
Msg(GERROR,
"Surface recovery failed (send a bug report with the geo file to <gmsh@geuz.org>!)");
Link_Simplexes(NULL, LOCAL->Simplexes);
if(CTX.mesh.initial_only == 3) {
POINTS_TREE = THEM->Vertices;
Tree_Action(v->Vertices, add_points);
POINTS_TREE = THEM->Simplexes;
Tree_Action(v->Simplexes, add_points);
return;
}
/* Suppression des noeuds de num < 0 */
Suppress = List_Create(10, 10, sizeof(Vertex *));
Tree_Action(v->Vertices, suppress_vertex);
for(i = 0; i < List_Nbr(Suppress); i++) {
Tree_Suppress(v->Vertices, List_Pointer(Suppress, i));
}
List_Delete(Suppress);
/* Suppression des elements dont le num de vol == 0 (cad qui
n'appartiennent a auncun volume defini) */
Suppress = List_Create(10, 10, sizeof(Simplex *));
Tree_Action(v->Simplexes, suppress_simplex);
for(i = 0; i < List_Nbr(Suppress); i++) {
Tree_Suppress(v->Simplexes, List_Pointer(Suppress, i));
}
List_Delete(Suppress);
if(Tree_Nbr(LOCAL->Simplexes) == 0)
return;
/* Si il reste quelque chose a mailler en volume : */
Msg(STATUS2, "Mesh 3D... (final)");
v->Simplexes = LOCAL->Simplexes;
Bgm_With_Points(LOCAL);
POINTS_TREE = THEM->Simplexes;
Tree_Right(LOCAL->Simplexes, &simp);
i = 0;
while(simp->Quality > CONV_VALUE) {
newv = NewVertex(simp);
while(!simp->Pt_In_Simplexe(newv, uvw, 1.e-5) &&
(simp->S[0] == &MyNewBoundary ||
!simp->S[0]->Pt_In_Simplexe(newv, uvw, 1.e-5)) &&
(simp->S[1] == &MyNewBoundary ||
!simp->S[1]->Pt_In_Simplexe(newv, uvw, 1.e-5)) &&
(simp->S[2] == &MyNewBoundary ||
!simp->S[2]->Pt_In_Simplexe(newv, uvw, 1.e-5)) &&
(simp->S[3] == &MyNewBoundary ||
!simp->S[3]->Pt_In_Simplexe(newv, uvw, 1.e-5))) {
Tree_Suppress(LOCAL->Simplexes, &simp);
simp->Quality = 0.1;
Tree_Insert(LOCAL->Simplexes, &simp);
Tree_Right(LOCAL->Simplexes, &simp);
if(simp->Quality < CONV_VALUE)
break;
newv = NewVertex(simp);
}
if(simp->Quality < CONV_VALUE)
break;
i++;
if(i % n == n - 1) {
volume = 0.0;
Tree_Action(LOCAL->Simplexes, VSIM);
Msg(STATUS3, "Nod=%d Elm=%d",
Tree_Nbr(LOCAL->Vertices), Tree_Nbr(LOCAL->Simplexes));
Msg(STATUS1, "Vol(%g) Conv(%g->%g)", volume, simp->Quality,
CONV_VALUE);
double adv = 100. * (CONV_VALUE / simp->Quality);
}
Bowyer_Watson(LOCAL, newv, simp, 0);
Tree_Right(LOCAL->Simplexes, &simp);
}
POINTS_TREE = THEM->Vertices;
Tree_Action(v->Vertices, add_points);
POINTS_TREE = THEM->Simplexes;
Tree_Action(v->Simplexes, add_points);
if(CTX.mesh.quality) {
extern void SwapEdges3D(Mesh * M, Volume * v, double GammaPrescribed,
bool order);
Msg(STATUS3, "Swapping edges (1st pass)");
SwapEdges3D(THEM, v, CTX.mesh.quality, true);
Msg(STATUS3, "Swapping edges (2nd pass)");
SwapEdges3D(THEM, v, CTX.mesh.quality, false);
Msg(STATUS3, "Swapping edges (last pass)");
SwapEdges3D(THEM, v, CTX.mesh.quality, true);
}
if(CTX.mesh.nb_smoothing) {
/*
Msg(STATUS3, "Smoothing volume %d", v->Num);
tnxe = Tree_Create (sizeof (NXE), compareNXE);
create_NXE (v->Vertices, v->Simplexes, tnxe);
for (int i = 0; i < CTX.mesh.nb_smoothing; i++)
Tree_Action (tnxe, ActionLiss);
delete_NXE (tnxe);
Msg(STATUS3, "Swapping edges (last pass)");
SwapEdges3D (THEM, v, 0.5, true);
*/
}
List_Delete(Simplexes_New);
List_Delete(Simplexes_Destroyed);
}
}
#ifndef _MGEOM_SEARCH_H
#define _MGEOM_SEARCH_H
#include <vector>
#include <algorithm>
#define MIN(x,y) ((x<y)?(x):(y))
#define MAX(x,y) ((x>y)?(x):(y))
#define TOL 1.e-06
namespace AOMD {
template <class T>
class Brick
{
public:
std::vector<T*> Objects;
Brick(){}
T* operator [] (int i)
{
if(i < 0 || i >= Objects.size())throw i;
T *obj = Objects[i];
return obj;
}
int size(){return Objects.size();}
};
template <class T, class GetBox, class InteriorCheck>
class mGeomSearch
{
Brick<T> *theTable;
int Nx,Ny,Nz;
double Xmin,Xmax,Ymin,Ymax,Zmin,Zmax;
int getBrickId (double X, double Y, double Z)
{
int Ix = (int)((double)Nx * (X-Xmin) / (Xmax-Xmin));
int Iy = (int)((double)Ny * (Y-Ymin) / (Ymax-Ymin));
int Iz = (int)((double)Nz * (Z-Zmin) / (Zmax-Zmin));
Ix = MIN(Ix,Nx-1);
Iy = MIN(Iy,Ny-1);
Iz = MIN(Iz,Nz-1);
if(Ix<0)Ix=0;
if(Iy<0)Iy=0;
if(Iz<0)Iz=0;
int index = Ix + Iy * Nx + Iz * Nx * Ny;
return index;
}
Brick<T> * getBrick (int index)
{
if(index <0 || index >= Nx*Ny*Nz)throw index;
Brick<T> *b = &(theTable[index]);
return b;
}
GetBox getBox;
InteriorCheck interiorCheck;
public:
mGeomSearch (double x1,
double x2,
double y1,
double y2,
double z1,
double z2,
GetBox g,
InteriorCheck i,
int nx = 10,
int ny = 10,
int nz = 10) : Nx(nx), Ny(ny), Nz(nz),getBox(g),interiorCheck(i)
{
Xmin = x1-TOL; Xmax = x2+TOL;
Ymin = y1-TOL; Ymax = y2+TOL;
Zmin = z1-TOL; Zmax = z2+TOL;
theTable = new Brick<T> [Nx*Ny*Nz];
}
~mGeomSearch ()
{
delete [] theTable;
};
Brick<T> *getBrick(double X, double Y, double Z)
{
return (getBrick(getBrickId(X,Y,Z)));
}
T * find (double X[3] , double U[3]);
bool AddObject ( T *);
bool RemoveObject ( T *);
};
template <class T,class GetBox, class InteriorCheck>
T * mGeomSearch<T,GetBox,InteriorCheck> :: find ( double X[3] ,
double U[3] )
{
Brick<T> *b = getBrick (X[0],X[1],X[2]);
if(!b) return 0;
for(int i=0;i<b->size();i++)
{
T * obj = (*b)[i];
if(interiorCheck(obj,X,U))return obj;
}
return 0;
}
template <class T,class GetBox, class InteriorCheck>
bool mGeomSearch<T,GetBox, InteriorCheck> :: AddObject ( T * obj )
{
int Ix1,Ix2,Iy1,Iy2,Iz1,Iz2;
int i,j,k,index;
Brick<T> *pBrick;
/*Template Objects must overload getBox function*/
double min[3];
double max[3];
getBox(obj,min,max);
Ix1 = (int)( (double)Nx * (min[0] - Xmin) /( Xmax - Xmin ));
Ix2 = (int)( (double)Nx * (max[0] - Xmin) /( Xmax - Xmin ));
Iy1 = (int)( (double)Ny * (min[1] - Ymin) /( Ymax - Ymin ));
Iy2 = (int)( (double)Ny * (max[1] - Ymin) /( Ymax - Ymin ));
Iz1 = (int)( (double)Nz * (min[2] - Zmin) /( Zmax - Zmin ));
Iz2 = (int)( (double)Nz * (max[2] - Zmin) /( Zmax - Zmin ));
Ix1 = MAX(Ix1,0);
Ix2 = MIN(Ix2,Nx-1);
Iy1 = MAX(Iy1,0);
Iy2 = MIN(Iy2,Ny-1);
Iz1 = MAX(Iz1,0);
Iz2 = MIN(Iz2,Nz-1);
for(i=Ix1;i<=Ix2;i++){
for(j=Iy1;j<=Iy2;j++){
for(k=Iz1;k<=Iz2;k++){
index = i + j * Nx + k * Nx * Ny;
pBrick = getBrick(index);
pBrick->Objects.push_back(obj);
}
}
}
return true;
}
template <class T,class GetBox, class InteriorCheck>
bool mGeomSearch<T,GetBox, InteriorCheck> :: RemoveObject ( T * obj )
{
int Ix1,Ix2,Iy1,Iy2,Iz1,Iz2;
int i,j,k,index;
Brick<T> *pBrick;
/*Template Objects must overload getBox function*/
double min[3];
double max[3];
getBox(obj,min,max);
Ix1 = (int)( (double)Nx * (min[0] - Xmin) /( Xmax - Xmin ));
Ix2 = (int)( (double)Nx * (max[0] - Xmin) /( Xmax - Xmin ));
Iy1 = (int)( (double)Ny * (min[1] - Ymin) /( Ymax - Ymin ));
Iy2 = (int)( (double)Ny * (max[1] - Ymin) /( Ymax - Ymin ));
Iz1 = (int)( (double)Nz * (min[2] - Zmin) /( Zmax - Zmin ));
Iz2 = (int)( (double)Nz * (max[2] - Zmin) /( Zmax - Zmin ));
Ix1 = MAX(Ix1,0);
Ix2 = MIN(Ix2,Nx-1);
Iy1 = MAX(Iy1,0);
Iy2 = MIN(Iy2,Ny-1);
Iz1 = MAX(Iz1,0);
Iz2 = MIN(Iz2,Nz-1);
for(i=Ix1;i<=Ix2;i++){
for(j=Iy1;j<=Iy2;j++){
for(k=Iz1;k<=Iz2;k++){
index = i + j * Nx + k * Nx * Ny;
pBrick = getBrick(index);
pBrick->Objects.erase ( std::remove (pBrick->Objects.begin(),pBrick->Objects.end(),obj) ,
pBrick->Objects.end () );
}
}
}
return true;
}
} // end of namespace
#undef TOL
#endif
lcar1 = .0275;
length = 0.25;
height = 1.0;
depth = 0.25;
Point(newp) = {length/2,height/2,depth,lcar1}; /* Point 1 */
Point(newp) = {length/2,height/2,0,lcar1}; /* Point 2 */
Point(newp) = {-length/2,height/2,depth,lcar1}; /* Point 3 */
Point(newp) = {-length/2,-height/2,depth,lcar1}; /* Point 4 */
Point(newp) = {length/2,-height/2,depth,lcar1}; /* Point 5 */
Point(newp) = {length/2,-height/2,0,lcar1}; /* Point 6 */
Point(newp) = {-length/2,height/2,0,lcar1}; /* Point 7 */
Point(newp) = {-length/2,-height/2,0,lcar1}; /* Point 8 */
Line(1) = {3,1};
Line(2) = {3,7};
Line(3) = {7,2};
Line(4) = {2,1};
Line(5) = {1,5};
Line(6) = {5,4};
Line(7) = {4,8};
Line(8) = {8,6};
Line(9) = {6,5};
Line(10) = {6,2};
Line(11) = {3,4};
Line(12) = {8,7};
Line Loop(13) = {-6,-5,-1,11};
Plane Surface(14) = {13};
Line Loop(15) = {4,5,-9,10};
Plane Surface(16) = {15};
Line Loop(17) = {-3,-12,8,10};
Plane Surface(18) = {17};
Line Loop(19) = {7,12,-2,11};
Plane Surface(20) = {19};
Line Loop(21) = {-4,-3,-2,1};
Plane Surface(22) = {21};
Line Loop(23) = {8,9,6,7};
Plane Surface(24) = {23};
Surface Loop(25) = {14,24,-18,22,16,-20};
Complex Volume(26) = {25};
n = 21;
/*
sizex = 4;
sizey = 6;
sizez = 4;
*/
sizex = n*length;
sizey = n*height;
sizez = n*depth;
sizex = 9;
sizey = 33;
sizez = 9;
Transfinite Line {2,4,9,7} = sizez;
Transfinite Line {11,5,10,12} = sizey;
Transfinite Line {3,1,6,8} = sizex;
Transfinite Surface {14} = {5,4,3,1};
Transfinite Surface {16} = {6,2,1,5};
Transfinite Surface {18} = {6,2,7,8};
Transfinite Surface {20} = {3,7,8,4};
Transfinite Surface {22} = {3,7,2,1};
Transfinite Surface {24} = {4,8,6,5};
Recombine Surface {14,16,18,20,22,24};
Transfinite Volume {26} = {3,7,2,1,4,8,6,5};
Physical Surface(200) = {14,16,18,20,24};
Physical Volume(100) = {26};
/*
Mesh.use_cut_plane = 1;
Mesh.cut_planea = 0;
Mesh.cut_planeb = 0;
Mesh.cut_planec = 1;
Mesh.cut_planed = -0.125;
*/
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment