119 const std::string& nom_inco = (le_champ_inco ? le_champ_inco.valeur() :
equation().inconnue()).le_nom().getString();
120 int i, j, k, l, e, o_e, f, o_f, fb, m, n, M, n_ext = (int)
op_ext.size(), n_sten = 0, semi = (int) semi_impl.count(nom_inco);
122 std::vector<Matrice_Morse*> mat(n_ext);
123 std::vector<int> N, ne_tot;
124 std::vector<std::reference_wrapper<const Domaine_PolyMAC_HFV>> domaine;
125 std::vector<std::reference_wrapper<const Conds_lim>> cls;
126 std::vector<std::reference_wrapper<const IntTab>> fcl, e_f, f_e;
127 std::vector<std::reference_wrapper<const DoubleTab>> diffu, inco;
128 std::deque<ConstDoubleTab_parts> v_part;
129 std::vector<Stencil> stencil(n_ext);
130 for (i = 0, M = 0; i < n_ext; M = std::max(M, N[i]), i++)
132 std::string nom_mat = i ? nom_inco +
"/" +
op_ext[i]->equation().probleme().le_nom().getString() : nom_inco;
133 mat[i] = matrices.count(nom_mat) ? matrices.at(nom_mat) :
nullptr;
135 f_e.push_back(std::ref(domaine[i].get().face_voisins())), e_f.push_back(std::ref(domaine[i].get().elem_faces()));
136 cls.push_back(std::ref(
op_ext[i]->
equation().domaine_Cl_dis().les_conditions_limites()));
140 N.push_back(ch.
valeurs().
line_size()), fcl.push_back(std::ref(ch.
fcl())), ne_tot.push_back(domaine[i].get().nb_elem_tot());
142 stencil[i].resize(0, 2);
146 IntTrav tpfa(0, N[0]);
147 domaine[0].get().creer_tableau_faces(tpfa), tpfa = 1;
150 Cerr <<
"Op_Diff_PolyMAC_HFV_Elem::dimensionner() : ";
153 for (e = 0; e < ne_tot[0]; e++)
155 domaine[0].get().W2(&diffu[0].get(), e, w2);
157 if (!aux_only && !semi)
159 if (!semi && fcl[0](f = e_f[0](e, i), 0) < 6)
161 if (e < domaine[0].get().nb_elem())
162 for (n = 0; n < N[0]; n++)
163 stencil[0].append_line(N[0] * e + n, N[0] * (ne_tot[0] + f) + n);
164 if (f < domaine[0].get().nb_faces())
165 for (n = 0; n < N[0]; n++)
166 stencil[0].append_line(N[0] * (ne_tot[0] + f) + n, N[0] * e + n);
170 if ((f = e_f[0](e, i)) >= domaine[0].get().nb_faces())
172 else if (semi || fcl[0](f = e_f[0](e, i), 0) > 5)
173 for (n = 0; n < N[0]; n++)
174 stencil[0].append_line(N[0] * (!aux_only * ne_tot[0] + f) + n, N[0] * (!aux_only * ne_tot[0] + f) + n);
177 for (fb = e_f[0](e, j), n = 0; n < N[0]; n++)
178 if (fcl[0](fb, 0) < 6 && w2(i, j, n))
179 stencil[0].append_line(N[0] * (!aux_only * ne_tot[0] + f) + n, N[0] * (!aux_only * ne_tot[0] + fb) + n), tpfa(f, n) &= (i == j);
184 for (i = 0; i < cls[0].get().size(); i++)
188 f = pcl->fvf->num_face(j), o_f = pcl->
f_dist(j), o_e = f_e[p](o_f, 0);
189 domaine[p].get().W2(&diffu[p].get(), o_e, w2);
190 k = (int) (std::find(&e_f[p](o_e, 0), &e_f[p](o_e, 0) + w2.
dimension(0), o_f) - &e_f[p](o_e, 0));
192 for (n = 0; n < N[0]; n++)
193 for (m = (N[0] == N[p]) * n; m < (N[0] == N[p] ? n + 1 : N[p]); m++)
194 stencil[p].append_line(N[0] * (ne_tot[0] + f) + n, N[p] * o_e + m);
196 if (fcl[p](fb = e_f[p](o_e, l), 0) < 6)
197 for (n = 0; n < N[0]; n++)
198 for (m = (N[0] == N[p]) * n; m < (N[0] == N[p] ? n + 1 : N[p]); m++)
200 stencil[p].
append_line(N[0] * (!aux_only * ne_tot[0] + f) + n, N[p] * (!aux_only * ne_tot[p] + fb) + m);
203 for (i = 0; i < n_ext; i++)
206 tableau_trier_retirer_doublons(stencil[i]);
208 Matrix_tools::allocate_morse_matrix(aux_only ? v_part[0][1].size_totale() : inco[0].get().size_totale(), aux_only ? v_part[i][1].size_totale() : inco[i].get().size_totale(), stencil[i], mat2);
209 mat[i]->nb_colonnes() ? *mat[i] += mat2 : *mat[i] = mat2;
212 for (
auto &&st : stencil)
216 const double elem_face_t =
static_cast<double>(domaine[0].get().mdv_elems_faces->nb_items_seq_tot()),
217 face_t =
static_cast<double>(domaine[0].get().md_vector_faces()->nb_items_seq_tot());
219 << mp_somme_vect_as_double(tpfa) * 100. / (N[0] * face_t) <<
"% TPFA " << finl;
226 const std::string& nom_inco = (le_champ_inco ? le_champ_inco.valeur() :
equation().inconnue()).le_nom().getString();
227 int i, j, k1, k2, e, f, fb, n, M, n_ext = (int)
op_ext.size(), semi = (int) semi_impl.count(nom_inco), d, D =
dimension;
228 std::vector<Matrice_Morse*> mat(n_ext);
229 std::vector<int> N, ne_tot;
230 std::vector<std::reference_wrapper<const Domaine_PolyMAC_HFV>> domaine;
231 std::vector<std::reference_wrapper<const Conds_lim>> cls;
232 std::vector<std::reference_wrapper<const IntTab>> fcl, e_f, f_e, f_s;
233 std::vector<std::reference_wrapper<const DoubleVect>> fs, pf, pe, ve;
234 std::vector<std::reference_wrapper<const DoubleTab>> inco, xp, xv, diffu, v_aux;
235 std::deque<ConstDoubleTab_parts> v_part;
236 std::vector<const Flux_parietal_base*> corr;
237 for (i = 0, M = 0; i < n_ext; M = std::max(M, N[i]), i++)
239 std::string nom_mat = i ? nom_inco +
"/" +
op_ext[i]->equation().probleme().le_nom().getString() : nom_inco;
240 mat[i] = matrices.count(nom_mat) ? matrices.at(nom_mat) :
nullptr;
242 f_e.push_back(std::ref(domaine[i].get().face_voisins())), e_f.push_back(std::ref(domaine[i].get().elem_faces())), f_s.push_back(std::ref(domaine[i].get().face_sommets()));
243 fs.push_back(std::ref(domaine[i].get().face_surfaces()));
244 xp.push_back(std::ref(domaine[i].get().xp())), xv.push_back(std::ref(domaine[i].get().xv()));
245 pe.push_back(std::ref(
equation().milieu().porosite_elem())), pf.push_back(std::ref(
equation().milieu().porosite_face())), ve.push_back(std::ref(domaine[i].get().volumes()));
246 cls.push_back(std::ref(
op_ext[i]->
equation().domaine_Cl_dis().les_conditions_limites()));
249 inco.push_back(std::ref(semi_impl.count(nom_mat) ? semi_impl.at(nom_mat) : ch.
valeurs())), v_part.emplace_back(inco.back());
253 N.push_back(inco[i].get().line_size()), ne_tot.push_back(domaine[i].get().nb_elem_tot()), fcl.push_back(std::ref(ch.
fcl()));
260 else if (mat[0] && !semi)
264 for (i = 0; i < n_ext; i++)
267 DoubleTrav w2, flux(N[0]), acc(N[0]);
268 for (e = 0; e < ne_tot[0]; e++)
270 domaine[0].get().W2(&diffu[0].get(), e, w2);
274 for (f = e_f[0](e, i), flux = 0, j = 0; j < w2.
dimension(1); j++)
275 for (fb = e_f[0](e, j), n = 0; n < N[0]; n++)
276 flux(n) += w2(i, j, n) * (v_aux[0](fb, n) - inco[0](e, n));
277 if (!semi && fcl[0](f, 0) < 6)
278 for (n = 0; n < N[0]; n++)
279 secmem(!aux_only * ne_tot[0] + f, n) -= flux(n);
281 for (n = 0; n < N[0]; n++)
282 secmem(e, n) += flux(n);
283 if (!aux_only && f < domaine[0].get().premiere_face_int())
284 for (n = 0; n < N[0]; n++)
291 for (acc = 0, i = 0; i < w2.
dimension(0); i++)
293 for (n = 0; n < N[0]; n++)
294 acc(n) += w2(i, j, n);
295 if (!aux_only && e < domaine[0].get().nb_elem())
296 for (n = 0; n < N[0]; n++)
297 (*mat[0])(N[0] * e + n, N[0] * e + n) += acc(n);
301 if (fcl[0](f = e_f[0](e, i), 0) < 6)
303 for (acc = 0, j = 0; j < w2.
dimension(1); j++)
304 for (n = 0; n < N[0]; n++)
305 acc(n) += w2(i, j, n);
306 if (f < domaine[0].get().nb_faces())
307 for (n = 0; n < N[0]; n++)
308 (*mat[0])(N[0] * (ne_tot[0] + f) + n, N[0] * e + n) -= acc(n);
309 if (e < domaine[0].get().nb_elem())
310 for (n = 0; n < N[0]; n++)
311 (*mat[0])(N[0] * e + n, N[0] * (ne_tot[0] + f) + n) -= acc(n);
315 if (fcl[0](f = e_f[0](e, i), 0) < 6 && f < domaine[0].get().nb_faces())
317 if (fcl[0](fb = e_f[0](e, j), 0) < 6)
318 for (n = 0; n < N[0]; n++)
320 (*mat[0])(N[0] * (!aux_only * ne_tot[0] + f) + n, N[0] * (!aux_only * ne_tot[0] + fb) + n) += w2(i, j, n);
324 for (f = 0; f < domaine[0].get().nb_faces(); f++)
325 if (!aux_only && semi && mat[0])
326 for (n = 0; n < N[0]; n++)
327 secmem(ne_tot[0] + f, n) += v_aux[0](f, n) - (le_champ_inco ? le_champ_inco->valeurs() :
equation().inconnue().valeurs())(ne_tot[0] + f, n), (*mat[0])(N[0] * (ne_tot[0] + f) + n,
328 N[0] * (ne_tot[0] + f) + n)++;
329 else if (fcl[0](f, 0) == 0 || fcl[0](f, 0) == 5)
333 if (fcl[0](f, 0) == 2)
336 int o_p = ech ? ech->o_idx : -1, o_f = ech ? ech->f_dist(fcl[0](f, 2)) : -1;
344 DoubleTrav qpk(N[0]), dTf_qpk(N[0], N[0]), dTp_qpk(N[0]), qpi(N[0], N[0]), dTf_qpi(N[0], N[0], N[0]), dTp_qpi(N[0], N[0]), v(N[0], D), nv(N[0]);
345 in.
N = N[0], in.
f = f, in.
D_h = dh(e), in.
D_ch = dh(e), in.
alpha = &alpha(e, 0), in.
T = &v_aux[0](f, 0), in.
p = press(e), in.
v = nv.
addr(), in.
lambda = &lambda(e, 0), in.
mu = &mu(e, 0), in.
rho =
346 &rho(e, 0), in.
Cp = &Cp(e, 0);
348 for (e = f_e[0](f, 0), i = 0; i < e_f[0].get().
dimension(1) && (fb = e_f[0](e, i)) >= 0; i++)
349 for (prefac = fs[0](fb) * pf[0](fb) * (e == f_e[0](fb, 0) ? 1 : -1) / (pe[0](e) * ve[0](e)), n = 0; n < N[0]; n++)
350 for (fac = prefac * vit(fb, n), d = 0; d < D; d++)
351 v(n, d) += fac * (xv[0](fb, d) - xp[0](e, d));
352 for (n = 0; n < N[0]; n++)
353 nv(n) = sqrt(domaine[0].get().dot(&v(n, 0), &v(n, 0)));
355 double h_imp = fcl[0](f, 0) == 1 ? ref_cast(
Echange_impose_base, cls[0].get()[fcl[0](f, 1)].valeur()).h_imp(fcl[0](f, 2), 0) : 0, T_ext =
356 fcl[0](f, 0) == 1 ? ref_cast(
Echange_impose_base, cls[0].get()[fcl[0](f, 1)].valeur()).T_ext(fcl[0](f, 2), 0) : 0, dTp, FT, dFTp;
357 in.
Tp = ech ? v_aux[o_p](o_f, 0) : fcl[0](f, 0) == 5 ? 0 : fcl[0](f, 0) == 6 ? ref_cast(
Dirichlet, cls[0].get()[fcl[0](f, 1)].valeur()).val_imp(fcl[0](f, 2), 0) :
358 fcl[0](f, 0) == 1 ? T_ext : v_aux[0](f, 0);
361 for (
int it = 0; it < 10 && (!it || std::abs(dTp) > 1e-5); in.
Tp += dTp, it++)
363 corr[0]->qp(in, out);
364 for (FT = 0, dFTp = 0; n < N[0]; n++)
365 FT += qpk(n), dFTp += dTp_qpk(n);
366 dTp = fcl[0](f, 0) == 5 ? (ref_cast(
Neumann, cls[0].get()[fcl[0](f, 1)].valeur()).flux_impose(fcl[0](f, 2), 0) - FT) / dFTp :
367 fcl[0](f, 0) == 1 ? (h_imp * (T_ext - in.
Tp) - FT) / (dFTp + h_imp) : 0;
369 for (n = 0; n < N[0]; n++)
370 secmem(!aux_only * ne_tot[0] + f, n) += fs[0](f) * qpk(n);
372 for (k1 = 0; k1 < N[0]; k1++)
373 for (k2 = 0; k2 < N[0]; k2++)
374 (*mat[0])(N[0] * (!aux_only * ne_tot[0] + f) + k1, N[0] * (!aux_only * ne_tot[0] + f) + k2) -= fs[0](f) * dTf_qpk(k1, k2);
376 for (n = 0; n < N[0]; n++)
377 (*mat[o_p])(N[0] * (!aux_only * ne_tot[0] + f) + n, !aux_only * ne_tot[o_p] + o_f) -= fs[0](f) * dTp_qpk(n);
379 else if (fcl[0](f, 0) > 5)
380 for (n = 0; n < N[0]; n++)
382 secmem(!aux_only * ne_tot[0] + f, n) += (fcl[0](f, 0) == 6 ? ref_cast(
Dirichlet, cls[0].get()[fcl[0](f, 1)].valeur()).val_imp(fcl[0](f, 2), n) : 0) - v_aux[0](f, n);
384 (*mat[0])(N[0] * (!aux_only * ne_tot[0] + f) + n, N[0] * (!aux_only * ne_tot[0] + f) + n)++;
386 else if (fcl[0](f, 0) == 3)
389 int o_p = ech.o_idx, o_f = ech.f_dist(fcl[0](f, 2)), o_e = f_e[o_p](o_f, 0);
390 if (corr[o_p] || N[o_p] != N[0])
397 DoubleTrav qpk(N[o_p]), dTf_qpk(N[o_p], N[o_p]), dTp_qpk(N[o_p]), qpi(N[o_p], N[o_p]), dTf_qpi(N[o_p], N[o_p], N[o_p]), dTp_qpi(N[o_p], N[o_p]), v(N[o_p], D), nv(N[o_p]);
398 for (i = 0; i < e_f[o_p].get().
dimension(1) && (fb = e_f[o_p](o_e, i)) >= 0; i++)
399 for (prefac = fs[o_p](fb) * pf[o_p](fb) * (o_e == f_e[o_p](fb, 0) ? 1 : -1) / (pe[o_p](o_e) * ve[o_p](o_e)), n = 0; n < N[o_p]; n++)
400 for (fac = prefac * vit(fb, n), d = 0; d < D; d++)
401 v(n, d) += fac * (xv[o_p](fb, d) - xp[o_p](o_e, d));
402 for (n = 0; n < N[o_p]; n++)
403 nv(n) = sqrt(domaine[0].get().dot(&v(n, 0), &v(n, 0)));
408 in.
N = N[o_p], in.
f = o_f, in.
D_h = dh(o_e), in.
D_ch = dh(o_e), in.
alpha = &alpha(o_e, 0), in.
T = &v_aux[o_p](o_f, 0), in.
p = press(e), in.
v = nv.
addr(), in.
Tp = v_aux[0](f, 0), in.
lambda =
409 &lambda(o_e, 0), in.
mu = &mu(o_e, 0), in.
rho = &rho(o_e, 0), in.
Cp = &Cp(o_e, 0);
411 corr[o_p]->qp(in, out);
412 for (n = 0; n < N[o_p]; n++)
413 secmem(!aux_only * ne_tot[0] + f, 0) -= fs[0](f) * qpk(n);
415 for (k1 = 0; k1 < N[o_p]; k1++)
416 for (k2 = 0; k2 < N[o_p]; k2++)
417 (*mat[o_p])(!aux_only * ne_tot[0] + f, N[o_p] * (!aux_only * ne_tot[o_p] + o_f) + k2) += fs[0](f) * dTf_qpk(k1, k2);
419 for (n = 0; n < N[o_p]; n++)
420 (*mat[0])(!aux_only * ne_tot[0] + f, !aux_only * ne_tot[0] + f) += fs[0](f) * dTp_qpk(n);
422 else if (ech.invh_paroi)
423 for (n = 0; n < N[0]; n++)
425 secmem(!aux_only * ne_tot[0] + f, n) -= fs[0](f) / ech.invh_paroi * (v_aux[0](f, n) - v_aux[o_p](o_f, n));
427 (*mat[0])(N[0] * (!aux_only * ne_tot[0] + f) + n, N[0] * (!aux_only * ne_tot[0] + f) + n) += fs[0](f) / ech.invh_paroi;
429 (*mat[o_p])(N[0] * (!aux_only * ne_tot[0] + f) + n, N[o_p] * (!aux_only * ne_tot[o_p] + o_f) + n) -= fs[0](f) / ech.invh_paroi;
432 for (domaine[o_p].get().W2(&diffu[o_p].get(), o_e, w2), i = 0; i < w2.
dimension(0); i++)
433 if (e_f[o_p](o_e, i) == o_f)
435 for (n = 0; n < N[0]; n++)
438 secmem(!aux_only * ne_tot[0] + f, n) -= w2(i, j, n) * (v_aux[o_p * (j != i)](j != i ? e_f[o_p](o_e, j) : f, n) - inco[o_p](o_e, n));
439 if (mat[o_p * (j != i)] && (j == i || fcl[o_p](o_f, 0) < 6))
440 (*mat[o_p * (j != i)])(N[0] * (!aux_only * ne_tot[0] + f) + n, N[0] * (!aux_only * ne_tot[o_p * (j != i)] + (j != i ? e_f[o_p](o_e, j) : f)) + n) += w2(i, j, n);
441 if (!aux_only && mat[o_p])
442 (*mat[o_p])(N[0] * (ne_tot[0] + f) + n, N[0] * o_e + n) -= w2(i, j, n);
445 else if (fcl[0](f, 0) == 4)
446 for (n = 0; n < N[0]; n++)
447 secmem(!aux_only * ne_tot[0] + f, n) += fs[0](f) * ref_cast(
Neumann, cls[0].get()[fcl[0](f, 1)].valeur()).flux_impose(fcl[0](f, 2), n);
448 else if (fcl[0](f, 0) && fcl[0](f, 0) < 3)
449 for (e = f_e[0](f, 0), n = 0; n < N[0]; n++)
452 double h = ech.h_imp(fcl[0](f, 2), n), T = ech.T_ext(fcl[0](f, 2), n);
453 secmem(!aux_only * ne_tot[0] + f, n) -= fs[0](f) * h * ((fcl[0](f, 0) == 1 ? v_aux[0](f, n) : inco[0](e, n)) - T);
454 if (mat[0] && fcl[0](f, 0) == 1)
455 (*mat[0])(N[0] * (!aux_only * ne_tot[0] + f) + n, N[0] * (!aux_only * ne_tot[0] + f) + n) += h * fs[0](f);
456 if (mat[0] && fcl[0](f, 0) == 2 && !aux_only)
457 (*mat[0])(N[0] * (ne_tot[0] + f) + n, N[0] * e + n) += h * fs[0](f);