214 int virt,
int full_stencil, IntTab& phif_d, IntTab& phif_e, DoubleTab& phif_c)
const
216#ifdef _COMPILE_AVEC_PGCC_AVANT_22_7
217 Cerr <<
"Internal error with nvc++: Internal error: read_memory_region: not all expected entries were read." << finl;
223 const Static_Int_Lists& s_e =
som_elem();
224 int i, i_s, j, k, l, e, f, s, sb, n_f, n_m, n_ef, n_e, n_eb, m, n, ne_tot =
nb_elem_tot(), sgn, nw, infoo=-1, d, db,
225 D =
dimension, rk=-1, nl, nc, un = 1, il, ok, essai;
229 double x, eps_g = 1e-6, eps = 1e-10, i3[3][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }}, fac[3], vol_s;
236 std::vector<int> s_eb, s_f;
237 std::vector<double> surf_fs, vol_es;
238 std::vector<std::array<std::array<double, 3>,2>> vec_fs;
239 std::vector<std::vector<int>> se_f;
240 DoubleTrav M, B, X, Ff, Feb, Mf, Meb, W(1), x_fs, A, S;
245 for (i_s = 0; i_s <= (som_ext ? som_ext->
size() : 0); i_s++)
246 for (s = (som_ext && i_s ? (*som_ext)(i_s - 1) + 1 : 0); s < (som_ext && i_s < som_ext->
size() ? (*som_ext)(i_s) : (virt ?
nb_som_tot() :
nb_som())); s++)
249 for (s_eb.clear(), n_e = 0; n_e < s_e.
get_list_size(s); n_e++) s_eb.push_back(s_e(s, n_e));
251 for (s_f.clear(), surf_fs.clear(), vec_fs.clear(), se_f.resize(std::max(
int(se_f.size()), n_e)), i = 0, ok = 1; i < n_e; i++)
252 for (se_f[i].clear(), e = s_eb[i], j = 0; j < e_f.dimension(1) && (f = e_f(e, j)) >= 0; j++)
254 for (k = 0, sb = 0; k < f_s.dimension(1) && (sb = f_s(f, k)) >= 0; k++)
256 if (sb != s)
continue;
257 if (
fbord(f) >= 0) s_eb.insert(std::lower_bound(s_eb.begin(), s_eb.end(), ne_tot + f), ne_tot + f);
258 else ok &= (f_e(f, 0) >= 0 && f_e(f, 1) >= 0);
259 se_f[i].push_back(f);
260 if ((ll = std::lower_bound(s_f.begin(), s_f.end(), f) - s_f.begin()) == s_f.size() || s_f[ll] != f)
262 s_f.insert(s_f.begin() + ll, f);
263 if (D < 3) surf_fs.insert(surf_fs.begin() + ll, fs(f) / 2), vec_fs.insert(vec_fs.begin() + ll, {{{ xs(s, 0) - xv_(f, 0), xs(s, 1) - xv_(f, 1), 0}, { 0, 0, 0 }}});
264 else for (surf_fs.insert(surf_fs.begin() + ll, 0), vec_fs.insert(vec_fs.begin() + ll, {{{ 0, 0, 0}, {0, 0, 0 }}}), m = 0; m < 2; m++)
266 if (m == 1 || k > 0) sb = f_s(f, m ? (k + 1 < f_s.dimension(1) && f_s(f, k + 1) >= 0 ? k + 1 : 0) : k - 1);
267 else for (n = f_s.dimension(1) - 1; (sb = f_s(f, n)) == -1; ) n--;
268 auto v =
cross(D, D, &xs(s, 0), &xs(sb, 0), &
xv_(f, 0), &
xv_(f, 0));
269 if (fs(f) > 0) surf_fs[ll] += std::fabs(
dot(&v[0], &nf(f, 0))) / fs(f) / 4;
270 for (d = 0; d < D; d++) vec_fs[ll][m][d] = (xs(s, d) + xs(sb, d)) / 2 -
xv_(f, d);
275 n_eb = (int)s_eb.size(), n_f = (int)s_f.size();
278 for (i = 0; i < n_e; i++)
279 for (j = 0; j < (int) se_f[i].size(); j++) se_f[i][j] = (
int)(std::lower_bound(s_f.begin(), s_f.end(), se_f[i][j]) - s_f.begin());
280 for (vol_es.resize(n_e), vol_s = 0, i = 0; i < n_e; vol_s += vol_es[i], i++)
281 for (e = s_eb[i], vol_es[i] = 0, j = 0; j < (int) se_f[i].size(); j++)
283 f = s_f[k = se_f[i][j]];
284 if (fs(f) > 0) vol_es[i] += surf_fs[k] * std::fabs(dot(&xp_(e, 0), &nf(f, 0), &xv_(f, 0))) / fs(f) / D;
287 for (essai = 0; essai < 3; essai++)
292 for (M.resize(N, nc = (D - 1) * n_f, nl = D * (D - 1) / 2 * n_e), B.resize(N, n_m = std::max(nc, nl)), M = 0, B = 0, i = 0, il = 0; i < n_e; i++)
293 for (d = 0; d < D; d++)
294 for (db = 0; db < d; db++, il++)
295 for (e = s_eb[i], j = 0; j < (int) se_f[i].size(); j++)
296 for (sgn = e == f_e(f = s_f[k = se_f[i][j]], 0) ? 1 : -1, n = 0; n < N; n++)
298 const double inv_fs = fs(f) > 0 ? 1. / fs(f) : 0.;
299 for (l = 0; l < D; l++) fac[l] = sgn * nu_dot(nu, e, n, &nf(f, 0), i3[l]) * surf_fs[k] * inv_fs / vol_es[i];
300 B(n, il) += fac[d] * (xv_(f, db) - xp_(e, db)) - fac[db] * (xv_(f, d) - xp_(e, d));
301 for (l = 0; l < D - 1; l++) M(n, (D - 1) * k + l, il) += fac[db] * vec_fs[k][l][d] - fac[d] * vec_fs[k][l][db];
305 nw = -1, piv.resize(nc), F77NAME(dgelsy)(&nl, &nc, &un, &M(0, 0, 0), &nl, &B(0, 0), &n_m, &piv(0), &eps_g, &rk, &W(0), &nw, &infoo);
306 for (W.resize(nw = (
int)std::lrint(W(0))), n = 0; n < N; n++) piv = 0, F77NAME(dgelsy)(&nl, &nc, &un, &M(n, 0, 0), &nl, &B(n, 0), &n_m, &piv(0), &eps_g, &rk, &W(0), &nw, &infoo);
308 for (x_fs.resize(N, n_f, D), n = 0; n < N; n++)
309 for (i = 0; i < n_f; i++)
310 for (f = s_f[i], d = 0; d < D; d++)
311 for (x_fs(n, i, d) = xv_(f, d), k = 0; k < D - 1; k++) x_fs(n, i, d) += std::min(std::max(B(n, (D - 1) * i + k), 0.), 0.5) * vec_fs[i][k][d];
315 Ff.resize(n_f, n_f, N), Feb.resize(n_f, n_eb, N), Mf.resize(N, n_f, n_f), Meb.resize(N, n_eb, n_f);
316 for (Ff = 0, Feb = 0, Mf = 0, Meb = 0, i = 0; i < n_e; i++)
317 for (e = s_eb[i], M.resize(n_ef = (
int)se_f[i].size(), D), B.resize(D, n_m = std::max(D, n_ef)), X.resize(n_ef, D), piv.resize(n_ef), n = 0; n < N; n++)
322 for (j = 0; j < n_ef; j++)
323 for (f = s_f[k = se_f[i][j]], d = 0; d < D; d++) M(j, d) = (essai ? x_fs(n, k, d) : xv_(f, d)) - xp_(e, d);
324 for (B = 0, d = 0; d < D; d++) B(d, d) = 1;
325 nw = -1, piv = 0, F77NAME(dgelsy)(&D, &n_ef, &D, &M(0, 0), &D, &B(0, 0), &n_m, &piv(0), &eps_g, &rk, &W(0), &nw, &infoo);
326 W.resize(nw = (
int)std::lrint(W(0))), F77NAME(dgelsy)(&D, &n_ef, &D, &M(0, 0), &D, &B(0, 0), &n_m, &piv(0), &eps_g, &rk, &W(0), &nw, &infoo);
327 for (j = 0; j < n_ef; j++)
328 for (d = 0; d < D; d++) X(j, d) = B(d, j);
330 else for (j = 0; j < n_ef; j++)
331 for (sgn = e == f_e(f = s_f[k = se_f[i][j]], 0) ? 1 : -1, d = 0; d < D; d++)
333 const double inv_fs = fs(f) > 0 ? 1. / fs(f) : 0.;
334 X(j, d) = surf_fs[k] / vol_es[i] * sgn * nf(f, d) * inv_fs;
338 for (j = 0; j < n_ef; j++)
340 k = se_f[i][j], f = s_f[k], sgn = e == f_e(f, 0) ? 1 : -1;
341 const Cond_lim_base *cl = fcl(f, 0) ? &cls[fcl(f, 1)].valeur() :
nullptr;
343 for (l = 0; l < n_ef; l++)
345 const double inv_fs = fs(f) > 0 ? 1. / fs(f) : 0.;
346 x = sgn * nu_dot(nu, e, n, &nf(f, 0), &X(l, 0)) * surf_fs[k] * inv_fs;
347 if (sgn > 0) Ff(k, se_f[i][l], n) += x, Feb(k, i, n) -= x;
348 if (!is_dir) Mf(n, se_f[i][l], k) += x, Meb(n, i, k) += x;
351 else if (is_dir) Mf(n, k, k) = Meb(n, (
int)(std::find(s_eb.begin(), s_eb.end(), ne_tot + f) - s_eb.begin()), k) = 1;
352 else if (is_p ? !is_dir : sub_type(
Neumann, *cl))
353 Meb(n, (
int)(std::find(s_eb.begin(), s_eb.end(), ne_tot + f) - s_eb.begin()), k) += surf_fs[k];
361 Meb(n, (
int)(std::find(s_eb.begin(), s_eb.end(), ne_tot + f) - s_eb.begin()), k) += surf_fs[k] * h;
363 else Meb(n, i, k) -= surf_fs[k] * h;
368 nw = -1, piv.resize(n_f), F77NAME(dgelsy)(&n_f, &n_f, &n_eb, &Mf(0, 0, 0), &n_f, &Meb(0, 0, 0), &n_f, &piv(0), &eps, &rk, &W(0), &nw, &infoo);
369 for (W.resize(nw = (
int)std::lrint(W(0))), n = 0; n < N; n++)
370 piv = 0, F77NAME(dgelsy)(&n_f, &n_f, &n_eb, &Mf(n, 0, 0), &n_f, &Meb(n, 0, 0), &n_f, &piv(0), &eps, &rk, &W(0), &nw, &infoo);
373 for (i = 0; i < n_f; i++)
374 for (j = 0; j < n_eb; j++)
375 for (n = 0; n < N; n++)
376 for (k = 0; k < n_f; k++)
377 Feb(i, j, n) += Ff(i, k, n) * Meb(n, j, k);
380 if (essai == 2)
break;
381 for (A.resize(N, n_e, n_e), A = 0, i = 0; i < n_e; i++)
382 for (e = s_eb[i], j = 0; j < (int) se_f[i].size(); j++)
383 for (sgn = e == f_e(f = s_f[k = se_f[i][j]], 0) ? 1 : -1, l = 0; l < n_e; l++)
384 for (n = 0; n < N; n++)
385 A(n, i, l) -= sgn * Feb(k, l, n);
387 for (n = 0; n < N; n++)
388 for (i = 0; i < n_e; i++)
389 for (j = 0; j <= i; j++) A(n, i, j) = A(n, j, i) = (A(n, i, j) + A(n, j, i)) / 2;
391 nw = -1, F77NAME(DSYEV)(
"N",
"U", &n_e, &A(0, 0, 0), &n_e, S.addr(), &W(0), &nw, &infoo);
392 for (W.resize(nw = (
int)std::lrint(W(0))), S.resize(n_e), n = 0, ok = 1; n < N; n++)
393 F77NAME(DSYEV)(
"N",
"U", &n_e, &A(n, 0, 0), &n_e, &S(0), &W(0), &nw, &infoo), ok &= S(0) > -1e-8 * vol_s;
396 if (first_fgrad_) ctr[essai](s) = 1;
399 for (i = 0; i < n_f; i++)
400 for (f = s_f[i], j = 0; j < n_eb; j++)
401 for (k = (
int)(std::lower_bound(fsten_eb.addr() + fsten_d(f), fsten_eb.addr() + fsten_d(f + 1), s_eb[j]) - fsten_eb.addr()), n = 0; n < N; n++)
402 if (fs(f) > 0) phif_c(k, n) += Feb(i, j, n) / fs(f);
410 for (phif_d.resize(1), phif_d = 0, phif_e.resize(0), f = 0, i = 0; f < nb_faces_tot(); f++, phif_d.append_line(i))
411 if (fbord(f) >= 0 || (f_e(f, 0) >= 0 && f_e(f, 1) >= 0))
413 for (n = 0; n < N; n++)
414 if (fs(f) > 0) scale(n) = nu_dot(nu, f_e(f, 0), n, &nf(f, 0), &nf(f, 0)) / (fs(f) * vf(f));
415 for (j = fsten_d(f); j < fsten_d(f + 1); j++)
417 for (skip = !full_stencil && fsten_eb(j) != f_e(f, 0), n = 0; n < N; n++) skip &= std::fabs(phif_c(j, n)) < 1e-8 * scale(n);
419 for (n = 0; n < N; n++) phif_c(i, n) = phif_c(j, n);
420 phif_e.append_line(fsten_eb(j)), i++;
424 if (!first_fgrad_)
return;
425 double count[3] = { mp_somme_vect_as_double(ctr[0]), mp_somme_vect_as_double(ctr[1]), mp_somme_vect_as_double(ctr[2]) }, tot = count[0] + count[1] + count[2];
427 Cerr << domaine().le_nom() <<
"::fgrad(): " << 100. * count[0] / tot <<
"% MPFA-O "
428 << 100. * count[1] / tot <<
"% MPFA-O(h) " << 100. * count[2] / tot <<
"% MPFA-SYM" << finl;