Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
anisomovpt.c
Go to the documentation of this file.
1/* =============================================================================
2** This file is part of the mmg software package for the tetrahedral
3** mesh modification.
4** Copyright (c) Bx INP/CNRS/Inria/UBordeaux/UPMC, 2004-
5**
6** mmg is free software: you can redistribute it and/or modify it
7** under the terms of the GNU Lesser General Public License as published
8** by the Free Software Foundation, either version 3 of the License, or
9** (at your option) any later version.
10**
11** mmg is distributed in the hope that it will be useful, but WITHOUT
12** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13** FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14** License for more details.
15**
16** You should have received a copy of the GNU Lesser General Public
17** License and of the GNU General Public License along with mmg (in
18** files COPYING.LESSER and COPYING). If not, see
19** <http://www.gnu.org/licenses/>. Please read their terms carefully and
20** use this copy of the mmg distribution only if you accept them.
21** =============================================================================
22*/
23
36#include "mmgcommon_private.h"
37
54 MMG5_pPoint p0, MMG5_Bezier *pb,double r[3][3],
55 double gv[2])
56{
57 MMG5_pPoint p1,p2;
58 double Jacsigma[3][2],Jactmp[3][2],m[6],mo[6],density,to[3],no[3],ll;
59 double dens[3],*n1,*n2,ps1,ps2,intpt[2],ux,uy,uz;
60 int8_t i0,i1,i2,j,nullDens;
61 static int8_t mmgErr=0;
62
63 i0 = 0;
64 i1 = 1;
65 i2 = 2;
66
67 nullDens = 0;
68 for (j=0; j<3; j++) {
69 /* Set jacobian matrix of parametric Bezier patch, for each quadrature point */
70 if ( j == 0 ) { //w,u = 1/2, v = 0
71 Jacsigma[0][0] = 0.75*(pb->b[7][0] - pb->b[0][0]) + 0.75*(pb->b[1][0] - pb->b[8][0]) + 1.5*(pb->b[8][0] - pb->b[7][0]);
72 Jacsigma[1][0] = 0.75*(pb->b[7][1] - pb->b[0][1]) + 0.75*(pb->b[1][1] - pb->b[8][1]) + 1.5*(pb->b[8][1] - pb->b[7][1]);
73 Jacsigma[2][0] = 0.75*(pb->b[7][2] - pb->b[0][2]) + 0.75*(pb->b[1][2] - pb->b[8][2]) + 1.5*(pb->b[8][2] - pb->b[7][2]);
74
75 Jacsigma[0][1] = 0.75*(pb->b[6][0] - pb->b[0][0]) + 0.75*(pb->b[3][0] - pb->b[8][0]) + 1.5*(pb->b[9][0] - pb->b[7][0]);
76 Jacsigma[1][1] = 0.75*(pb->b[6][1] - pb->b[0][1]) + 0.75*(pb->b[3][1] - pb->b[8][1]) + 1.5*(pb->b[9][1] - pb->b[7][1]);
77 Jacsigma[2][1] = 0.75*(pb->b[6][2] - pb->b[0][2]) + 0.75*(pb->b[3][2] - pb->b[8][2]) + 1.5*(pb->b[9][2] - pb->b[7][2]);
78 }
79 else if( j == 1 ) { //u,v = 1/2, w = 0
80 Jacsigma[0][0] = 0.75*(pb->b[1][0] - pb->b[8][0]) + 0.75*(pb->b[4][0] - pb->b[5][0]) + 1.5*(pb->b[3][0] - pb->b[9][0]);
81 Jacsigma[1][0] = 0.75*(pb->b[1][1] - pb->b[8][1]) + 0.75*(pb->b[4][1] - pb->b[5][1]) + 1.5*(pb->b[3][1] - pb->b[9][1]);
82 Jacsigma[2][0] = 0.75*(pb->b[1][2] - pb->b[8][2]) + 0.75*(pb->b[4][2] - pb->b[5][2]) + 1.5*(pb->b[3][2] - pb->b[9][2]);
83
84 Jacsigma[0][1] = 0.75*(pb->b[3][0] - pb->b[8][0]) + 0.75*(pb->b[2][0] - pb->b[5][0]) + 1.5*(pb->b[4][0] - pb->b[9][0]);
85 Jacsigma[1][1] = 0.75*(pb->b[3][1] - pb->b[8][1]) + 0.75*(pb->b[2][1] - pb->b[5][1]) + 1.5*(pb->b[4][1] - pb->b[9][1]);
86 Jacsigma[2][1] = 0.75*(pb->b[3][2] - pb->b[8][2]) + 0.75*(pb->b[2][2] - pb->b[5][2]) + 1.5*(pb->b[4][2] - pb->b[9][2]);
87 }
88 else { //w,v = 1/2, u= 0
89 Jacsigma[0][0] = 0.75*(pb->b[7][0] - pb->b[0][0]) + 0.75*(pb->b[4][0] - pb->b[5][0]) + 1.5*(pb->b[9][0] - pb->b[6][0]);
90 Jacsigma[1][0] = 0.75*(pb->b[7][1] - pb->b[0][1]) + 0.75*(pb->b[4][1] - pb->b[5][1]) + 1.5*(pb->b[9][1] - pb->b[6][1]);
91 Jacsigma[2][0] = 0.75*(pb->b[7][2] - pb->b[0][2]) + 0.75*(pb->b[4][2] - pb->b[5][2]) + 1.5*(pb->b[9][2] - pb->b[6][2]);
92
93 Jacsigma[0][1] = 0.75*(pb->b[6][0] - pb->b[0][0]) + 0.75*(pb->b[2][0] - pb->b[5][0]) + 1.5*(pb->b[5][0] - pb->b[6][0]);
94 Jacsigma[1][1] = 0.75*(pb->b[6][1] - pb->b[0][1]) + 0.75*(pb->b[2][1] - pb->b[5][1]) + 1.5*(pb->b[5][1] - pb->b[6][1]);
95 Jacsigma[2][1] = 0.75*(pb->b[6][2] - pb->b[0][2]) + 0.75*(pb->b[2][2] - pb->b[5][2]) + 1.5*(pb->b[5][2] - pb->b[6][2]);
96 }
97
98 /* Take metric at control point */
99 if ( !MG_GEO_OR_NOM(pt->tag[i2]) ) {
100 int ier = MMG5_interpreg_ani(mesh,met,pt,i2,0.5,m);
101 if ( !ier ) {
102 if ( mesh->info.ddebug ) {
103 fprintf(stdout," ## Warning:%s:%d: unable to move point (interpreg_ani failure).\n",
104 __func__,__LINE__);
105 }
106 return 0;
107 }
108 }
109 else {
110 if ( !MMG5_nortri(mesh,pt,no) ) return 0;
111 if ( !MMG5_intridmet(mesh,met,pt->v[i0],pt->v[i1],0.5,no,mo) ) return 0;
112
113 p1 = &mesh->point[pt->v[i0]];
114 p2 = &mesh->point[pt->v[i1]];
115
116 to[0] = p2->c[0] - p1->c[0];
117 to[1] = p2->c[1] - p1->c[1];
118 to[2] = p2->c[2] - p1->c[2];
119
120 ll = to[0]*to[0] + to[1]*to[1] + to[2]*to[2];
121 if ( ll < MMG5_EPSD ) return 0;
122 ll = 1.0 / sqrt(ll);
123 to[0] *= ll;
124 to[1] *= ll;
125 to[2] *= ll;
126
127 if ( ( MG_SIN(p1->tag) || (p1->tag & MG_NOM) )
128 && ( MG_SIN(p2->tag) || (p2->tag & MG_NOM) ) ) {
129 if ( !MMG5_buildridmetfic(mesh,to,no,mo[0],mo[0],mo[0],m) )
130 return 0;
131 }
132 else if ( !(MG_SIN(p1->tag) || (p1->tag & MG_NOM)) ) {
133 n1 = &mesh->xpoint[p1->xp].n1[0];
134 n2 = &mesh->xpoint[p1->xp].n2[0];
135 ps1 = n1[0]*no[0] + n1[1]*no[1] + n1[2]*no[2];
136 ps2 = n2[0]*no[0] + n2[1]*no[1] + n2[2]*no[2];
137 if ( fabs(ps1) > fabs(ps2) ) {
138 if ( !MMG5_buildridmetfic(mesh,to,no,mo[0],mo[1],mo[3],m) ) return 0;
139 }
140 else {
141 if ( !MMG5_buildridmetfic(mesh,to,no,mo[0],mo[2],mo[4],m) ) return 0;
142 }
143 }
144 else {
145 assert(!(MG_SIN(p2->tag)||(p2->tag & MG_NOM)));
146 n1 = &mesh->xpoint[p2->xp].n1[0];
147 n2 = &mesh->xpoint[p2->xp].n2[0];
148 ps1 = n1[0]*no[0] + n1[1]*no[1] + n1[2]*no[2];
149 ps2 = n2[0]*no[0] + n2[1]*no[1] + n2[2]*no[2];
150 if ( fabs(ps1) > fabs(ps2) ) {
151 if ( !MMG5_buildridmetfic(mesh,to,no,mo[0],mo[1],mo[3],m) ) return 0;
152 }
153 else {
154 if ( !MMG5_buildridmetfic(mesh,to,no,mo[0],mo[2],mo[4],m) ) return 0;
155 }
156 }
157 }
158
159 /* Compute density matrix {^t}Jacsigma * M * Jacsigma */
160 Jactmp[0][0] = m[0]*Jacsigma[0][0] + m[1]*Jacsigma[1][0] + m[2]*Jacsigma[2][0];
161 Jactmp[1][0] = m[1]*Jacsigma[0][0] + m[3]*Jacsigma[1][0] + m[4]*Jacsigma[2][0];
162 Jactmp[2][0] = m[2]*Jacsigma[0][0] + m[4]*Jacsigma[1][0] + m[5]*Jacsigma[2][0];
163
164 Jactmp[0][1] = m[0]*Jacsigma[0][1] + m[1]*Jacsigma[1][1] + m[2]*Jacsigma[2][1];
165 Jactmp[1][1] = m[1]*Jacsigma[0][1] + m[3]*Jacsigma[1][1] + m[4]*Jacsigma[2][1];
166 Jactmp[2][1] = m[2]*Jacsigma[0][1] + m[4]*Jacsigma[1][1] + m[5]*Jacsigma[2][1];
167
168 dens[0] = Jacsigma[0][0]*Jactmp[0][0] + Jacsigma[1][0]*Jactmp[1][0] + Jacsigma[2][0]*Jactmp[2][0];
169 dens[1] = Jacsigma[0][0]*Jactmp[0][1] + Jacsigma[1][0]*Jactmp[1][1] + Jacsigma[2][0]*Jactmp[2][1];
170 dens[2] = Jacsigma[0][1]*Jactmp[0][1] + Jacsigma[1][1]*Jactmp[1][1] + Jacsigma[2][1]*Jactmp[2][1];
171
172 density = dens[0]*dens[2] - dens[1]*dens[1];
173 if ( density <= MMG5_EPSD2 ) {
174#ifndef NDEBUG
175 if ( !mmgErr ) {
176 fprintf(stderr,"\n ## Warning: %s: at least 1 negative or null density.\n",
177 __func__);
178 mmgErr = 1;
179 }
180#endif
181 ++nullDens;
182 continue;
183 }
184
185 density = sqrt(density);
186 /* Coordinates of the integration point */
187 p1 = &mesh->point[pt->v[i0]];
188 p2 = &mesh->point[pt->v[i1]];
189
190 ux = 0.5*(p1->c[0] + p2->c[0]) - p0->c[0];
191 uy = 0.5*(p1->c[1] + p2->c[1]) - p0->c[1];
192 uz = 0.5*(p1->c[2] + p2->c[2]) - p0->c[2];
193
194 intpt[0] = r[0][0]*ux + r[0][1]*uy + r[0][2]*uz;
195 intpt[1] = r[1][0]*ux + r[1][1]*uy + r[1][2]*uz;
196
197 gv[0] += density*MMG5_ATHIRD*intpt[0];
198 gv[1] += density*MMG5_ATHIRD*intpt[1];
199
200 i0 = MMG5_inxt2[i0];
201 i1 = MMG5_inxt2[i1];
202 i2 = MMG5_inxt2[i2];
203 }
204
205 if ( nullDens==3 ) return 0;
206
207 return 1;
208}
int ier
MMG5_pMesh * mesh
int MMG5_elementWeight(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTria pt, MMG5_pPoint p0, MMG5_Bezier *pb, double r[3][3], double gv[2])
Definition: anisomovpt.c:53
#define MMG5_EPSD
int MMG5_interpreg_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTria pt, int8_t i, double s, double mr[6])
Definition: intmet.c:504
int MMG5_intridmet(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int ip1, MMG5_int ip2, double s, double v[3], double mr[6])
Definition: intmet.c:163
int MMG5_buildridmetfic(MMG5_pMesh mesh, double t[3], double n[3], double dtan, double dv, double dn, double m[6])
Definition: mettools.c:601
#define MMG5_ATHIRD
#define MG_SIN(tag)
#define MG_GEO_OR_NOM(tag)
static const uint8_t MMG5_inxt2[6]
int MMG5_nortri(MMG5_pMesh mesh, MMG5_pTria pt, double *n)
Definition: tools.c:209
#define MG_NOM
#define MMG5_EPSD2
double b[10][3]
int8_t ddebug
Definition: libmmgtypes.h:532
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_Info info
Definition: libmmgtypes.h:651
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_pxPoint xpoint
Definition: libmmgtypes.h:642
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
int16_t tag
Definition: libmmgtypes.h:284
double c[3]
Definition: libmmgtypes.h:271
MMG5_int xp
Definition: libmmgtypes.h:279
int16_t tag[3]
Definition: libmmgtypes.h:342
MMG5_int v[3]
Definition: libmmgtypes.h:334
double n2[3]
Definition: libmmgtypes.h:295
double n1[3]
Definition: libmmgtypes.h:295