Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
zaldy_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
36
37/* Create a new vertex in the mesh, and return its number */
38MMG5_int MMG2D_newPt(MMG5_pMesh mesh,double c[2],uint16_t tag) {
39 MMG5_pPoint ppt;
40 MMG5_int curpt;
41
42 if ( !mesh->npnil ) return 0;
43
44 curpt = mesh->npnil;
45 if ( mesh->npnil > mesh->np ) mesh->np = mesh->npnil;
46 ppt = &mesh->point[curpt];
47 memcpy(ppt->c,c,2*sizeof(double));
48 ppt->tag &= ~MG_NUL;
49 mesh->npnil = ppt->tmp;
50 ppt->tmp = 0;
51 ppt->tag = tag;
52
53 return curpt;
54}
55
56/* Delete a point in the mesh and update the garbage collector accordingly */
57void MMG2D_delPt(MMG5_pMesh mesh,MMG5_int ip) {
58 MMG5_pPoint ppt;
59
60 ppt = &mesh->point[ip];
61
62 memset(ppt,0,sizeof(MMG5_Point));
63 ppt->tag = MG_NUL;
64 ppt->tmp = mesh->npnil;
65
66 mesh->npnil = ip;
67 if ( ip == mesh->np ) {
68 while ( (!MG_VOK((&mesh->point[mesh->np]))) && mesh->np ) mesh->np--;
69 }
70}
71
72void MMG5_delEdge(MMG5_pMesh mesh,MMG5_int iel) {
73 MMG5_pEdge pt;
74
75 pt = &mesh->edge[iel];
76 if ( !pt->a ) {
77 fprintf(stdout," ## INVALID EDGE.\n");
78 return;
79 }
80 memset(pt,0,sizeof(MMG5_Edge));
81 pt->b = mesh->nanil;
82 mesh->nanil = iel;
83 if ( iel == mesh->na ) mesh->na--;
84}
85
86/* Create a new triangle in the mesh and return its address */
88 MMG5_int curiel;
89
90 if ( !mesh->nenil ) {
91 return 0;
92 }
93 curiel = mesh->nenil;
94 if ( mesh->nenil > mesh->nt ) mesh->nt = mesh->nenil;
95 mesh->nenil = mesh->tria[curiel].v[2];
96 mesh->tria[curiel].v[2] = 0;
97 mesh->tria[curiel].ref = 0;
98 mesh->tria[curiel].base = 0;
99 mesh->tria[curiel].edg[0] = 0;
100 mesh->tria[curiel].edg[1] = 0;
101 mesh->tria[curiel].edg[2] = 0;
102
103 return curiel;
104}
105
106/* Delete a triangle in the mesh and update the garbage collector accordingly */
107int MMG2D_delElt(MMG5_pMesh mesh,MMG5_int iel) {
108 MMG5_pTria pt;
109 MMG5_int iadr;
110
111 pt = &mesh->tria[iel];
112 if ( !MG_EOK(pt) ) {
113 fprintf(stdout," ## INVALID ELEMENT.\n");
114 return 0;
115 }
116 memset(pt,0,sizeof(MMG5_Tria));
117 pt->v[2] = mesh->nenil;
118 pt->qual = 0.0;
119 iadr = (iel-1)*3 + 1;
120 if ( mesh->adja )
121 memset(&mesh->adja[iadr],0,3*sizeof(MMG5_int));
122
123 mesh->nenil = iel;
124 if ( iel == mesh->nt ) {
125 while ( (!MG_EOK((&mesh->tria[mesh->nt]))) && mesh->nt ) mesh->nt--;
126 }
127 return 1;
128}
129
145static inline
147 size_t usedMem,avMem,reservedMem,npadd;
148 int ctri,bytes;
149
151
152 /* init allocation need MMG5_MEMMIN B */
153 reservedMem = MMG5_MEMMIN + mesh->nquad*sizeof(MMG5_Quad);
154
155 /* Compute the needed initial memory */
156 usedMem = reservedMem + (mesh->np+1)*sizeof(MMG5_Point)
157 + (mesh->nt+1)*sizeof(MMG5_Tria) + (3*mesh->nt+1)*sizeof(MMG5_int)
158 + (mesh->na+1)*sizeof(MMG5_Edge) + (mesh->np+1)*sizeof(double);
159
160 if ( usedMem > mesh->memMax ) {
161 fprintf(stderr,"\n ## Error: %s: %zu MB of memory ",__func__,
163 fprintf(stderr,"is not enough to load mesh. You need to ask %zu MB minimum\n",
164 usedMem/MMG5_MILLION+1);
165 return 0;
166 }
167
168 ctri = 2;
169
170 /* Euler-poincare: ne = 6*np; nt = 2*np; na = np/5 *
171 * point+tria+edges+adjt+ aniso sol */
172 bytes = sizeof(MMG5_Point) +
173 2*sizeof(MMG5_Tria) + 3*2*sizeof(MMG5_int)
174 + 0.2*sizeof(MMG5_Edge) + 3*sizeof(double);
175
176 avMem = mesh->memMax-usedMem;
177
178 /* If npadd is exactly the maximum memory available, we will use all the
179 * memory and the analysis step will fail. As arrays may be reallocated, we
180 * can have smaller values for npmax and ntmax (npadd/2). */
181 npadd = avMem/(2*bytes);
182 mesh->npmax = MG_MIN(mesh->npmax,mesh->np+npadd);
183 mesh->ntmax = MG_MIN(mesh->ntmax,ctri*npadd+mesh->nt);
184 mesh->namax = MG_MIN(mesh->namax,ctri*npadd+mesh->na);
185
186 if ( sizeof(MMG5_int) == sizeof(int32_t) ) {
189 int coef;
190 if ( mesh->nquad ) {
191 coef = 4;
192 }
193 else {
194 coef = 3;
195 }
196
197 /* maximal number of triangles, taking the
198 * computation of adjacency relationships into account */
199 int32_t int32_ntmax = (INT32_MAX-(coef+1))/coef;
200
201 if ( int32_ntmax < mesh->ntmax ) {
202 if ( int32_ntmax <= mesh->nt ) {
203 /* No possible allocation without int32 overflow */
204 fprintf(stderr,"\n ## Error: %s: with %" MMG5_PRId " triangles Mmg will overflow"
205 " the 32-bit integer.\n",__func__,mesh->nt);
206 fprintf(stderr,"Please, configure Mmg with MMG5_INT=int64_t argument.\n");
207 return 0;
208 }
209 else {
210 /* Correction of maximal number of triangles */
211 mesh->ntmax = int32_ntmax;
212 }
213 }
214 }
215
216 if ( abs(mesh->info.imprim) > 4 || mesh->info.ddebug ) {
217 fprintf(stdout," MAXIMUM MEMORY AUTHORIZED (MB) %zu\n",
219 }
220
221 if ( abs(mesh->info.imprim) > 5 || mesh->info.ddebug ) {
222 fprintf(stdout," MMG2D_NPMAX %" MMG5_PRId "\n",mesh->npmax);
223 fprintf(stdout," MMG2D_NTMAX %" MMG5_PRId "\n",mesh->ntmax);
224 }
225
226 return 1;
227}
228
238
240
241 mesh->npmax = MG_MAX((MMG5_int)(1.5*mesh->np),MMG2D_NPMAX);
242 mesh->ntmax = MG_MAX((MMG5_int)(1.5*mesh->nt),MMG2D_NEMAX);
243 mesh->namax = mesh->na;
244
246}
247
257 MMG5_int k;
258
259 MMG5_ADD_MEM(mesh,(mesh->npmax+1)*sizeof(MMG5_Point),"initial vertices",
260 printf(" Exit program.\n");
261 return 0);
263
264 MMG5_ADD_MEM(mesh,(mesh->ntmax+1)*sizeof(MMG5_Tria),"initial triangles",return 0);
266 memset(&mesh->tria[0],0,sizeof(MMG5_Tria));
267
268 if ( mesh->nquad ) {
269 MMG5_ADD_MEM(mesh,(mesh->nquad+1)*sizeof(MMG5_Quad),"initial quadrilaterals",return 0);
271 }
272
273 mesh->namax = mesh->na;
274 if ( mesh->na ) {
275 MMG5_ADD_MEM(mesh,(mesh->namax+1)*sizeof(MMG5_Edge),"initial edges",return 0);
277 }
278
279 /* keep track of empty links */
280 mesh->npnil = mesh->np + 1;
281 mesh->nenil = mesh->nt + 1;
282 mesh->nanil = 0;
283
284 for (k=mesh->npnil; k<mesh->npmax-1; k++) {
285 /* Set tangent field of point to 0 */
286 mesh->point[k].n[0] = 0;
287 mesh->point[k].n[1] = 0;
288 mesh->point[k].n[2] = 0;
289 /* link */
290 mesh->point[k].tmp = k+1;
291 }
292
293 for (k=mesh->nenil; k<mesh->ntmax-1; k++)
294 mesh->tria[k].v[2] = k+1;
295
296 return 1;
297}
298
308
309 if ( !MMG2D_memOption(mesh) ) return 0;
310
312}
MMG5_pMesh * mesh
#define MMG2D_NPMAX
#define MMG2D_NEMAX
#define MMG5_SAFE_CALLOC(ptr, size, type, law)
size_t MMG5_memSize(void)
Definition: tools.c:852
#define MG_EOK(pt)
void MMG5_memOption_memSet(MMG5_pMesh mesh)
Definition: tools.c:891
#define MG_NUL
#define MG_MIN(a, b)
#define MG_MAX(a, b)
#define MMG5_ADD_MEM(mesh, size, message, law)
#define MMG5_MILLION
#define MG_VOK(ppt)
#define MMG5_MEMMIN
Structure to store edges of am MMG mesh.
Definition: libmmgtypes.h:311
MMG5_int b
Definition: libmmgtypes.h:312
MMG5_int a
Definition: libmmgtypes.h:312
int8_t ddebug
Definition: libmmgtypes.h:539
MMG mesh structure.
Definition: libmmgtypes.h:613
MMG5_int ntmax
Definition: libmmgtypes.h:620
MMG5_pQuad quadra
Definition: libmmgtypes.h:656
MMG5_Info info
Definition: libmmgtypes.h:659
MMG5_pPoint point
Definition: libmmgtypes.h:649
MMG5_int * adja
Definition: libmmgtypes.h:632
MMG5_int nquad
Definition: libmmgtypes.h:621
size_t memMax
Definition: libmmgtypes.h:614
MMG5_int npmax
Definition: libmmgtypes.h:620
MMG5_int nenil
Definition: libmmgtypes.h:630
MMG5_int namax
Definition: libmmgtypes.h:620
MMG5_int nt
Definition: libmmgtypes.h:620
MMG5_pTria tria
Definition: libmmgtypes.h:655
MMG5_int np
Definition: libmmgtypes.h:620
MMG5_pEdge edge
Definition: libmmgtypes.h:657
MMG5_int nanil
Definition: libmmgtypes.h:631
MMG5_int na
Definition: libmmgtypes.h:620
MMG5_int npnil
Definition: libmmgtypes.h:629
Structure to store vertices of an MMG mesh.
Definition: libmmgtypes.h:276
double n[3]
Definition: libmmgtypes.h:278
MMG5_int tmp
Definition: libmmgtypes.h:286
double c[3]
Definition: libmmgtypes.h:277
uint16_t tag
Definition: libmmgtypes.h:290
Structure to store quadrangles of an MMG mesh.
Definition: libmmgtypes.h:372
Structure to store triangles of a MMG mesh.
Definition: libmmgtypes.h:338
MMG5_int edg[3]
Definition: libmmgtypes.h:345
double qual
Definition: libmmgtypes.h:339
MMG5_int ref
Definition: libmmgtypes.h:341
MMG5_int base
Definition: libmmgtypes.h:342
MMG5_int v[3]
Definition: libmmgtypes.h:340
void MMG5_delEdge(MMG5_pMesh mesh, MMG5_int iel)
Definition: zaldy_2d.c:72
int MMG2D_memOption(MMG5_pMesh mesh)
Definition: zaldy_2d.c:237
static int MMG2D_memOption_memSet(MMG5_pMesh mesh)
Definition: zaldy_2d.c:146
int MMG2D_zaldy(MMG5_pMesh mesh)
Definition: zaldy_2d.c:307
MMG5_int MMG2D_newPt(MMG5_pMesh mesh, double c[2], uint16_t tag)
Definition: zaldy_2d.c:38
int MMG2D_delElt(MMG5_pMesh mesh, MMG5_int iel)
Definition: zaldy_2d.c:107
void MMG2D_delPt(MMG5_pMesh mesh, MMG5_int ip)
Definition: zaldy_2d.c:57
int MMG2D_setMeshSize_alloc(MMG5_pMesh mesh)
Definition: zaldy_2d.c:256
MMG5_int MMG2D_newElt(MMG5_pMesh mesh)
Definition: zaldy_2d.c:87