Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
movpt_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"
36
37//extern int8_t ddb;
38
53int MMG2D_movedgpt(MMG5_pMesh mesh,MMG5_pSol met,int ilist,MMG5_int *list, int8_t improve) {
54 MMG5_pTria pt,pt0;
55 MMG5_pPoint p0,p1,p2,ppt;
56 double step,ll1,ll2,o[2],no[2],calold,calnew;
57 MMG5_int k,iel,ip0,ip1,ip2,it1,it2;
58 int8_t i,i1,i2;
59 static int8_t mmgWarn0=0,mmgWarn1=0;
60
61 pt0 = &mesh->tria[0];
62 step = 0.1;
63 ip1 = ip2 = it1 = it2 = 0;
64 calold = calnew = DBL_MAX;
65
66 /* First step: retrieve the two boundary points connected to p0 */
67 for (k=0; k<ilist; k++) {
68 iel = list[k] / 3;
69 i = list[k] % 3;
70 i1 = MMG5_inxt2[i];
71 i2 = MMG5_iprv2[i];
72
73 pt = &mesh->tria[iel];
74 calold = MG_MIN(MMG2D_caltri(mesh,met,pt),calold);
75
76 if ( MG_EDG(pt->tag[i1]) ) {
77 if ( ip1 == 0 ) {
78 ip1 = pt->v[i2];
79 it1 = 3*iel+i1;
80 }
81 else if ( ip1 != pt->v[i2] ) {
82 if ( ip2 == 0 ) {
83 ip2 = pt->v[i2];
84 it2 = 3*iel+i1;
85 }
86 else if ( ip2 != pt->v[i2] ) {
87 if ( !mmgWarn0 ) {
88 mmgWarn0 = 1;
89 fprintf(stderr,"\n ## Warning: %s: at least 1 point at the "
90 "intersection of 3 edges. abort.\n",__func__);
91 }
92 return 0;
93 }
94 }
95 }
96
97 if ( MG_EDG(pt->tag[i2]) ) {
98 if ( ip1 == 0 ) {
99 ip1 = pt->v[i1];
100 it1 = 3*iel+i2;
101 }
102 else if ( ip1 != pt->v[i1] ) {
103 if ( ip2 == 0 ) {
104 ip2 = pt->v[i1];
105 it2 = 3*iel+i2;
106 }
107 else if ( ip2 != pt->v[i1] ) {
108 if ( !mmgWarn0 ) {
109 mmgWarn0 = 1;
110 fprintf(stderr,"\n ## Warning: %s: at least 1 point at the "
111 "intersection of 3 edges. abort.\n",__func__);
112 }
113 return 0;
114 }
115 }
116 }
117 }
118
119 /* Check that there are exactly two boundary points connected at p0 */
120 if ( ip1 == 0 || ip2 == 0 ) {
121 if ( !mmgWarn1 ) {
122 mmgWarn1 = 1;
123 fprintf(stderr,"\n ## Warning: %s: non singular point at end of edge.\n",
124 __func__);
125 }
126 return 0;
127 }
128
129 ip0 = pt->v[i];
130 p0 = &mesh->point[ip0];
131 p1 = &mesh->point[ip1];
132 p2 = &mesh->point[ip2];
133
134 /* Calculate length of both edges */
135 /* Anisotropic case: ll1 and ll2 = anisotropic edge lengths */
136 if ( met->m && met->size == 3 ) {
137 ll1 = MMG2D_lencurv_ani(mesh,met,ip0,ip1);
138 ll2 = MMG2D_lencurv_ani(mesh,met,ip0,ip2);
139 }
140 /* In all the remaining cases, ll1 and ll2 = squared edge lengths;
141 inconsistency between both cases is not problematic since these values serve only for comparison */
142 else {
143 ll1 = (p1->c[0]-p0->c[0])*(p1->c[0]-p0->c[0]) + (p1->c[1]-p0->c[1])*(p1->c[1]-p0->c[1]);
144 ll2 = (p2->c[0]-p0->c[0])*(p2->c[0]-p0->c[0]) + (p2->c[1]-p0->c[1])*(p2->c[1]-p0->c[1]);
145 }
146
147 /* Relocate p0 slightly towards p1 */
148 if ( ll1 > ll2 ) {
149 iel = it1 / 3;
150 i = it1 % 3;
151 }
152 /* Relocate p0 slightly towards p2 */
153 else {
154 iel = it2 / 3;
155 i = it2 % 3;
156 }
157
158 i1 = MMG5_inxt2[i];
159
160 pt = &mesh->tria[iel];
161
162 /* step = distance of the relocated position from ip0
163 bezierCurv = distance s from inxt2[i] */
164 if ( pt->v[i1] == ip0 ) MMG2D_bezierCurv(mesh,iel,i,step,o,no);
165 else MMG2D_bezierCurv(mesh,iel,i,1.0-step,o,no);
166
167 /* Evaluate resulting configuration */
168 ppt = &mesh->point[0];
169 ppt->c[0] = o[0];
170 ppt->c[1] = o[1];
171 ppt->n[0] = no[0];
172 ppt->n[1] = no[1];
173
174 for (k=0; k<ilist; k++) {
175 iel = list[k] / 3;
176 i = list[k] % 3;
177 pt = &mesh->tria[iel];
178 memcpy(pt0,pt,sizeof(MMG5_Tria));
179 pt0->v[i] = 0;
180
181 calnew = MG_MIN(MMG2D_caltri(mesh,met,pt0),calnew);
182 }
183
184 if ( calold < MMG2D_NULKAL && calnew <= calold ) return 0;
185 else if ( calnew < MMG2D_NULKAL ) return 0;
186 else if ( improve && calnew < 1.02 * calold ) return 0;
187 else if ( calnew < 0.3 * calold ) return 0;
188
189 /* Update of the coordinates and normal of the point */
190 p0 = &mesh->point[pt->v[i]];
191 p0->c[0] = o[0];
192 p0->c[1] = o[1];
193
194 p0->n[0] = no[0];
195 p0->n[1] = no[1];
196
197 return 1;
198}
199
213int MMG2D_movintpt(MMG5_pMesh mesh,MMG5_pSol met,int ilist,MMG5_int *list,int8_t improve) {
214 MMG5_pTria pt,pt0;
215 MMG5_pPoint p0,p1,p2,ppt0;
216 double calold,calnew,vol,volbal,b[2];
217 MMG5_int k,iel;
218 int8_t i,i1,i2;
219
220 ppt0 = &mesh->point[0];
221 pt0 = &mesh->tria[0];
222
223 volbal = 0.0;
224 b[0] = b[1] = 0.0;
225 calold = calnew = DBL_MAX;
226
227 /* Calculate the now position for vertex, as well as the quality of the previous configuration */
228 for (k=0; k<ilist; k++) {
229 iel = list[k] / 3;
230 i = list[k] % 3;
231 i1 = MMG5_inxt2[i];
232 i2 = MMG5_iprv2[i];
233
234 pt = &mesh->tria[iel];
235
236 /* Volume of iel */
237 p0 = &mesh->point[pt->v[i]];
238 p1 = &mesh->point[pt->v[i1]];
239 p2 = &mesh->point[pt->v[i2]];
240 vol = 0.5* fabs((p1->c[0]-p0->c[0])*(p2->c[1]-p0->c[1]) - (p1->c[1]-p0->c[1])*(p2->c[0]-p0->c[0]));
241
242 volbal += vol;
243
244 /* Add coordinates of the centre of mass of iel, weighted by its volume */
245 b[0] += MMG5_ATHIRD*vol*(p0->c[0]+p1->c[0]+p2->c[0]);
246 b[1] += MMG5_ATHIRD*vol*(p0->c[1]+p1->c[1]+p2->c[1]);
247
248 /* Quality of pt */
249 calold = MG_MIN(MMG2D_caltri_iso(mesh,NULL,pt),calold);
250 }
251
252 if ( volbal < MMG5_EPSD ) return 0;
253 volbal = 1.0 / volbal;
254 b[0] *= volbal;
255 b[1] *= volbal;
256
257 /* Check the quality of the resulting configuration */
258 ppt0->c[0] = b[0];
259 ppt0->c[1] = b[1];
260
261 for (k=0; k<ilist; k++) {
262 iel = list[k] / 3;
263 i = list[k] % 3;
264 pt = &mesh->tria[iel];
265 memcpy(pt0,pt,sizeof(MMG5_Tria));
266 pt0->v[i] = 0;
267
268 calnew = MG_MIN(MMG2D_caltri_iso(mesh,NULL,pt0),calnew);
269 }
270
271 if (calold < MMG2D_NULKAL && calnew <= calold) return 0;
272 else if (calnew < MMG2D_NULKAL) return 0;
273 else if ( improve && calnew < 1.02 * calold ) return 0;
274 else if ( calnew < 0.3 * calold ) return 0;
275
276 /* Update of the coordinates of the point */
277 pt = &mesh->tria[list[0]/3];
278 i = list[0] % 3;
279 p0 = &mesh->point[pt->v[i]];
280 p0->c[0] = b[0];
281 p0->c[1] = b[1];
282
283 return 1;
284}
MMG5_pMesh * mesh
int MMG2D_bezierCurv(MMG5_pMesh mesh, MMG5_int k, int8_t i, double s, double *o, double *no)
Definition: bezier_2d.c:185
#define MMG5_EPSD
double MMG2D_lencurv_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int ip1, MMG5_int ip2)
Definition: length_2d.c:82
#define MMG2D_NULKAL
double MMG2D_caltri_iso(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pTria)
Definition: quality_2d.c:107
#define MG_MIN(a, b)
#define MG_EDG(tag)
static const uint8_t MMG5_iprv2[3]
#define MMG5_ATHIRD
static const uint8_t MMG5_inxt2[6]
int MMG2D_movintpt(MMG5_pMesh mesh, MMG5_pSol met, int ilist, MMG5_int *list, int8_t improve)
Definition: movpt_2d.c:213
int MMG2D_movedgpt(MMG5_pMesh mesh, MMG5_pSol met, int ilist, MMG5_int *list, int8_t improve)
Definition: movpt_2d.c:53
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_pTria tria
Definition: libmmgtypes.h:647
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
double n[3]
Definition: libmmgtypes.h:272
double c[3]
Definition: libmmgtypes.h:271
double * m
Definition: libmmgtypes.h:671
int16_t tag[3]
Definition: libmmgtypes.h:342
MMG5_int v[3]
Definition: libmmgtypes.h:334