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 has been filled successfully" << 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 <<
"Non-stabilized matrix: warning, the mesh is too deformed!!" << 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));
class Cond_lim_base Base class for the hierarchy of classes that represent the different boundary con...
virtual Frontiere_dis_base & frontiere_dis()
Returns the discretized boundary to which the boundary conditions apply.
class Conds_lim This class represents a vector of boundary conditions.
int_t nb_aretes_tot() const
returns the total number of edges (real+virtual).
virtual void creer_tableau_elements(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
Creates a parallel array of values at elements.
int nb_faces_elem(int=0) const
Returns the number of faces of type i of the geometric elements that make up the domain.
const DoubleTab_t & coord_sommets() const
int_t elem_aretes(int_t i, int j) const
returns the number of the j-th edge of the i-th element.
int_t nb_som_tot() const
Returns the total number of vertices of the domain i.e. the number of real and virtual vertices on th...
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
Returns the total number of faces.
IntTab & face_sommets() override
Returns the face/vertex connectivity array.
DoubleVect volumes_entrelaces_
int nb_faces_tot() const
Returns the total number of faces.
void creer_tableau_faces(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
IntTab & elem_faces()
Returns the element/face connectivity array.
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
Returns the face-element connectivity array; see above.
void marquer_faces_double_contrib(const Conds_lim &)
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
const Domaine & domaine() const
An input stream whose source is a character string.
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)
Computes the inverse.
const Nom & que_suis_je() const
Returns the string identifying the class.
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
class Periodique This class represents a periodic boundary condition.
int face_associee(int i) const
static double mp_min(double)
static double mp_max(double)
static Sortie & Journal(int message_level=0)
Returns a static Sortie object used as an event journal.
static double mp_sum_as_double(int v)
static void barrier()
Synchronizes all processors in the current group (waits until all processors have reached the barrier...
static int me()
Returns the rank of the local processor in the current communication group. See Comm_Group::rank() an...
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Base class for output streams.
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")