16#include <Linear_algebra_tools_impl.h>
17#include <MD_Vector_composite.h>
18#include <Domaine_Cl_PolyMAC_family.h>
19#include <Domaine_PolyMAC_CDO.h>
20#include <Option_PolyMAC_family.h>
21#include <Quadrangle_VEF.h>
22#include <Option_PolyMAC_family.h>
23#include <Poly_geom_base.h>
24#include <communications.h>
25#include <TRUSTTab_parts.h>
26#include <Segment_poly.h>
27#include <Matrix_tools.h>
28#include <Hexaedre_VEF.h>
29#include <Quadri_poly.h>
30#include <Array_tools.h>
31#include <TRUSTLists.h>
32#include <Tetra_poly.h>
53#pragma GCC diagnostic push
54#pragma GCC diagnostic ignored "-Wunused-variable"
56#pragma GCC diagnostic pop
77 Elem_geom_base& elem_geom =
domaine().type_elem().valeur();
78 int is_polyedre = sub_type(Poly_geom_base, elem_geom) ? 1 : 0;
79 const ArrOfInt PolyIndex = is_polyedre ? ref_cast(Poly_geom_base,
domaine().
type_elem().valeur()).getElemIndex() : ArrOfInt(0);
82 for (
int num_elem=0; num_elem<nbe; num_elem++)
85 const int nb_faces_elem = is_polyedre ? PolyIndex[num_elem+1] - PolyIndex[num_elem] :
domaine().
nb_faces_elem();
86 for (
int i=0; i<nb_faces_elem; i++)
88 double surf = surfaces(
elem_faces(num_elem,i));
89 surf_max = (surf > surf_max)? surf : surf_max;
91 double vol =
volumes(num_elem)/surf_max;
102 for (
int num_face=0; num_face<
nb_faces(); num_face++)
103 for (
int dir=0; dir<2; dir++)
121 int i, j, e1, e2, f1, f2, d, D =
dimension, ok;
123 IntTrav ntot, nequiv;
131 const bool is_PolyMAC_CDO = (
que_suis_je() ==
"Domaine_PolyMAC_CDO");
134 if ((e1 = f_e(f, 0)) >= 0 && (e2 = f_e(f, 1)) >= 0)
135 for (i = 0; i < e_f.
dimension(1) && (f1 = e_f(e1, i)) >= 0; i++)
136 for (j = 0, ntot(f)++; j < e_f.
dimension(1) && (f2 = e_f(e2, j)) >= 0; j++)
138 if (std::fabs(fs(f1) * fs(f2)) < 1e-20)
continue;
140 if (std::fabs(std::fabs(
dot(&nf(f1, 0), &nf(f2, 0)) / (fs(f1) * fs(f2))) - 1) > 1e-6)
150 const bool same_orn = (orn_f1 == orn_f2);
154 for (d = 0; d < D; d++)
156 if ((
xv_(f1, d) !=
xv_(f2, d)) )
162 if (same_orn && aligned && ( f1 != f2 ))
165 int ee1 = f_e(f1, 0), ee2 = f_e(f1, 1);
167 for (
int ii = 0; ii < e_f.
dimension(1); ii++)
169 int ff1 = ee1 >= 0 ? e_f(ee1, ii) : -1;
170 int ff2 = ee2 >= 0 ? e_f(ee2, ii) : -1;
172 if (f2 == ff1 || f2 == ff2)
182 for (ok = 1, d = 0; d < D; d++)
183 ok &= std::fabs((
xv_(f1, d) -
xp_(e1, d)) - (
xv_(f2, d) -
xp_(e2, d))) < 1e-12;
187 std::array<double, 3> v1 =
cross(D, D, &
xv_(f1, 0), &nf(f1, 0), &
xp_(e1, 0));
188 std::array<double, 3> v2 =
cross(D, D, &
xv_(f2, 0), &nf(f2, 0), &
xp_(e2, 0));
190 double norm1 = (D < 3 ? v1[2]*v1[2] : 0.), norm2 = (D < 3 ? v2[2]*v2[2] : 0.);
191 for (ok = 1, d = 0; d < D; d++)
193 ok &= std::fabs((
xv_(f1, d) -
xp_(e1, d)) - (
xv_(f2, d) -
xp_(e2, d))) < (is_PolyMAC_CDO ? 1.e-12 : 1e-12);
194 norm1 += v1[d]*v1[d];
195 norm2 += v2[d]*v2[d];
197 ok &= sqrt(norm1) < 1e-12;
198 ok &= sqrt(norm2) < 1e-12;
209 Cerr << mp_somme_vect_as_double(nequiv) * 100. / mp_somme_vect_as_double(ntot) <<
"% equivalent faces!" << finl;
214 Cerr <<
"Le Domaine_PolyMAC_CDO a ete rempli avec succes" << finl;
217 Journal() <<
"Domaine_PolyMAC_CDO::Modifier_pour_Cl" << finl;
218 int nb_cond_lim=conds_lim.size();
220 for (; num_cond_lim<nb_cond_lim; num_cond_lim++)
234 int num_derniere_face = num_premiere_face+nfin;
236 int nbr_faces_bord = la_front_dis.
nb_faces();
250 for (
int ind_face=ndeb; ind_face<nfin; ind_face++)
253 face = la_front_dis.
num_face(ind_face);
257 if (ind_face<nbr_faces_bord)
259 assert(faassociee>=num_premiere_face);
260 assert(faassociee<num_derniere_face);
298 int i, j, k, i1, i2, j1, j2, n_f = M.
dimension(0), lwork = -1, infoo = 0;
299 DoubleTab A, S, b(n_f, 1), D(1, 1), x(1, 1), work(1), U(n_f -
dimension, n_f -
dimension), V;
302 kersol(M, b, 1e-12,
nullptr, x, S);
303 double l_max = S(0), l_min = S(
dimension - 1);
306 b.resize(
dimension, 1), kersol(N, b, 1e-12, &D, x, S);
307 assert(D.dimension(1) == n_f -
dimension);
311 int n_k = D.dimension(1), n_l = n_f * (n_f - 1) / 2, n_c = n_k * (n_k + 1) / 2, un = 1;
312 A.
resize(n_l, n_c), b.resize(n_l, 1);
313 for (i1 = i = 0; i1 < n_f; i1++)
314 for (i2 = i1 + 1; i2 < n_f; i2++, i++)
315 for (j1 = j = 0, b(i, 0) = -M(i1, i2); j1 < n_k; j1++)
316 for (j2 = j1; j2 < n_k; j2++, j++)
317 A(i, j) = D(i1, j1) * D(i2, j2) + (j1 != j2) * D(i1, j2) * D(i2, j1);
320 F77NAME(dgels)(&trans, &n_c, &n_l, &un, &A(0, 0), &n_c, &b(0, 0), &n_l, &work(0), &lwork, &infoo);
321 work.resize(lwork = (
int)work(0));
322 F77NAME(dgels)(&trans, &n_c, &n_l, &un, &A(0, 0), &n_c, &b(0, 0), &n_l, &work(0), &lwork, &infoo);
325 for (j1 = j = 0; j1 < n_k; j1++)
326 for (j2 = j1; j2 < n_k; j2++, j++) U(j1, j2) = U(j2, j1) = b(j, 0);
330 char jobz =
'V', uplo =
'U';
332 F77NAME(dsyev)(&jobz, &uplo, &n_k, &V(0, 0), &n_k, &S(0), &work(0), &lwork, &infoo);
333 work.resize(lwork = (
int)work(0));
334 F77NAME(dsyev)(&jobz, &uplo, &n_k, &V(0, 0), &n_k, &S(0), &work(0), &lwork, &infoo);
337 for (i = 0, U = 0; i < n_k; i++)
338 for (j = 0; j < n_k; j++)
339 for (k = 0; k < n_k; k++) U(i, j) += V(k, i) * std::min(std::max(S(k), l_min), l_max) * V(k, j);
342 for (i1 = 0; i1 < n_f; i1++)
343 for (i2 = 0; i2 < n_f; i2++)
344 for (j1 = 0; j1 < n_k; j1++)
345 for (j2 = 0; j2 < n_k; j2++)
346 M(i1, i2) += D(i1, j1) * U(j1, j2) * D(i2, j2);
353 int i, j, k, l, n_f = R.
dimension(0), nv = 0, d = R.
dimension(1), infoo = 0, lwork = -1, sym, diag, ret, it, cv;
357 Matrice33 NtR(0, 0, 0, 0, d < 2, 0, 0, 0, d < 3), iNtR;
358 for (i = 0; i < d; i++)
359 for (j = 0; j < d; j++)
360 for (k = 0; k < n_f; k++) NtR(i, j) += N(k, i) * R(k, j);
361 for (i = 0, sym = 1; i < d; i++)
362 for (j = i + 1; j < d; j++) sym &= (std::fabs(NtR(i, j) - NtR(j, i)) < 1e-8);
364 IntTrav idx(n_f, n_f);
366 for (i = 0; i < n_f; i++)
367 for (j = i; j < n_f; j++) idx(i, j) = idx(j, i) = (W(i, j) ? nv++ : -1);
368 else for (i = 0; i < n_f; i++)
369 for (j = 0; j < n_f; j++) idx(i, j) = (W(i, j) ? nv++ : -1);
373 for (i = 0, W = 0; i < n_f; i++)
374 for (j = 0; j < d; j++)
375 for (k = 0; k < d; k++)
376 for (l = 0; l < n_f; l++) W(i, l) += N(i, j) * iNtR(j, k) * N(l, k);
378 DoubleTrav Ws(n_f, n_f), S(n_f), work(1);
379 for (i = 0; i < n_f; i++)
380 for (j = 0; j < n_f; j++) Ws(i, j) = (W(i, j) + W(j, i)) / 2;
381 char jobz =
'N', uplo =
'U';
382 F77NAME(dsyev)(&jobz, &uplo, &n_f, &Ws(0, 0), &n_f, &S(0), &work(0), &lwork, &infoo);
383 work.
resize(lwork = (
int)work(0));
384 F77NAME(dsyev)(&jobz, &uplo, &n_f, &Ws(0, 0), &n_f, &S(0), &work(0), &lwork, &infoo);
385 assert(S(0) > -1e-8 && S(n_f -
dimension) > 0);
386 if (spectre) spectre[0] = std::min(spectre[0], S(n_f -
dimension)), spectre[2] = std::max(spectre[2], S(n_f - 1));
388 double l_min = S(n_f -
dimension) / 100, l_max = S(n_f - 1) * 100;
392 OSQPSettings settings;
393 osqp_set_default_settings(&settings);
394 settings.scaled_termination = 1, settings.polish = 1, settings.eps_abs = settings.eps_rel = 1e-8, settings.max_iter = 1e3;
397 std::vector<std::map<int, double>> C(nv);
398 std::vector<double> lb, ub;
400 for (i = 0; i < n_f; i++)
401 for (j = 0; j < d; j++, il++)
402 for (k = 0, lb.push_back(N(i, j)), ub.push_back(N(i, j)); k < n_f; k++)
403 if (idx(i, k) >= 0) C[idx(i, k)][il] += R(k, j);
406 std::vector<int> P_c(nv + 1), P_l(nv), A_c, A_l;
407 std::vector<double> P_v(nv), A_v, Q(nv, 0.);
408 for (i = 0; i < nv; i++) P_l[i] = i, P_c[i + 1] = i + 1;
409 for (i = 0; i < n_f; i++)
410 for (j = 0; j < n_f; j++)
411 if (idx(i, j) >= 0) P_v[idx(i, j)] += (i == j ? 0 : 1);
412 data.n = nv, data.P = csc_matrix(nv, nv, (
int)P_v.size(), P_v.data(), P_l.data(), P_c.data()), data.q = Q.data();
416 std::feholdexcept(&fenv);
417 std::vector<double> sol(nv);
418 for (cv = 0, it = 0; !cv && it < 100; it++)
421 for (j = 0, A_c.resize(1), A_l.resize(0), A_v.resize(0); j < nv; j++, A_c.push_back((
int)A_l.size()))
422 for (
auto && l_v : C[j]) A_l.push_back(l_v.first), A_v.push_back(l_v.second);
423 data.A = csc_matrix((
int)lb.size(), nv, (
int)A_v.size(), A_v.data(), A_l.data(), A_c.data());
424 data.l = lb.data(), data.u = ub.data(), data.m = (int)lb.size();
427 OSQPWorkspace *osqp =
nullptr;
428 if (osqp_setup(&osqp, &data, &settings)) Cerr <<
"Domaine_PolyMAC_CDO::W_stabiliser : osqp_setup error" << finl,
Process::exit();
429 if (it) osqp_warm_start_x(osqp, sol.data());
431 ret = osqp->info->status_val, sol.assign(osqp->solution->x, osqp->solution->x + nv);
432 if (ret == OSQP_PRIMAL_INFEASIBLE || ret == OSQP_PRIMAL_INFEASIBLE_INACCURATE)
434 osqp_cleanup(osqp), free(data.A);
437 for (i = 0; i < n_f; i++)
438 for (j = 0; j < n_f; j++) W(i, j) = (idx(i, j) >= 0 ? sol[idx(i, j)] : 0);
441 for (i = 0; i < n_f; i++)
442 for (j = 0; j < n_f; j++) Ws(i, j) = (W(i, j) + W(j, i)) / 2;
443 jobz =
'V', F77NAME(dsyev)(&jobz, &uplo, &n_f, &Ws(0, 0), &n_f, &S(0), &work(0), &lwork, &infoo);
446 for (i = 0, cv = (osqp->info->status_val == OSQP_SOLVED); i < n_f; i++)
447 if (S(i) < l_min || S(i) > l_max)
449 for (j = 0; j < n_f; j++)
450 for (k = 0; k < n_f; k++)
451 if(idx(j, k) >= 0) C[idx(j, k)][il] += Ws(i, j) * Ws(i, k);
452 lb.push_back(l_min * (S(i) < l_min ? 1.1 : 1)), ub.push_back(l_max / (S(i) > l_max ? 1.1 : 1));
455 osqp_cleanup(osqp), free(data.A);
458 std::fesetenv(&fenv);
462 Cerr <<
"Matrice non stabilisee : attention le maillage est trop deforme!!" << finl;
466 for (i = 0; i < n_f; i++) spectre[1] = std::min(spectre[1], S(i)), spectre[3] = std::max(spectre[3], S(i));
470 for (i = 0, diag = 1; i < n_f; i++)
471 for (j = 0; j < n_f; j++) diag &= (i == j || std::fabs(W(i, j)) < 1e-6);
472 ctr[0] += diag, ctr[1] += sym;
476void Domaine_PolyMAC_CDO::init_m2_new()
const
480 int i, j, e, n_f, ctr[3] = {0, 0, 0 };
481 double spectre[4] = { DBL_MAX, DBL_MAX, 0, 0 };
497 for (e = 0; e <
nb_elem(); e++)
502 for (n_f = 0; n_f < e_f.
dimension(1) && e_f(e, n_f) >= 0; ) n_f++;
503 for (i = 0; i < n_f; i++)
504 for (j = 0, nef(e)++; j < n_f; j++) w2e(e, i, j) = W(i, j, 0), nnz(e) += (std::fabs(W(i, j, 0)) > 1e-6);
505 for (i = 0; i < n_f; i++)
506 for (j = 0; j < n_f; j++) m2e(e, i, j) = M(i, j, 0);
510 m2e.echange_espace_virtuel(), w2e.echange_espace_virtuel();
511 for (e = 0,
m2d.append_line(0),
m2i.append_line(0),
w2i.append_line(0); e <
nb_elem_tot(); e++,
m2d.append_line(
m2i.size() - 1))
513 for (n_f = 0; n_f < e_f.
dimension(1) && e_f(e, n_f) >= 0; ) n_f++;
514 for (i = 0; i < n_f; i++,
m2i.append_line(
m2j.size()))
515 for (j = 0,
m2j.append_line(i),
m2c.append_line(m2e(e, i, i)); j < n_f; j++)
516 if (j != i && std::fabs(m2e(e, i, j)) > 1e-6)
m2j.append_line(j),
m2c.append_line(m2e(e, i, j));
517 for (i = 0; i < n_f; i++,
w2i.append_line(
w2j.size()))
518 for (j = 0,
w2j.append_line(i),
w2c.append_line(w2e(e, i, i)); j < n_f; j++)
519 if (j != i && std::fabs(w2e(e, i, j)) > 1e-6)
w2j.append_line(j),
w2c.append_line(w2e(e, i, j));
523 for (i = 0; i <
m2d(e + 1) -
m2d(e); i++)
524 for (f = e_f(e, i), j =
w2i(
m2d(e) + i); j <
w2i(
m2d(e) + i + 1); j++)
527 w2c(j) /= fs(f) * fs(fb) / ve(e);
531 for (i = 0; i <
m2d(e + 1) -
m2d(e); i++)
532 for (f = e_f(e, i), j =
m2i(
m2d(e) + i); j <
m2i(
m2d(e) + i + 1); j++)
535 m2c(j) *= fs(f) * fs(fb) / ve(e);
543 <<
" / " <<
Process::mp_max(spectre[3]) <<
" width : " << mp_somme_vect_as_double(nnz) * 1. / mp_somme_vect_as_double(nef) << finl;
547void Domaine_PolyMAC_CDO::init_m2_osqp()
const
552 int i, j, e, f, s, n_f, ctr[3] = {0, 0, 0 }, infoo = 0;
553 double spectre[4] = { DBL_MAX, DBL_MAX, 0, 0 };
559 DoubleTab W, M, R, N;
567 std::map<int, std::vector<int>> som_face;
570 for (e = 0; e <
nb_elem(); e++)
572 for (n_f = 0; n_f < e_f.
dimension(1) && e_f(e, n_f) >= 0; ) n_f++;
576 for (i = 0; i < n_f; i++)
577 for (j = 0, f = e_f(e, i); j <
dimension; j++)
578 N(i, j) = nf(f, j) / fs(f) * (e == f_e(f, 0) ? 1 : -1), R(i, j) = (
xv_(f, j) -
xp_(e, j)) * fs(f) / ve(e);
581 for (i = 0, W = 0, som_face.clear(); i < n_f; i++)
582 for (j = 0, f = e_f(e, i); j < f_s.
dimension(1) && (s = f_s(f, j)) >= 0; j++) som_face[s].push_back(i);
583 for (
auto &s_fs : som_face)
584 for (
auto i1 : s_fs.second)
585 for (
auto i2 : s_fs.second) W(i1, i2) = 1;
592 F77NAME(dpotrf)(&uplo, &n_f, M.
addr(), &n_f, &infoo);
593 F77NAME(dpotri)(&uplo, &n_f, M.
addr(), &n_f, &infoo);
595 for (i = 0; i < n_f; i++)
596 for (j = i + 1; j < n_f; j++) M(i, j) = M(j, i);
598 for (i = 0; i < n_f; i++)
599 for (j = 0, nef(e)++; j < n_f; j++) w2e(e, i, j) = W(i, j), nnz(e) += (std::fabs(W(i, j)) > 1e-6);
600 for (i = 0; i < n_f; i++)
601 for (j = 0; j < n_f; j++) m2e(e, i, j) = M(i, j);
605 m2e.echange_espace_virtuel(), w2e.echange_espace_virtuel();
606 for (e = 0,
m2d.append_line(0),
m2i.append_line(0),
w2i.append_line(0); e <
nb_elem_tot(); e++,
m2d.append_line(
m2i.size() - 1))
608 for (n_f = 0; n_f < e_f.
dimension(1) && e_f(e, n_f) >= 0; ) n_f++;
609 for (i = 0; i < n_f; i++,
m2i.append_line(
m2j.size()))
610 for (j = 0,
m2j.append_line(i),
m2c.append_line(m2e(e, i, i)); j < n_f; j++)
611 if (j != i && std::fabs(m2e(e, i, j)) > 1e-6)
m2j.append_line(j),
m2c.append_line(m2e(e, i, j));
612 for (i = 0; i < n_f; i++,
w2i.append_line(
w2j.size()))
613 for (j = 0,
w2j.append_line(i),
w2c.append_line(w2e(e, i, i)); j < n_f; j++)
614 if (j != i && std::fabs(w2e(e, i, j)) > 1e-6)
w2j.append_line(j),
w2c.append_line(w2e(e, i, j));
622 <<
" / " <<
Process::mp_max(spectre[3]) <<
" width : " << mp_somme_vect_as_double(nnz) * 1. / mp_somme_vect_as_double(nef) << finl;
647 for (i = 0; i < e_f.
dimension(1) && (f = e_f(e, i)) >= 0; i++)
649 double x[3] = { 0, };
650 for (k = 0; k <
dimension; k++) x[k] = fs(f) * (
xv(f, k) -
xp(e, k)) * (e == f_e(f, 0) ? 1 : -1) / ve(e);
651 veji.append_line(f),
veci.append_line(x[0], x[1], x[2]);
654 is_init[
"ve"] = 1, Cerr <<
"OK" << finl;
668 for (i = 0; i < f_s.
dimension(1) && (s = f_s(f, i)) >= 0; i++)
670 int s2 = f_s(f, i + 1 < f_s.
dimension(1) && f_s(f, i + 1) >= 0 ? i + 1 : 0),
672 std::array<double, 3> taz = {{ 0, 0, 1 }}, vec;
674 int sgn =
dot(&vec[0], &nf(f, 0)) > 0 ? 1 : -1;
675 rfji.append_line(a),
rfci.append_line(sgn * (
dimension < 3 ? 1 : la(a)) / fs(f));
690 for (i = 0; i < f_s.
dimension(1) && (s1 = f_s(f, i)) >= 0; i++)
692 int s2 = f_s(f, i + 1 < f_s.
dimension(1) && f_s(f, i + 1) >= 0 ? i + 1 : 0);
696 for (
int i = 0; i < (int) a_f_vect.size(); i++) a_f_max = std::max(a_f_max, (
int) a_f_vect[i].size());
697 arete_faces_.resize((
int)a_f_vect.size(), a_f_max), arete_faces_ = -1;
698 for (
int i = 0, j; i < arete_faces_.dimension(0); i++)
699 for (j = 0; j < (int) a_f_vect[i].size(); j++) arete_faces_(i, j) = a_f_vect[i][j];
709 const DoubleVect& ve =
volumes();
713 std::map<int, double> wemi;
717 for (i = 0; i < e_f.
dimension(1) && (f = e_f(e, i)) >= 0; i++)
718 for (j = 0; j < f_s.dimension(1) && (s = f_s(f, j)) >= 0; j++)
719 wemi[s] += std::fabs(
cross(2, 2, &
xp_(e, 0), &
xv_(f, 0), &xs(s, 0), &xs(s, 0))[2]) / (2 * ve(e));
720 for (
auto &&kv : wemi)
weji.append_line(kv.first),
weci.append_line(kv.second);
729 int i, j, k, e, f, s;
733 std::map<int, std::array<double, 3> > wemi;
737 for (i = 0; i < e_f.
dimension(1) && (f = e_f(e, i)) >= 0; i++)
738 for (j = 0; j < f_s.dimension(1) && (s = f_s(f, j)) >= 0; j++)
740 int s2 = f_s(f, j + 1 < f_s.dimension(1) && f_s(f, j + 1) >= 0 ? j + 1 : 0),
742 std::array<double, 3> vec =
cross(3, 3, &
xp_(e, 0), &
xv_(f, 0), &
xa_(a, 0), &
xa_(a, 0));
744 int sgn =
dot(&
ta_(a, 0), &vec[0]) > 0 ? 1 : -1;
745 for (k = 0; k < 3; k++) wemi[a][k] += sgn * vec[k] * la(a) / (2 * ve(e));
747 for (
auto &&kv : wemi)
weji.append_line(kv.first),
weci.append_line(kv.second[0], kv.second[1], kv.second[2]);
764 for (i = 0; i < e_f.
dimension(1) && (f = e_f(e, i)) >= 0; i++)
765 for (j = 0; j < f_s.dimension(1) && (s = f_s(f, j)) >= 0; j++)
766 m1[s][ {{ s, e }}] += std::fabs(
cross(2, 2, &
xp_(e, 0), &
xv_(f, 0), &xs(s, 0), &xs(s, 0))[2]) / 2;
773 for (
auto &&kv : m1[i])
774 m1ji.append_line(kv.first[0], kv.first[1]),
m1ci.append_line(kv.second);
783 int a, ab, i, j, k, e, f, s, s2, n_a;
789 DoubleTrav m1e(0, e_a.dimension(1), e_a.dimension(1));
791 std::map<int, int> idxa;
792 for (e = 0; e <
nb_elem(); e++)
795 for (i = 0, idxa.clear(), n_a = 0; i < e_a.dimension(1) && (a = e_a(e, i)) >= 0; i++) idxa[a] = i, n_a++;
797 for (i = 0, M = 0; i < e_f.
dimension(1) && (f = e_f(e, i)) >= 0; i++)
798 for (j = 0; j < f_s.
dimension(1) && (s = f_s(f, j)) >= 0; j++)
800 s2 = f_s(f, j + 1 < f_s.
dimension(1) && f_s(f, j + 1) >= 0 ? j + 1 : 0), a =
som_arete[s].at(s2);
801 std::array<double, 3> vec =
cross(3, 3, &
xp_(e, 0), &
xv_(f, 0), &
xa_(a, 0), &
xa_(a, 0));
803 int sgn =
dot(&
ta_(a, 0), &vec[0]) > 0 ? 1 : -1;
804 for (k =
wedeb(e); k <
wedeb(e + 1); k++) M(idxa[a], idxa[
weji(k)]) += sgn * la(a) *
dot(&vec[0], &
weci(k, 0)) / 2 / ve(e);
806 for (i = 0; i < e_a.dimension(1) && (a = e_a(e, i)) >= 0; i++)
811 for (i = 0; i < n_a; i++)
812 for (j = 0; j < n_a; j++) m1e(e, i, j) = M(i, j);
817 std::vector<std::map<std::array<int, 2>,
double>> m1(
domaine().nb_aretes_tot());
819 for (i = 0; i < e_a.dimension(1) && (a = e_a(e, i)) >= 0; i++)
820 for (j = 0; j < e_a.dimension(1) && (ab = e_a(e, j)) >= 0; j++)
821 if (std::fabs(m1e(e, i, j)) > 1e-8) m1[a][ {{ ab, e }}] += ve(e) * m1e(e, i, j);
827 for (
auto &&kv : m1[a])
828 m1ji.append_line(kv.first[0], kv.first[1]),
m1ci.append_line(kv.second);
831 Cerr <<
"OK" << finl;
849 Stencil stencil(0, 2);
850 int e, i, j, k, f, fb;
852 for (i = 0, j =
m2d(e); j <
m2d(e + 1); i++, j++)
853 for (f = e_f(e, i), k =
m2i(j); f <
nb_faces() && k <
m2i(j + 1); k++)
854 if (f <= (fb = e_f(e,
m2j(k))))
856 tableau_trier_retirer_doublons(stencil);
861 for (i = 0, j =
m2d(e); j <
m2d(e + 1); i++, j++)
862 for (f = e_f(e, i), k =
m2i(j); f <
nb_faces() && k <
m2i(j + 1); k++)
863 if (f <= (fb = e_f(e,
m2j(k))))
864 m2mat(f, fb) += (e == f_e(f, 0) ? 1 : -1) * (e == f_e(fb, 0) ? 1 : -1) *
volumes(e) *
m2c(k);
865 m2mat.set_est_definie(1);
867 char lu[] =
"Petsc Cholesky { quiet }";
875 if (
is_init[
"virt_ef"])
return;
877 IntTrav p_e(0, 2), p_f(0, 2);
889inline void clamp(DoubleTab& m)
894 if (1e6 * std::abs(m(i, j, n)) < std::abs(m(i, i, n)) + std::abs(m(j, j, n))) m(i, j, n) = 0;
904 const DoubleVect& ve =
volumes();
905 for (n_f = 0; n_f < e_f.
dimension(1) && e_f(e, n_f) >= 0; ) n_f++;
906 double prefac, fac, beta = n_f == D + 1 ? 1. / D : D == 2 ? 1. / sqrt(2) : 1. / sqrt(3);
907 m2.
resize(n_f, n_f, N), m2 = 0;
908 DoubleTrav v_e(n_f, D), v_ef(n_f, n_f, D);
909 for (i = 0; i < n_f; i++)
910 for (f = e_f(e, i), d = 0; d < D; d++) v_e(i, d) = (xf(f, d) - xe(e, d)) / ve(e);
911 for (i = 0; i < n_f; i++)
912 for (f = e_f(e, i), prefac = D * beta / std::abs(
dot(&xf(f, 0), &nf(f, 0), &xe(e, 0))), j = 0; j < n_f; j++)
913 for (fac = prefac * ((j == i) - (e == f_e(f, 0) ? 1 : -1) *
dot(&nf(f, 0), &v_e(j, 0))), d = 0; d < D; d++)
914 v_ef(i, j, d) = v_e(j, d) + fac * (xf(f, d) - xe(e, d));
916 for (m2 = 0, i = 0; i < n_f; i++)
917 for (j = 0; j < n_f; j++)
919 for (n = 0; n < N; n++) m2(i, j, n) = m2(j, i, n);
920 else for (k = 0; k < n_f; k++)
921 for (f = e_f(e, k), fac = std::abs(
dot(&xf(f, 0), &nf(f, 0), &xe(e, 0))) / D, n = 0; n < N; n++)
922 m2(i, j, n) += fac *
nu_dot(nu, e_nu, n, &v_ef(k, i, 0), &v_ef(k, j, 0));
932 const DoubleVect& ve =
volumes();
933 for (n_f = 0; n_f < e_f.
dimension(1) && e_f(e, n_f) >= 0; ) n_f++;
934 double prefac, fac, beta = n_f == D + 1 ? 1. / D : D == 2 ? 1. / sqrt(2) : 1. / sqrt(3);
935 w2.
resize(n_f, n_f, N), w2 = 0;
936 DoubleTrav v_e(n_f, D), v_ef(n_f, n_f, D);
937 for (i = 0; i < n_f; i++)
938 for (f = e_f(e, i), d = 0; d < D; d++) v_e(i, d) = (e == f_e(f, 0) ? 1 : -1) * nf(f, d) / ve(e);
939 for (i = 0; i < n_f; i++)
940 for (f = e_f(e, i), prefac = D * beta * (e == f_e(f, 0) ? 1 : -1) / std::abs(
dot(&xf(f, 0), &nf(f, 0), &xe(e, 0))), j = 0; j < n_f; j++)
941 for (fac = prefac * ((j == i) -
dot(&xf(f, 0), &v_e(j, 0), &xe(e, 0))), d = 0; d < D; d++)
942 v_ef(i, j, d) = v_e(j, d) + fac * nf(f, d);
944 for (i = 0; i < n_f; i++)
945 for (j = 0; j < n_f; j++)
947 for (n = 0; n < N; n++) w2(i, j, n) = w2(j, i, n);
948 else for (k = 0; k < n_f; k++)
949 for (f = e_f(e, k), fac = std::abs(
dot(&xf(f, 0), &nf(f, 0), &xe(e, 0))) / D, n = 0; n < N; n++)
950 w2(i, j, n) += fac *
nu_dot(nu, e_nu, n, &v_ef(k, i, 0), &v_ef(k, j, 0));
classe Cond_lim_base Classe de base pour la hierarchie des classes qui representent les differentes c...
virtual Frontiere_dis_base & frontiere_dis()
Renvoie la frontiere discretisee a laquelle les conditions aux limites s'appliquent.
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
int_t nb_aretes_tot() const
renvoie le nombre d'aretes total (reelles+virtuelles).
virtual void creer_tableau_elements(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
creation d'un tableau parallele de valeurs aux elements.
int nb_faces_elem(int=0) const
Renvoie le nombre de face de type i des elements geometriques constituants le domaine.
const DoubleTab_t & coord_sommets() const
int_t elem_aretes(int_t i, int j) const
renvoie le numero de la jeme arete du ieme element.
int_t nb_som_tot() const
Renvoie le nombre total de sommets du domaine i.e. le nombre de sommets reels et virtuels sur le proc...
void W2(const DoubleTab *nu, int e, DoubleTab &w2) const
int W_stabiliser(DoubleTab &W, DoubleTab &R, DoubleTab &N, int *ctr, double *spectre) const
double dot(const double *a, const double *b, const double *ma=nullptr, const double *mb=nullptr) const
void discretiser() override
void ajouter_stabilisation(DoubleTab &M, DoubleTab &N) const
void calculer_volumes_entrelaces() override
std::map< std::string, int > is_init
void M2(const DoubleTab *nu, int e, DoubleTab &m2) const
void init_equiv() const override
void init_virt_ef_map() const
std::map< std::array< int, 2 >, int > virt_ef_map
void modifier_pour_Cl(const Conds_lim &) override
void calculer_h_carre() override
DoubleVect longueur_aretes_
const Elem_poly_base & type_elem() const
const DoubleVect & longueur_aretes() const
void discretiser_aretes()
std::vector< std::map< int, int > > som_arete
void discretiser() override
double nu_dot(const DoubleTab *nu, int e, int n, const double *a, const double *b, const double *ma=nullptr, const double *mb=nullptr) const
virtual const DoubleVect & face_surfaces() const
int nb_faces() const
renvoie le nombre global de faces.
IntTab & face_sommets() override
renvoie le tableau de connectivite faces/sommets.
DoubleVect volumes_entrelaces_
int nb_faces_tot() const
renvoie le nombre total de faces.
void creer_tableau_faces(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
IntTab & elem_faces()
renvoie le tableau de connectivite element/faces
virtual const IntVect & orientation() const
std::array< double, 3 > cross(int dima, int dimb, const double *a, const double *b, const double *ma=nullptr, const double *mb=nullptr) const
DoubleTab volumes_entrelaces_dir_
virtual DoubleTab & face_normales()
IntTab & face_voisins() override
renvoie le tableaux des volumes des connectivites face elements cf au dessus.
void marquer_faces_double_contrib(const Conds_lim &)
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
const Domaine & domaine() const
Une entree dont la source est une chaine de caracteres.
Class defining operators and methods for all reading operation in an input flow (file,...
int num_premiere_face() const
int num_face(const int) const
static double inverse(const Matrice33 &m, Matrice33 &resu, int exit_on_error=1)
calcul de l'inverse.
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
classe Periodique Cette classe represente une condition aux limites periodique.
int face_associee(int i) const
static double mp_min(double)
static double mp_max(double)
static Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
static double mp_sum_as_double(int v)
static void barrier()
Synchronise tous les processeurs du groupe courant (attend que tous les processeurs soient arrives a ...
static int me()
renvoie mon rang dans le groupe de communication courant.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Classe de base des flux de sortie.
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension_tot(int) const override
_SIZE_ dimension(int d) const
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")