16 #include "GmshConfig.h"
25 #if defined(HAVE_BAMG)
30 Mesh2 *Bamg(Mesh2 *Thh,
double *args,
double *mm11,
double *mm12,
double *mm22,
33 static void computeMeshMetricsForBamg(
GFace *gf,
int numV,
34 Vertex2 *bamgVertices,
double *mm11,
35 double *mm12,
double *mm22)
45 for(
int i = 0; i < numV; ++i) {
46 double u = bamgVertices[i][0];
47 double v = bamgVertices[i][1];
54 J(0, 0) = JT(0, 0) = der.
first().
x();
55 J(0, 1) = JT(1, 0) = der.
first().
y();
56 J(0, 2) = JT(2, 0) = der.
first().
z();
57 J(1, 0) = JT(0, 1) = der.
second().
x();
58 J(1, 1) = JT(1, 1) = der.
second().
y();
59 J(1, 2) = JT(2, 1) = der.
second().
z();
73 std::vector<GEdge *>
const &
edges = gf->
edges();
74 std::set<MVertex *> bcVertex;
75 for(
auto it =
edges.begin(); it !=
edges.end(); it++) {
76 for(std::size_t i = 0; i < (*it)->lines.size(); i++) {
77 bcVertex.insert((*it)->lines[i]->getVertex(0));
78 bcVertex.insert((*it)->lines[i]->getVertex(1));
83 std::set<MVertex *> all;
84 std::map<int, MVertex *> recover;
85 for(std::size_t i = 0; i < gf->
triangles.size(); i++) {
86 for(std::size_t j = 0; j < 3; j++)
87 all.insert(gf->
triangles[i]->getVertex(j));
90 Vertex2 *bamgVertices =
new Vertex2[all.size()];
92 for(
auto it = all.begin(); it != all.end(); ++it) {
93 if((*it)->onWhat()->dim() <= 1) {
96 bamgVertices[index][0] = p.
x();
97 bamgVertices[index][1] = p.
y();
98 bamgVertices[index].lab = index;
100 (*it)->setIndex(index++);
104 int nbFixedVertices = index;
105 for(
auto it = all.begin(); it != all.end(); ++it) {
107 if((*it)->onWhat()->dim() >= 2) {
110 bamgVertices[index][0] = p.
x();
111 bamgVertices[index][1] = p.
y();
112 recover[index] = *it;
113 (*it)->setIndex(index++);
117 std::vector<MElement *> myParamElems;
118 std::vector<MVertex *> newVert;
119 Triangle2 *bamgTriangles =
new Triangle2[gf->
triangles.size()];
120 for(std::size_t i = 0; i < gf->
triangles.size(); i++) {
121 int nodes[3] = {(int)gf->
triangles[i]->getVertex(0)->getIndex(),
122 (int)gf->
triangles[i]->getVertex(1)->getIndex(),
123 (int)gf->
triangles[i]->getVertex(2)->getIndex()};
124 double u1(bamgVertices[nodes[0]][0]);
125 double u2(bamgVertices[nodes[1]][0]);
126 double u3(bamgVertices[nodes[2]][0]);
127 double v1(bamgVertices[nodes[0]][1]);
128 double v2(bamgVertices[nodes[1]][1]);
129 double v3(bamgVertices[nodes[2]][1]);
130 double sign = (u2 - u1) * (v3 - v1) - (u3 - u1) * (v2 - v1);
136 bamgTriangles[i].init(bamgVertices, nodes, gf->
tag());
139 const auto numEdges =
140 std::accumulate(begin(
edges), end(
edges), std::size_t(0),
141 [](std::size_t
const partial_sum,
const GEdge *
const edge) {
142 return partial_sum + edge->
lines.size();
145 Seg *bamgBoundary =
new Seg[numEdges];
147 for(
auto it =
edges.begin(); it !=
edges.end(); ++it) {
148 for(std::size_t i = 0; i < (*it)->lines.size(); ++i) {
149 int nodes[2] = {(int)(*it)->lines[i]->getVertex(0)->getIndex(),
150 (int)(*it)->lines[i]->getVertex(1)->getIndex()};
151 bamgBoundary[count].init(bamgVertices, nodes, (*it)->tag());
152 bamgBoundary[count].lab = count;
157 Mesh2 *bamgMesh =
new Mesh2(all.size(), gf->
triangles.size(), numEdges,
158 bamgVertices, bamgTriangles, bamgBoundary);
162 Mesh2 *refinedBamgMesh =
nullptr;
164 for(
int k = 0; k < iterMax; k++) {
165 int nbVert = bamgMesh->nv;
167 double *mm11 =
new double[nbVert];
168 double *mm12 =
new double[nbVert];
169 double *mm22 =
new double[nbVert];
171 for(
int i = 0; i < 256; i++) args[i] = -1.1e100;
175 computeMeshMetricsForBamg(gf, nbVert, bamgMesh->vertices, mm11, mm12, mm22);
178 refinedBamgMesh = Bamg(bamgMesh, args, mm11, mm12, mm22,
false);
179 Msg::Info(
"BAMG succeeded %d vertices %d triangles", refinedBamgMesh->nv,
180 refinedBamgMesh->nt);
189 int nT = bamgMesh->nt;
190 int nTnow = refinedBamgMesh->nt;
193 bamgMesh = refinedBamgMesh;
194 if(fabs((
double)(nTnow - nT)) < 0.01 * nT)
break;
197 std::map<int, MVertex *> yetAnother;
198 for(
int i = 0; i < refinedBamgMesh->nv; i++) {
199 Vertex2 &v = refinedBamgMesh->vertices[i];
200 if(i >= nbFixedVertices) {
218 for(std::size_t i = 0; i < gf->
triangles.size(); i++) {
222 for(
int i = 0; i < refinedBamgMesh->nt; i++) {
223 Triangle2 &t = refinedBamgMesh->triangles[i];
228 yetAnother[(*refinedBamgMesh)(v2)],
229 yetAnother[(*refinedBamgMesh)(v3)]));
233 if(refinedBamgMesh)
delete refinedBamgMesh;
234 if(_octree)
delete _octree;
235 for(
auto it = myParamElems.begin(); it != myParamElems.end(); it++)
237 for(
auto it = newVert.begin(); it != newVert.end(); it++)
delete *it;
244 Msg::Error(
"This version of Gmsh is not compiled with BAMG support");