TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Perte_Charge_PolyMAC_CDO.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Fluide_Incompressible.h>
17#include <Perte_Charge_PolyMAC_CDO.h>
18#include <Champ_Face_PolyMAC_CDO.h>
19#include <Domaine_PolyMAC_MPFA.h>
20#include <Domaine_Cl_PolyMAC_family.h>
21#include <Schema_Temps_base.h>
22#include <Champ_Uniforme.h>
23#include <Equation_base.h>
24#include <Probleme_base.h>
25#include <Sous_Domaine.h>
26#include <Param.h>
27
28Implemente_base(Perte_Charge_PolyMAC_CDO, "Perte_Charge_PolyMAC_CDO", Perte_Charge_Gen);
29
30Sortie& Perte_Charge_PolyMAC_CDO::printOn(Sortie& s) const { return s << que_suis_je() << finl; }
31
33
34DoubleTab& Perte_Charge_PolyMAC_CDO::ajouter(DoubleTab& resu) const
35{
36 if (has_interface_blocs()) return Source_base::ajouter(resu); // for derived classes
37
38 const Domaine_PolyMAC_CDO& domaine = le_dom_poly();
39 const Champ_Face_PolyMAC_CDO& ch = ref_cast(Champ_Face_PolyMAC_CDO, equation().inconnue());
40 const Champ_Don_base& nu = le_fluide->viscosite_cinematique(), &dh = diam_hydr;
41 const DoubleTab& xp = domaine.xp(), &xv = domaine.xv(), &vit = la_vitesse->valeurs();
42 const DoubleVect& pe = equation().milieu().porosite_elem(), &pf = equation().milieu().porosite_face(), &fs = domaine.face_surfaces();
43 const Sous_Domaine *pssz = sous_domaine ? &le_sous_domaine.valeur() : nullptr;
44 const IntTab& e_f = domaine.elem_faces(), &f_e = domaine.face_voisins();
45 int i, j, k, f, fb, r, C_nu = sub_type(Champ_Uniforme, nu), C_dh = sub_type(Champ_Uniforme, diam_hydr.valeur());
46 double t = equation().schema_temps().temps_courant();
47 DoubleVect pos(dimension), ve(dimension), dir(dimension);
48
49 /* contribution of each element where the pressure drop is applied */
50 for (i = 0; i < (pssz ? pssz->nb_elem_tot() : domaine.nb_elem_tot()); i++)
51 {
52 int e = pssz ? (*pssz)[i] : i;
53 for (r = 0; r < dimension; r++)
54 pos(r) = xp(e, r);
55
56 /* values evaluated at the element: nu, Dh, velocity vector, Re, isotropic and directional pressure drop coefficients + the direction */
57 double nu_e = C_nu ? nu.valeurs()(0, 0) : nu.valeur_a_compo(pos, 0), dh_e = C_dh ? dh.valeurs()(0, 0) : dh.valeur_a_compo(pos, 0);
58 for (j = domaine.vedeb(e), ve = 0; j < domaine.vedeb(e + 1); j++)
59 for (r = 0; r < dimension; r++)
60 fb = domaine.veji(j), ve(r) += domaine.veci(j, r) * vit(fb) * pf(fb) / pe(e);
61 double n_ve = sqrt(domaine.dot(ve.addr(), ve.addr())), Re = std::max(n_ve * dh_e / nu_e, 1e-10), C_iso, C_dir, v_dir;
62 coeffs_perte_charge(ve, pos, t, n_ve, dh_e, nu_e, Re, C_iso, C_dir, v_dir, dir);
63
64 /* contributions at faces of e */
65 for (j = 0; j < e_f.dimension(1) && (f = e_f(e, j)) >= 0; j++)
66 if (f < domaine.nb_faces() && ch.fcl()(f, 0) < 2)
67 {
68 double m2vf = 0, contrib;
69 for (k = domaine.m2i(domaine.m2d(e) + j); k < domaine.m2i(domaine.m2d(e) + j + 1); k++)
70 fb = e_f(e, domaine.m2j(k)), m2vf += pf(f) * (e == f_e(f, 0) ? 1 : -1) * (e == f_e(fb, 0) ? 1 : -1) * domaine.volumes(e) * domaine.m2c(k) * vit(fb) * pf(fb) / pe(e);
71 contrib = C_iso * m2vf + fs(f) * pf(f) * (C_dir - C_iso) * domaine.dot(&ve(0), &dir(0)) * (e == f_e(f, 0) ? 1 : -1) * domaine.dot(&xv(f, 0), &dir(0), &xp(e, 0));
72 if (contrib <= std::min(C_dir, C_iso) * m2vf)
73 contrib = std::min(C_dir, C_iso) * m2vf; //to guarantee a minimum friction
74 resu(f) -= contrib;
75 }
76 }
77 return resu;
78}
79
80void Perte_Charge_PolyMAC_CDO::contribuer_a_avec(const DoubleTab& inco, Matrice_Morse& matrice) const
81{
82 if (has_interface_blocs()) // for derived classes
83 {
84 Source_base::contribuer_a_avec(inco, matrice);
85 return;
86 }
87
88 const Domaine_PolyMAC_CDO& domaine = le_dom_poly();
89 const Champ_Face_PolyMAC_CDO& ch = ref_cast(Champ_Face_PolyMAC_CDO, equation().inconnue());
90 const Champ_Don_base& nu = le_fluide->viscosite_cinematique(), &dh = diam_hydr;
91 const DoubleTab& xp = domaine.xp(), &xv = domaine.xv(), &vit = inco;
92 const DoubleVect& pe = equation().milieu().porosite_elem(), &pf = equation().milieu().porosite_face(), &fs = domaine.face_surfaces();
93 const Sous_Domaine *pssz = sous_domaine ? &le_sous_domaine.valeur() : nullptr;
94 const IntTab& e_f = domaine.elem_faces(), &f_e = domaine.face_voisins();
95 int i, j, k, f, fb, r, C_nu = sub_type(Champ_Uniforme, nu), C_dh = sub_type(Champ_Uniforme, diam_hydr.valeur());
96 double t = equation().schema_temps().temps_courant();
97 DoubleVect pos(dimension), ve(dimension), dir(dimension);
98
99 for (i = 0; i < (pssz ? pssz->nb_elem_tot() : domaine.nb_elem_tot()); i++)
100 {
101 int e = pssz ? (*pssz)[i] : i;
102 for (r = 0; r < dimension; r++)
103 pos(r) = xp(e, r);
104
105 /* values evaluated at the element: nu, Dh, velocity vector, Re, isotropic and directional pressure drop coefficients + the direction */
106 double nu_e = C_nu ? nu.valeurs()(0, 0) : nu.valeur_a_compo(pos, 0), dh_e = C_dh ? dh.valeurs()(0, 0) : dh.valeur_a_compo(pos, 0);
107 for (j = domaine.vedeb(e), ve = 0; j < domaine.vedeb(e + 1); j++)
108 for (r = 0; r < dimension; r++)
109 fb = domaine.veji(j), ve(r) += domaine.veci(j, r) * vit(fb) * pf(fb) / pe(e);
110 double n_ve = sqrt(domaine.dot(ve.addr(), ve.addr())), Re = std::max(n_ve * dh_e / nu_e, 1e-10), C_iso, C_dir, v_dir;
111 coeffs_perte_charge(ve, pos, t, n_ve, dh_e, nu_e, Re, C_iso, C_dir, v_dir, dir);
112
113 /* contributions at faces of e */
114 for (j = 0; j < e_f.dimension(1) && (f = e_f(e, j)) >= 0; j++)
115 if (f < domaine.nb_faces() && ch.fcl()(f, 0) < 2)
116 {
117 double m2vf = 0, contrib;
118 for (k = domaine.m2i(domaine.m2d(e) + j); k < domaine.m2i(domaine.m2d(e) + j + 1); k++)
119 fb = e_f(e, domaine.m2j(k)), m2vf += pf(f) * (e == f_e(f, 0) ? 1 : -1) * (e == f_e(fb, 0) ? 1 : -1) * domaine.volumes(e) * domaine.m2c(k) * vit(fb) * pf(fb) / pe(e);
120 contrib = C_iso * m2vf + fs(f) * pf(f) * (C_dir - C_iso) * domaine.dot(&ve(0), &dir(0)) * (e == f_e(f, 0) ? 1 : -1) * domaine.dot(&xv(f, 0), &dir(0), &xp(e, 0));
121 if (contrib >= std::min(C_dir, C_iso) * m2vf)
122 {
123 for (k = domaine.m2i(domaine.m2d(e) + j); k < domaine.m2i(domaine.m2d(e) + j + 1); k++)
124 if (ch.fcl()(fb = e_f(e, domaine.m2j(k)), 0) < 2)
125 matrice(f, fb) += C_iso * pf(f) * (e == f_e(f, 0) ? 1 : -1) * (e == f_e(fb, 0) ? 1 : -1) * domaine.volumes(e) * domaine.m2c(k) * pf(fb) / pe(e);
126 for (k = domaine.vedeb(e); k < domaine.vedeb(e + 1); k++)
127 if (ch.fcl()(fb = domaine.veji(k), 0) < 2)
128 matrice(f, fb) += fs(f) * pf(f) * (C_dir - C_iso) * domaine.dot(&domaine.veci(k, 0), &dir(0)) * pf(fb) / pe(e) * (e == f_e(f, 0) ? 1 : -1)
129 * domaine.dot(&xv(f, 0), &dir(0), &xp(e, 0));
130 }
131 else
132 {
133 for (k = domaine.m2i(domaine.m2d(e) + j); k < domaine.m2i(domaine.m2d(e) + j + 1); k++)
134 if (ch.fcl()(fb = e_f(e, domaine.m2j(k)), 0) < 2)
135 matrice(f, fb) += std::min(C_dir, C_iso) * pf(f) * (e == f_e(f, 0) ? 1 : -1) * (e == f_e(fb, 0) ? 1 : -1) * domaine.volumes(e) * domaine.m2c(k) * pf(fb) / pe(e);
136 }
137 }
138 }
139}
140
class Champ_Don_base base class of Given Fields (not calculated)
DoubleTab & valeurs() override
Overrides Champ_base::valeurs() Returns the array of values.
const IntTab & fcl() const
Champ_Uniforme Represents a field that is constant in space and time.
virtual double valeur_a_compo(const DoubleVect &position, int ncomp) const
Computes the point value of the component "compo" of the field at the point with coordinates pos.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual const Milieu_base & milieu() const =0
Schema_Temps_base & schema_temps()
Returns the time scheme associated with the equation.
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
DoubleVect & porosite_elem()
Definition Milieu_base.h:58
DoubleVect & porosite_face()
Definition Milieu_base.h:62
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
static int dimension
Definition Objet_U.h:94
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
virtual void coeffs_perte_charge(const DoubleVect &u, const DoubleVect &pos, double t, double norme_u, double dh, double nu, double reynolds, double &coeff_ortho, double &coeff_long, double &u_l, DoubleVect &v_valeur) const =0
Called for each face by ajouter().
bool sous_domaine
Is the term limited to a sub-domain?
Factorises the features of several pressure drop classes in VEF, face velocity.
DoubleTab & ajouter(DoubleTab &) const override
Calls perte_charge for each face where it is necessary.
const Domaine_PolyMAC_CDO & le_dom_poly() const
void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const override
contribution to the implicit matrix of source terms, by default no contribution
double temps_courant() const
Returns the current time.
Base class for output streams.
Definition Sortie.h:52
virtual void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const
contribution to the implicit matrix of source terms, by default no contribution
virtual int has_interface_blocs() const
Definition Source_base.h:68
virtual DoubleTab & ajouter(DoubleTab &) const
int_t nb_elem_tot() const
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133