Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
solmap_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*/
35#include "libmmg2d.h"
36#include "libmmg2d_private.h"
38#include "mmgexterns_private.h"
39
51static inline
53 MMG5_pTria ptt;
54 MMG5_int k;
55 int i,ier;
56
57 assert ( mesh->info.optim || mesh->info.hsiz > 0. );
58
59 /* Detect the points not used by triangles */
60 ++mesh->base;
61#ifndef NDEBUG
62 for (k=1; k<=mesh->np; k++) {
63 assert ( mesh->point[k].flag < mesh->base );
64 }
65#endif
66
67 for (k=1; k<=mesh->nt; k++) {
68 ptt = &mesh->tria[k];
69 if ( !MG_EOK(ptt) ) continue;
70
71 for (i=0; i<3; i++) {
72 mesh->point[ptt->v[i]].flag = mesh->base;
73 }
74 }
75
76 /* Compute hmin/hmax on unflagged points and truncate the metric */
77 if ( !ani ) {
79 }
80 else {
81 MMG5_solTruncature_ani = MMG5_2dSolTruncature_ani;
82 ier = MMG5_solTruncature_ani(mesh,met);
83 }
84
85 return ier;
86}
87
98 MMG5_pTria ptt,pt;
99 MMG5_pPoint p1,p2;
100 double ux,uy,dd;
101 MMG5_int k,ipa,ipb;
102 int i,ib;
103 int MMG_inxtt[5] = {0,1,2,0,1};
104
105 // here we guess that we have less than int32 edges passing through a point
106 int *mark;
107 MMG5_SAFE_CALLOC(mark,mesh->np+1,int,return 0);
108
109 /* Memory alloc */
110 if ( sol->size!=1 ) {
111 fprintf(stderr,"\n ## Error: %s: unexpected size of metric: %d.\n",
112 __func__,sol->size);
113 return 0;
114 }
115
117 return 0;
118
119 /* Travel the triangles edges and add the edge contribution to edges
120 * extermities */
121 for (k=1; k<=mesh->nt; k++) {
122 ptt = &mesh->tria[k];
123 if ( !ptt->v[0] ) continue;
124
125 for (i=0; i<3; i++) {
126 ib = MMG_inxtt[i+1];
127 ipa = ptt->v[i];
128 ipb = ptt->v[ib];
129 p1 = &mesh->point[ipa];
130 p2 = &mesh->point[ipb];
131
132 ux = p1->c[0] - p2->c[0];
133 uy = p1->c[1] - p2->c[1];
134 dd = sqrt(ux*ux + uy*uy);
135
136 sol->m[ipa] += dd;
137 mark[ipa]++;
138 sol->m[ipb] += dd;
139 mark[ipb]++;
140 }
141 }
142
143 /* vertex size */
144 for (k=1; k<=mesh->np; k++) {
145 if ( !mark[k] ) {
146 continue;
147 }
148 sol->m[k] = sol->m[k] / (double)mark[k];
149 }
150 MMG5_SAFE_FREE(mark);
151
152 /* Computation of hmin/hmax if not provided + size truncature */
154
155 /* compute quality */
156 if ( MMG2D_caltri ) {
157 for (k=1; k<=mesh->nt; k++) {
158 pt = &mesh->tria[k];
159 pt->qual = MMG2D_caltri_iso(mesh,sol,pt);
160 }
161 }
162
163 return 1;
164}
165
176 MMG5_pTria ptt,pt;
177 MMG5_pPoint p1,p2;
178 double ux,uy,dd,tensordot[3];
179 MMG5_int k,ipa,ipb,iadr;
180 int i,ib;
181 int MMG_inxtt[5] = {0,1,2,0,1};
182
183 // here we guess that we have less than int32 edges passing through a point
184 int *mark;
185 MMG5_SAFE_CALLOC(mark,mesh->np+1,int,return 0);
186
187 /* Memory alloc */
188 if ( sol->size!=3 ) {
189 fprintf(stderr,"\n ## Error: %s: unexpected size of metric: %d.\n",
190 __func__,sol->size);
191 return 0;
192 }
193
195 return 0;
196
197 /* Travel the triangles edges and add the edge contribution to edges
198 * extermities */
199 for (k=1; k<=mesh->nt; k++) {
200 ptt = &mesh->tria[k];
201 if ( !ptt->v[0] ) continue;
202
203 for (i=0; i<3; i++) {
204 ib = MMG_inxtt[i+1];
205 ipa = ptt->v[i];
206 ipb = ptt->v[ib];
207 p1 = &mesh->point[ipa];
208 p2 = &mesh->point[ipb];
209
210 ux = p1->c[0] - p2->c[0];
211 uy = p1->c[1] - p2->c[1];
212
213 tensordot[0] = ux*ux;
214 tensordot[1] = ux*uy;
215 tensordot[2] = uy*uy;
216
217 iadr = 3*ipa;
218 sol->m[iadr] += tensordot[0];
219 sol->m[iadr+1] += tensordot[1];
220 sol->m[iadr+2] += tensordot[2];
221 mark[ipa]++;
222
223 iadr = 3*ipb;
224 sol->m[iadr] += tensordot[0];
225 sol->m[iadr+1] += tensordot[1];
226 sol->m[iadr+2] += tensordot[2];
227 mark[ipb]++;
228 }
229 }
230
231 /* Compute metric tensor and hmax if not specified */
232 for (k=1; k<=mesh->np; k++) {
233 p1 = &mesh->point[k];
234 if ( !mark[k] ) {
235 continue;
236 }
237
238 iadr = 3*k;
239 /* Metric = nedges/dim * inv (sum(tensor_dot(edges,edges))).
240 * sum(tensor_dot) is stored in sol->m so reuse tensordot to
241 * compute M. */
242 dd = 1./(sol->m[iadr]*sol->m[iadr+2] - sol->m[iadr+1]*sol->m[iadr+1]);
243 dd *= (double)mark[k]*0.5;
244
245 tensordot[0] = sol->m[iadr+2];
246 tensordot[1] = -sol->m[iadr+1];
247 tensordot[2] = sol->m[iadr];
248
249 sol->m[iadr] = dd*tensordot[0];
250 sol->m[iadr+1] = dd*tensordot[1];
251 sol->m[iadr+2] = dd*tensordot[2];
252
253#ifndef NDEBUG
254 /* Check metric */
255 double lambda[2],vp[2][2];
256 MMG5_eigensym(sol->m+iadr,lambda,vp);
257
258 assert (lambda[0] > 0. && lambda[1] > 0. && "Negative eigenvalue");
259
260 /* Normally the case where the point belongs to only 2 colinear points is
261 impossible */
262 assert (isfinite(lambda[0]) && isfinite(lambda[1]) && "wrong eigenvalue");
263#endif
264 }
265 MMG5_SAFE_FREE(mark);
266
267 /* Size truncature */
269
270 /* compute quality */
271 if ( MMG2D_caltri ) {
272 for (k=1; k<=mesh->nt; k++) {
273 pt = &mesh->tria[k];
274 pt->qual = MMG2D_caltri_ani(mesh,sol,pt);
275 }
276 }
277
278 return 1;
279}
int MMG2D_Set_solSize(MMG5_pMesh mesh, MMG5_pSol sol, int typEntity, MMG5_int np, int typSol)
int ier
MMG5_pMesh MMG5_pSol * sol
MMG5_pMesh * mesh
int MMG5_eigensym(double m[3], double lambda[2], double vp[2][2])
Definition: eigenv.c:973
API headers for the mmg2d library.
double MMG2D_caltri_ani(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pTria)
Definition: quality_2d.c:121
double MMG2D_caltri_iso(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pTria)
Definition: quality_2d.c:107
@ MMG5_Vertex
Definition: libmmgtypes.h:224
#define MMG5_SAFE_CALLOC(ptr, size, type, law)
#define MG_EOK(pt)
int MMG5_solTruncature_iso(MMG5_pMesh mesh, MMG5_pSol met)
Definition: scalem.c:299
int MMG5_2dSolTruncature_ani(MMG5_pMesh mesh, MMG5_pSol met)
Definition: scalem.c:365
#define MMG5_SAFE_FREE(ptr)
static int MMG2D_solTruncatureForOptim(MMG5_pMesh mesh, MMG5_pSol met, int ani)
Definition: solmap_2d.c:52
int MMG2D_doSol_iso(MMG5_pMesh mesh, MMG5_pSol sol)
Definition: solmap_2d.c:97
int MMG2D_doSol_ani(MMG5_pMesh mesh, MMG5_pSol sol)
Definition: solmap_2d.c:175
double hsiz
Definition: libmmgtypes.h:518
uint8_t optim
Definition: libmmgtypes.h:546
MMG mesh structure.
Definition: libmmgtypes.h:605
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
double c[3]
Definition: libmmgtypes.h:271
MMG5_int flag
Definition: libmmgtypes.h:282
double qual
Definition: libmmgtypes.h:333
MMG5_int v[3]
Definition: libmmgtypes.h:334