124 const IntTab& a_f =
domaine.arete_faces(), &e_f =
domaine.elem_faces(), &f_e =
domaine.face_voisins();
126 const DoubleVect& fs =
domaine.face_surfaces(), &ve =
domaine.volumes();
127 int i, j, k, l, r, e, f, fb, a, idx;
129 if (
radeb.dimension(0))
return;
134 std::map<int, double> rami;
135 std::map<int, std::array<double, 3> > ramf;
136 for (a = 0; a < xa.dimension_tot(0);
radeb.append_line(
raji.dimension(0),
rajf.dimension(0)), rami.clear(), ramf.clear(), a++)
139 for (i = 0; i < a_f.
dimension(1) && (f = a_f(a, i)) >= 0; i++)
142 std::array<double, 3> taz = {{ 0, 0, 1 }}, vec;
144 int sgn =
domaine.dot(&vec[0], &nf(f, 0)) > 0 ? 1 : -1;
147 for (j = 0; j < 2 && (e = f_e(f, j)) >= 0; j++)
148 for (k =
domaine.m2d(e), idx = 0; k <
domaine.m2d(e + 1); k++, idx++)
149 for (l =
domaine.m2i(k); f == e_f(e, idx) && l <
domaine.m2i(k + 1); l++)
150 if (
fcl_(fb = e_f(e,
domaine.m2j(l)), 0) < 2) rami[fb] += sgn * (e == f_e(f, 0) ? 1 : -1) * (e == f_e(fb, 0) ? 1 : -1) * ve(e) *
domaine.m2c(l) / fs(f);
151 else if (
fcl_(fb, 0) == 3)
153 ramf[fb][r] += sgn * (e == f_e(f, 0) ? 1 : -1) * (e == f_e(fb, 0) ? 1 : -1) * ve(e) *
domaine.m2c(l) / fs(f) * nf(fb, r) / fs(fb);
155 if (
fcl_(f, 0) == 1 ||
fcl_(f, 0) == 2)
160 else if (
fcl_(f, 0) == 3)
162 ramf[f][k] += sgn * (xa(a, k) - xv(f, k));
166 for (
auto &&kv : rami)
167 if (std::fabs(kv.second) > 1e-8 * la)
168 raji.append_line(kv.first),
raci.append_line(kv.second * la);
169 for (
auto &&kv : ramf)
170 if (
domaine.dot(&kv.second[0], &kv.second[0]) > 1e-16 * la * la)
171 rajf.append_line(kv.first),
racf.append_line(kv.second[0] * la, kv.second[1] * la, kv.second[2] * la);
180 const IntTab& f_e =
domaine.face_voisins(), &a_f =
domaine.arete_faces();
185 int i, j, k, l, m, e, f, fb, a;
187 if (
vadeb.dimension(0))
return;
189 std::map<int, std::array<double, 3>> vami;
190 std::map<std::array<int, 2>, std::array<double, 3>> vamf;
195 for (a = 0; a < xa.dimension_tot(0);
vadeb.append_line(
vaji.dimension(0),
vajf.dimension(0)), vami.clear(), vamf.clear(), a++)
199 std::array<double, 3> taz = {{ 0, 0, 1 }}, v0 =
domaine.cross(3,
dimension,
dimension < 3 ? &taz[0] : &ta(a, 0), &xv(a_f(a, 0), 0),
nullptr, &xa(a, 0)),
202 std::map<double, int> fmap;
203 for (i = 0; i < a_f.dimension(1) && (f = a_f(a, i)) >= 0; i++) fmap[atan2(
domaine.dot(&xv(f, 0), &v1[0], &xa(a, 0)),
domaine.dot(&xv(f, 0), &v0[0], &xa(a, 0)))] = f;
204 std::vector<int> fas, sgn;
205 for (
auto && kv : fmap) fas.push_back(kv.second);
208 DoubleTrav xe((
int)fas.size(),
dimension), surf((
int)fas.size(), 2), nsurf((
int)fas.size(), 2, 3);
209 double surf_tot = 0, xg[3] = { 0, 0, 0 };
211 for (i = 0; i < (int) fas.size(); i++)
213 std::array <double, 3> vec =
domaine.cross(3,
dimension,
dimension < 3 ? &taz[0] : &ta(a, 0), &xv(fas[i], 0),
nullptr, &xa(a, 0));
214 sgn.push_back(
domaine.dot(&vec[0], &nf(fas[i], 0)) > 0 ? 1 : -1);
216 for (i = 0; i < (int) fas.size(); i++)
219 int fa[2] = { f = fas[i], fb = fas[(i + 1) * (i + 1 < (
int) fas.size())] }, sgfa[2] = { sgn[i], sgn[(i + 1) * (i + 1 < (
int) fas.size())] };
220 if (
domaine.dot(&xv(fb, 0), &nf(f, 0), &xv(f, 0)) * sgn[i] < 0)
221 for (k = 0; k <
dimension; k++) xe(i, k) = xa(a, k);
222 else if (
domaine.dot(&xv(f, 0), &xv(fb, 0), &xa(a, 0), &xa(a, 0)) - (
dimension < 3 ? 0 :
domaine.dot(&xv(f, 0), &ta(a, 0), &xa(a, 0)) *
domaine.dot(&xv(fb, 0), &ta(a, 0), &xa(a, 0))) <= 0)
223 for (k = 0; k <
dimension; k++) xe(i, k) = xv(f, k) + xv(fb, k) - xa(a, k);
227 for (j = 0; j < 2; j++)
228 for (k = 0, s[j] =
domaine.dot(&xv(fa[j], 0), &xv(fa[j], 0), &xa(a, 0), &xa(a, 0)); k < 3; k++)
229 M(j, k) = k <
dimension ? xv(fa[j], k) - xa(a, k) : 0;
230 for (k = 0, s[2] =
dimension < 3 ? 0 : (
domaine.dot(&xv(f, 0), &ta(a, 0), &xa(a, 0)) +
domaine.dot(&xv(fb, 0), &ta(a, 0), &xa(a, 0))) / 2; k < 3; k++)
231 M(2, k) =
dimension < 3 ? (k == 2) : ta(a, k);
233 for (j = 0; eps != 0 && j <
dimension; j++)
234 for (k = 0, xe(i, j) = xa(a, j); k <
dimension; k++) xe(i, j) += iM(j, k) * s[k];
236 if (eps == 0 ||
domaine.dot(&xe(i, 0), &nf(f, 0), &xv(f, 0)) * sgfa[0] < 0 ||
domaine.dot(&xe(i, 0), &nf(fb, 0), &xv(fb, 0)) * sgfa[1] > 0)
238 if ((e = f_e(f, sgfa[0] > 0)) >= 0)
239 for (k = 0; k <
dimension; k++) xe(i, k) = xp(e, k);
240 else for (k = 0; k <
dimension; k++) xe(i, k) = (xv(f, k) + xv(fb, k)) / 2;
245 for (j = 0; j < 2; j++)
247 std::array<double, 3> vsurf3 =
domaine.cross(
dimension,
dimension, &xe(i, 0), &xv(fa[j], 0), &xa(a, 0), &xa(a, 0));
249 for (k = 0, l = (
dimension < 3 ? vsurf3[2] < 0 :
domaine.dot(&ta(a, 0), &vsurf3[0]) < 0); k < 3; k++) vsurf3[k] *= (l ? -1. : 1.) / 2;
250 surf(i, j) =
dimension < 3 ? std::fabs(vsurf3[2]) : sqrt(
domaine.dot(&vsurf3[0], &vsurf3[0]));
251 surf_tot += surf(i, j);
252 for (k = 0; surf(i, j) > 1e-16 && k < 3; k++) nsurf(i, j, k) = vsurf3[k] / surf(i, j);
253 for (k = 0; k <
dimension; k++) xg[k] += surf(i, j) * (xv(fa[j], k) + xe(i, k) - 2 * xa(a, k)) / 3;
256 for (k = 0; k <
dimension; k++) xg[k] = xa(a, k) + (surf_tot ==0 ? 0. : xg[k] / surf_tot);
258 if (!surf_tot)
continue;
259 M =
Matrice33(surf_tot, 0, 0, 0, surf_tot, 0, 0, 0, surf_tot);
261 std::array<double, 3> vec;
262 for (i = 0; i < (int) fas.size(); i++)
263 for (j = 0; j < 2; j++)
264 if (surf(i, j) > 1e-16)
266 f = fas[(i + j) * (i + j < (
int) fas.size())], e = f_e(f, sgn[i] > 0);
267 double x[2][3] = { { 0, }, };
268 for (k = 0; k < 2; k++)
269 for (l = 0; l <
dimension; l++) x[k][l] = j == k ? xv(f, l) : xe(i, l);
272 for (k = 0; k < 2; k++)
274 for (l = 0; l <
dimension; l++) vec[l] = (xa(a, l) + x[k][l]) / 2 - xg[l];
276 for (l = 0; l < 3; l++)
277 for (m = 0; m <
dimension; m++) M(l, m) -= (k ? -1 : 1) * (x[k][m] - xa(a, m)) * vec[l];
281 for (k = 0; k <
dimension; k++) vec[k] = (x[0][k] + x[1][k]) / 2 - xg[k];
286 vami[f][k] +=
domaine.dot(x[1], &nf(f, 0), x[0]) / fs(f) * vec[k];
287 else if (
fcl_(f, 0) == 3)
290 vamf[ {{ f, l }}][l] +=
domaine.dot(x[1], &nf(f, 0), x[0]) / fs(f) * vec[k] * nf(f, l) / fs(f);
297 vami[fb][l] += (
domaine.dot(x[1], &
domaine.veci(k, 0), x[0]) -
domaine.dot(x[1], &nf(f, 0), x[0]) *
domaine.dot(&
domaine.veci(k, 0), &nf(f, 0)) / (fs(f) * fs(f))) * vec[l] * pf(fb) / pe(e);
298 else if (
fcl_(fb, 0) == 3)
301 vamf[ {{ fb, m }}][l] += (
domaine.dot(x[1], &
domaine.veci(k, 0), x[0]) -
domaine.dot(x[1], &nf(f, 0), x[0]) *
domaine.dot(&
domaine.veci(k, 0), &nf(f, 0)) / (fs(f) * fs(f)))
302 * vec[l] * nf(fb, m) / fs(f) * pf(fb) / pe(e);
304 else if (
fcl_(f, 0) == 3)
307 vamf[ {{ f, k }}][l] += (x[1][k] - x[0][k] -
domaine.dot(x[1], &nf(f, 0), x[0]) * nf(f, k) / (fs(f) * fs(f))) * vec[l];
308 else if (
fcl_(f, 0) == 1 ||
fcl_(f, 0) == 2)
311 M(k, l) -= (x[1][l] - x[0][l] -
domaine.dot(x[1], &nf(f, 0), x[0]) * nf(f, l) / (fs(f) * fs(f))) * vec[k];
320 vami[fb][l] += surf(i, j) *
domaine.dot(&nsurf(i, j, 0), &
domaine.veci(k, 0)) * nsurf(i, j, l) * pf(fb) / pe(e);
321 else if (
fcl_(fb, 0) == 3)
324 vamf[ {{ fb, m }}][l] += surf(i, j) *
domaine.dot(&nsurf(i, j, 0), &
domaine.veci(k, 0)) * nsurf(i, j, l) * nf(fb, m) / fs(f) * pf(fb) / pe(e);
326 else if (
fcl_(f, 0) == 3)
329 vamf[ {{ f, k }}][l] += surf(i, j) * nsurf(i, j, k) * nsurf(i, j, l);
330 else if (
fcl_(f, 0) == 1 ||
fcl_(f, 0) == 2)
333 M(k, l) -= surf(i, j) * nsurf(i, j, k) * nsurf(i, j, l);
338 if (std::fabs(eps) < 1e-24)
continue;
339 for (
auto && kv : vami)
341 double inc[3] = { 0, 0, 0 };
343 for (l = 0; l <
dimension; l++) inc[k] += iM(k, l) * kv.second[l];
344 if (
domaine.dot(inc, inc) > 1e-16)
vaji.append_line(kv.first),
vaci.append_line(inc[0], inc[1], inc[2]);
346 for (
auto && kv : vamf)
348 double inc[3] = { 0, 0, 0 };
350 for (l = 0; l <
dimension; l++) inc[k] += iM(k, l) * kv.second[l];
351 if (
domaine.dot(inc, inc) > 1e-16)
vajf.append_line(kv.first[0], kv.first[1]),
vacf.append_line(inc[0], inc[1], inc[2]);