Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
velextls_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*/
23
36#ifdef USE_ELAS
37
38#define _LS_LAMBDA 10.0e5
39#define _LS_MU 8.2e5
40
41#include "libmmg2d_private.h"
42#include "ls_calls.h"
43
48MMG5_int* MMG2D_packLS(MMG5_pMesh mesh,MMG5_pSol disp,LSst *lsst,MMG5_int *npfin) {
49 MMG5_pTria pt,pt1;
50 MMG5_pPoint p0;
51 double u[2];
52 MMG5_int k,iel,jel,n,npf,nef,ip,nlay,refdirh,refdirnh,ilist,ilisto,ilistck;
53 MMG5_int vper[3],*perm,*list,*adja,*invperm;
54 int8_t i,j,jedg;
55
56 nlay = 20;
57 refdirh = 0;
58 refdirnh = 1;
59 npf = 0;
60 nef = 0;
61 u[0] = u[1] = 0.0;
62 ilist = ilisto = ilistck = 0;
63 MMG5_ADD_MEM(mesh,(mesh->nt+1)*sizeof(MMG5_int),"element list",return NULL);
64 MMG5_SAFE_CALLOC(list,mesh->nt+1,MMG5_int,return NULL);
65
66 MMG5_ADD_MEM(mesh,(mesh->np+1)*sizeof(MMG5_int),"point permutation",return NULL);
67 MMG5_SAFE_CALLOC(perm,mesh->np+1,MMG5_int,return NULL);
68
69
70 /* Reset flag field at triangles */
71 for(k=1; k<=mesh->nt; k++)
72 mesh->tria[k].flag = 0;
73
74 /* Step 1: pile up all the triangles with one edge with ref DISPREF, and get the corresponding points */
75 for (k=1; k<=mesh->nt; k++) {
76 pt = &mesh->tria[k];
77 if ( !MG_EOK(pt) ) continue;
78
79 for (i=0; i<3; i++) {
80 if ( pt->edg[i] == MMG5_DISPREF ) {
81 ilist++;
82 list[ilist] = k;
83 MG_SET(pt->flag,0);
84
85 for (j=0; j<3; j++) {
86 ip = pt->v[j];
87 if ( !perm[ip] ) {
88 npf++;
89 perm[ip] = npf;
90 }
91 }
92 break;
93 }
94 }
95 }
96
97 /* Step 2: Create a hull of nlay layers around these triangles */
98 for (n=0; n<nlay; n++) {
99 ilistck = ilisto;
100 ilisto = ilist;
101
102 for (k=ilistck+1; k<=ilisto; k++) {
103 iel = list[k];
104 adja = &mesh->adja[3*(iel-1)+1];
105
106 for (i=0; i<3; i++) {
107 jel = adja[i] / 3;
108 if ( !jel ) continue;
109 pt1 = &mesh->tria[jel];
110
111 if ( MG_EOK(pt1) && ( !MG_GET(pt1->flag,0) ) ) {
112 ilist++;
113 assert ( ilist <= mesh->nt );
114 MG_SET(pt1->flag,0);
115 list[ilist] = jel;
116
117 for (j=0; j<3; j++) {
118 ip = pt1->v[j];
119 if ( !perm[ip] ) {
120 npf++;
121 perm[ip] = npf;
122 }
123 }
124 }
125 }
126 }
127 }
128 if ( !npf ) {
129 fprintf(stderr,
130 "\n ## Error: %s: no triangle with reference %d in the mesh.\n"
131 " Nothing to move.\n",__func__,MMG5_DISPREF);
132 MMG5_DEL_MEM ( mesh,list );
133 MMG5_DEL_MEM ( mesh,perm );
134 return NULL;
135 }
136
137 /* Creation of the inverse permutation table */
138 MMG5_ADD_MEM ( mesh,(npf+1)*sizeof(MMG5_int),"permutation table",
139 MMG5_DEL_MEM ( mesh,list );
140 MMG5_DEL_MEM ( mesh,perm );
141 return NULL );
142 MMG5_SAFE_CALLOC ( invperm,(npf+1),MMG5_int,
143 MMG5_DEL_MEM ( mesh,list );
144 MMG5_DEL_MEM ( mesh,perm );
145 return NULL );
146
147 /* Step 3: count of the surface triangles in the new mesh
148 Code for pt->flag : if pt->flag = 1 -> in the list
149 if pt->flag = 0 -> not in the list
150 if MG_GET(pt->mark, i+1) : edge i has already been counted */
151 for (k=1; k<=ilist; k++) {
152 iel = list[k];
153 pt = &mesh->tria[iel];
154 adja = &mesh->adja[3*(iel-1)+1];
155
156 for (i=0; i<3; i++) {
157 jel = adja[i] / 3;
158 jedg = adja[i] % 3;
159
160 /* Face i carries a non homogeneous Dirichlet BC */
161 if ( pt->edg[i] == MMG5_DISPREF ) {
162
163 /* If this triangle has not been taken into account */
164 if ( MG_GET(pt->flag,i+1) ) continue;
165
166 nef++;
167 if ( !jel ) continue;
168 pt1 = &mesh->tria[jel];
169 MG_SET(pt1->flag,jedg+1);
170 }
171 /* iel has no neighbour through face i within the list */
172 else if ( !jel || !MG_GET(mesh->tria[jel].flag,0) ) nef++;
173 }
174 }
175
176 /* Step 4: creation of the mesh for elasticity */
177 if ( !LS_mesh(lsst,npf,nef,ilist,0) ) {
178 fprintf(stdout," ## Problem in function LS_mesh. Exiting.\n");
179 MMG5_DEL_MEM ( mesh,list );
180 MMG5_DEL_MEM ( mesh,perm );
181 return 0;
182 }
183
184 /* Set verbosity and debug info */
185 LS_setPar(lsst, (mesh->info.imprim > 0),0);
186
187 /* Step 5: fill the LS mesh */
188 /* Add vertices, and fill in table invperm on the fly */
189 for (k=1; k<=mesh->np; k++) {
190 ip = perm[k];
191 if ( !ip ) continue;
192
193 p0 = &mesh->point[k];
194 invperm[ip] = k;
195
196 if ( !LS_addVer(lsst,ip,p0->c,p0->ref) ) {
197 fprintf(stdout," ## Problem in fn LS_addVer. Exiting.\n");
198 MMG5_DEL_MEM ( mesh,list );
199 MMG5_DEL_MEM ( mesh,perm );
200 return 0;
201 }
202 }
203
204 /* Add triangles */
205 for (k=1; k<=ilist; k++) {
206 iel = list[k];
207 pt = &mesh->tria[iel];
208
209 for (i=0; i<3; i++)
210 vper[i] = perm[pt->v[i]];
211
212 if (!LS_addTri(lsst,(int)k,(int*)vper,0) ) {
213 fprintf(stdout," ## Problem in fn LS_addTet. Exiting.\n");
214 MMG5_DEL_MEM ( mesh,list );
215 MMG5_DEL_MEM ( mesh,perm );
216 return 0;
217 }
218 }
219
220 /* Add boundary edges */
221 nef = 0;
222 for (k=1; k<=ilist; k++) {
223 iel = list[k];
224 pt = &mesh->tria[iel];
225 adja = &mesh->adja[3*(iel-1)+1];
226
227 for (i=0; i<3; i++) {
228 jel = adja[i] / 3;
229
230 /* Case where face i carries a non homogeneous Dirichlet BC */
231 if ( pt->edg[i] == MMG5_DISPREF ) {
232 /* If this triangle has not been taken into account */
233 if ( MG_GET(pt->flag,i+1) ) continue;
234 nef ++;
235
236 vper[0] = perm[pt->v[MMG5_inxt2[i]]];
237 vper[1] = perm[pt->v[MMG5_iprv2[i]]];
238
239 if ( !LS_addEdg(lsst,(int)nef,(int*)vper,refdirnh) ) {
240 fprintf(stdout," ## Problem in fn LS_addEdg. Exiting.\n");
241 MMG5_DEL_MEM ( mesh,list );
242 MMG5_DEL_MEM ( mesh,perm );
243 return 0;
244 }
245 }
246 /* iel has no neighbour through face i within the list */
247 else if ( !jel || !MG_GET(mesh->tria[jel].flag,0) ) {
248 nef++;
249 vper[0] = perm[pt->v[MMG5_inxt2[i]]];
250 vper[1] = perm[pt->v[MMG5_iprv2[i]]];
251
252 if ( !LS_addEdg(lsst,(int)nef,(int*)vper,refdirh) ) {
253 fprintf(stdout," ## Problem in fn LS_addEdg. Exiting.\n");
254 MMG5_DEL_MEM ( mesh,list );
255 MMG5_DEL_MEM ( mesh,perm );
256 return 0;
257 }
258 }
259 }
260 }
261
262 if ( (abs(mesh->info.imprim) > 4 || mesh->info.ddebug) && (ilist+npf+nef > 0) )
263 printf("Number of packed triangles %" MMG5_PRId ", points %" MMG5_PRId ", edges %" MMG5_PRId "\n",ilist,npf,nef);
264
265 /* Add boundary conditions */
266 /*if ( !LS_setBC(lsst,Dirichlet,refdirnh,'v',LS_edg,v) ) {
267 fprintf(stdout," ## Problem in fn LS_set BC. Exiting.\n");
268 MMG5_DEL_MEM ( mesh,list );
269 MMG5_DEL_MEM ( mesh,perm );
270 return 0;
271 }*/
272 if ( !LS_setBC(lsst,Dirichlet,refdirnh,'f',LS_edg,NULL) ) {
273 fprintf(stdout," ## Problem in fn LS_set BC. Exiting.\n");
274 MMG5_DEL_MEM ( mesh,list );
275 MMG5_DEL_MEM ( mesh,perm );
276 return 0;
277 }
278
279 if ( !LS_setBC(lsst,Dirichlet,refdirh,'v',LS_edg,u) ) {
280 fprintf(stdout," ## Problem in fn LS_set BC. Exiting.\n");
281 MMG5_DEL_MEM ( mesh,list );
282 MMG5_DEL_MEM ( mesh,perm );
283 return 0;
284 }
285
286 /* Add materials */
287 if ( !LS_setLame(lsst,0,_LS_LAMBDA,_LS_MU) ) {
288 fprintf(stdout," ## Problem in fn LS_setLame. Exiting.\n");
289 MMG5_DEL_MEM ( mesh,list );
290 MMG5_DEL_MEM ( mesh,perm );
291 return 0;
292 }
293
294 /* Transfer displacement */
295 if ( !LS_newSol(lsst) ) {
296 fprintf(stdout," ## Problem in fn LS_CreaSol. Exiting.\n");
297 MMG5_DEL_MEM ( mesh,list );
298 MMG5_DEL_MEM ( mesh,perm );
299 return 0;
300 }
301
302 for(k=1; k<=mesh->np; k++) {
303 ip = perm[k];
304 if ( !ip ) continue;
305 if ( !LS_addSol(lsst,ip,&disp->m[2*k]) ) {
306 fprintf(stdout," ## Problem in fn LS_addSol. Exiting.\n");
307 return 0;
308 }
309 }
310
311 *npfin = npf;
312 MMG5_DEL_MEM ( mesh,list );
313 MMG5_DEL_MEM ( mesh,perm );
314 return invperm;
315}
316
318int MMG2D_unpackLS(MMG5_pMesh mesh,MMG5_pSol disp,LSst *lsst,MMG5_int npf,MMG5_int *invperm) {
319 double *u;
320 MMG5_int k,ip;
321 int8_t i;
322
323 u = LS_getSol(lsst);
324
325 for (k=1; k<=mesh->np; k++) {
326 for (i=0; i<2; i++)
327 disp->m[2*k+i] = 0.0;
328 }
329
330 for (k=1; k<=npf; k++) {
331 ip = invperm[k];
332 for (i=0; i<2; i++)
333 disp->m[2*ip+i] = u[2*(k-1)+i];
334 }
335
336 return 1;
337}
338
341 LSst *lsst;
342 MMG5_int npf,*invperm;
343
344 /* Creation of the data structure for storing the submesh */
345 lsst = LS_init(mesh->dim,mesh->ver,P1,1);
346
347 /* Creation of the submesh */
348 invperm = MMG2D_packLS(mesh,disp,lsst,&npf);
349
350 if ( !npf ) {
351 fprintf(stdout," ## Problem in fn MMG2D_packLS. Exiting.\n");
352 return 0;
353 }
354
355 /* Resolution of the elasticity system on the submesh */
356 if ( !LS_elastic(lsst) ) {
357 fprintf(stdout," ## Problem in function elasti1. Exiting.\n");
358 return 0;
359 }
360
361 /* Update of the displacement */
362 if ( !MMG2D_unpackLS(mesh,disp,lsst,npf,invperm) ) {
363 fprintf(stdout," ## Problem in fn MMG2D_unpackLS. Exiting.\n");
364 return 0;
365 }
366
367 /* Memory release */
368 MMG5_DEL_MEM ( mesh,invperm );
369
370 /* Release of the Lsst structure */
371 if ( !LS_stop(lsst) ) {
372 fprintf(stdout," ## Problem in fn LS_stop. Exiting.\n");
373 return 0;
374 }
375
376 return 1;
377}
378
379#else
385#ifdef _WIN32
386void MMG2D_unused_function(void) {
387 return;
388}
389#else
390void __attribute__((unused)) MMG2D_unused_function(void) {
391 return;
392}
393#endif
394
395#endif
if(!ier) exit(EXIT_FAILURE)
MMG5_pMesh * mesh
#define MMG5_SAFE_CALLOC(ptr, size, type, law)
#define MG_EOK(pt)
#define MMG5_DISPREF
#define MMG5_ADD_MEM(mesh, size, message, law)
static const uint8_t MMG5_iprv2[3]
#define MG_GET(flag, bit)
static const uint8_t MMG5_inxt2[6]
#define MMG5_DEL_MEM(mesh, ptr)
#define MG_SET(flag, bit)
int8_t ddebug
Definition: libmmgtypes.h:532
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_Info info
Definition: libmmgtypes.h:651
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_int * adja
Definition: libmmgtypes.h:624
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 ref
Definition: libmmgtypes.h:278
double * m
Definition: libmmgtypes.h:671
MMG5_int edg[3]
Definition: libmmgtypes.h:339
MMG5_int flag
Definition: libmmgtypes.h:341
MMG5_int v[3]
Definition: libmmgtypes.h:334
#define _LS_MU
Definition: velextls_2d.c:39
MMG5_int * MMG2D_packLS(MMG5_pMesh mesh, MMG5_pSol disp, LSst *lsst, MMG5_int *npfin)
Definition: velextls_2d.c:48
int MMG2D_unpackLS(MMG5_pMesh mesh, MMG5_pSol disp, LSst *lsst, MMG5_int npf, MMG5_int *invperm)
Definition: velextls_2d.c:318
int MMG2D_velextLS(MMG5_pMesh mesh, MMG5_pSol disp)
Definition: velextls_2d.c:340
#define _LS_LAMBDA
Definition: velextls_2d.c:38