98 if (!matrices.count(nom_inco))
102 const IntTab& e_f = domaine.elem_faces(), &f_s = domaine.face_sommets(), &e_a = domaine.domaine().elem_aretes(), &fcl = ch.
fcl();
108 ConstDoubleTab_parts p_inco(ch.
valeurs());
111 N_nu =
nu_.line_size(), semi = (int) semi_impl.count(nom_inco);
113 Stencil stencil(0, 2);
115 Cerr <<
"Op_Diff_PolyMAC_HFV_Face::dimensionner() : ";
118 if (!semi && !aux_only)
119 for (
int f = 0; f < domaine.nb_faces(); f++)
120 for (
int i = 0; i < f_s.dimension(1); i++)
122 const int s = f_s(f, i);
125 const int a = D < 3 ? s :
126 domaine.som_arete[s].at(f_s(f, i + 1 < f_s.dimension(1) && f_s(f, i + 1) >= 0 ? i + 1 : 0));
128 for (
int n = 0; n < N; n++)
129 stencil.
append_line(N * f + n, N * (nf_tot + a) + n);
133 Matrice33 L(0, 0, 0, 0, 0, 0, 0, 0, D < 3), iL;
135 DoubleTrav inu, m2, w1, v_e, v_ea;
138 nu_.nb_dim() == 3 ? inu.
resize(1, N, D) :
142 for (
int e = 0; e < domaine.nb_elem_tot(); e++)
145 if (
nu_.nb_dim() < 4)
147 for (
int i = 0; i < N_nu; i++)
148 inu.
addr()[i] = 1. /
nu_.addr()[N_nu * e + i];
152 for (
int n = 0; n < N; n++)
154 for (
int d = 0; d < D; d++)
155 for (
int db = 0; db < D; db++)
156 L(d, db) =
nu_(e, n, d, db);
160 for (
int d = 0; d < D; d++)
161 for (
int db = 0; db < D; db++)
162 inu(0, n, d, db) = iL(d, db);
166 domaine.M2(&inu, e, m2);
169 domaine.W1(&
nu_, e, w1, v_e, v_ea);
173 for (
int i = 0; i < m2.
dimension(0); i++)
175 const int f = e_f(e, i);
177 for (
int j = 0; j < f_s.dimension(1); j++)
179 const int s = f_s(f, j);
182 const int a = D < 3 ? s : domaine.som_arete[s].at(f_s(f, j + 1 < f_s.dimension(1) && f_s(f, j + 1) >= 0 ? j + 1 : 0));
184 if (a < (D < 3 ? domaine.domaine().nb_som() : domaine.domaine().nb_aretes()))
185 for (
int k = 0; k < m2.
dimension(1); k++)
187 const int fb = e_f(e, k);
188 for (
int n = 0; n < N; n++)
189 if (fcl(f, 0) == 2 || m2(i, k, n))
190 stencil.
append_line(N * (nf_tot + a) + n, N * fb + n);
197 for (
int i = 0; i < w1.
dimension(0); i++)
199 const int a = e_a(e, i);
201 if (a < domaine.domaine().nb_aretes())
202 for (
int j = 0; j < w1.
dimension(1); j++)
204 const int ab = e_a(e, j);
205 for (
int n = 0; n < N; n++)
207 stencil.
append_line(N * (!aux_only * nf_tot + a) + n, N * (!aux_only * nf_tot + ab) + n);
212 for (
int s = 0; s < (D < 3 ? domaine.nb_som() : domaine.domaine().nb_aretes()); s++)
213 for (
int n = 0; n < N; n++)
214 stencil.
append_line(N * (!aux_only * nf_tot + s) + n, N * (!aux_only * nf_tot + s) + n);
216 tableau_trier_retirer_doublons(stencil);
218 Cerr <<
"OK" << finl;
235 const IntTab& e_f = domaine.elem_faces(), &f_s = domaine.face_sommets(), &e_a = domaine.domaine().elem_aretes(),
236 &fcl = ch.
fcl(), &f_e = domaine.face_voisins();
239 Matrice_Morse *mat = matrices.count(nom_inco) ? matrices.at(nom_inco) :
nullptr;
244 N_nu =
nu_.line_size(), semi = (int) semi_impl.count(nom_inco);
246 double vecz[3] = { 0, 0, 1 }, v_cl[3];
249 const DoubleTab& xp = domaine.xp(), &xv = domaine.xv(), &xs = domaine.domaine().coord_sommets(),
250 &xa = D < 3 ? xs : domaine.xa(), &ta = domaine.ta(), &nf = domaine.face_normales(),
251 &inco = semi_impl.count(nom_inco) ? semi_impl.at(nom_inco) : ch.
valeurs();
253 const DoubleVect& la = domaine.longueur_aretes(), &vf = domaine.volumes_entrelaces(), &fs = domaine.face_surfaces(), &ve = domaine.volumes();
258 else if (mat && !semi)
266 ConstDoubleTab_parts p_inco(inco);
272 for (
int f = 0; f < domaine.nb_faces(); f++)
273 for (
int i = 0; i < f_s.dimension(1); i++)
275 const int s = f_s(f, i);
278 const int a = D < 3 ? s : domaine.som_arete[s].at(f_s(f, i + 1 < f_s.dimension(1) && f_s(f, i + 1) >= 0 ? i + 1 : 0));
280 auto vec = domaine.cross(3, D, D < 3 ? vecz : &ta(a, 0), &xv(f, 0),
nullptr, &xa(a, 0));
282 const int sgn = domaine.dot(&nf(f, 0), &vec[0]) > 0 ? 1 : -1;
284 for (
int n = 0; n < N; n++)
285 secmem(f, n) -= sgn * vf(f) / fs(f) * (D < 3 ? 1 : la(a)) * omega(a, n);
288 for (
int n = 0; n < N; n++)
289 (*mat)(N * f + n, N * (nf_tot + a) + n) += sgn * vf(f) / fs(f) * (D < 3 ? 1 : la(a));
293 Matrice33 L(0, 0, 0, 0, 0, 0, 0, 0, D < 3), iL;
294 DoubleTrav dL(N), inu, m2, w1, v_e, v_ea;
296 if (
nu_.nb_dim() == 2)
298 else if (
nu_.nb_dim() == 3)
303 if (!aux_only && mat && semi)
305 for (
int a = 0; a < xa.dimension(0); a++)
306 for (
int n = 0; n < N; n++)
308 secmem(nf_tot + a, n) += omega(a, n) - ch.
valeurs()(nf_tot + a, n);
309 (*mat)(N * (nf_tot + a) + n, N * (nf_tot + a) + n)++;
312 else if (mat && !semi)
313 for (
int e = 0; e < domaine.nb_elem_tot(); e++)
316 if (
nu_.nb_dim() == 2)
318 for (
int n = 0; n < N; n++)
320 inu(0, n) = 1. /
nu_(e, n);
321 dL(n) = std::pow(
nu_(e, n), D);
324 else if (
nu_.nb_dim() == 3)
326 for (
int n = 0; n < N; n++)
329 for (
int d = 0; d < D; d++)
331 inu(0, n, d) = 1. /
nu_(e, n, d);
332 dL(n) *=
nu_(e, n, d);
337 if (
nu_.nb_dim() < 4)
339 for (
int i = 0; i < N_nu; i++)
340 inu.
addr()[i] = 1. /
nu_.addr()[N_nu * e + i];
344 for (
int n = 0; n < N; n++)
346 for (
int d = 0; d < D; d++)
347 for (
int db = 0; db < D; db++)
348 L(d, db) =
nu_(e, n, d, db);
352 for (
int d = 0; d < D; d++)
353 for (
int db = 0; db < D; db++)
354 inu(0, n, d, db) = iL(d, db);
358 domaine.M2(&inu, e, m2);
360 domaine.W1(&
nu_, e, w1, v_e, v_ea);
363 for (
int i = 0; i < m2.
dimension(0); i++)
365 const int f = e_f(e, i);
366 for (
int j = 0; j < f_s.dimension(1); j++)
368 const int s = f_s(f, j);
371 const int a = D < 3 ? s : domaine.som_arete[s].at(f_s(f, j + 1 < f_s.dimension(1) && f_s(f, j + 1) >= 0 ? j + 1 : 0));
373 if (a < (D < 3 ? domaine.domaine().nb_som() : domaine.domaine().nb_aretes()))
375 auto vec = domaine.cross(3, D, D < 3 ? vecz : &ta(a, 0), &xv(f, 0),
nullptr, &xa(a, 0));
377 const int sgn = (e == f_e(f, 0) ? 1 : -1) * domaine.dot(&nf(f, 0), &vec[0]) > 0 ? 1 : -1;
379 for (
int k = 0; k < m2.
dimension(1); k++)
381 const int fb = e_f(e, k);
382 for (
int n = 0; n < N; n++)
384 const double coeff = m2(i, k, n) + (fcl(f, 0) == 2 ? domaine.nu_dot(&inu, 0, n, &xa(a, 0), &xv(fb, 0), &xv(f, 0), &xp(e, 0)) / ve(e) : 0);
389 secmem(!aux_only * nf_tot + a, n) += sgn * coeff * inco(fb, n) * fs(fb) * (e == f_e(fb, 0) ? 1 : -1);
392 (*mat)(N * (nf_tot + a) + n, N * fb + n) -= sgn * coeff * fs(fb) * (e == f_e(fb, 0) ? 1 : -1);
396 if (fcl(f, 0) == 3 && sub_type(
Dirichlet, cls[fcl(f, 1)].valeur()))
397 for (
int n = 0; n < N; n++)
399 for (
int d = 0; d < D; d++)
400 v_cl[d] = ref_cast(
Dirichlet, cls[fcl(f, 1)].valeur()).val_imp(fcl(f, 2), N * d + n);
402 secmem(!aux_only * nf_tot + a, n) += sgn * domaine.nu_dot(&inu, 0, n, &xa(a, 0), v_cl, &xv(f, 0));
411 for (
int i = 0; i < e_f.
dimension(1); i++)
413 const int f = e_f(e, i);
416 for (
int j = 0; j < 2; j++)
418 const int s = f_s(f, j);
419 if (s < domaine.nb_som())
421 auto vec = domaine.cross(D, D, &xv(f, 0), &xs(s, 0), &xp(e, 0), &xp(e, 0));
423 const double surf = std::abs(vec[2]) / 2.;
425 for (
int n = 0; n < N; n++)
426 secmem(!aux_only * nf_tot + s, n) -= surf * inco(nf_tot + s, n) / dL(n);
428 for (
int n = 0; n < N; n++)
429 (*mat)(N * (!aux_only * nf_tot + s) + n, N * (!aux_only * nf_tot + s) + n) += surf / dL(n);
435 for (
int i = 0; i < w1.
dimension(0); i++)
437 const int a = e_a(e, i);
439 if (a < domaine.domaine().nb_aretes())
440 for (
int j = 0; j < w1.
dimension(1); j++)
442 const int ab = e_a(e, j);
443 for (
int n = 0; n < N; n++)
446 secmem(!aux_only * nf_tot + a, n) -= w1(i, j, n) * la(ab) * inco(nf_tot + ab, n) / dL(n);
447 (*mat)(N * (!aux_only * nf_tot + a) + n, N * (!aux_only * nf_tot + ab) + n) += w1(i, j, n) * la(ab) / dL(n);