TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Div_PolyMAC_HFV.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 <Champ_Face_PolyMAC_HFV.h>
17#include <Op_Div_PolyMAC_HFV.h>
18#include <Check_espace_virtuel.h>
19#include <Domaine_Cl_PolyMAC_family.h>
20#include <Navier_Stokes_std.h>
21#include <Schema_Temps_base.h>
22#include <Probleme_base.h>
23#include <EcrFicPartage.h>
24#include <Matrice_Morse.h>
25#include <Matrix_tools.h>
26#include <Array_tools.h>
27#include <Debog.h>
28
29Implemente_instanciable(Op_Div_PolyMAC_HFV, "Op_Div_PolyMAC_HFV", Op_Div_PolyMAC_CDO);
30
31Sortie& Op_Div_PolyMAC_HFV::printOn(Sortie& s) const { return s << que_suis_je(); }
32
34
35void Op_Div_PolyMAC_HFV::dimensionner_blocs(matrices_t matrices, const tabs_t& semi_impl) const
36{
37 const Domaine_PolyMAC_HFV& domaine = ref_cast(Domaine_PolyMAC_HFV, le_dom_PolyMAC_CDO.valeur());
38 const Champ_Face_PolyMAC_HFV& ch = ref_cast(Champ_Face_PolyMAC_HFV, equation().inconnue());
39 const DoubleTab& inco = ch.valeurs(), &press = ref_cast(Navier_Stokes_std, equation()).pression().valeurs();
40 const IntTab& e_f = domaine.elem_faces(), &f_e = domaine.face_voisins(), &fcl = ch.fcl();
41 const int ne_tot = domaine.nb_elem_tot();
42
43 Matrice_Morse *matv = matrices.count("vitesse") ? matrices["vitesse"] : nullptr,
44 *matp = matrices.count("pression") ? matrices["pression"] : nullptr,
45 matv2, matp2;
46
47 Stencil sten_v(0, 2), sten_p(0, 2);
48 DoubleTab w2; //w2 matrix at elements (same as in Op_Grad and Assembleur_P)
49
50 // Dependence on v: divergence per element and v = v_imp at Dirichlet faces
51 if (matv)
52 for (int f = 0; f < domaine.nb_faces(); f++)
53 {
54 if (fcl(f, 0) > 1) // v imposed by boundary conditions
55 sten_v.append_line(ne_tot + f, f);
56 else // v computed: contribution to element divergence
57 for (int i = 0; i < 2; i++)
58 {
59 const int e = f_e(f, i);
60 if (e < 0) continue;
61
62 if (e < domaine.nb_elem())
63 sten_v.append_line(e, f);
64 }
65 }
66
67 // Dependence on p: equation on p_f
68 if (matp)
69 {
70 for (int e = 0; e < domaine.nb_elem_tot(); e++)
71 {
72 domaine.W2(nullptr, e, w2); // Compute the W2 matrix
73
74 for (int i = 0; i < w2.dimension(0); i++)
75 {
76 int f = e_f(e, i);
77 if (fcl(f, 0) == 1) // At Neumann faces: p_f = p_imp
78 sten_p.append_line(ne_tot + f, ne_tot + f);
79 else if (!fcl(f, 0))
80 {
81 // At internal faces: equality of the two gradients
82 sten_p.append_line(ne_tot + f, e);
83 for (int j = 0; j < w2.dimension(1); j++)
84 if (w2(i, j, 0))
85 sten_p.append_line(ne_tot + f, ne_tot + e_f(e, j));
86 }
87 }
88 }
89
90 // Empty diagonal for matp
91 for (int e = 0; e < domaine.nb_elem(); e++)
92 sten_p.append_line(e, e);
93 }
94
95 // Allocate matrices for matv
96 if (matv)
97 {
98 tableau_trier_retirer_doublons(sten_v);
99 Matrix_tools::allocate_morse_matrix(press.size_totale(), inco.size_totale(), sten_v, matv2);
100
101 if (matv->nb_colonnes())
102 *matv += matv2;
103 else
104 *matv = matv2;
105 }
106
107 // Allocate matrices for matp
108 if (matp)
109 {
110 tableau_trier_retirer_doublons(sten_p);
111 Matrix_tools::allocate_morse_matrix(press.size_totale(), press.size_totale(), sten_p, matp2);
112
113 if (matp->nb_colonnes())
114 *matp += matp2;
115 else
116 *matp = matp2;
117 }
118}
119
120void Op_Div_PolyMAC_HFV::ajouter_blocs_ext(const DoubleTab& vit, matrices_t matrices, DoubleTab& secmem, const tabs_t& semi_impl) const
121{
122 const Domaine_PolyMAC_HFV& domaine = ref_cast(Domaine_PolyMAC_HFV, le_dom_PolyMAC_CDO.valeur());
123 const Champ_Face_PolyMAC_HFV& ch = ref_cast(Champ_Face_PolyMAC_HFV, equation().inconnue());
124 const Conds_lim& cls = le_dcl_PolyMAC_CDO->les_conditions_limites();
125 const DoubleTab& press = ref_cast(Navier_Stokes_std, equation()).pression().valeurs(), &nf = domaine.face_normales();
126 const IntTab& e_f = domaine.elem_faces(), &f_e = domaine.face_voisins(), &fcl = ch.fcl();
127 const DoubleVect& fs = domaine.face_surfaces(), &pf = equation().milieu().porosite_face();
128 const int ne_tot = domaine.nb_elem_tot(), D = dimension, has_f = secmem.dimension_tot(0) > ne_tot;
129 Matrice_Morse *matv = matrices.count("vitesse") ? matrices["vitesse"] : nullptr, *matp = matrices.count("pression") ? matrices["pression"] : nullptr; //, matv2, matp2;
130
131 DoubleTrav w2; //w2 matrix at elements (same as in Op_Grad and Assembleur_P)
132
133
134 DoubleTab& tab_flux_bords = flux_bords_;
135 tab_flux_bords.resize(domaine.nb_faces_bord(), 1);
136
137 for (int f = 0; f < domaine.nb_faces(); f++) /* divergence at elements + equations at boundaries */
138 {
139 for (int i = 0; i < 2; i++)
140 {
141 const int e = f_e(f, i);
142 if (e < 0) continue;
143
144 if (e < domaine.nb_elem()) /* divergence at elements */
145 {
146 secmem(e) -= (i ? 1 : -1) * fs(f) * pf(f) * vit(f);
147 if (fcl(f, 0) < 2 && matv)
148 (*matv)(e, f) += (i ? 1 : -1) * fs(f) * pf(f);
149 }
150 }
151
152 if (f < domaine.premiere_face_int())
153 tab_flux_bords(f) = fs(f) * pf(f) * vit(f);
154
155 /* equations v = v_imp or p = p_imp at boundary faces */
156 if (has_f && fcl(f, 0) > 1)
157 {
158 if (fcl(f, 0) == 3)
159 for (int d = 0; d < D; d++)
160 secmem(ne_tot + f) += nf(f, d) * pf(f) * ref_cast(Dirichlet, cls[fcl(f, 1)].valeur()).val_imp(fcl(f, 2), d);
161 secmem(ne_tot + f) -= fs(f) * pf(f) * vit(f);
162 if (matv)
163 (*matv)(ne_tot + f, f) += fs(f) * pf(f);
164 }
165 else if (has_f && matp && fcl(f, 0) == 1) // if called from ajouter(vpoint, div) then do nothing here
166 {
167 secmem(ne_tot + f) += ref_cast(Neumann, cls[fcl(f, 1)].valeur()).flux_impose(fcl(f, 2), 0) - press(ne_tot + f);
168 (*matp)(ne_tot + f, ne_tot + f) += 1;
169 }
170 }
171
172 /* equations at internal faces: gradient equality */
173 if (!has_f || matrices.size() == 0) return; // already done in assembleur_pression
174 for (int e = 0; e < domaine.nb_elem_tot(); e++)
175 {
176 domaine.W2(nullptr, e, w2);
177 for (int i = 0; i < w2.dimension(0); i++)
178 {
179 const int f = e_f(e, i);
180
181 if (f < domaine.nb_faces() && !fcl(f, 0))
182 {
183 double coeff_e = 0.;
184
185 for (int j = 0; j < w2.dimension(1); j++)
186 if (w2(i, j, 0))
187 {
188 const int fb = e_f(e, j);
189
190 secmem(ne_tot + f) -= pf(f) * w2(i, j, 0) * (press(ne_tot + fb) - press(e));
191
192 if (matp)
193 (*matp)(ne_tot + f, ne_tot + fb) += pf(f) * w2(i, j, 0), coeff_e += pf(f) * w2(i, j, 0);
194 }
195
196 if (matp)
197 (*matp)(ne_tot + f, e) -= coeff_e;
198 }
199 }
200 }
201}
: class Champ_Face_PolyMAC_HFV
const IntTab & fcl() const
DoubleTab & valeurs() override
Returns the array of field values at the current time.
class Conds_lim This class represents a vector of boundary conditions.
Definition Conds_lim.h:32
Dirichlet This class is the base class of the hierarchy of Dirichlet-type boundary conditions.
Definition Dirichlet.h:31
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
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
int nb_colonnes() const override
Return local number of columns (=size on the current proc).
static void allocate_morse_matrix(const int nb_lines, const int nb_columns, const Stencil &stencil, Matrice_Morse &matrix, const bool &attach_stencil_to_matrix=false)
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
Navier_Stokes_std This class carries the terms of the momentum equation.
Classe Neumann This class is the base class of the hierarchy of Neumann-type boundary conditions.
Definition Neumann.h:31
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
class Op_Div_PolyMAC_CDO
class Op_Div_PolyMAC_HFV
void dimensionner_blocs(matrices_t matrices, const tabs_t &semi_impl={ }) const override
void ajouter_blocs_ext(const DoubleTab &vit, matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl={ }) const override
DoubleTab flux_bords_
Base class for output streams.
Definition Sortie.h:52
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
void append_line(_TYPE_)
Definition TRUSTTab.tpp:213
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size_totale() const
Definition TRUSTVect.tpp:61