TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
OpConvQuickSharpIJK.tpp
1/****************************************************************************
2* Copyright (c) 2015 - 2016, 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#ifndef OpConvQuickSharpIJK_TPP_included
17#define OpConvQuickSharpIJK_TPP_included
18
19#include <OpConvQuickSharpIJK.h>
20
21#ifndef OpConvQuickSharpIJK_included
22#error __FILE__ should only be included from corresponding header
23#endif
24
25inline double sharp(const double utc)
26{
27 double cf;
28 if (utc > 0)
29 {
30 if (utc > 0.25)
31 {
32 if (utc <= 1.)
33 {
34 cf = 0.25 * (1. - utc);
35 }
36 else if (utc < 1.5)
37 {
38 cf = 0.25 * (utc - 1.);
39 }
40 else
41 {
42 cf = 0.125;
43 }
44 }
45 else
46 {
47 cf = 0.5 - 0.625*sqrt(utc);
48 }
49 }
50 else
51 {
52 if (utc > -1)
53 {
54 cf = 0.5 + 0.375*utc;
55 }
56 else
57 {
58 cf = 0.125;
59 }
60 }
61 return cf;
62}
63
64inline double conv_quick_sharp_plus(const double psc,const double vit_0, const double vit_1,
65 const double vit_0_0, const double dx,
66 const double dm, const double dxam)
67{
68 double cf;
69 double curv;
70 double delta_0 = vit_0 - vit_0_0;
71 double delta = vit_1 - vit_0;
72 double dd1,utc;
73 double delta_delta;
74
75 curv = (delta/dx - delta_0/dxam)/dm ;
76
77 // Calcul de cf:
78
79 delta_delta = delta_0+delta;
80 dd1 = std::fabs(delta_delta);
81 if (dd1 < 1.e-5)
82 cf = 0.125;
83 else
84 {
85 utc = delta_0/delta_delta;
86 cf = sharp(utc);
87 }
88
89 return (0.5*(vit_0 + vit_1) - cf*(dx*dx)*curv)*psc;
90
91}
92
93inline double conv_quick_sharp_moins(const double psc,const double vit_0,const double vit_1,
94 const double vit_1_1,const double dx,
95 const double dm, const double dxam)
96{
97 double cf;
98 double curv;
99 double delta_1 = vit_1_1 - vit_1;
100 double delta = vit_1 - vit_0;
101 double dd1,utc;
102 double delta_delta;
103
104 curv = ( delta_1/dxam - delta/dx )/dm ;
105
106 // Calcul de cf:
107
108 delta_delta = delta_1+delta;
109 dd1 = std::fabs(delta_delta);
110 if (dd1 < 1.e-5)
111 cf = 0.125;
112 else
113 {
114 utc = delta_1/delta_delta;
115 cf = sharp(utc);
116 }
117
118 return (0.5*(vit_0 + vit_1) - cf*(dx*dx)*curv)*psc;
119
120}
121
122/*! @brief compute fluxes in direction x for velocity component x for the layer of fluxes k_layer
123 *
124 * 4-th order centered convection scheme
125 *
126 */
127template <DIRECTION _DIR_, DIRECTION _VCOMPO_>
128void OpConvQuickSharpIJK_double::compute_flux_(IJK_Field_local_double& resu, const int k_layer)
129{
130 // convected field
131 const IJK_Field_local_double& src = get_input(_VCOMPO_);
132 // Convected vector field:
133 ConstIJK_double_ptr src_ptr(src, 0, 0, k_layer);
134 // Velocity in x direction (convecting velocity)
135 ConstIJK_double_ptr vconv_ptr(get_v(_DIR_), 0, 0, k_layer);
136
137 const int idir = (int)_DIR_;
138 const int nx = _DIR_ == DIRECTION::X ? src.ni() + 1 : src.ni();
139 const int ny = _DIR_ == DIRECTION::Y ? src.nj() + 1 : src.nj();
140 const int icompo = (int)_VCOMPO_;
141
142 // Result (fluxes in direction x for component x of the convected field)
143 IJK_double_ptr resu_ptr(resu, 0, 0, 0);
144
145
146 const int global_k_layer = k_layer + channel_data_.offset_to_global_k_layer();
147 // global index of the layer of flux of the wall
148 // (assume one walls at zmin and zmax)
149 const int first_global_k_layer = channel_data_.first_global_k_layer_flux(icompo, idir);
150 const int last_global_k_layer = channel_data_.last_global_k_layer_flux(icompo, idir);
151
152 // GB 23/04/2020. Before, it was not working for tri-periodic cases :
153 // if (global_k_layer < first_global_k_layer || global_k_layer > last_global_k_layer) {
154 // BUT ALSO, it was strict inf or sup to.
155 // It was replaced by "<=" and ">=" to be identic to the condition in OpCentre4IJK
156 // I'm not sure which one is correct, or if it makes a difference on a wall
157 // (maybe the convection is zero anyway at the wall, and besides, the contribution
158 // of convection at the wal is set to zero anyway)?
159 if (!perio_k_ && (global_k_layer <= first_global_k_layer || global_k_layer >= last_global_k_layer))
160 {
161 // We are in the wall
162 putzero(resu);
163 return;
164 }
165
166 const double half_surface = channel_data_.get_surface(k_layer, icompo, idir) * 0.5;
167 const double delta = get_delta(_DIR_);
168 // Non vectorized coding
169 for (int j = 0; j < ny; j++)
170 {
171 for (int i = 0; i < nx; i++)
172 {
173 // get convecting velocity
174 double vconv0, vconv1;
175 vconv_ptr.get_left_center(_VCOMPO_,i, vconv0, vconv1);
176 double psc = (vconv0 + vconv1) * half_surface;
177 double vit_0_0,vit_0,vit_1,vit_1_1; // 4 adjacent velocity values
178 src_ptr.get_leftleft_left_center_right(_DIR_,i,vit_0_0,vit_0,vit_1,vit_1_1);
179 double flux;
180 if (psc > 0)
181 {
182 flux = conv_quick_sharp_plus(psc, vit_0, vit_1, vit_0_0, delta, delta, delta);
183 }
184 else
185 {
186 flux = conv_quick_sharp_moins(psc, vit_0, vit_1, vit_1_1, delta, delta, delta);
187 }
188 resu_ptr.put_val(i, flux);
189 }
190 if (j < ny-1)
191 {
192 src_ptr.next_j();
193 resu_ptr.next_j();
194 vconv_ptr.next_j();
195 }
196 }
197}
198
199#endif
200
const IJK_Field_double & get_input(DIRECTION _DIR_)
const IJK_Field_double & get_v(DIRECTION _DIR_)