Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
lissmet_2d.c
Go to the documentation of this file.
1/* =============================================================================
2** This file is part of the mmg software package for the tetrahedral
3** mesh modification.
4** Copyright (c) Bx INP/CNRS/Inria/UBordeaux/UPMC, 2004-
5**
6** mmg is free software: you can redistribute it and/or modify it
7** under the terms of the GNU Lesser General Public License as published
8** by the Free Software Foundation, either version 3 of the License, or
9** (at your option) any later version.
10**
11** mmg is distributed in the hope that it will be useful, but WITHOUT
12** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13** FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14** License for more details.
15**
16** You should have received a copy of the GNU Lesser General Public
17** License and of the GNU General Public License along with mmg (in
18** files COPYING.LESSER and COPYING). If not, see
19** <http://www.gnu.org/licenses/>. Please read their terms carefully and
20** use this copy of the mmg distribution only if you accept them.
21** =============================================================================
22*/
34#include "libmmg2d_private.h"
35
48 MMG5_Hash edgeTable;
49 MMG5_hedge *pht;
50 MMG5_pTria pt;
51 MMG5_pPoint p1,p2;
52 double logh,logs,*ma,*mb,ux,uy,d1,d2,dd,rap,dh;
53 double tail,coef,ma1[3],mb1[3],m[3],dd1,dd2;
54 double SQRT3DIV2=0.8660254037844386;
55 int i,itour,maxtou;
56 MMG5_int ncor,nc,k,iadr,a,b;
57 int8_t ier;
58 static int8_t mmgWarn = 0;
59
60 if ( abs(mesh->info.imprim) > 5 || mesh->info.ddebug ) {
61 fprintf(stdout," ** Grading mesh\n");
62 }
63
65
66 logh = mesh->info.hgrad;
67 logs = 0.001 + logh;
68 maxtou = 100;
69 ncor = 0;
70 itour = 0;
71
72 /* alloc hashtable */
73 if ( !MMG5_hashNew(mesh,&edgeTable,mesh->ntmax,3*mesh->ntmax) ) {
74 fprintf(stderr,"\n ## Error: %s: unable to allocate hash table.\n",__func__);
75 return 0;
76 }
77
78 /* build edge table */
79 for(k=1 ; k<=mesh->nt ; k++) {
80 pt = &mesh->tria[k];
81 if ( !MG_EOK(pt) ) {
82 continue;
83 }
84 for(i=0 ; i<3 ; i++) {
85 a = pt->v[MMG2D_iare[i][0]];
86 b = pt->v[MMG2D_iare[i][1]];
87
88 /* Skip edges with a required vertex */
89 if ( mesh->point[a].s || mesh->point[b].s ) {
90 continue;
91 }
92 ier = MMG5_hashEdge(mesh,&edgeTable,a,b,k);
93 if ( !ier ) {
94 if ( !mmgWarn ) {
95 mmgWarn = 1;
96 fprintf(stderr,"\n ## Warning: %s: unable to hash at least one edge"
97 " (tria %" MMG5_PRId ", edge %d).\n",__func__,MMG2D_indElt(mesh,k),i);
98 }
99 }
100 }
101 }
102
103 /* reset color */
104 for (k=1; k<=mesh->np; k++)
105 (&mesh->point[k])->tagdel = mesh->base+1;
106
107 /* analyze mesh edges via hash table */
108 do {
109 ++mesh->base;
110 nc = 0;
111 for (k=0; k<edgeTable.siz; k++) {
112 pht = &edgeTable.item[k];
113 /* analyze linked list */
114 while ( pht ) {
115 if ( !pht->a ) break;
116 a = pht->a;
117 b = pht->b;
118 p1 = &mesh->point[a];
119 p2 = &mesh->point[b];
120 iadr = a*sol->size;
121 ma = &sol->m[iadr];
122 iadr = b*sol->size;
123 mb = &sol->m[iadr];
124
125 if ( (p1->tagdel < mesh->base) && (p2->tagdel < mesh->base) ) {
126 pht = pht->nxt ? &edgeTable.item[pht->nxt] : 0;
127 continue;
128 }
129
130 /* compute edge lengths */
131 ux = p2->c[0] - p1->c[0];
132 uy = p2->c[1] - p1->c[1];
133
134 d1 = ma[0]*ux*ux + ma[2]*uy*uy + 2.0*ma[1]*ux*uy;
135 assert(d1 >=0);
136 if ( d1 < 0.0 ) d1 = 0.0;
137 dd1 = M_MAX(MMG2D_EPSD,sqrt(d1));
138
139 d2 = mb[0]*ux*ux + mb[2]*uy*uy+ 2.0*mb[1]*ux*uy;
140 assert(d2 >=0);
141 if ( d2 < 0.0 ) d2 = 0.0;
142 dd2 = M_MAX(MMG2D_EPSD,sqrt(d2));
143
144 /* swap vertices */
145 if ( dd1 > dd2 ) {
146 p1 = &mesh->point[b];
147 p2 = &mesh->point[a];
148 mb = ma;
149 iadr = b*sol->size;
150 ma = &sol->m[iadr];
151 dd = dd1;
152 dd1 = dd2;
153 dd2 = dd;
154 }
155 rap = dd2 / dd1;
156 dh = rap - 1.0;
157 if ( fabs(dh) > MMG2D_EPSD ) {
158 // Edge length in the metric
159 tail = (dd1+dd2+4*sqrt(0.5*(d1+d2))) / 6.0;
160 coef = log(rap) / tail;
161 p1->tagdel = mesh->base+1;
162 p2->tagdel = mesh->base+1;
163
164 /* update sizes */
165 if ( coef > logs ) {
166 coef = exp(tail*logh);
167 p1->tagdel = mesh->base;
168 p2->tagdel = mesh->base;
169
170 /* metric intersection */
171 coef = 1.0 / (coef*coef);
172 for (i=0; i<3; i++) {
173 ma1[i] = coef * ma[i];
174 mb1[i] = coef * mb[i];
175 }
176
177 if ( MMG5_intersecmet22(mesh,ma,mb1,m) ) {
178 for (i=0; i<3; i++) ma[i] = m[i];
179 }
180 else {
181 for (i=0; i<3; i++) ma[i] = SQRT3DIV2 * (ma[i]+mb1[i]);
182 }
183 if ( MMG5_intersecmet22(mesh,ma1,mb,m) ) {
184 for (i=0; i<3; i++) mb[i] = m[i];
185 }
186 else {
187 for (i=0; i<3; i++) mb[i] = SQRT3DIV2 * (mb[i]+ma1[i]);
188 }
189 nc++;
190 }
191 }
192 /* next edge */
193 pht = pht->nxt ? &edgeTable.item[pht->nxt] : 0;
194 }
195 }
196 ncor += nc;
197 } while ( nc && ++itour < maxtou );
198 MMG5_SAFE_FREE(edgeTable.item);
199
200 if ( abs(mesh->info.imprim) > 3 && ncor ) {
201 fprintf(stdout," gradation: %7" MMG5_PRId " updated, %d iter.\n",ncor,itour);
202 }
203
204 return 1;
205}
int ier
MMG5_pMesh MMG5_pSol * sol
MMG5_pMesh * mesh
int MMG5_hashNew(MMG5_pMesh mesh, MMG5_Hash *hash, MMG5_int hsiz, MMG5_int hmax)
Definition: hash.c:526
int MMG5_hashEdge(MMG5_pMesh mesh, MMG5_Hash *hash, MMG5_int a, MMG5_int b, MMG5_int k)
Definition: hash.c:345
void MMG5_mark_pointsOnReqEdge_fromTria(MMG5_pMesh mesh)
Definition: isosiz.c:243
static const int MMG2D_iare[3][2]
#define M_MAX(a, b)
#define MMG2D_EPSD
MMG5_int MMG2D_indElt(MMG5_pMesh mesh, MMG5_int kel)
Definition: tools_2d.c:46
int lissmet_ani(MMG5_pMesh mesh, MMG5_pSol sol)
Definition: lissmet_2d.c:47
int MMG5_intersecmet22(MMG5_pMesh mesh, double *m, double *n, double *mr)
Definition: mettools.c:814
#define MG_EOK(pt)
#define MMG5_SAFE_FREE(ptr)
Identic as MMG5_HGeom but use MMG5_hedge to store edges instead of MMG5_hgeom (memory economy).
Definition: libmmgtypes.h:595
MMG5_hedge * item
Definition: libmmgtypes.h:597
MMG5_int siz
Definition: libmmgtypes.h:596
int8_t ddebug
Definition: libmmgtypes.h:532
double hgrad
Definition: libmmgtypes.h:518
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_int ntmax
Definition: libmmgtypes.h:612
MMG5_Info info
Definition: libmmgtypes.h:651
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_int base
Definition: libmmgtypes.h:616
MMG5_int nt
Definition: libmmgtypes.h:612
MMG5_pTria tria
Definition: libmmgtypes.h:647
MMG5_int np
Definition: libmmgtypes.h:612
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
int8_t tagdel
Definition: libmmgtypes.h:286
double c[3]
Definition: libmmgtypes.h:271
MMG5_int s
Definition: libmmgtypes.h:283
MMG5_int v[3]
Definition: libmmgtypes.h:334
Used to hash edges (memory economy compared to MMG5_hgeom).
Definition: libmmgtypes.h:584
MMG5_int b
Definition: libmmgtypes.h:585
MMG5_int a
Definition: libmmgtypes.h:585
MMG5_int nxt
Definition: libmmgtypes.h:585