Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
API_functions_3d.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
41#include "libmmg3d.h"
42#include "libmmg3d_private.h"
44#include "PRoctree_3d_private.h"
45
46int MMG3D_Init_mesh(const int starter,...) {
47 va_list argptr;
48 int ier;
49
51
53
55
56 return ier;
57}
59 ) {
60
62 return;
63}
64
66
68}
69
71 return MMG5_Set_inputSolName(mesh,sol,solin);
72}
73
74int MMG3D_Set_inputParamName(MMG5_pMesh mesh, const char* fparamin) {
75 return MMG5_Set_inputParamName(mesh,fparamin);
76}
77
78int MMG3D_Set_outputMeshName(MMG5_pMesh mesh, const char* meshout) {
79
80 return MMG5_Set_outputMeshName(mesh,meshout);
81}
82
84 return MMG5_Set_outputSolName(mesh,sol,solout);
85}
86
88
89 /* Init common parameters for mmgs and mmg3d. */
91
92 /* default values for integers */
97 /* [0/1] ,avoid/allow surface modifications */
99#ifdef USE_SCOTCH
100 /* [1/0] , Turn on/off the renumbering using SCOTCH */
102#else
103 /* [0] , Turn on/off the renumbering using SCOTCH */
105#endif
106
107 /* default values for doubles */
108 /* level set value */
109 mesh->info.ls = MMG5_LS;
110
111#ifndef MMG_PATTERN
113#endif
114}
115
116int MMG3D_Set_solSize(MMG5_pMesh mesh, MMG5_pSol sol, int typEntity, MMG5_int np, int typSol) {
117
118 if ( ( (mesh->info.imprim > 5) || mesh->info.ddebug ) && sol->m )
119 fprintf(stderr,"\n ## Warning: %s: old solution deletion.\n",__func__);
120
121 if ( typEntity != MMG5_Vertex ) {
122 fprintf(stderr,"\n ## Error: %s: mmg3d need a solution imposed on vertices.\n",
123 __func__);
124 return 0;
125 }
126
127 sol->type = typSol;
128
129 if ( typSol == MMG5_Scalar ) {
130 sol->size = 1;
131 }
132 else if ( typSol == MMG5_Vector ) {
133 sol->size = 3;
134 }
135 else if ( typSol == MMG5_Tensor ) {
136 sol->size = 6;
137 /* User will provide its own metric: classical storage at ridges */
138 mesh->info.metRidTyp = 0;
139 }
140 else {
141 fprintf(stderr,"\n ## Error: %s: type of solution not yet implemented.\n",
142 __func__);
143 return 0;
144 }
145
146 sol->dim = 3;
147 if ( np ) {
148 sol->np = np;
149 sol->npi = np;
150 if ( sol->m )
152
153 sol->npmax = mesh->npmax;
154 MMG5_ADD_MEM(mesh,(sol->size*(sol->npmax+1))*sizeof(double),"initial solution",
155 return 0);
156 MMG5_SAFE_CALLOC(sol->m,(sol->size*(sol->npmax+1)),double,return 0);
157 }
158 return 1;
159}
160
162 MMG5_int nentities, int *typSol) {
163 MMG5_pSol psl;
164 char data[18];
165 int j;
166
167 if ( ( (mesh->info.imprim > 5) || mesh->info.ddebug ) && mesh->nsols ) {
168 if ( *sol ) {
169 fprintf(stderr,"\n ## Warning: %s: old solutions array deletion.\n",
170 __func__);
172 }
173 }
174
176 mesh->nsols = nsols;
177
178 MMG5_ADD_MEM(mesh,nsols*sizeof(MMG5_Sol),"solutions array",
179 return 0);
180 MMG5_SAFE_CALLOC(*sol,nsols,MMG5_Sol,return 0);
181
182 for ( j=0; j<nsols; ++j ) {
183 psl = *sol + j;
184 psl->ver = 2;
185
186 /* Give an arbitrary name to the solution */
187 sprintf(data,"sol_%d",j);
188 if ( !MMG3D_Set_inputSolName(mesh,psl,data) ) {
189 return 0;
190 }
191 /* Give an arbitrary name to the solution */
192 sprintf(data,"sol_%d.o",j);
193 if ( !MMG3D_Set_outputSolName(mesh,psl,data) ) {
194 return 0;
195 }
196
197 if ( !MMG3D_Set_solSize(mesh,psl,MMG5_Vertex,mesh->np,typSol[j]) ) {
198 fprintf(stderr,"\n ## Error: %s: unable to set the size of the"
199 " solution num %d.\n",__func__,j);
200 return 0;
201 }
202 }
203 return 1;
204}
205
220int MMG3D_setMeshSize_initData(MMG5_pMesh mesh, MMG5_int np, MMG5_int ne, MMG5_int nprism,
221 MMG5_int nt, MMG5_int nquad, MMG5_int na ) {
222
223 if ( ( (mesh->info.imprim > 5) || mesh->info.ddebug ) &&
224 ( mesh->point || mesh->tria || mesh->tetra || mesh->edge) )
225 fprintf(stderr,"\n ## Warning: %s: old mesh deletion.\n",__func__);
226
227 if ( !np ) {
228 fprintf(stderr," ** MISSING DATA:\n");
229 fprintf(stderr," Your mesh must contains at least points.\n");
230 return 0;
231 }
232 if ( !ne && (mesh->info.imprim > 4 || mesh->info.ddebug) ) {
233 fprintf(stderr," ** WARNING:\n");
234 fprintf(stderr," Your mesh don't contains tetrahedra.\n");
235 }
236 if ( mesh->point )
238 if ( mesh->tetra )
240 if ( mesh->prism )
242 if ( mesh->tria )
244 if ( mesh->quadra )
246 if ( mesh->edge )
248
249 mesh->np = np;
250 mesh->ne = ne;
251 mesh->nt = nt;
252 mesh->na = na;
253 mesh->nprism = nprism;
254 mesh->nquad = nquad;
255
256 mesh->npi = mesh->np;
257 mesh->nei = mesh->ne;
258 mesh->nti = mesh->nt;
259 mesh->nai = mesh->na;
260
261 return 1;
262}
263
264int MMG3D_Set_meshSize(MMG5_pMesh mesh, MMG5_int np, MMG5_int ne, MMG5_int nprism,
265 MMG5_int nt, MMG5_int nquad, MMG5_int na ) {
266
267 /* Check input data and set mesh->ne/na/np/nt to the suitable values */
268 if ( !MMG3D_setMeshSize_initData(mesh,np,ne,nprism,nt,nquad,na) )
269 return 0;
270
271 /* Check the -m option */
272 if( mesh->info.mem > 0) {
273 if((mesh->npmax < mesh->np || mesh->ntmax < mesh->nt || mesh->nemax < mesh->ne)) {
274 if ( !MMG3D_memOption(mesh) ) return 0;
275 } else if(mesh->info.mem < 39) {
276 fprintf(stderr,"\n ## Error: %s: not enough memory %d\n",__func__,
277 mesh->info.mem);
278 return 0;
279 }
280 } else {
281 if ( !MMG3D_memOption(mesh) ) return 0;
282 }
283
284 /* Mesh allocation and linkage */
285 if ( !MMG3D_setMeshSize_alloc( mesh ) ) return 0;
286
287 return 1;
288}
289
290int MMG3D_Get_solSize(MMG5_pMesh mesh, MMG5_pSol sol, int* typEntity, MMG5_int* np, int* typSol) {
291
292 if ( typEntity != NULL )
293 *typEntity = MMG5_Vertex;
294
295 if ( typSol != NULL ) {
296 if ( sol->size == 1 )
297 *typSol = MMG5_Scalar;
298 else if ( sol->size == 3 )
299 *typSol = MMG5_Vector;
300 else if ( sol->size == 6 )
301 *typSol = MMG5_Tensor;
302 else
303 *typSol = MMG5_Notype;
304 }
305
306 assert( (!sol->np) || (sol->np == mesh->np));
307
308 if ( np != NULL )
309 *np = sol->np;
310
311 return 1;
312}
313
315 MMG5_int* np, int* typSol) {
316 MMG5_pSol psl;
317 MMG5_int j;
318
319 if ( !mesh ) {
320 fprintf(stderr,"\n ## Error: %s: your mesh structure must be allocated"
321 " and filled\n",__func__);
322 return 0;
323 }
324
325 if ( nsols != NULL )
326 *nsols = mesh->nsols;
327
328 for ( j=0; j<mesh->nsols; ++j ) {
329 psl = *sol + j;
330
331 if ( typSol != NULL ) {
332 typSol[j] = psl->type;
333 }
334
335 assert( (!psl->np) || (psl->np == mesh->np));
336 }
337 if ( np != NULL )
338 *np = mesh->np;
339
340 return 1;
341}
342
343int MMG3D_Get_meshSize(MMG5_pMesh mesh, MMG5_int* np, MMG5_int* ne, MMG5_int* nprism,
344 MMG5_int* nt, MMG5_int * nquad, MMG5_int* na) {
345
346 if ( np != NULL )
347 *np = mesh->np;
348 if ( ne != NULL )
349 *ne = mesh->ne;
350 if ( nprism != NULL )
351 *nprism = mesh->nprism;
352 if ( nt != NULL )
353 *nt = mesh->nt;
354 if ( nquad != NULL )
355 *nquad = mesh->nquad;
356 if ( na != NULL )
357 *na = mesh->na;
358
359 return 1;
360}
361
362int MMG3D_Set_vertex(MMG5_pMesh mesh, double c0, double c1, double c2, MMG5_int ref, MMG5_int pos) {
363
364 if ( !mesh->np ) {
365 fprintf(stderr,"\n ## Error: %s: you must set the number of points with the",
366 __func__);
367 fprintf(stderr," MMG3D_Set_meshSize function before setting vertices in mesh.\n");
368 return 0;
369 }
370
371 if ( pos > mesh->npmax ) {
372 fprintf(stderr,"\n ## Error: %s: unable to allocate a new point.\n",__func__);
373 fprintf(stderr," max number of points: %" MMG5_PRId "\n",mesh->npmax);
375 return 0;
376 }
377
378 if ( pos > mesh->np ) {
379 fprintf(stderr,"\n ## Error: %s: attempt to set new vertex at position %" MMG5_PRId ".",
380 __func__,pos);
381 fprintf(stderr," Overflow of the given number of vertices: %" MMG5_PRId "\n",mesh->np);
382 fprintf(stderr,"\n ## Check the mesh size, its compactness or the position");
383 fprintf(stderr," of the vertex.\n");
384 return 0;
385 }
386
387 mesh->point[pos].c[0] = c0;
388 mesh->point[pos].c[1] = c1;
389 mesh->point[pos].c[2] = c2;
390 mesh->point[pos].ref = ref;
391 mesh->point[pos].tag = MG_NUL;
392 mesh->point[pos].flag = 0;
393 mesh->point[pos].tmp = 0;
394
395 return 1;
396}
397
398int MMG3D_Get_vertex(MMG5_pMesh mesh, double* c0, double* c1, double* c2, MMG5_int* ref,
399 int* isCorner, int* isRequired) {
400
401 if ( mesh->npi == mesh->np ) {
402 mesh->npi = 0;
403 if ( mesh->info.ddebug ) {
404 fprintf(stderr,"\n ## Warning: %s: reset the internal counter of points.\n",
405 __func__);
406 fprintf(stderr," You must pass here exactly one time (the first time ");
407 fprintf(stderr,"you call the MMG3D_Get_vertex function).\n");
408 fprintf(stderr," If not, the number of call of this function");
409 fprintf(stderr," exceed the number of points: %" MMG5_PRId "\n ",mesh->np);
410 }
411 }
412
413 mesh->npi++;
414
415 if ( mesh->npi > mesh->np ) {
416 fprintf(stderr,"\n ## Error: %s: unable to get point.\n",__func__);
417 fprintf(stderr," The number of call of MMG3D_Get_vertex function");
418 fprintf(stderr," can not exceed the number of points: %" MMG5_PRId "\n ",mesh->np);
419 return 0;
420 }
421
422 return MMG3D_GetByIdx_vertex( mesh,c0,c1,c2,ref,isCorner,isRequired,mesh->npi);
423}
424
425int MMG3D_GetByIdx_vertex(MMG5_pMesh mesh, double* c0, double* c1, double* c2, MMG5_int* ref,
426 int* isCorner, int* isRequired, MMG5_int idx) {
427
428 if ( idx < 1 || idx > mesh->np ) {
429 fprintf(stderr,"\n ## Error: %s: unable to get point at position %" MMG5_PRId ".\n",
430 __func__,idx);
431 fprintf(stderr," Your vertices numbering goes from 1 to %" MMG5_PRId "\n",mesh->np);
432 return 0;
433 }
434
435 *c0 = mesh->point[idx].c[0];
436 *c1 = mesh->point[idx].c[1];
437 *c2 = mesh->point[idx].c[2];
438 if ( ref != NULL )
439 *ref = mesh->point[idx].ref;
440
441 if ( isCorner != NULL ) {
442 if ( mesh->point[idx].tag & MG_CRN )
443 *isCorner = 1;
444 else
445 *isCorner = 0;
446 }
447
448 if ( isRequired != NULL ) {
449 if ( mesh->point[idx].tag & MG_REQ )
450 *isRequired = 1;
451 else
452 *isRequired = 0;
453 }
454
455 return 1;
456}
457
458int MMG3D_Set_vertices(MMG5_pMesh mesh, double *vertices,MMG5_int *refs) {
459
460 MMG5_pPoint ppt;
461 MMG5_int i,j;
462
463 /*coordinates vertices*/
464 for (i=1;i<=mesh->np;i++)
465 {
466 ppt = &mesh->point[i];
467
468 j = (i-1)*3;
469 ppt->c[0] = vertices[j];
470 ppt->c[1] = vertices[j+1];
471 ppt->c[2] = vertices[j+2];
472
473 ppt->tag = MG_NUL;
474 ppt->flag = 0;
475 ppt->tmp = 0;
476
477 if ( refs != NULL )
478 ppt->ref = refs[i-1];
479 }
480
481 return 1;
482}
483
484
485int MMG3D_Get_vertices(MMG5_pMesh mesh, double* vertices, MMG5_int* refs,
486 int* areCorners, int* areRequired) {
487 MMG5_pPoint ppt;
488 MMG5_int i,j;
489
490 for (i=1;i<=mesh->np;i++)
491 {
492 ppt = &mesh->point[i];
493
494 j = (i-1)*3;
495 vertices[j] = ppt->c[0];
496 vertices[j+1] = ppt->c[1];
497 vertices[j+2] = ppt->c[2];
498
499 j = i-1;
500 if ( refs != NULL )
501 refs[j] = ppt->ref;
502
503 if ( areCorners !=NULL ) {
504 if ( ppt->tag & MG_CRN )
505 areCorners[j] = 1;
506 else
507 areCorners[j] = 0;
508 }
509
510 if ( areRequired != NULL ) {
511 if ( ppt->tag & MG_REQ )
512 areRequired[j] = 1;
513 else
514 areRequired[j] = 0;
515 }
516 }
517
518 return 1;
519}
520
521int MMG3D_Set_tetrahedron(MMG5_pMesh mesh, MMG5_int v0, MMG5_int v1, MMG5_int v2, MMG5_int v3, MMG5_int ref, MMG5_int pos) {
522 MMG5_pTetra pt;
523 MMG5_pPoint ppt;
524 double vol;
525 MMG5_int aux;
526 int j,ip;
527
528 if ( !mesh->ne ) {
529 fprintf(stderr,"\n ## Error: %s: You must set the number of elements with the",
530 __func__);
531 fprintf(stderr," MMG3D_Set_meshSize function before setting elements in mesh\n");
532 return 0;
533 }
534
535 if ( pos > mesh->nemax ) {
536 fprintf(stderr,"\n ## Error: %s: unable to allocate a new element.\n",
537 __func__);
538 fprintf(stderr," max number of element: %" MMG5_PRId "\n",mesh->nemax);
540 return 0;
541 }
542
543 if ( pos > mesh->ne ) {
544 fprintf(stderr,"\n ## Error: %s: attempt to set new tetrahedron at position %" MMG5_PRId ".",
545 __func__,pos);
546 fprintf(stderr," Overflow of the given number of tetrahedron: %" MMG5_PRId "\n",mesh->ne);
547 fprintf(stderr,"\n ## Check the mesh size, its compactness or the position");
548 fprintf(stderr," of the tetrahedron.\n");
549 return 0;
550 }
551
552 pt = &mesh->tetra[pos];
553 pt->v[0] = v0;
554 pt->v[1] = v1;
555 pt->v[2] = v2;
556 pt->v[3] = v3;
557 pt->ref = MMG5_abs(ref);
558
559 mesh->point[pt->v[0]].tag &= ~MG_NUL;
560 mesh->point[pt->v[1]].tag &= ~MG_NUL;
561 mesh->point[pt->v[2]].tag &= ~MG_NUL;
562 mesh->point[pt->v[3]].tag &= ~MG_NUL;
563
564 vol = MMG5_orvol(mesh->point,pt->v);
565 if ( fabs(vol) <= MMG5_EPSD2 ) {
566 fprintf(stderr,"\n ## Error: %s: tetrahedron %" MMG5_PRId " has volume null.\n",
567 __func__,pos);
568 for ( ip=0; ip<4; ip++ ) {
569 ppt = &mesh->point[pt->v[ip]];
570 for ( j=0; j<3; j++ ) {
571 if ( fabs(ppt->c[j])>0. ) {
572 fprintf(stderr," Check that you don't have a sliver tetrahedron.\n");
573 return 0;
574 }
575 }
576 }
577 fprintf(stderr," All vertices have zero coordinates.");
578 fprintf(stderr," Check that you have set the vertices before the tetrahedra.\n");
579 return 0;
580 }
581 else if ( vol < 0.0 ) {
582 /* Possibly switch 2 vertices number so that each tet is positively oriented */
583 aux = pt->v[2];
584 pt->v[2] = pt->v[3];
585 pt->v[3] = aux;
586 /* mesh->xt temporary used to count reoriented tetra */
587 mesh->xt++;
588 }
589
590 return 1;
591}
592
593int MMG3D_Get_tetrahedron(MMG5_pMesh mesh, MMG5_int* v0, MMG5_int* v1, MMG5_int* v2, MMG5_int* v3,
594 MMG5_int* ref, int* isRequired) {
595
596 if ( mesh->nei == mesh->ne ) {
597 mesh->nei = 0;
598 if ( mesh->info.ddebug ) {
599 fprintf(stderr,"\n ## Warning: %s: reset the internal counter of"
600 " tetrahedra.\n",__func__);
601 fprintf(stderr," You must pass here exactly one time (the first time ");
602 fprintf(stderr,"you call the MMG3D_Get_tetrahedron function).\n");
603 fprintf(stderr," If not, the number of call of this function");
604 fprintf(stderr," exceed the number of tetrahedron: %" MMG5_PRId "\n ",mesh->ne);
605 }
606 }
607
608 mesh->nei++;
609
610 if ( mesh->nei > mesh->ne ) {
611 fprintf(stderr,"\n ## Error: %s: unable to get tetra.\n",__func__);
612 fprintf(stderr," The number of call of MMG3D_Get_tetrahedron function");
613 fprintf(stderr," can not exceed the number of tetra: %" MMG5_PRId "\n ",mesh->ne);
614 return 0;
615 }
616
617 *v0 = mesh->tetra[mesh->nei].v[0];
618 *v1 = mesh->tetra[mesh->nei].v[1];
619 *v2 = mesh->tetra[mesh->nei].v[2];
620 *v3 = mesh->tetra[mesh->nei].v[3];
621 if ( ref != NULL ) {
622 *ref = mesh->tetra[mesh->nei].ref;
623 }
624
625 if ( isRequired != NULL ) {
626 if ( mesh->tetra[mesh->nei].tag & MG_REQ )
627 *isRequired = 1;
628 else
629 *isRequired = 0;
630 }
631
632 return 1;
633}
634
635int MMG3D_Set_tetrahedra(MMG5_pMesh mesh, MMG5_int *tetra, MMG5_int *refs) {
636 MMG5_pPoint ppt;
637 MMG5_pTetra pt;
638 double vol;
639 int ip;
640 MMG5_int aux,i,j;
641
642 mesh->xp = 0;
643 for (i=1;i<=mesh->ne;i++)
644 {
645 j = (i-1)*4;
646 pt = &mesh->tetra[i];
647 pt->v[0] = tetra[j];
648 pt->v[1] = tetra[j+1];
649 pt->v[2] = tetra[j+2];
650 pt->v[3] = tetra[j+3];
651
652 if ( refs != NULL )
653 pt->ref = MMG5_abs(refs[i-1]);
654
655 mesh->point[pt->v[0]].tag &= ~MG_NUL;
656 mesh->point[pt->v[1]].tag &= ~MG_NUL;
657 mesh->point[pt->v[2]].tag &= ~MG_NUL;
658 mesh->point[pt->v[3]].tag &= ~MG_NUL;
659
660 vol = MMG5_orvol(mesh->point,pt->v);
661
662 if ( fabs(vol) <= MMG5_EPSD2 ) {
663 fprintf(stderr,"\n ## Error: %s: tetrahedron %" MMG5_PRId " has volume null.\n",
664 __func__,i);
665
666 for ( ip=0; ip<4; ip++ ) {
667 ppt = &mesh->point[pt->v[ip]];
668 for ( j=0; j<3; j++ ) {
669 if ( fabs(ppt->c[j])>0. ) {
670 fprintf(stderr," Check that you don't have a sliver tetrahedron.\n");
671 return 0;
672 }
673 }
674 }
675
676 fprintf(stderr," All vertices have zero coordinates.");
677 fprintf(stderr," Check that you have set the vertices before the tetrahedra.\n");
678 return 0;
679 }
680 else if ( vol < 0.0 ) {
681 /* Possibly switch 2 vertices number so that each tet is positively oriented */
682 aux = pt->v[2];
683 pt->v[2] = pt->v[3];
684 pt->v[3] = aux;
685
686 ++mesh->xp;
687 }
688 }
689
690 return 1;
691}
692
693int MMG3D_Get_tetrahedra(MMG5_pMesh mesh, MMG5_int *tetra, MMG5_int *refs, int * areRequired) {
694 MMG5_pTetra pt;
695 MMG5_int i, j;
696
697 for (i=1;i<=mesh->ne;i++)
698 {
699 j = (i-1)*4;
700 pt = &mesh->tetra[i];
701 tetra[j] = pt->v[0];
702 tetra[j+1] = pt->v[1];
703 tetra[j+2] = pt->v[2];
704 tetra[j+3] = pt->v[3];
705 if ( refs!=NULL )
706 refs[i-1] = pt->ref ;
707 if ( areRequired != NULL ) {
708 if ( pt->tag & MG_REQ )
709 areRequired[i-1] = 1;
710 else
711 areRequired[i-1] = 0;
712 }
713 }
714 return 1;
715}
716
717int MMG3D_Set_prism(MMG5_pMesh mesh, MMG5_int v0, MMG5_int v1, MMG5_int v2,
718 MMG5_int v3, MMG5_int v4, MMG5_int v5, MMG5_int ref, MMG5_int pos) {
719 MMG5_pPrism pp;
720
721 if ( !mesh->nprism ) {
722 fprintf(stderr,"\n ## Error: %s: You must set the number of prisms with the",
723 __func__);
724 fprintf(stderr," MMG3D_Set_meshSize function before setting elements in mesh\n");
725 return 0;
726 }
727
728 if ( pos > mesh->nprism ) {
729 fprintf(stderr,"\n ## Error: %s: attempt to set new prism at position %" MMG5_PRId ".",
730 __func__,pos);
731 fprintf(stderr," Overflow of the given number of prism: %" MMG5_PRId "\n",mesh->nprism);
732 fprintf(stderr,"\n ## Check the mesh size, its compactness or the position");
733 fprintf(stderr," of the prism.\n");
734 return 0;
735 }
736
737 pp = &mesh->prism[pos];
738 pp->v[0] = v0;
739 pp->v[1] = v1;
740 pp->v[2] = v2;
741 pp->v[3] = v3;
742 pp->v[4] = v4;
743 pp->v[5] = v5;
744 pp->ref = ref;
745
746 mesh->point[pp->v[0]].tag &= ~MG_NUL;
747 mesh->point[pp->v[1]].tag &= ~MG_NUL;
748 mesh->point[pp->v[2]].tag &= ~MG_NUL;
749 mesh->point[pp->v[3]].tag &= ~MG_NUL;
750 mesh->point[pp->v[4]].tag &= ~MG_NUL;
751 mesh->point[pp->v[5]].tag &= ~MG_NUL;
752
753
754 return 1;
755}
756
757int MMG3D_Get_prism(MMG5_pMesh mesh, MMG5_int* v0, MMG5_int* v1, MMG5_int* v2, MMG5_int* v3,
758 MMG5_int* v4, MMG5_int* v5, MMG5_int* ref, int* isRequired) {
759 static MMG5_int npri = 0;
760
761 if ( npri == mesh->nprism ) {
762 npri = 0;
763 if ( mesh->info.ddebug ) {
764 fprintf(stderr,"\n ## Warning: %s: reset the internal counter of prisms.\n",
765 __func__);
766 fprintf(stderr," You must pass here exactly one time (the first time ");
767 fprintf(stderr,"you call the MMG3D_Get_prism function).\n");
768 fprintf(stderr," If not, the number of call of this function");
769 fprintf(stderr," exceed the number of prisms: %" MMG5_PRId "\n ",mesh->nprism);
770 }
771 }
772
773 ++npri;
774
775 if ( npri > mesh->nprism ) {
776 fprintf(stderr,"\n ## Error: %s: unable to get prism.\n",__func__);
777 fprintf(stderr," The number of call of MMG3D_Get_prism function");
778 fprintf(stderr," can not exceed the number of prism: %" MMG5_PRId "\n ",mesh->nprism);
779 return 0;
780 }
781
782 *v0 = mesh->prism[npri].v[0];
783 *v1 = mesh->prism[npri].v[1];
784 *v2 = mesh->prism[npri].v[2];
785 *v3 = mesh->prism[npri].v[3];
786 *v4 = mesh->prism[npri].v[4];
787 *v5 = mesh->prism[npri].v[5];
788
789 if ( ref != NULL ) {
790 *ref = mesh->prism[npri].ref;
791 }
792
793 if ( isRequired != NULL ) {
794 if ( mesh->prism[npri].tag & MG_REQ )
795 *isRequired = 1;
796 else
797 *isRequired = 0;
798 }
799
800 return 1;
801}
802
803int MMG3D_Set_prisms(MMG5_pMesh mesh, MMG5_int *prisms, MMG5_int *refs) {
804 MMG5_pPrism pp;
805 MMG5_int j,i;
806
807 for (i=1;i<=mesh->nprism;i++)
808 {
809 j = (i-1)*6;
810 pp = &mesh->prism[i];
811 pp->v[0] = prisms[j];
812 pp->v[1] = prisms[j+1];
813 pp->v[2] = prisms[j+2];
814 pp->v[3] = prisms[j+3];
815 pp->v[4] = prisms[j+4];
816 pp->v[5] = prisms[j+5];
817
818 if ( refs != NULL )
819 pp->ref = refs[i-1];
820
821 mesh->point[pp->v[0]].tag &= ~MG_NUL;
822 mesh->point[pp->v[1]].tag &= ~MG_NUL;
823 mesh->point[pp->v[2]].tag &= ~MG_NUL;
824 mesh->point[pp->v[3]].tag &= ~MG_NUL;
825 mesh->point[pp->v[4]].tag &= ~MG_NUL;
826 mesh->point[pp->v[5]].tag &= ~MG_NUL;
827
828 }
829
830 return 1;
831}
832
833int MMG3D_Get_prisms(MMG5_pMesh mesh, MMG5_int *prisms, MMG5_int *refs, int * areRequired) {
834 MMG5_pPrism pp;
835 MMG5_int j,i;
836
837 for (i=1;i<=mesh->nprism;i++)
838 {
839 j = (i-1)*6;
840 pp = &mesh->prism[i];
841 prisms[j] = pp->v[0];
842 prisms[j+2] = pp->v[1];
843 prisms[j+1] = pp->v[2];
844 prisms[j+3] = pp->v[3];
845 prisms[j+4] = pp->v[4];
846 prisms[j+5] = pp->v[5];
847
848 if ( refs!=NULL )
849 refs[i-1] = pp->ref ;
850 if ( areRequired != NULL ) {
851 if ( pp->tag & MG_REQ )
852 areRequired[i-1] = 1;
853 else
854 areRequired[i-1] = 0;
855 }
856 }
857 return 1;
858}
859
860
861
862int MMG3D_Set_triangle(MMG5_pMesh mesh, MMG5_int v0, MMG5_int v1, MMG5_int v2, MMG5_int ref,MMG5_int pos) {
863
864 if ( !mesh->nt ) {
865 fprintf(stderr,"\n ## Error: %s: You must set the number of triangles"
866 " with the",__func__);
867 fprintf(stderr," MMG3D_Set_meshSize function before setting triangles in mesh\n");
868 return 0;
869 }
870
871 if ( pos > mesh->ntmax ) {
872 fprintf(stderr,"\n ## Error: %s: unable to allocate a new triangle.\n",
873 __func__);
874 fprintf(stderr," max number of triangle: %" MMG5_PRId "\n",mesh->ntmax);
876 return 0;
877 }
878
879 if ( pos > mesh->nt ) {
880 fprintf(stderr,"\n ## Error: %s: attempt to set new triangle at"
881 " position %" MMG5_PRId ".",__func__,pos);
882 fprintf(stderr," Overflow of the given number of triangles: %" MMG5_PRId "\n",mesh->nt);
883 fprintf(stderr,"\n ## Check the mesh size, its compactness or the position");
884 fprintf(stderr," of the triangle.\n");
885 return 0;
886 }
887
888 mesh->tria[pos].v[0] = v0;
889 mesh->tria[pos].v[1] = v1;
890 mesh->tria[pos].v[2] = v2;
891 mesh->tria[pos].ref = ref;
892
893 return 1;
894}
895
896int MMG3D_Get_triangle(MMG5_pMesh mesh, MMG5_int* v0, MMG5_int* v1, MMG5_int* v2, MMG5_int* ref
897 ,int* isRequired) {
898 MMG5_pTria ptt;
899
900 if ( mesh->nti == mesh->nt ) {
901 mesh->nti = 0;
902 if ( mesh->info.ddebug ) {
903 fprintf(stderr,"\n ## Warning: %s: reset the internal counter of"
904 " triangles.\n",__func__);
905 fprintf(stderr," You must pass here exactly one time (the first time ");
906 fprintf(stderr,"you call the MMG3D_Get_triangle function).\n");
907 fprintf(stderr," If not, the number of call of this function");
908 fprintf(stderr," exceed the number of triangles: %" MMG5_PRId "\n ",mesh->nt);
909 }
910 }
911
912 mesh->nti++;
913
914 if ( mesh->nti > mesh->nt ) {
915 fprintf(stderr,"\n ## Error: %s: unable to get triangle.\n",__func__);
916 fprintf(stderr," The number of call of MMG3D_Get_triangle function");
917 fprintf(stderr," can not exceed the number of triangles: %" MMG5_PRId "\n ",mesh->nt);
918 return 0;
919 }
920
921 ptt = &mesh->tria[mesh->nti];
922 *v0 = ptt->v[0];
923 *v1 = ptt->v[1];
924 *v2 = ptt->v[2];
925 if ( ref != NULL )
926 *ref = ptt->ref;
927
928 if ( isRequired != NULL ) {
929 if ( (ptt->tag[0] & MG_REQ) && (ptt->tag[1] & MG_REQ) &&
930 (ptt->tag[2] & MG_REQ) )
931 *isRequired = 1;
932 else
933 *isRequired = 0;
934 }
935
936 return 1;
937}
938int MMG3D_Set_triangles(MMG5_pMesh mesh, MMG5_int *tria, MMG5_int *refs) {
939
940 MMG5_pTria ptt;
941 MMG5_int i, j;
942
943 for (i=1;i<=mesh->nt;i++)
944 {
945 j = (i-1)*3;
946 ptt = &mesh->tria[i];
947 ptt->v[0] = tria[j] ;
948 ptt->v[1] = tria[j+1];
949 ptt->v[2] = tria[j+2];
950 if ( refs != NULL )
951 ptt->ref = refs[i-1];
952 }
953 return 1;
954}
955
956int MMG3D_Get_triangles(MMG5_pMesh mesh, MMG5_int *tria, MMG5_int *refs, int *areRequired) {
957 MMG5_pTria ptt;
958 MMG5_int i, j;
959
960 for (i=1;i<=mesh->nt;i++)
961 {
962 j = (i-1)*3;
963 ptt = &mesh->tria[i];
964 tria[j] = ptt->v[0];
965 tria[j+1] = ptt->v[1];
966 tria[j+2] = ptt->v[2];
967
968 if ( refs!=NULL )
969 refs[i-1] = ptt->ref ;
970 if ( areRequired != NULL ) {
971 if ( (ptt->tag[0] & MG_REQ) && (ptt->tag[1] & MG_REQ) &&
972 (ptt->tag[2] & MG_REQ) )
973 areRequired[i-1] = 1;
974 else
975 areRequired[i-1] = 0;
976 }
977 }
978 return 1;
979}
980
981int MMG3D_Set_quadrilateral(MMG5_pMesh mesh, MMG5_int v0, MMG5_int v1, MMG5_int v2, MMG5_int v3,
982 MMG5_int ref,MMG5_int pos) {
983
984 if ( !mesh->nquad ) {
985 fprintf(stderr,"\n ## Error: %s: You must set the number of quadrilaterals"
986 " with the",__func__);
987 fprintf(stderr," MMG3D_Set_meshSize function before setting quadrilaterals in mesh\n");
988 return 0;
989 }
990
991 if ( pos > mesh->nquad ) {
992 fprintf(stderr,"\n ## Error: %s: attempt to set new quadrilateral"
993 " at position %" MMG5_PRId ".",__func__,pos);
994 fprintf(stderr," Overflow of the given number of quadrilaterals: %" MMG5_PRId "\n",mesh->nquad);
995 fprintf(stderr,"\n ## Check the mesh size, its compactness or the position");
996 fprintf(stderr," of the quadrilateral.\n");
997 return 0;
998 }
999
1000 mesh->quadra[pos].v[0] = v0;
1001 mesh->quadra[pos].v[1] = v1;
1002 mesh->quadra[pos].v[2] = v2;
1003 mesh->quadra[pos].v[3] = v3;
1004 mesh->quadra[pos].ref = ref;
1005
1006 return 1;
1007}
1008
1009int MMG3D_Get_quadrilateral(MMG5_pMesh mesh, MMG5_int* v0, MMG5_int* v1, MMG5_int* v2, MMG5_int* v3,
1010 MMG5_int* ref,int* isRequired) {
1011 MMG5_pQuad pq;
1012 static MMG5_int nqi = 0;
1013
1014 if ( nqi == mesh->nquad ) {
1015 nqi = 0;
1016 if ( mesh->info.ddebug ) {
1017 fprintf(stderr,"\n ## Warning: %s: reset the internal counter"
1018 " of quadrilaterals.\n",__func__);
1019 fprintf(stderr," You must pass here exactly one time (the first time ");
1020 fprintf(stderr,"you call the MMG3D_Get_quadrilateral function).\n");
1021 fprintf(stderr," If not, the number of call of this function");
1022 fprintf(stderr," exceed the number of quadrilaterals: %" MMG5_PRId "\n ",mesh->nquad);
1023 }
1024 }
1025
1026 nqi++;
1027
1028 if ( nqi > mesh->nquad ) {
1029 fprintf(stderr,"\n ## Error: %s: unable to get quadrilateral.\n",__func__);
1030 fprintf(stderr," The number of call of MMG3D_Get_quadrilateral function");
1031 fprintf(stderr," can not exceed the number of quadrilaterals: %" MMG5_PRId "\n ",mesh->nquad);
1032 return 0;
1033 }
1034
1035 pq = &mesh->quadra[nqi];
1036 *v0 = pq->v[0];
1037 *v1 = pq->v[1];
1038 *v2 = pq->v[2];
1039 *v3 = pq->v[3];
1040 if ( ref != NULL )
1041 *ref = pq->ref;
1042
1043 if ( isRequired != NULL ) {
1044 if ( (pq->tag[0] & MG_REQ) && (pq->tag[1] & MG_REQ) &&
1045 (pq->tag[2] & MG_REQ) && (pq->tag[3] & MG_REQ))
1046 *isRequired = 1;
1047 else
1048 *isRequired = 0;
1049 }
1050
1051 return 1;
1052}
1053
1054int MMG3D_Set_quadrilaterals(MMG5_pMesh mesh, MMG5_int *quads, MMG5_int *refs) {
1055 MMG5_pQuad pq;
1056 MMG5_int j,i;
1057
1058 for (i=1;i<=mesh->nquad;i++)
1059 {
1060 j = (i-1)*4;
1061 pq = &mesh->quadra[i];
1062 pq->v[0] = quads[j] ;
1063 pq->v[1] = quads[j+1];
1064 pq->v[2] = quads[j+2];
1065 pq->v[3] = quads[j+3];
1066 if ( refs != NULL )
1067 pq->ref = refs[i-1];
1068 }
1069 return 1;
1070}
1071
1072int MMG3D_Get_quadrilaterals(MMG5_pMesh mesh, MMG5_int *quads, MMG5_int *refs, int *areRequired) {
1073 MMG5_pQuad pq;
1074 MMG5_int j,i;
1075
1076 for (i=1;i<=mesh->nquad;i++)
1077 {
1078 j = (i-1)*4;
1079 pq = &mesh->quadra[i];
1080 quads[j] = pq->v[0];
1081 quads[j+1] = pq->v[1];
1082 quads[j+2] = pq->v[2];
1083 quads[j+3] = pq->v[3];
1084
1085 if ( refs!=NULL )
1086 refs[i-1] = pq->ref ;
1087 if ( areRequired != NULL ) {
1088 if ( (pq->tag[0] & MG_REQ) && (pq->tag[1] & MG_REQ) &&
1089 (pq->tag[2] & MG_REQ) && (pq->tag[3] & MG_REQ) )
1090 areRequired[i-1] = 1;
1091 else
1092 areRequired[i-1] = 0;
1093 }
1094 }
1095 return 1;
1096}
1097
1098int MMG3D_Set_edge(MMG5_pMesh mesh, MMG5_int v0, MMG5_int v1, MMG5_int ref, MMG5_int pos) {
1099
1100 if ( !mesh->na ) {
1101 fprintf(stderr,"\n ## Error: %s: You must set the number of edges with"
1102 " the",__func__);
1103 fprintf(stderr," MMG3D_Set_meshSize function before setting edges in mesh\n");
1104 return 0;
1105 }
1106 if ( pos > mesh->namax ) {
1107 fprintf(stderr,"\n ## Error: %s: unable to allocate a new edge.\n",
1108 __func__);
1109 fprintf(stderr," max number of edge: %" MMG5_PRId "\n",mesh->namax);
1111 return 0;
1112 }
1113 if ( pos > mesh->na ) {
1114 fprintf(stderr,"\n ## Error: %s: attempt to set new edge at position %" MMG5_PRId ".",
1115 __func__,pos);
1116 fprintf(stderr," Overflow of the given number of edges: %" MMG5_PRId "\n",mesh->na);
1117 fprintf(stderr,"\n ## Check the mesh size, its compactness or the position");
1118 fprintf(stderr," of the edge.\n");
1119 return 0;
1120 }
1121
1122 mesh->edge[pos].a = v0;
1123 mesh->edge[pos].b = v1;
1124 mesh->edge[pos].ref = ref;
1125 mesh->edge[pos].tag |= MG_REF;
1126
1127 return 1;
1128}
1129
1130int MMG3D_Get_edge(MMG5_pMesh mesh, MMG5_int* e0, MMG5_int* e1, MMG5_int* ref
1131 ,int* isRidge, int* isRequired) {
1132
1133 if ( mesh->nai == mesh->na ) {
1134 mesh->nai = 0;
1135 if ( mesh->info.ddebug ) {
1136 fprintf(stderr,"\n ## Warning: %s: reset the internal counter of edges.\n",
1137 __func__);
1138 fprintf(stderr," You must pass here exactly one time (the first time ");
1139 fprintf(stderr,"you call the MMG3D_Get_edge function).\n");
1140 fprintf(stderr," If not, the number of call of this function");
1141 fprintf(stderr," exceed the number of edges: %" MMG5_PRId "\n ",mesh->na);
1142 }
1143 }
1144
1145 mesh->nai++;
1146
1147 if ( mesh->nai > mesh->na ) {
1148 fprintf(stderr,"\n ## Error: %s: unable to get edge.\n",__func__);
1149 fprintf(stderr," The number of call of MMG3D_Get_edge function");
1150 fprintf(stderr," can not exceed the number of edges: %" MMG5_PRId "\n ",mesh->na);
1151 return 0;
1152 }
1153
1154 *e0 = mesh->edge[mesh->nai].a;
1155 *e1 = mesh->edge[mesh->nai].b;
1156 if ( ref!=NULL )
1157 *ref = mesh->edge[mesh->nai].ref;
1158
1159 if ( isRidge != NULL ) {
1160 if ( mesh->edge[mesh->nai].tag & MG_GEO )
1161 *isRidge = 1;
1162 else
1163 *isRidge = 0;
1164 }
1165
1166 if ( isRequired != NULL ) {
1167 if ( mesh->edge[mesh->nai].tag & MG_REQ )
1168 *isRequired = 1;
1169 else
1170 *isRequired = 0;
1171 }
1172
1173 return 1;
1174}
1175
1176int MMG3D_Set_edges(MMG5_pMesh mesh, MMG5_int *edges, MMG5_int *refs) {
1177 MMG5_int i,j;
1178
1179 for (i=1;i<=mesh->na;i++)
1180 {
1181 j = (i-1)*2;
1182
1183 mesh->edge[i].a = edges[j];
1184 mesh->edge[i].b = edges[j+1];
1185 if ( refs != NULL )
1186 mesh->edge[i].ref = refs[i-1];
1187 mesh->edge[i].tag |= MG_REF;
1188 }
1189
1190 return 1;
1191}
1192
1193int MMG3D_Get_edges(MMG5_pMesh mesh, MMG5_int* edges,MMG5_int *refs,int* areRidges,int* areRequired) {
1194 MMG5_int i,j;
1195
1196 for (i=1;i<=mesh->na;i++)
1197 {
1198 j = (i-1)*2;
1199 edges[j] = mesh->edge[i].a;
1200 edges[j+1] = mesh->edge[i].b;
1201
1202 if ( refs!=NULL )
1203 refs[i-1] = mesh->edge[i].ref;
1204
1205 if ( areRidges != NULL ) {
1206 if ( mesh->edge[i].tag & MG_GEO )
1207 areRidges[i-1] = 1;
1208 else
1209 areRidges[i-1] = 0;
1210 }
1211
1212 if ( areRequired != NULL ) {
1213 if ( mesh->edge[i].tag & MG_REQ )
1214 areRequired[i-1] = 1;
1215 else
1216 areRequired[i-1] = 0;
1217 }
1218 }
1219
1220 return 1;
1221}
1222
1224 assert ( k <= mesh->np );
1225 mesh->point[k].tag |= MG_CRN;
1226 return 1;
1227}
1228
1230 assert ( k <= mesh->np );
1231 mesh->point[k].tag &= ~MG_CRN;
1232 return 1;
1233}
1234
1236 assert ( k <= mesh->np );
1237 mesh->point[k].tag |= MG_REQ;
1238 mesh->point[k].tag &= ~MG_NUL;
1239 return 1;
1240}
1241
1243 assert ( k <= mesh->np );
1244 mesh->point[k].tag &= ~MG_REQ;
1245 return 1;
1246}
1247
1249 assert ( k <= mesh->ne );
1250 mesh->tetra[k].tag |= MG_REQ;
1251 return 1;
1252}
1253
1255 assert ( k <= mesh->ne );
1256 mesh->tetra[k].tag &= ~MG_REQ;
1257 return 1;
1258}
1259
1260int MMG3D_Set_requiredTetrahedra(MMG5_pMesh mesh, MMG5_int *reqIdx, MMG5_int nreq) {
1261 MMG5_int k;
1262
1263 for ( k=0; k<nreq; ++k ){
1264 mesh->tetra[reqIdx[k]].tag |= MG_REQ;
1265 }
1266
1267 return 1;
1268}
1269
1270int MMG3D_Unset_requiredTetrahedra(MMG5_pMesh mesh, MMG5_int *reqIdx, MMG5_int nreq) {
1271 MMG5_int k;
1272
1273 for ( k=0; k<nreq; ++k ){
1274 mesh->tetra[reqIdx[k]].tag &= ~MG_REQ;
1275 }
1276
1277 return 1;
1278}
1279
1281 assert ( k <= mesh->nt );
1282 mesh->tria[k].tag[0] |= MG_REQ;
1283 mesh->tria[k].tag[1] |= MG_REQ;
1284 mesh->tria[k].tag[2] |= MG_REQ;
1285 return 1;
1286}
1287
1289 assert ( k <= mesh->nt );
1290 mesh->tria[k].tag[0] &= ~MG_REQ;
1291 mesh->tria[k].tag[1] &= ~MG_REQ;
1292 mesh->tria[k].tag[2] &= ~MG_REQ;
1293 return 1;
1294}
1295
1296int MMG3D_Set_requiredTriangles(MMG5_pMesh mesh, MMG5_int* reqIdx, MMG5_int nreq) {
1297 MMG5_int k;
1298
1299 for ( k=0; k<nreq; ++k ){
1300 mesh->tria[reqIdx[k]].tag[0] |= MG_REQ;
1301 mesh->tria[reqIdx[k]].tag[1] |= MG_REQ;
1302 mesh->tria[reqIdx[k]].tag[2] |= MG_REQ;
1303 }
1304 return 1;
1305}
1306
1307int MMG3D_Unset_requiredTriangles(MMG5_pMesh mesh, MMG5_int* reqIdx, MMG5_int nreq) {
1308 MMG5_int k;
1309
1310 for ( k=0; k<nreq; ++k ){
1311 mesh->tria[reqIdx[k]].tag[0] &= ~MG_REQ;
1312 mesh->tria[reqIdx[k]].tag[1] &= ~MG_REQ;
1313 mesh->tria[reqIdx[k]].tag[2] &= ~MG_REQ;
1314 }
1315 return 1;
1316}
1317
1319 assert ( k <= mesh->nt );
1320 mesh->tria[k].tag[0] |= MG_PARBDY;
1321 mesh->tria[k].tag[1] |= MG_PARBDY;
1322 mesh->tria[k].tag[2] |= MG_PARBDY;
1323 return 1;
1324}
1325
1327 assert ( k <= mesh->nt );
1328 mesh->tria[k].tag[0] &= ~MG_PARBDY;
1329 mesh->tria[k].tag[1] &= ~MG_PARBDY;
1330 mesh->tria[k].tag[2] &= ~MG_PARBDY;
1331 return 1;
1332}
1333
1334int MMG3D_Set_parallelTriangles(MMG5_pMesh mesh, MMG5_int* parIdx, MMG5_int npar) {
1335 MMG5_int k;
1336
1337 for ( k=0; k<npar; ++k ){
1338 mesh->tria[parIdx[k]].tag[0] |= MG_PARBDY;
1339 mesh->tria[parIdx[k]].tag[1] |= MG_PARBDY;
1340 mesh->tria[parIdx[k]].tag[2] |= MG_PARBDY;
1341 }
1342 return 1;
1343}
1344
1345int MMG3D_Unset_parallelTriangles(MMG5_pMesh mesh, MMG5_int* parIdx, MMG5_int npar) {
1346 MMG5_int k;
1347
1348 for ( k=0; k<npar; ++k ){
1349 mesh->tria[parIdx[k]].tag[0] &= ~MG_PARBDY;
1350 mesh->tria[parIdx[k]].tag[1] &= ~MG_PARBDY;
1351 mesh->tria[parIdx[k]].tag[2] &= ~MG_PARBDY;
1352 }
1353 return 1;
1354}
1355
1357 assert ( k <= mesh->na );
1358 mesh->edge[k].tag |= MG_GEO;
1359 return 1;
1360}
1361
1363 assert ( k <= mesh->na );
1364 mesh->edge[k].tag &= ~MG_GEO;
1365 return 1;
1366}
1367
1369 assert ( k <= mesh->na );
1370 mesh->edge[k].tag |= MG_REQ;
1371 return 1;
1372}
1373
1375 assert ( k <= mesh->na );
1376 mesh->edge[k].tag &= ~MG_REQ;
1377 return 1;
1378}
1379
1380int MMG3D_Set_normalAtVertex(MMG5_pMesh mesh, MMG5_int k, double n0, double n1, double n2) {
1381
1382 assert ( k <= mesh->np );
1383 mesh->point[k].n[0] = n0;
1384 mesh->point[k].n[1] = n1;
1385 mesh->point[k].n[2] = n2;
1386
1387 ++mesh->nc1;
1388
1389 return 1;
1390}
1391
1392int MMG3D_Get_normalAtVertex(MMG5_pMesh mesh, MMG5_int k, double *n0, double *n1, double *n2) {
1393
1394 assert ( k <= mesh->np );
1395 (*n0) = mesh->point[k].n[0];
1396 (*n1) = mesh->point[k].n[1];
1397 (*n2) = mesh->point[k].n[2];
1398
1399 return 1;
1400}
1401
1403 double qual = 0.;
1404 MMG5_pTetra pt;
1405
1406 if ( k < 1 || k > mesh->ne ) {
1407 fprintf(stderr,"\n ## Error: %s: unable to access to tetra %" MMG5_PRId ".\n",
1408 __func__,k);
1409 fprintf(stderr," Tetra numbering goes from 1 to %" MMG5_PRId "\n",mesh->ne);
1410 return 0.;
1411 }
1412 pt = &mesh->tetra[k];
1413 assert ( MG_EOK(pt) );
1414
1415 if ( (!met) || (!met->m) || met->size==1 ) {
1416 if ( mesh->info.optimLES) {
1417 /* Skewness */
1418 qual = MMG3D_ALPHAD * MMG3D_caltetLES_iso(mesh,met,pt);
1419 } else {
1420 /* iso quality */
1421 qual = MMG3D_ALPHAD * MMG5_caltet_iso(mesh,NULL,pt);
1422 }
1423 }
1424 else if ( !mesh->info.metRidTyp ) {
1425 qual = MMG3D_ALPHAD * MMG5_caltet33_ani(mesh,met,pt);
1426 }
1427 else {
1428 qual = MMG3D_ALPHAD * MMG5_caltet_ani(mesh,met,pt);
1429 }
1430
1431 return qual;
1432}
1433
1434int MMG3D_Set_scalarSol(MMG5_pSol met, double s, MMG5_int pos) {
1435
1436 if ( !met->np ) {
1437 fprintf(stderr,"\n ## Error: %s: You must set the number of"
1438 " solution with the",__func__);
1439 fprintf(stderr," MMG3D_Set_solSize function before setting values");
1440 fprintf(stderr," in solution structure \n");
1441 return 0;
1442 }
1443 if ( pos < 1 ) {
1444 fprintf(stderr,"\n ## Error: %s: unable to set a new solution.\n",__func__);
1445 fprintf(stderr," Minimal index of the solution position must be 1.\n");
1446 return 0;
1447 }
1448 if ( pos >= met->npmax ) {
1449 fprintf(stderr,"\n ## Error: %s: unable to set a new solution.\n",__func__);
1450 fprintf(stderr," max number of solutions: %" MMG5_PRId "\n",met->npmax);
1451 return 0;
1452 }
1453
1454 if ( pos > met->np ) {
1455 fprintf(stderr,"\n ## Error: %s: attempt to set new solution at"
1456 " position %" MMG5_PRId ".",__func__,pos);
1457 fprintf(stderr," Overflow of the given number of solutions: %" MMG5_PRId "\n",met->np);
1458 fprintf(stderr,"\n ## Check the solution size, its compactness or the position");
1459 fprintf(stderr," of the solution.\n");
1460 return 0;
1461 }
1462
1463 met->m[pos] = s;
1464 return 1;
1465}
1466
1467
1468int MMG3D_Get_scalarSol(MMG5_pSol met, double* s) {
1469
1470 int ddebug = 0;
1471
1472 if ( met->npi == met->np ) {
1473 met->npi = 0;
1474 if ( ddebug ) {
1475 fprintf(stderr,"\n ## Warning: %s: reset the internal counter of points.\n",
1476 __func__);
1477 fprintf(stderr," You must pass here exactly one time (the first time ");
1478 fprintf(stderr,"you call the MMG3D_Get_scalarSol function).\n");
1479 fprintf(stderr," If not, the number of call of this function");
1480 fprintf(stderr," exceed the number of points: %" MMG5_PRId "\n ",met->np);
1481 }
1482 }
1483
1484 met->npi++;
1485
1486 if ( met->npi > met->np ) {
1487 fprintf(stderr,"\n ## Error: %s: unable to get solution.\n",__func__);
1488 fprintf(stderr," The number of call of MMG3D_Get_scalarSol function");
1489 fprintf(stderr," can not exceed the number of points: %" MMG5_PRId "\n ",met->np);
1490 return 0;
1491 }
1492
1493 *s = met->m[met->npi];
1494
1495 return 1;
1496}
1497
1498int MMG3D_Set_scalarSols(MMG5_pSol met, double *s ) {
1499 MMG5_int k;
1500
1501 if ( !met->np ) {
1502 fprintf(stderr,"\n ## Error: %s: You must set the number of solution"
1503 " with the",__func__);
1504 fprintf(stderr," MMG3D_Set_solSize function before setting values");
1505 fprintf(stderr," in solution structure \n");
1506 return 0;
1507 }
1508
1509 for ( k=0; k<met->np; ++k )
1510 met->m[k+1] = s[k];
1511
1512 return 1;
1513}
1514
1515int MMG3D_Get_scalarSols(MMG5_pSol met, double* s) {
1516 MMG5_int k;
1517
1518 for ( k=0; k<met->np; ++k )
1519 s[k] = met->m[k+1];
1520
1521 return 1;
1522}
1523
1524int MMG3D_Set_vectorSol(MMG5_pSol met, double vx,double vy, double vz, MMG5_int pos) {
1525
1526 if ( !met->np ) {
1527 fprintf(stderr,"\n ## Error: %s: You must set the number of solution"
1528 " with the",__func__);
1529 fprintf(stderr," MMG3D_Set_solSize function before setting values");
1530 fprintf(stderr," in solution structure \n");
1531 return 0;
1532 }
1533 if ( pos < 1 ) {
1534 fprintf(stderr,"\n ## Error: %s: unable to set a new solution.\n",__func__);
1535 fprintf(stderr," Minimal index of the solution position must be 1.\n");
1536 return 0;
1537 }
1538 if ( pos >= met->npmax ) {
1539 fprintf(stderr,"\n ## Error: %s: unable to set a new solution.\n",__func__);
1540 fprintf(stderr," max number of solutions: %" MMG5_PRId "\n",met->npmax);
1541 return 0;
1542 }
1543
1544 if ( pos > met->np ) {
1545 fprintf(stderr,"\n ## Error: %s: attempt to set new solution at"
1546 " position %" MMG5_PRId ".",__func__,pos);
1547 fprintf(stderr," Overflow of the given number of solutions: %" MMG5_PRId "\n",met->np);
1548 fprintf(stderr,"\n ## Check the solution size, its compactness or the position");
1549 fprintf(stderr," of the solution.\n");
1550 return 0;
1551 }
1552
1553 met->m[3*pos] = vx;
1554 met->m[3*pos+1] = vy;
1555 met->m[3*pos+2] = vz;
1556
1557 return 1;
1558}
1559
1560
1561int MMG3D_Get_vectorSol(MMG5_pSol met, double* vx, double* vy, double* vz) {
1562
1563 int ddebug = 0;
1564
1565 if ( met->npi == met->np ) {
1566 met->npi = 0;
1567 if ( ddebug ) {
1568 fprintf(stderr,"\n ## Warning: %s: reset the internal counter of points.\n",
1569 __func__);
1570 fprintf(stderr," You must pass here exactly one time (the first time ");
1571 fprintf(stderr,"you call the MMG3D_Get_vectorSol function).\n");
1572 fprintf(stderr," If not, the number of call of this function");
1573 fprintf(stderr," exceed the number of points: %" MMG5_PRId "\n ",met->np);
1574 }
1575 }
1576
1577 met->npi++;
1578
1579 if ( met->npi > met->np ) {
1580 fprintf(stderr,"\n ## Error: %s: unable to get solution.\n",__func__);
1581 fprintf(stderr," The number of call of MMG3D_Get_vectorSol function");
1582 fprintf(stderr," can not exceed the number of points: %" MMG5_PRId "\n ",met->np);
1583 return 0;
1584 }
1585
1586 *vx = met->m[3*met->npi];
1587 *vy = met->m[3*met->npi+1];
1588 *vz = met->m[3*met->npi+2];
1589
1590 return 1;
1591}
1592
1593int MMG3D_Set_vectorSols(MMG5_pSol met, double *sols) {
1594 double *m;
1595 MMG5_int k,j;
1596
1597 if ( !met->np ) {
1598 fprintf(stderr,"\n ## Error: %s: You must set the number of solution"
1599 " with the",__func__);
1600 fprintf(stderr," MMG3D_Set_solSize function before setting values");
1601 fprintf(stderr," in solution structure \n");
1602 return 0;
1603 }
1604
1605 for ( k=0; k<met->np; ++k ) {
1606 j = 3*k;
1607 m = &met->m[j+3];
1608 m[0] = sols[j];
1609 m[1] = sols[j+1];
1610 m[2] = sols[j+2];
1611 }
1612
1613 return 1;
1614}
1615
1616int MMG3D_Get_vectorSols(MMG5_pSol met, double* sols) {
1617 double *m;
1618 MMG5_int k, j;
1619
1620 for ( k=0; k<met->np; ++k ) {
1621 j = 3*k;
1622 m = &met->m[j+3];
1623 sols[j] = m[0];
1624 sols[j+1] = m[1];
1625 sols[j+2] = m[2];
1626 }
1627
1628 return 1;
1629}
1630
1631int MMG3D_Set_tensorSol(MMG5_pSol met, double m11,double m12, double m13,
1632 double m22,double m23, double m33, MMG5_int pos) {
1633
1634 if ( !met->np ) {
1635 fprintf(stderr,"\n ## Error: %s: You must set the number of solution"
1636 " with the",__func__);
1637 fprintf(stderr," MMG3D_Set_solSize function before setting values");
1638 fprintf(stderr," in solution structure \n");
1639 return 0;
1640 }
1641 if ( pos < 1 ) {
1642 fprintf(stderr,"\n ## Error: %s: unable to set a new solution.\n",
1643 __func__);
1644 fprintf(stderr," Minimal index of the solution position must be 1.\n");
1645 return 0;
1646 }
1647 if ( pos >= met->npmax ) {
1648 fprintf(stderr,"\n ## Error: %s: unable to set a new solution.\n",__func__);
1649 fprintf(stderr," max number of solutions: %" MMG5_PRId "\n",met->npmax);
1650 return 0;
1651 }
1652
1653 if ( pos > met->np ) {
1654 fprintf(stderr,"\n ## Error: %s: attempt to set new solution at "
1655 "position %" MMG5_PRId ".",__func__,pos);
1656 fprintf(stderr," Overflow of the given number of solutions: %" MMG5_PRId "\n",met->np);
1657 fprintf(stderr,"\n ## Check the solution size, its compactness or the position");
1658 fprintf(stderr," of the solution.\n");
1659 return 0;
1660 }
1661
1662 met->m[6*pos] = m11;
1663 met->m[6*pos+1] = m12;
1664 met->m[6*pos+2] = m13;
1665 met->m[6*pos+3] = m22;
1666 met->m[6*pos+4] = m23;
1667 met->m[6*pos+5] = m33;
1668
1669 return 1;
1670}
1671
1672
1673int MMG3D_Get_tensorSol(MMG5_pSol met, double *m11,double *m12, double *m13,
1674 double *m22,double *m23, double *m33) {
1675
1676 int ddebug = 0;
1677
1678 if ( met->npi == met->np ) {
1679 met->npi = 0;
1680 if ( ddebug ) {
1681 fprintf(stderr,"\n ## Warning: %s: reset the internal counter of points.\n",
1682 __func__);
1683 fprintf(stderr," You must pass here exactly one time (the first time ");
1684 fprintf(stderr,"you call the MMG3D_Get_tensorSol function).\n");
1685 fprintf(stderr," If not, the number of call of this function");
1686 fprintf(stderr," exceed the number of points: %" MMG5_PRId "\n ",met->np);
1687 }
1688 }
1689
1690 met->npi++;
1691
1692 if ( met->npi > met->np ) {
1693 fprintf(stderr,"\n ## Error: %s: unable to get solution.\n",__func__);
1694 fprintf(stderr," The number of call of MMG3D_Get_tensorSol function");
1695 fprintf(stderr," can not exceed the number of points: %" MMG5_PRId "\n ",met->np);
1696 return 0;
1697 }
1698
1699 *m11 = met->m[6*met->npi];
1700 *m12 = met->m[6*met->npi+1];
1701 *m13 = met->m[6*met->npi+2];
1702 *m22 = met->m[6*met->npi+3];
1703 *m23 = met->m[6*met->npi+4];
1704 *m33 = met->m[6*met->npi+5];
1705
1706 return 1;
1707}
1708
1709int MMG3D_Set_tensorSols(MMG5_pSol met, double *sols) {
1710 double *m;
1711 MMG5_int k,j;
1712
1713 if ( !met->np ) {
1714 fprintf(stderr,"\n ## Error: %s: You must set the number of"
1715 " solution with the",__func__);
1716 fprintf(stderr," MMG3D_Set_solSize function before setting values");
1717 fprintf(stderr," in solution structure \n");
1718 return 0;
1719 }
1720
1721 for ( k=0; k<met->np; ++k ) {
1722 j = 6*k;
1723 m = &met->m[j+6];
1724
1725 m[0] = sols[j];
1726 m[1] = sols[j+1];
1727 m[2] = sols[j+2];
1728 m[3] = sols[j+3];
1729 m[4] = sols[j+4];
1730 m[5] = sols[j+5];
1731 }
1732 return 1;
1733}
1734
1735int MMG3D_Get_tensorSols(MMG5_pSol met, double *sols) {
1736 double *m;
1737 MMG5_int k,j;
1738
1739 for ( k=0; k<met->np; ++k ) {
1740 j = 6*k;
1741 m = &met->m[j+6];
1742
1743 sols[j] = m[0];
1744 sols[j+1] = m[1];
1745 sols[j+2] = m[2];
1746 sols[j+3] = m[3];
1747 sols[j+4] = m[4];
1748 sols[j+5] = m[5];
1749 }
1750
1751 return 1;
1752}
1753
1754int MMG3D_Set_ithSol_inSolsAtVertices(MMG5_pSol sol,int i, double* s,MMG5_int pos) {
1755 MMG5_pSol psl;
1756
1757 /* Warning: users give indices from 1 to nsols */
1758 psl = sol + (i-1);
1759
1760 switch ( psl->type ) {
1761 case MMG5_Scalar:
1762 return MMG3D_Set_scalarSol(psl,s[0],pos);
1763 break;
1764
1765 case MMG5_Vector:
1766 MMG3D_Set_vectorSol(psl,s[0],s[1],s[2],pos);
1767 break;
1768
1769 case MMG5_Tensor:
1770 MMG3D_Set_tensorSol(psl,s[0],s[1],s[2],s[3],s[4],s[5],pos);
1771 break;
1772
1773 default:
1774 fprintf(stderr,"\n ## Error: %s: unexpected type of solution: %s.\n",
1775 __func__,MMG5_Get_typeName(psl->type));
1776 return 0;
1777 }
1778 return 1;
1779}
1780
1781int MMG3D_Get_ithSol_inSolsAtVertices(MMG5_pSol sol,int i, double *s,MMG5_int pos) {
1782 MMG5_pSol psl;
1783
1784 /* Warning: users give indices from 1 to nsols */
1785 psl = sol + (i-1);
1786
1787 psl->npi = pos-1;
1788
1789 switch ( psl->type ) {
1790 case MMG5_Scalar:
1791 return MMG3D_Get_scalarSol(psl,&s[0]);
1792 break;
1793
1794 case MMG5_Vector:
1795 MMG3D_Get_vectorSol(psl,&s[0],&s[1],&s[2]);
1796 break;
1797
1798 case MMG5_Tensor:
1799 MMG3D_Get_tensorSol(psl,&s[0],&s[1],&s[2],&s[3],&s[4],&s[5]);
1800 break;
1801
1802 default:
1803 fprintf(stderr,"\n ## Error: %s: unexpected type of solution: %s\n",
1804 __func__,MMG5_Get_typeName(psl->type));
1805 return 0;
1806 }
1807
1808 return 1;
1809}
1810
1812 MMG5_pSol psl;
1813
1814 /* Warning: users give indices from 1 to nsols */
1815 psl = sol + (i-1);
1816
1817 switch ( psl->type ) {
1818 case MMG5_Scalar:
1819 return MMG3D_Set_scalarSols(psl,s);
1820 break;
1821
1822 case MMG5_Vector:
1823 MMG3D_Set_vectorSols(psl,s);
1824 break;
1825
1826 case MMG5_Tensor:
1827 MMG3D_Set_tensorSols(psl,s);
1828 break;
1829
1830 default:
1831 fprintf(stderr,"\n ## Error: %s: unexpected type of solution: %s.\n",
1832 __func__,MMG5_Get_typeName(psl->type));
1833 return 0;
1834 }
1835
1836 return 1;
1837}
1838
1840 MMG5_pSol psl;
1841
1842 /* Warning: users give indices from 1 to nsols */
1843 psl = sol + (i-1);
1844
1845 switch ( psl->type ) {
1846 case MMG5_Scalar:
1847 return MMG3D_Get_scalarSols(psl,s);
1848 break;
1849
1850 case MMG5_Vector:
1851 MMG3D_Get_vectorSols(psl,s);
1852 break;
1853
1854 case MMG5_Tensor:
1855 MMG3D_Get_tensorSols(psl,s);
1856 break;
1857
1858 default:
1859 fprintf(stderr,"\n ## Error: %s: unexpected type of solution: %s\n",
1860 __func__,MMG5_Get_typeName(psl->type));
1861 return 0;
1862 }
1863
1864 return 1;
1865}
1866
1868 MMG5_int k, aux;
1869
1870 /* Possibly switch 2 vertices number so that each tet is positively oriented */
1871 for (k=1; k<=mesh->ne; k++) {
1872 if ( MMG5_orvol(mesh->point,mesh->tetra[k].v) < 0.0 ) {
1873 /* mesh->xt temporary used to count reoriented tetra */
1874 mesh->xt++;
1875 aux = mesh->tetra[k].v[2];
1876 mesh->tetra[k].v[2] = mesh->tetra[k].v[3];
1877 mesh->tetra[k].v[3] = aux;
1878 }
1879 }
1880 return;
1881}
1882
1884
1885 if ( (mesh->npi != mesh->np) || (mesh->nei != mesh->ne) ) {
1886 fprintf(stderr,"\n ## Error: %s: if you don't use the MMG3D_loadMesh"
1887 " function,",__func__);
1888 fprintf(stderr," you must call the MMG3D_Set_meshSize function to have a");
1889 fprintf(stderr," valid mesh.\n");
1890 fprintf(stderr," Missing datas.\n");
1891 return 0;
1892 }
1893
1894 if ( met->npi != met->np ) {
1895 fprintf(stderr,"\n ## Error: %s: if you don't use the MMG3D_loadSol"
1896 " function,",__func__);
1897 fprintf(stderr," you must call the MMG3D_Set_solSize function to have a");
1898 fprintf(stderr," valid solution.\n");
1899 fprintf(stderr," Missing datas.\n");
1900 return 0;
1901 }
1902
1903 /* Check mesh data */
1904 if ( mesh->info.ddebug ) {
1905 if ( (!mesh->np) || (!mesh->point) ||
1906 (!mesh->ne) || (!mesh->tetra) ) {
1907 fprintf(stderr," ** MISSING DATA.\n");
1908 fprintf(stderr," Check that your mesh contains points and tetrahedra.\n");
1909 fprintf(stderr," Exit program.\n");
1910 return 0;
1911 }
1912 }
1913
1914 if ( mesh->dim != 3 ) {
1915 fprintf(stderr," ** 3 DIMENSIONAL MESH NEEDED. Exit program.\n");
1916 return 0;
1917 }
1918 if ( met->dim != 3 ) {
1919 fprintf(stderr," ** WRONG DIMENSION FOR METRIC. Exit program.\n");
1920 return 0;
1921 }
1922 if ( !mesh->ver ) mesh->ver = 2;
1923 if ( !met ->ver ) met ->ver = 2;
1924
1925 return 1;
1926}
1927
1928static inline
1930 MMG5_pTria ptt,ptt1;
1931 MMG5_pEdge pa,pa1;
1932 MMG5_int k;
1933
1934 if ( (mesh->info.imprim > 5) || mesh->info.ddebug )
1935 fprintf(stderr,"\n ## Warning: %s: skip of all entites with %"MMG5_PRId
1936 " reference.\n",__func__,mesh->info.isoref);
1937
1938 /* Skip triangles with mesh->info.isoref refs */
1939 k = 1;
1940 do {
1941 ptt = &mesh->tria[k];
1942 if ( MMG5_abs(ptt->ref) != mesh->info.isoref ) continue;
1943 /* here ptt is the first tri of mesh->tria that we want to delete */
1944 do {
1945 ptt1 = &mesh->tria[mesh->nti];
1946 }
1947 while( (MMG5_abs(ptt1->ref) == mesh->info.isoref) && (k <= --mesh->nti) );
1948
1949 if ( MMG5_abs(ptt1->ref) != mesh->info.isoref )
1950 /* ptt1 is the last tri of mesh->tria that we want to keep */
1951 memcpy(ptt,ptt1,sizeof(MMG5_Tria));
1952 } while( ++k <= mesh->nti );
1953
1954 if ( mesh->nti < mesh->nt ) {
1955 if( !mesh->nti )
1957 else {
1958 MMG5_ADD_MEM(mesh,mesh->nti-mesh->nt,"triangles",return 0);
1960 "triangles",return 0);
1961 }
1962 mesh->nt = mesh->nti;
1963 }
1964
1965 /* Skip edges with mesh->info.isoref refs */
1966 if ( mesh->na ) {
1967 k = 1;
1968 do {
1969 pa = &mesh->edge[k];
1970 if ( MMG5_abs(pa->ref) != mesh->info.isoref ) {
1971 pa->ref = MMG5_abs(pa->ref);
1972 continue;
1973 }
1974 /* here pa is the first edge of mesh->edge that we want to delete */
1975 do {
1976 pa1 = &mesh->edge[mesh->nai];
1977 }
1978 while( (MMG5_abs(pa1->ref) == mesh->info.isoref) && (k <= --mesh->nai) );
1979
1980 if ( MMG5_abs(pa1->ref) != mesh->info.isoref ) {
1981 /* pa1 is the last edge of mesh->edge that we want to keep */
1982 memcpy(pa,pa1,sizeof(MMG5_Edge));
1983 pa1->ref = MMG5_abs(pa1->ref);
1984 }
1985 } while( ++k <= mesh->nai );
1986
1987 if ( mesh->nai < mesh->na ) {
1988 if( !mesh->nai )
1990 else {
1991 MMG5_ADD_MEM(mesh,mesh->nai-mesh->na,"Edges",return 0);
1993 "edges",return 0);
1994 }
1995 mesh->na = mesh->nai;
1996 }
1997 }
1998 assert ( mesh->nai == mesh->na );
1999
2000 /* delete tetrahedra references */
2001 for (k=1; k<=mesh->ne; k++) {
2002 mesh->tetra[k].ref = 0;
2003 }
2004 return 1;
2005}
2006
2007int MMG3D_Add_tetrahedron(MMG5_pMesh mesh, MMG5_int v0, MMG5_int v1, MMG5_int v2, MMG5_int v3, MMG5_int ref) {
2008 MMG5_pTetra pt;
2009 MMG5_pPoint ppt;
2010 double vol;
2011 int j,ip;
2012 MMG5_int aux,vv[4],iel;
2013
2014 vv[0] = v0;
2015 vv[1] = v1;
2016 vv[2] = v2;
2017 vv[3] = v3;
2018
2019 for ( j=0; j<4; ++j ) {
2020 if ( vv[j] > mesh->np ) {
2021 fprintf(stderr,"\n ## Error: %s: vertex %" MMG5_PRId " doesn't exist in the mesh.\n",
2022 __func__,vv[j]);
2023 fprintf(stderr," Use the MMG3D_Add_vertex function to add it.\n");
2024 return 0;
2025 }
2026 }
2027
2028 iel = MMG3D_newElt(mesh);
2029 if ( !iel ) {
2031 fprintf(stderr,"\n ## Error: %s: unable to allocate"
2032 " a new element.\n",__func__);
2034 fprintf(stderr," Exit program.\n");
2035 return 0);
2036 }
2037
2038 pt = &mesh->tetra[iel];
2039 pt->v[0] = v0;
2040 pt->v[1] = v1;
2041 pt->v[2] = v2;
2042 pt->v[3] = v3;
2043 pt->ref = MMG5_abs(ref);
2044
2045 mesh->point[pt->v[0]].tag &= ~MG_NUL;
2046 mesh->point[pt->v[1]].tag &= ~MG_NUL;
2047 mesh->point[pt->v[2]].tag &= ~MG_NUL;
2048 mesh->point[pt->v[3]].tag &= ~MG_NUL;
2049
2050 vol = MMG5_orvol(mesh->point,pt->v);
2051 if ( fabs(vol) <= MMG5_EPSD2 ) {
2052 fprintf(stderr,"\n ## Error: %s: tetrahedron %" MMG5_PRId ": null volume.\n",
2053 __func__,iel);
2054 for ( ip=0; ip<4; ip++ ) {
2055 ppt = &mesh->point[pt->v[ip]];
2056 for ( j=0; j<3; j++ ) {
2057 if ( fabs(ppt->c[j])>0. ) {
2058 fprintf(stderr," Check that you don't have a sliver tetrahedron.\n");
2059 return -iel;
2060 }
2061 }
2062 }
2063 fprintf(stderr," All vertices have zero coordinates.");
2064 fprintf(stderr," Check that you have set the vertices before the tetrahedra.\n");
2065 return -iel;
2066 }
2067 else if ( vol < 0.0 ) {
2068 /* Possibly switch 2 vertices number so that each tet is positively oriented */
2069 aux = pt->v[2];
2070 pt->v[2] = pt->v[3];
2071 pt->v[3] = aux;
2072 /* mesh->xt temporary used to count reoriented tetra */
2073 mesh->xt++;
2074
2075 return -iel;
2076 }
2077
2078 return iel;
2079}
2080
2081MMG5_int MMG3D_Add_vertex(MMG5_pMesh mesh,double c0,double c1,double c2,MMG5_int ref) {
2082 double c[3];
2083 MMG5_int ip,klink;
2084
2085 c[0] = c0;
2086 c[1] = c1;
2087 c[2] = c2;
2088
2089 ip = MMG3D_newPt(mesh,c,0,1);
2090 if ( !ip ) {
2092 "larger point table",
2093 fprintf(stderr,"\n ## Error: %s: unable to allocate"
2094 " a new point\n",__func__);
2095 MMG5_INCREASE_MEM_MESSAGE();return 0);
2096
2097 mesh->npnil = mesh->np+1;
2098 for (klink=mesh->npnil; klink<mesh->npmax-1; klink++)
2099 mesh->point[klink].tmp = klink+1;
2100
2101 /* We try again to add the point */
2102 ip = MMG3D_newPt(mesh,c,0,1);
2103 if ( !ip ) {
2104 fprintf(stderr,"\n ## Error: %s: unable to allocate"
2105 " a new point\n",__func__);
2107 return 0;
2108 }
2109 }
2110 return ip;
2111}
2112
2113int MMG3D_Set_iparameter(MMG5_pMesh mesh, MMG5_pSol sol, int iparam,MMG5_int val){
2114 int k;
2115
2116 switch ( iparam ) {
2117 /* Integer parameters */
2119 mesh->info.imprim = val;
2120 break;
2121 case MMG3D_IPARAM_mem :
2122 if ( val <= 0 ) {
2123 fprintf(stderr,"\n ## Warning: %s: maximal memory authorized must be"
2124 " strictly positive.\n",__func__);
2125 fprintf(stderr," Reset to default value.\n");
2126 }
2127 else
2128 mesh->info.mem = val;
2129 if ( !MMG3D_memOption(mesh) ) return 0;
2130 break;
2131#ifndef MMG_PATTERN
2132 case MMG3D_IPARAM_octree :
2133 mesh->info.PROctree = val;
2134 break;
2135#endif
2136 case MMG3D_IPARAM_debug :
2137 mesh->info.ddebug = val;
2138 break;
2139 case MMG3D_IPARAM_angle :
2140 /* free table that may contains old ridges */
2141 if ( mesh->htab.geom )
2143 if ( mesh->xpoint )
2145 if ( mesh->xtetra )
2147 if ( !val )
2148 mesh->info.dhd = -1.;
2149 else {
2150 if ( (mesh->info.imprim > 5) || mesh->info.ddebug )
2151 fprintf(stderr,"\n ## Warning: %s: angle detection parameter set"
2152 " to default value\n",__func__);
2154 }
2155 break;
2156 case MMG3D_IPARAM_nofem :
2157 mesh->info.setfem = (val==1)? 0 : 1;
2158 break;
2159 case MMG3D_IPARAM_opnbdy :
2160 mesh->info.opnbdy = val;
2161 break;
2162 case MMG3D_IPARAM_iso :
2163 mesh->info.iso = val;
2164 if ( mesh->info.iso )
2165 if ( mesh->nt && !MMG3D_skipIso(mesh) )
2166 return 0;
2167 break;
2168 case MMG3D_IPARAM_isoref :
2169 mesh->info.isoref = val;
2170 break;
2172 mesh->info.isosurf = val;
2173 break;
2174 case MMG3D_IPARAM_lag :
2175#ifdef USE_ELAS
2176 if ( val < 0 || val > 2 )
2177 return 0;
2178 mesh->info.lag = val;
2179 /* No connectivity changes unless lag >= 2 */
2180 if ( val < 2 ) {
2182 return 0;
2183 }
2184#else
2185 fprintf(stderr,"\n ## Error: %s"
2186 " \"lagrangian motion\" option unavailable (-lag):\n"
2187 " set the USE_ELAS CMake's flag to ON when compiling the mmg3d"
2188 " library to enable this feature.\n",__func__);
2189 return 0;
2190#endif
2191 break;
2193 mesh->info.nsd = val;
2194 break;
2195 case MMG3D_IPARAM_optim :
2196 mesh->info.optim = val;
2197 break;
2199 mesh->info.optimLES = val;
2200 break;
2202 mesh->info.noinsert = val;
2203 break;
2204 case MMG3D_IPARAM_noswap :
2205 mesh->info.noswap = val;
2206 break;
2207 case MMG3D_IPARAM_nomove :
2208 mesh->info.nomove = val;
2209 break;
2210 case MMG3D_IPARAM_nosurf :
2211 mesh->info.nosurf = val;
2212 break;
2213 case MMG3D_IPARAM_nreg :
2214 mesh->info.nreg = val;
2215 break;
2216 case MMG3D_IPARAM_xreg :
2217 mesh->info.xreg = val;
2218 break;
2220 mesh->info.nosizreq = val;
2221 break;
2223 if ( mesh->info.par ) {
2225 if ( (mesh->info.imprim > 5) || mesh->info.ddebug )
2226 fprintf(stderr,"\n ## Warning: %s: new local parameter values\n",__func__);
2227 }
2228 mesh->info.npar = val;
2229 mesh->info.npari = 0;
2230 mesh->info.parTyp = 0;
2231
2232 MMG5_ADD_MEM(mesh,mesh->info.npar*sizeof(MMG5_Par),"parameters",
2233 printf(" Exit program.\n");
2234 return 0);
2236
2237 MMG5_int inival;
2238 inival = MMG5_INTMAX;
2239
2240 for (k=0; k<mesh->info.npar; k++) {
2242 mesh->info.par[k].ref = inival;
2243 mesh->info.par[k].hausd = mesh->info.hausd;
2244 mesh->info.par[k].hmin = mesh->info.hmin;
2245 mesh->info.par[k].hmax = mesh->info.hmax;
2246 }
2247
2248 break;
2250 mesh->info.nbr = val;
2251 MMG5_ADD_MEM(mesh,mesh->info.nbr*sizeof(int),"References",
2252 printf(" Exit program.\n");
2253 return 0);
2254 MMG5_SAFE_CALLOC(mesh->info.br,mesh->info.nbr,MMG5_int,return 0);
2255
2256 for (k=0; k<mesh->info.nbr; k++)
2257 mesh->info.br[k] = 0;
2258
2259 break;
2260
2262 if ( mesh->info.mat ) {
2264 if ( (mesh->info.imprim > 5) || mesh->info.ddebug )
2265 fprintf(stderr,"\n ## Warning: %s: new multi materials values\n",__func__);
2266 }
2267 mesh->info.nmat = val;
2268 mesh->info.nmati = 0;
2269
2270 MMG5_ADD_MEM(mesh,(mesh->info.nmat)*sizeof(MMG5_Mat),"multi material",
2271 printf(" Exit program.\n");
2272 return 0);
2274 for (k=0; k<mesh->info.nmat; k++) {
2275 mesh->info.mat[k].ref = 0;
2276 }
2277
2278 break;
2279
2280#ifdef USE_SCOTCH
2281 case MMG3D_IPARAM_renum :
2282 mesh->info.renum = val;
2283 break;
2284#endif
2286 mesh->info.ani = val;
2287 break;
2288 default :
2289 fprintf(stderr,"\n ## Error: %s: unknown type of parameter\n",__func__);
2290 return 0;
2291 }
2292 /* other options */
2293
2294 return 1;
2295}
2296
2297int MMG3D_Get_iparameter(MMG5_pMesh mesh, MMG5_int iparam) {
2298
2299 switch ( iparam ) {
2300 /* Integer parameters */
2302 return mesh->info.imprim;
2303 break;
2304 case MMG3D_IPARAM_mem :
2305 return mesh->info.mem;
2306 break;
2307#ifndef MMG_PATTERN
2308 case MMG3D_IPARAM_octree :
2309 return mesh->info.PROctree;
2310 break;
2311#endif
2312 case MMG3D_IPARAM_debug :
2313 return mesh->info.ddebug;
2314 break;
2315 case MMG3D_IPARAM_angle :
2316 if ( mesh->info.dhd <= 0. ) {
2317 return 0;
2318 }
2319 else {
2320 return 1;
2321 }
2322 break;
2323 case MMG3D_IPARAM_iso :
2324 return mesh->info.iso;
2325 break;
2326 case MMG3D_IPARAM_lag :
2327 return mesh->info.lag;
2328 break;
2330 return mesh->info.noinsert;
2331 break;
2332 case MMG3D_IPARAM_noswap :
2333 return mesh->info.noswap;
2334 break;
2335 case MMG3D_IPARAM_nomove :
2336 return mesh->info.nomove;
2337 break;
2338 case MMG3D_IPARAM_nosurf :
2339 return mesh->info.nosurf;
2340 break;
2341 case MMG3D_IPARAM_nreg :
2342 return mesh->info.nreg;
2343 break;
2344 case MMG3D_IPARAM_xreg :
2345 return mesh->info.xreg;
2346 break;
2348 return mesh->info.npar;
2349 break;
2351 return mesh->info.nmat;
2352 break;
2353#ifdef USE_SCOTCH
2354 case MMG3D_IPARAM_renum :
2355 return mesh->info.renum;
2356 break;
2357#endif
2358 default :
2359 fprintf(stderr,"\n ## Error: %s: unknown type of parameter\n",__func__);
2360 return 0;
2361 }
2362}
2363
2364int MMG3D_Set_dparameter(MMG5_pMesh mesh, MMG5_pSol sol, int dparam, double val){
2365
2366 switch ( dparam ) {
2367 /* double parameters */
2369 mesh->info.dhd = val;
2370 mesh->info.dhd = MG_MAX(0.0, MG_MIN(180.0,mesh->info.dhd));
2371 mesh->info.dhd = cos(mesh->info.dhd*M_PI/180.0);
2372 break;
2373 case MMG3D_DPARAM_hmin :
2374 mesh->info.sethmin = 1;
2375 mesh->info.hmin = val;
2376 if ( mesh->info.sethmax && ( mesh->info.hmin >= mesh->info.hmax ) ) {
2377 fprintf(stderr,"\n ## Warning: hmin value must be strictly lower than hmax one"
2378 " (hmin = %lf hmax = %lf ).\n",mesh->info.hmin, mesh->info.hmax);
2379 }
2380
2381 break;
2382 case MMG3D_DPARAM_hmax :
2383 mesh->info.sethmax = 1;
2384 mesh->info.hmax = val;
2385 if ( mesh->info.sethmin && ( mesh->info.hmin >= mesh->info.hmax ) ) {
2386 fprintf(stderr,"\n ## Warning: hmin value must be strictly lower than hmax one"
2387 " (hmin = %lf hmax = %lf ).\n",mesh->info.hmin, mesh->info.hmax);
2388 }
2389
2390 break;
2391 case MMG3D_DPARAM_hsiz :
2392 mesh->info.hsiz = val;
2393 break;
2394 case MMG3D_DPARAM_hgrad :
2395 mesh->info.hgrad = val;
2396 if ( mesh->info.hgrad <= 0.0 )
2397 mesh->info.hgrad = -1.0;
2398 else
2399 mesh->info.hgrad = log(mesh->info.hgrad);
2400 break;
2402 mesh->info.hgradreq = val;
2403 if ( mesh->info.hgradreq <= 0.0 )
2404 mesh->info.hgradreq = -1.0;
2405 else
2407 break;
2408 case MMG3D_DPARAM_hausd :
2409 if ( val <=0 ) {
2410 fprintf(stderr,"\n ## Error: %s: hausdorff number must be strictly"
2411 " positive.\n",__func__);
2412 return 0;
2413 }
2414 else
2415 mesh->info.hausd = val;
2416 break;
2417 case MMG3D_DPARAM_ls :
2418 mesh->info.ls = val;
2419 break;
2420 case MMG3D_DPARAM_xreg :
2421 if (val < 0.0 || val > 1.0) {
2422 fprintf(stderr,"\n ## Error: %s: Coordinate regularization parameter must be comprised between 0 and 1.\n",__func__);
2423 }
2424 else
2425 mesh->info.lxreg = val;
2426 break;
2427 case MMG3D_DPARAM_rmc :
2428 if ( !val ) {
2429 /* Default value */
2431 }
2432 else {
2433 /* User customized value */
2434 mesh->info.rmc = val;
2435 }
2436 break;
2437 default :
2438 fprintf(stderr,"\n ## Error: %s: unknown type of parameter\n", __func__);
2439 return 0;
2440 }
2441 return 1;
2442}
2443
2445 double hmin,double hmax,double hausd){
2446 MMG5_pPar par;
2447 int k;
2448
2449 if ( !mesh->info.npar ) {
2450 fprintf(stderr,"\n ## Error: %s: You must set the number of local"
2451 " parameters",__func__);
2452 fprintf(stderr," with the MMG3D_Set_iparameters function before setting");
2453 fprintf(stderr," values in local parameters structure. \n");
2454 return 0;
2455 }
2456 if ( mesh->info.npari >= mesh->info.npar ) {
2457 fprintf(stderr,"\n ## Error: %s: unable to set a new local parameter.\n",
2458 __func__);
2459 fprintf(stderr," max number of local parameters: %d\n",mesh->info.npar);
2460 return 0;
2461 }
2462 if ( typ != MMG5_Triangle && typ != MMG5_Tetrahedron ) {
2463 fprintf(stderr,"\n ## Warning: %s: you must apply your local parameters",
2464 __func__);
2465 fprintf(stderr," on triangles (MMG5_Triangle or %d) or tetrahedron"
2466 " (MMG5_Tetrahedron or %d).\n",MMG5_Triangle,MMG5_Tetrahedron);
2467 fprintf(stderr,"\n ## Unknown type of entity: ignored.\n");
2468 return 0;
2469 }
2470 if ( ref < 0 ) {
2471 fprintf(stderr,"\n ## Error: %s: negative references are not allowed.\n",
2472 __func__);
2473 return 0;
2474 }
2475
2476 if ( hmin <= 0 ) {
2477 fprintf(stderr,"\n ## Error: %s: negative hmin value is not allowed.\n",
2478 __func__);
2479 return 0;
2480 }
2481 if ( hmax <= 0 ) {
2482 fprintf(stderr,"\n ## Error: %s: negative hmax value is not allowed.\n",
2483 __func__);
2484 return 0;
2485 }
2486 if ( hausd <= 0 ) {
2487 fprintf(stderr,"\n ## Error: %s: negative hausd value is not allowed.\n",
2488 __func__);
2489 return 0;
2490 }
2491
2492 for (k=0; k<mesh->info.npari; k++) {
2493 par = &mesh->info.par[k];
2494
2495 if ( par->elt == typ && par->ref == ref ) {
2496 par->hausd = hausd;
2497 par->hmin = hmin;
2498 par->hmax = hmax;
2499 if ( (mesh->info.imprim > 5) || mesh->info.ddebug ) {
2500 fprintf(stderr,"\n ## Warning: %s: new parameters (hausd, hmin and hmax)",
2501 __func__);
2502 fprintf(stderr," for entities of type %d and of ref %" MMG5_PRId "\n",typ,ref);
2503 }
2504 return 1;
2505 }
2506 }
2507
2508 mesh->info.par[mesh->info.npari].elt = typ;
2509 mesh->info.par[mesh->info.npari].ref = ref;
2510 mesh->info.par[mesh->info.npari].hmin = hmin;
2511 mesh->info.par[mesh->info.npari].hmax = hmax;
2512 mesh->info.par[mesh->info.npari].hausd = hausd;
2513
2514 switch ( typ )
2515 {
2516 case ( MMG5_Triangle ):
2517 mesh->info.parTyp |= MG_Tria;
2518 break;
2519 case ( MMG5_Tetrahedron ):
2521 break;
2522 default:
2523 fprintf(stderr,"\n ## Error: %s: unexpected entity type: %s.\n",
2524 __func__,MMG5_Get_entitiesName(typ));
2525 return 0;
2526 }
2527
2528 mesh->info.npari++;
2529
2530 return 1;
2531}
2532
2533int MMG3D_Set_multiMat(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_int ref,int split,MMG5_int rmin,MMG5_int rplus) {
2534 return MMG5_Set_multiMat(mesh,sol,ref,split,rmin,rplus);
2535}
2536
2539}
2540
2541
2543
2544 return MMG5_Free_allSols(mesh,sol);
2545}
2546
2547int MMG3D_Free_all(const int starter,...)
2548{
2549 va_list argptr;
2550 int ier;
2551
2553
2555
2556 va_end(argptr);
2557
2558 return ier;
2559}
2560
2562{
2563 va_list argptr;
2564 int ier;
2565
2567
2569
2570 va_end(argptr);
2571
2572 return ier;
2573}
2574
2575int MMG3D_Free_names(const int starter,...)
2576{
2577 va_list argptr;
2578 int ier;
2579
2581
2583
2584 va_end(argptr);
2585
2586 return ier;
2587}
const char * MMG5_Get_typeName(enum MMG5_type typ)
int MMG5_Set_inputParamName(MMG5_pMesh mesh, const char *fparamin)
int MMG5_Set_outputMeshName(MMG5_pMesh mesh, const char *meshout)
int MMG5_Set_inputSolName(MMG5_pMesh mesh, MMG5_pSol sol, const char *solin)
int MMG5_Free_allSols(MMG5_pMesh mesh, MMG5_pSol *sol)
int MMG5_Set_inputMeshName(MMG5_pMesh mesh, const char *meshin)
void MMG5_Init_parameters(MMG5_pMesh mesh)
Definition: API_functions.c:51
const char * MMG5_Get_entitiesName(enum MMG5_entities ent)
void MMG5_Init_fileNames(MMG5_pMesh mesh, MMG5_pSol sol)
int MMG5_Set_outputSolName(MMG5_pMesh mesh, MMG5_pSol sol, const char *solout)
int MMG3D_Init_mesh(const int starter,...)
Initialize a mesh structure and optionally the associated solution and metric structures.
int MMG3D_Set_vectorSol(MMG5_pSol met, double vx, double vy, double vz, MMG5_int pos)
Set a single element of a vector solution structure.
int MMG3D_Unset_requiredEdge(MMG5_pMesh mesh, MMG5_int k)
Remove the "required" attribute from a single edge.
int MMG3D_GetByIdx_vertex(MMG5_pMesh mesh, double *c0, double *c1, double *c2, MMG5_int *ref, int *isCorner, int *isRequired, MMG5_int idx)
Get the coordinates and reference of a specific vertex in the mesh.
int MMG3D_Get_vectorSol(MMG5_pSol met, double *vx, double *vy, double *vz)
Get the next element of a vector solution structure.
int MMG3D_Get_vertices(MMG5_pMesh mesh, double *vertices, MMG5_int *refs, int *areCorners, int *areRequired)
Get the coordinates and references of all vertices in the mesh.
int MMG3D_Get_prism(MMG5_pMesh mesh, MMG5_int *v0, MMG5_int *v1, MMG5_int *v2, MMG5_int *v3, MMG5_int *v4, MMG5_int *v5, MMG5_int *ref, int *isRequired)
Get the vertices and reference of the next prism in the mesh.
int MMG3D_Get_normalAtVertex(MMG5_pMesh mesh, MMG5_int k, double *n0, double *n1, double *n2)
Get the normal orientation at a single mesh vertex.
int MMG3D_Set_triangles(MMG5_pMesh mesh, MMG5_int *tria, MMG5_int *refs)
Set the vertices and references of all triangles in a mesh.
int MMG3D_Unset_corner(MMG5_pMesh mesh, MMG5_int k)
Remove the "corner" attribute from a vertex.
void MMG3D_Init_fileNames(MMG5_pMesh mesh, MMG5_pSol sol)
Initialize file names to their default values.
int MMG3D_Set_quadrilateral(MMG5_pMesh mesh, MMG5_int v0, MMG5_int v1, MMG5_int v2, MMG5_int v3, MMG5_int ref, MMG5_int pos)
Set the vertices and reference of a single quadrilateral in a mesh.
int MMG3D_Unset_ridge(MMG5_pMesh mesh, MMG5_int k)
Remove the "ridge" attribute from a single edge.
int MMG3D_Set_corner(MMG5_pMesh mesh, MMG5_int k)
Assign the "corner" attribute to a vertex.
int MMG3D_Get_edge(MMG5_pMesh mesh, MMG5_int *e0, MMG5_int *e1, MMG5_int *ref, int *isRidge, int *isRequired)
Get the vertices and reference of the next edge in the mesh.
int MMG3D_Set_inputMeshName(MMG5_pMesh mesh, const char *meshin)
Set the name of input mesh.
int MMG3D_Set_inputParamName(MMG5_pMesh mesh, const char *fparamin)
Set the name of the input parameter file.
int MMG3D_Set_ithSols_inSolsAtVertices(MMG5_pSol sol, int i, double *s)
Set all elements of one out of multiple solution fields that are defined on vertices.
int MMG3D_Get_prisms(MMG5_pMesh mesh, MMG5_int *prisms, MMG5_int *refs, int *areRequired)
Get the vertices and references of all prisms in the mesh.
int MMG3D_Set_edges(MMG5_pMesh mesh, MMG5_int *edges, MMG5_int *refs)
Set the vertices and references of all edges in a mesh.
int MMG3D_Set_tensorSols(MMG5_pSol met, double *sols)
Set all elements of a tensor solution structure.
int MMG3D_Set_requiredTetrahedron(MMG5_pMesh mesh, MMG5_int k)
Assign the "required" attribute to a tetrahedron.
int MMG3D_Get_triangle(MMG5_pMesh mesh, MMG5_int *v0, MMG5_int *v1, MMG5_int *v2, MMG5_int *ref, int *isRequired)
Get the vertices and reference of the next triangle in the mesh.
double MMG3D_Get_tetrahedronQuality(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k)
Get the quality measure of a single tetrahedron in the mesh.
int MMG3D_Set_dparameter(MMG5_pMesh mesh, MMG5_pSol sol, int dparam, double val)
set a real-valued parameter of the remesher
int MMG3D_Get_tensorSol(MMG5_pSol met, double *m11, double *m12, double *m13, double *m22, double *m23, double *m33)
Get the next element of a tensor solution structure.
int MMG3D_Set_localParameter(MMG5_pMesh mesh, MMG5_pSol sol, int typ, MMG5_int ref, double hmin, double hmax, double hausd)
set a local parameter
int MMG3D_Set_tetrahedron(MMG5_pMesh mesh, MMG5_int v0, MMG5_int v1, MMG5_int v2, MMG5_int v3, MMG5_int ref, MMG5_int pos)
set a single tetrahedron's vertices
int MMG3D_Set_triangle(MMG5_pMesh mesh, MMG5_int v0, MMG5_int v1, MMG5_int v2, MMG5_int ref, MMG5_int pos)
Set the vertices and reference of a single triangle in a mesh.
int MMG3D_Get_tetrahedron(MMG5_pMesh mesh, MMG5_int *v0, MMG5_int *v1, MMG5_int *v2, MMG5_int *v3, MMG5_int *ref, int *isRequired)
Get the vertices and reference of the next tetrahedron in the mesh.
int MMG3D_Set_scalarSols(MMG5_pSol met, double *s)
Set the values of all elements of a scalar solution structure.
int MMG3D_Get_quadrilaterals(MMG5_pMesh mesh, MMG5_int *quads, MMG5_int *refs, int *areRequired)
Get the vertices and references of all quadrilaterals of the mesh.
int MMG3D_Get_solSize(MMG5_pMesh mesh, MMG5_pSol sol, int *typEntity, MMG5_int *np, int *typSol)
Get the number of elements, dimension, and type of a solution structure.
int MMG3D_Set_edge(MMG5_pMesh mesh, MMG5_int v0, MMG5_int v1, MMG5_int ref, MMG5_int pos)
Set the vertices and reference of a single edge in a mesh.
int MMG3D_Get_ithSol_inSolsAtVertices(MMG5_pSol sol, int i, double *s, MMG5_int pos)
Get one out of several solutions at a specific vertex.
int MMG3D_Set_scalarSol(MMG5_pSol met, double s, MMG5_int pos)
Set a single element of a scalar solution structure.
int MMG3D_Free_allSols(MMG5_pMesh mesh, MMG5_pSol *sol)
Deallocate an array of solution fields.
int MMG3D_Get_vectorSols(MMG5_pSol met, double *sols)
Get all elements of a vector solution structure.
int MMG3D_Set_quadrilaterals(MMG5_pMesh mesh, MMG5_int *quads, MMG5_int *refs)
Set the vertices and references of all quadrilaterals in a mesh.
int MMG3D_Get_vertex(MMG5_pMesh mesh, double *c0, double *c1, double *c2, MMG5_int *ref, int *isCorner, int *isRequired)
Get the coordinates c0, c1,c2 and reference ref of the next vertex of mesh.
int MMG3D_Set_ithSol_inSolsAtVertices(MMG5_pSol sol, int i, double *s, MMG5_int pos)
Set a single element of one out of multiple solution fields that are defined on vertices.
int MMG3D_Get_edges(MMG5_pMesh mesh, MMG5_int *edges, MMG5_int *refs, int *areRidges, int *areRequired)
Get the vertices and references of all edges in a mesh.
int MMG3D_Get_tensorSols(MMG5_pSol met, double *sols)
Get all elements of a tensor solution field.
int MMG3D_Set_lsBaseReference(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_int br)
Set a new level-set base reference.
int MMG3D_Set_parallelTriangles(MMG5_pMesh mesh, MMG5_int *parIdx, MMG5_int npar)
Assign the "parallel" attribute to multiple triangles.
int MMG3D_Set_vectorSols(MMG5_pSol met, double *sols)
Set all elements of a vector solution structure.
void MMG3D_Set_handGivenMesh(MMG5_pMesh mesh)
Finish providing mesh data without using the API functions.
int MMG3D_Set_requiredVertex(MMG5_pMesh mesh, MMG5_int k)
Assign the "required" attribute to a vertex.
int MMG3D_Set_inputSolName(MMG5_pMesh mesh, MMG5_pSol sol, const char *solin)
Set the name of input solution file.
int MMG3D_Unset_requiredTriangles(MMG5_pMesh mesh, MMG5_int *reqIdx, MMG5_int nreq)
Remove the "required" attribute from multiple triangles.
int MMG3D_Unset_requiredTetrahedra(MMG5_pMesh mesh, MMG5_int *reqIdx, MMG5_int nreq)
Remove the "required" attribute from multiple tetrahedra.
int MMG3D_Set_multiMat(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_int ref, int split, MMG5_int rmin, MMG5_int rplus)
Set the reference mapping for the elements of reference ref in level-set discretization mode.
int MMG3D_Set_requiredTriangle(MMG5_pMesh mesh, MMG5_int k)
Assign the "required" attribute to a single triangle.
int MMG3D_Set_vertices(MMG5_pMesh mesh, double *vertices, MMG5_int *refs)
Set all vertex coordinates and references in a mesh structure.
int MMG3D_Free_structures(const int starter,...)
Structure deallocations before return.
int MMG3D_Add_tetrahedron(MMG5_pMesh mesh, MMG5_int v0, MMG5_int v1, MMG5_int v2, MMG5_int v3, MMG5_int ref)
Add a tetrahedron to the mesh.
int MMG3D_Set_ridge(MMG5_pMesh mesh, MMG5_int k)
Assign the "ridge" attribute to a single edge.
int MMG3D_Set_solsAtVerticesSize(MMG5_pMesh mesh, MMG5_pSol *sol, int nsols, MMG5_int nentities, int *typSol)
Initialize an array of solution values defined at vertices.
int MMG3D_Free_names(const int starter,...)
Structure deallocations before return.
int MMG3D_Set_outputSolName(MMG5_pMesh mesh, MMG5_pSol sol, const char *solout)
Set the name of the output solution file.
int MMG3D_Get_iparameter(MMG5_pMesh mesh, MMG5_int iparam)
Get the value of an integer parameter of the remesher.
int MMG3D_Set_outputMeshName(MMG5_pMesh mesh, const char *meshout)
Set the name of output mesh file.
int MMG3D_Set_parallelTriangle(MMG5_pMesh mesh, MMG5_int k)
Assign the "parallel" attribute to a single triangle.
int MMG3D_Set_prism(MMG5_pMesh mesh, MMG5_int v0, MMG5_int v1, MMG5_int v2, MMG5_int v3, MMG5_int v4, MMG5_int v5, MMG5_int ref, MMG5_int pos)
Set the vertices and reference of a single prism in a mesh.
int MMG3D_Get_ithSols_inSolsAtVertices(MMG5_pSol sol, int i, double *s)
Get one out of several solutions at all vertices in the mesh.
int MMG3D_setMeshSize_initData(MMG5_pMesh mesh, MMG5_int np, MMG5_int ne, MMG5_int nprism, MMG5_int nt, MMG5_int nquad, MMG5_int na)
int MMG3D_Chk_meshData(MMG5_pMesh mesh, MMG5_pSol met)
Check if the number of given entities match with mesh and sol size.
int MMG3D_Get_scalarSols(MMG5_pSol met, double *s)
Get all elements of a scalar solution structure defined at vertices.
MMG5_int MMG3D_Add_vertex(MMG5_pMesh mesh, double c0, double c1, double c2, MMG5_int ref)
Add a vertex to the mesh.
int MMG3D_Get_solsAtVerticesSize(MMG5_pMesh mesh, MMG5_pSol *sol, int *nsols, MMG5_int *np, int *typSol)
Get the number of elements, type, and dimensions of several solutions defined on vertices.
int MMG3D_Get_triangles(MMG5_pMesh mesh, MMG5_int *tria, MMG5_int *refs, int *areRequired)
Get the vertices and references of all triangles in the mesh.
int MMG3D_Unset_parallelTriangle(MMG5_pMesh mesh, MMG5_int k)
Remove the "parallel" attribute from a single triangle.
int MMG3D_Set_tensorSol(MMG5_pSol met, double m11, double m12, double m13, double m22, double m23, double m33, MMG5_int pos)
Set a single element of a tensor solution structure.
int MMG3D_Get_quadrilateral(MMG5_pMesh mesh, MMG5_int *v0, MMG5_int *v1, MMG5_int *v2, MMG5_int *v3, MMG5_int *ref, int *isRequired)
Get the vertices and reference of the next quadrilateral of the mesh.
int MMG3D_Get_tetrahedra(MMG5_pMesh mesh, MMG5_int *tetra, MMG5_int *refs, int *areRequired)
Get the vertices and reference of all tetrahedra in the mesh.
int MMG3D_Set_vertex(MMG5_pMesh mesh, double c0, double c1, double c2, MMG5_int ref, MMG5_int pos)
Set the coordinates of a single vertex.
int MMG3D_Get_scalarSol(MMG5_pSol met, double *s)
Get the next element of a scalar solution structure defined at vertices.
int MMG3D_Get_meshSize(MMG5_pMesh mesh, MMG5_int *np, MMG5_int *ne, MMG5_int *nprism, MMG5_int *nt, MMG5_int *nquad, MMG5_int *na)
Get the number of vertices, tetrahedra, prisms, triangles, quadrilaterals and edges of the mesh.
int MMG3D_Set_prisms(MMG5_pMesh mesh, MMG5_int *prisms, MMG5_int *refs)
Set the vertices and references of all prisms in a mesh.
void MMG3D_Init_parameters(MMG5_pMesh mesh)
Initialize parameters to their default values.
int MMG3D_Free_all(const int starter,...)
Deallocations before return.
int MMG3D_Set_iparameter(MMG5_pMesh mesh, MMG5_pSol sol, int iparam, MMG5_int val)
set an integer parameter of the remesher
int MMG3D_Unset_requiredTetrahedron(MMG5_pMesh mesh, MMG5_int k)
Remove the "required" attribute from a tetrahedron.
int MMG3D_Unset_requiredVertex(MMG5_pMesh mesh, MMG5_int k)
Remove required attribute from a vertex.
int MMG3D_Set_normalAtVertex(MMG5_pMesh mesh, MMG5_int k, double n0, double n1, double n2)
Set the normal orientation at a single vertex.
int MMG3D_Set_requiredEdge(MMG5_pMesh mesh, MMG5_int k)
Assign the "required" attribute to a single edge.
int MMG3D_Set_meshSize(MMG5_pMesh mesh, MMG5_int np, MMG5_int ne, MMG5_int nprism, MMG5_int nt, MMG5_int nquad, MMG5_int na)
Set the number of vertices, tetrahedra, prisms, triangles, quadrilaterals, and edges of a mesh.
int MMG3D_Unset_requiredTriangle(MMG5_pMesh mesh, MMG5_int k)
Remove the "required" attribute from a single triangle.
int MMG3D_Unset_parallelTriangles(MMG5_pMesh mesh, MMG5_int *parIdx, MMG5_int npar)
Remove the "parallel" attribute from multiple triangles.
int MMG3D_Set_requiredTriangles(MMG5_pMesh mesh, MMG5_int *reqIdx, MMG5_int nreq)
Assign the "required" attribute to multiple triangles.
int MMG3D_Set_requiredTetrahedra(MMG5_pMesh mesh, MMG5_int *reqIdx, MMG5_int nreq)
Assign the "required" attribute to multiple tetrahedra.
int MMG3D_Set_solSize(MMG5_pMesh mesh, MMG5_pSol sol, int typEntity, MMG5_int np, int typSol)
Initialize a solution field.
int MMG3D_Set_tetrahedra(MMG5_pMesh mesh, MMG5_int *tetra, MMG5_int *refs)
Set the vertices and references of all tetrahedra in a mesh structure.
static int MMG3D_skipIso(MMG5_pMesh mesh)
int ier
const int starter
MMG5_pMesh MMG5_pSol * sol
if(!ier) exit(EXIT_FAILURE)
va_start(argptr, starter)
MMG5_pMesh char * meshin
MMG5_pMesh * mesh
va_end(argptr)
const int va_list argptr
static double MMG5_caltet_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTetra pt)
static double MMG5_caltet_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTetra pt)
static double MMG3D_caltetLES_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTetra pt)
API headers and documentation for the mmg3d library, for volumetric meshes in 3D.
@ MMG3D_DPARAM_hmin
Definition: libmmg3d.h:171
@ MMG3D_IPARAM_debug
Definition: libmmg3d.h:146
@ MMG3D_IPARAM_numberOfLocalParam
Definition: libmmg3d.h:161
@ MMG3D_IPARAM_isoref
Definition: libmmg3d.h:169
@ MMG3D_IPARAM_noswap
Definition: libmmg3d.h:156
@ MMG3D_IPARAM_opnbdy
Definition: libmmg3d.h:151
@ MMG3D_DPARAM_angleDetection
Definition: libmmg3d.h:170
@ MMG3D_DPARAM_hsiz
Definition: libmmg3d.h:173
@ MMG3D_IPARAM_isosurf
Definition: libmmg3d.h:149
@ MMG3D_DPARAM_hausd
Definition: libmmg3d.h:174
@ MMG3D_IPARAM_nosurf
Definition: libmmg3d.h:158
@ MMG3D_IPARAM_anisosize
Definition: libmmg3d.h:166
@ MMG3D_IPARAM_nomove
Definition: libmmg3d.h:157
@ MMG3D_IPARAM_renum
Definition: libmmg3d.h:165
@ MMG3D_DPARAM_hgrad
Definition: libmmg3d.h:175
@ MMG3D_IPARAM_nosizreq
Definition: libmmg3d.h:168
@ MMG3D_DPARAM_rmc
Definition: libmmg3d.h:179
@ MMG3D_IPARAM_angle
Definition: libmmg3d.h:147
@ MMG3D_IPARAM_noinsert
Definition: libmmg3d.h:155
@ MMG3D_DPARAM_ls
Definition: libmmg3d.h:177
@ MMG3D_DPARAM_hgradreq
Definition: libmmg3d.h:176
@ MMG3D_IPARAM_xreg
Definition: libmmg3d.h:160
@ MMG3D_DPARAM_hmax
Definition: libmmg3d.h:172
@ MMG3D_IPARAM_numsubdomain
Definition: libmmg3d.h:164
@ MMG3D_IPARAM_lag
Definition: libmmg3d.h:152
@ MMG3D_IPARAM_nreg
Definition: libmmg3d.h:159
@ MMG3D_IPARAM_numberOfMat
Definition: libmmg3d.h:163
@ MMG3D_IPARAM_verbose
Definition: libmmg3d.h:144
@ MMG3D_DPARAM_xreg
Definition: libmmg3d.h:178
@ MMG3D_IPARAM_numberOfLSBaseReferences
Definition: libmmg3d.h:162
@ MMG3D_IPARAM_optimLES
Definition: libmmg3d.h:154
@ MMG3D_IPARAM_optim
Definition: libmmg3d.h:153
@ MMG3D_IPARAM_iso
Definition: libmmg3d.h:148
@ MMG3D_IPARAM_octree
Definition: libmmg3d.h:167
@ MMG3D_IPARAM_nofem
Definition: libmmg3d.h:150
@ MMG3D_IPARAM_mem
Definition: libmmg3d.h:145
#define MMG3D_ALPHAD
MMG5_int MMG3D_newElt(MMG5_pMesh mesh)
Definition: zaldy_3d.c:99
int MMG3D_Free_all_var(va_list argptr)
Definition: variadic_3d.c:261
int MMG3D_Free_structures_var(va_list argptr)
Definition: variadic_3d.c:449
MMG5_int MMG3D_newPt(MMG5_pMesh mesh, double c[3], uint16_t tag, MMG5_int src)
Definition: zaldy_3d.c:39
double MMG5_caltet33_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTetra pt)
Definition: quality_3d.c:109
int MMG3D_Free_names_var(va_list argptr)
Definition: variadic_3d.c:547
#define MMG3D_VOLFRAC
int MMG3D_Init_mesh_var(va_list argptr)
Definition: variadic_3d.c:177
#define MMG3D_TETRA_REALLOC(mesh, jel, wantedGap, law)
int MMG3D_memOption(MMG5_pMesh mesh)
Definition: zaldy_3d.c:271
int MMG3D_setMeshSize_alloc(MMG5_pMesh)
Definition: zaldy_3d.c:288
LIBMMG_CORE_EXPORT int MMG5_Set_multiMat(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_int ref, int split, MMG5_int rin, MMG5_int rex)
Definition: libtools.c:104
LIBMMG_CORE_EXPORT int MMG5_Set_lsBaseReference(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_int br)
Definition: libtools.c:176
@ MMG5_Vector
Definition: libmmgtypes.h:220
@ MMG5_Tensor
Definition: libmmgtypes.h:221
@ MMG5_Scalar
Definition: libmmgtypes.h:219
@ MMG5_Notype
Definition: libmmgtypes.h:218
@ MMG5_Noentity
Definition: libmmgtypes.h:229
@ MMG5_Vertex
Definition: libmmgtypes.h:230
@ MMG5_Tetrahedron
Definition: libmmgtypes.h:233
@ MMG5_Triangle
Definition: libmmgtypes.h:232
#define MG_Tria
#define MG_REQ
#define MG_GEO
#define MMG5_SAFE_CALLOC(ptr, size, type, law)
#define MG_EOK(pt)
#define MG_NUL
#define MMG5_INCREASE_MEM_MESSAGE()
#define MMG5_ON
#define MG_PARBDY
#define MMG5_LAG
#define MMG5_PROCTREE
#define MG_MIN(a, b)
#define MG_MAX(a, b)
#define MMG5_ADD_MEM(mesh, size, message, law)
#define MMG5_TAB_RECALLOC(mesh, ptr, initSize, wantedGap, type, message, law)
#define MG_Tetra
#define MMG5_LS
#define MMG5_OFF
#define MG_CRN
double MMG5_orvol(MMG5_pPoint point, MMG5_int *v)
Definition: tools.c:951
#define MMG5_ANGEDG
#define MMG5_EPSD2
#define MG_REF
#define MMG5_FEM
#define MMG5_DEL_MEM(mesh, ptr)
#define MMG5_SAFE_RECALLOC(ptr, prevSize, newSize, type, message, law)
Structure to store edges of am MMG mesh.
Definition: libmmgtypes.h:311
MMG5_int b
Definition: libmmgtypes.h:312
uint16_t tag
Definition: libmmgtypes.h:316
MMG5_int ref
Definition: libmmgtypes.h:313
MMG5_int a
Definition: libmmgtypes.h:312
MMG5_hgeom * geom
Definition: libmmgtypes.h:583
int8_t iso
Definition: libmmgtypes.h:541
int8_t parTyp
Definition: libmmgtypes.h:548
int8_t ddebug
Definition: libmmgtypes.h:539
double hsiz
Definition: libmmgtypes.h:525
int8_t isosurf
Definition: libmmgtypes.h:542
int8_t sethmin
Definition: libmmgtypes.h:551
MMG5_int * br
Definition: libmmgtypes.h:527
uint8_t ani
Definition: libmmgtypes.h:553
uint8_t noswap
Definition: libmmgtypes.h:553
double rmc
Definition: libmmgtypes.h:526
double hmin
Definition: libmmgtypes.h:525
int8_t setfem
Definition: libmmgtypes.h:543
MMG5_pMat mat
Definition: libmmgtypes.h:562
double hgrad
Definition: libmmgtypes.h:525
double lxreg
Definition: libmmgtypes.h:526
uint8_t noinsert
Definition: libmmgtypes.h:553
MMG5_int isoref
Definition: libmmgtypes.h:528
uint8_t metRidTyp
Definition: libmmgtypes.h:554
double hmax
Definition: libmmgtypes.h:525
int PROctree
Definition: libmmgtypes.h:534
double ls
Definition: libmmgtypes.h:526
uint8_t nomove
Definition: libmmgtypes.h:553
uint8_t optimLES
Definition: libmmgtypes.h:553
int8_t lag
Definition: libmmgtypes.h:547
MMG5_int nsd
Definition: libmmgtypes.h:529
uint8_t nosurf
Definition: libmmgtypes.h:553
int8_t sethmax
Definition: libmmgtypes.h:552
uint8_t nosizreq
Definition: libmmgtypes.h:553
MMG5_pPar par
Definition: libmmgtypes.h:524
uint8_t optim
Definition: libmmgtypes.h:553
double dhd
Definition: libmmgtypes.h:525
double hgradreq
Definition: libmmgtypes.h:525
double hausd
Definition: libmmgtypes.h:525
int8_t xreg
Definition: libmmgtypes.h:538
int8_t nreg
Definition: libmmgtypes.h:537
To store user-defined references in the mesh (useful in LS mode)
Definition: libmmgtypes.h:502
MMG5_int ref
Definition: libmmgtypes.h:504
MMG mesh structure.
Definition: libmmgtypes.h:613
MMG5_int ntmax
Definition: libmmgtypes.h:620
MMG5_pQuad quadra
Definition: libmmgtypes.h:656
MMG5_int nc1
Definition: libmmgtypes.h:623
MMG5_Info info
Definition: libmmgtypes.h:659
MMG5_int xt
Definition: libmmgtypes.h:628
MMG5_int ne
Definition: libmmgtypes.h:620
MMG5_pPoint point
Definition: libmmgtypes.h:649
MMG5_pPrism prism
Definition: libmmgtypes.h:653
MMG5_int nquad
Definition: libmmgtypes.h:621
MMG5_int nemax
Definition: libmmgtypes.h:620
MMG5_int npmax
Definition: libmmgtypes.h:620
MMG5_pxPoint xpoint
Definition: libmmgtypes.h:650
MMG5_HGeom htab
Definition: libmmgtypes.h:658
MMG5_int xp
Definition: libmmgtypes.h:628
double gap
Definition: libmmgtypes.h:616
MMG5_int namax
Definition: libmmgtypes.h:620
MMG5_int nei
Definition: libmmgtypes.h:620
MMG5_pTetra tetra
Definition: libmmgtypes.h:651
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 nti
Definition: libmmgtypes.h:620
MMG5_int npi
Definition: libmmgtypes.h:620
MMG5_pxTetra xtetra
Definition: libmmgtypes.h:652
MMG5_int nai
Definition: libmmgtypes.h:620
MMG5_int nprism
Definition: libmmgtypes.h:621
MMG5_int na
Definition: libmmgtypes.h:620
MMG5_int npnil
Definition: libmmgtypes.h:629
Local parameters for a specific entity and reference.
Definition: libmmgtypes.h:263
double hmin
Definition: libmmgtypes.h:264
double hmax
Definition: libmmgtypes.h:265
double hausd
Definition: libmmgtypes.h:266
MMG5_int ref
Definition: libmmgtypes.h:267
int8_t elt
Definition: libmmgtypes.h:268
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
MMG5_int ref
Definition: libmmgtypes.h:284
MMG5_int flag
Definition: libmmgtypes.h:288
Structure to store prsim of a MMG mesh.
Definition: libmmgtypes.h:469
MMG5_int v[6]
Definition: libmmgtypes.h:470
uint8_t tag
Definition: libmmgtypes.h:476
MMG5_int ref
Definition: libmmgtypes.h:471
Structure to store quadrangles of an MMG mesh.
Definition: libmmgtypes.h:372
MMG5_int ref
Definition: libmmgtypes.h:374
MMG5_int v[4]
Definition: libmmgtypes.h:373
uint16_t tag[4]
Definition: libmmgtypes.h:378
MMG5_int npi
Definition: libmmgtypes.h:676
MMG5_int npmax
Definition: libmmgtypes.h:675
double * m
Definition: libmmgtypes.h:680
MMG5_int np
Definition: libmmgtypes.h:674
Structure to store tetrahedra of an MMG mesh.
Definition: libmmgtypes.h:407
MMG5_int v[4]
Definition: libmmgtypes.h:409
MMG5_int ref
Definition: libmmgtypes.h:410
uint16_t tag
Definition: libmmgtypes.h:417
Structure to store triangles of a MMG mesh.
Definition: libmmgtypes.h:338
MMG5_int ref
Definition: libmmgtypes.h:341
uint16_t tag[3]
Definition: libmmgtypes.h:348
MMG5_int v[3]
Definition: libmmgtypes.h:340