Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
librnbg.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
34#include "mmgcommon_private.h"
35#include "mmgexterns_private.h"
36
37#ifdef USE_SCOTCH
38
39#include "librnbg_private.h"
40
53int MMG5_kPartBoxCompute(SCOTCH_Graph *graf, MMG5_int vertNbr, MMG5_int boxVertNbr,
54 SCOTCH_Num *permVrtTab,MMG5_pMesh mesh) {
55 MMG5_int boxNbr, vertIdx;
56 SCOTCH_Num logMaxVal, SupMaxVal, InfMaxVal, maxVal;
57 char s[200];
58 SCOTCH_Num *sortPartTb;
59 SCOTCH_Strat strat ;
60 SCOTCH_Arch arch;
61
62 /* Computing the number of boxes */
63 boxNbr = vertNbr / boxVertNbr;
64 if (boxNbr * boxVertNbr != vertNbr) {
65 boxNbr = boxNbr + 1;
66 }
67
68
69 /* Initializing SCOTCH functions */
70 CHECK_SCOTCH(SCOTCH_stratInit(&strat), "scotch_stratInit", 0) ;
71 if ( SCOTCH_6 || SCOTCH_7 ) {
72 CHECK_SCOTCH(SCOTCH_archCmplt(&arch, boxNbr), "scotch_archCmplt", 0) ;
73 }
74 else {
75 CHECK_SCOTCH(SCOTCH_archVcmplt(&arch), "scotch_archVcmplt", 0) ;
76 }
77 sprintf(s, "m{vert=%" MMG5_PRId ",low=r{job=t,map=t,poli=S,sep=m{vert=80,low=h{pass=10}f{bal=0.0005,move=80},asc=f{bal=0.005,move=80}}}}", vertNbr / boxVertNbr);
78 CHECK_SCOTCH(SCOTCH_stratGraphMap(&strat, s), "scotch_stratGraphMap", 0) ;
79
80 MMG5_ADD_MEM(mesh,2*vertNbr*sizeof(SCOTCH_Num),"sortPartTb",return 1);
81 MMG5_SAFE_CALLOC(sortPartTb,2*vertNbr,SCOTCH_Num,return 0);
82
83 /* Partionning the graph */
84 if ( 0!=SCOTCH_graphMap(graf, &arch, &strat, sortPartTb) ) {
85 perror("scotch_graphMap");
86 MMG5_DEL_MEM(mesh,sortPartTb);
87 return 0;
88 }
89
90
91 if ( SCOTCH_6 || SCOTCH_7 ) {
92 // Looking for the max value in sortPartTb and computing sortPartTb as
93 // followed :
94 // - sortPartTb[2i] is the box value
95 // - sortPartTb[2i+1] is the vertex number
96 maxVal = sortPartTb[0];
97 }
98 for (vertIdx = vertNbr - 1 ; vertIdx >= 0 ; vertIdx--) {
99 sortPartTb[2*vertIdx] = sortPartTb[vertIdx];
100 sortPartTb[2*vertIdx+1] = vertIdx + 1;
101 if ( SCOTCH_5 ) {
102 if (sortPartTb[vertIdx] > maxVal)
103 maxVal = sortPartTb[vertIdx];
104 }
105 }
106
107 if ( SCOTCH_5 ) {
108 // Determining the log of MaxVal
109 logMaxVal = 0;
110 while ( maxVal > 0) {
111 logMaxVal++;
112 maxVal >>= 1;
113 }
114
115 // Infering the interval in which box values will be
116 InfMaxVal = logMaxVal << logMaxVal;
117 SupMaxVal = (logMaxVal << (logMaxVal + 1)) - 1;
118
119 // Increasing box values until they are in the previous interval
120 for (vertIdx = 0 ; vertIdx < vertNbr ; vertIdx++) {
121 while (!(sortPartTb[2*vertIdx] >= InfMaxVal && sortPartTb[2*vertIdx] <= SupMaxVal)) {
122 sortPartTb[2*vertIdx] <<= 1;
123 }
124 }
125 }
126
127 // Sorting the tabular, which contains box values and vertex numbers
128 _SCOTCHintSort2asc1(sortPartTb, vertNbr);
129
130
131 /* Infering the new numbering */
132 for (vertIdx = 0; vertIdx < vertNbr ; vertIdx++) {
133 permVrtTab[sortPartTb[2*vertIdx + 1]] = vertIdx + 1;
134 }
135
136 SCOTCH_stratExit(&strat) ;
137 SCOTCH_archExit(&arch) ;
138
139 MMG5_DEL_MEM(mesh,sortPartTb);
140
141 return 0;
142}
143
158void MMG5_swapNod(MMG5_pMesh mesh,MMG5_pPoint points, double* sols,
159 MMG5_pSol field,MMG5_int* perm,MMG5_int ind1, MMG5_int ind2, int solsiz) {
160 MMG5_Point ptttmp;
161 MMG5_pSol psl;
162 MMG5_Sol soltmp;
163 int i,pslsiz;
164 MMG5_int tmp,addr2,addr1;
165
166 /* swap the points */
167 memcpy(&ptttmp ,&points[ind2],sizeof(MMG5_Point));
168 memcpy(&points[ind2],&points[ind1],sizeof(MMG5_Point));
169 memcpy(&points[ind1],&ptttmp ,sizeof(MMG5_Point));
170
171 /* swap the sols */
172 if ( sols ) {
173 addr1 = ind1*solsiz;
174 addr2 = ind2*solsiz;
175 memcpy(&soltmp ,&sols[addr2],solsiz*sizeof(double));
176 memcpy(&sols[addr2],&sols[addr1],solsiz*sizeof(double));
177 memcpy(&sols[addr1],&soltmp ,solsiz*sizeof(double));
178 }
179
180 /* swap solution fields (for ParMmg) */
181 if ( field ) {
182 if( mesh->nsols ) { /* swap solution fields (for ParMmg) */
183 for ( i=0; i<mesh->nsols; ++i ) {
184 psl = field+i;
185 assert ( psl && psl->m );
186
187 pslsiz = psl->size;
188 addr1 = ind1*pslsiz;
189 addr2 = ind2*pslsiz;
190
191 memcpy(&soltmp , psl->m + addr2,pslsiz*sizeof(double));
192 memcpy(psl->m + addr2, psl->m + addr1,pslsiz*sizeof(double));
193 memcpy(psl->m + addr1, &soltmp ,pslsiz*sizeof(double));
194 }
195 } else { /* swap a single displacement field (for Lagrangian motion) */
196 psl = field;
197 assert ( psl );
198
199 if( psl->m ) { /* it is null after Lagrangian step */
200 pslsiz = psl->size;
201 addr1 = ind1*pslsiz;
202 addr2 = ind2*pslsiz;
203
204 memcpy(&soltmp , psl->m + addr2,pslsiz*sizeof(double));
205 memcpy(psl->m + addr2, psl->m + addr1,pslsiz*sizeof(double));
206 memcpy(psl->m + addr1, &soltmp ,pslsiz*sizeof(double));
207 }
208 }
209 }
210
211 /* swap the permutaion table */
212 tmp = perm[ind2];
213 perm[ind2] = perm[ind1];
214 perm[ind1] = tmp;
215}
216#endif
217
232 MMG5_pSol fields, MMG5_int *permNodGlob)
233{
234
235#ifdef USE_SCOTCH
236 static int8_t mmgWarn = 0;
237 static int8_t mmgError = 0;
238
239 /*check enough vertex to renum*/
240 if ( mesh->info.renum && (mesh->np/2. > MMG5_BOXSIZE) ) {
241
242 if ( (SCOTCH_5 && SCOTCH_6 && SCOTCH_7 ) || ( (!SCOTCH_5) && (!SCOTCH_6) && (!SCOTCH_7) ) ) {
243 if ( !mmgWarn ) {
244 fprintf(stderr,"\n ## Warning: %s: fail to determine scotch version."
245 " No renumbering.\n",__func__);
246 mmgWarn = 1;
247 }
248 return 1;
249 }
250
251 /* renumbering begin */
252 if ( mesh->info.imprim > 5 )
253 fprintf(stdout," -- RENUMBERING. \n");
254
255 if ( !MMG5_renumbering(MMG5_BOXSIZE,mesh, met,fields,permNodGlob) ) {
256 if ( !mmgError ) {
257 fprintf(stderr,"\n ## Error: %s: Unable to renumber mesh. "
258 "Try to run without renumbering option (-rn 0).\n",
259 __func__);
260 mmgError = 1;
261 }
262 return 0;
263 }
264
265 if ( mesh->info.imprim > 5) {
266 fprintf(stdout," -- PHASE RENUMBERING COMPLETED. \n");
267 }
268
269 if ( mesh->info.ddebug ) {
270 if ( !MMG5_chkmsh(mesh,1,0) )
271 return 0;
272 }
273 /* renumbering end */
274 }
275 return 1;
276#else
277 return 1;
278#endif
279}
tmp[*strlen0]
MMG5_pMesh * mesh
int MMG5_kPartBoxCompute(SCOTCH_Graph *graf, MMG5_int vertNbr, MMG5_int boxVertNbr, SCOTCH_Num *permVrtTab, MMG5_pMesh mesh)
Definition: librnbg.c:53
void MMG5_swapNod(MMG5_pMesh mesh, MMG5_pPoint points, double *sols, MMG5_pSol field, MMG5_int *perm, MMG5_int ind1, MMG5_int ind2, int solsiz)
Definition: librnbg.c:158
int MMG5_scotchCall(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pSol fields, MMG5_int *permNodGlob)
Definition: librnbg.c:231
#define CHECK_SCOTCH(t, m, e)
#define SCOTCH_7
#define SCOTCH_6
#define SCOTCH_5
int _SCOTCHintSort2asc1(SCOTCH_Num *sortPartTb, MMG5_int vertNbr)
#define MMG5_SAFE_CALLOC(ptr, size, type, law)
#define MMG5_ADD_MEM(mesh, size, message, law)
#define MMG5_BOXSIZE
#define MMG5_DEL_MEM(mesh, ptr)
int8_t ddebug
Definition: libmmgtypes.h:532
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_Info info
Definition: libmmgtypes.h:651
MMG5_int np
Definition: libmmgtypes.h:612
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
double * m
Definition: libmmgtypes.h:671