1 /*============================================================================
2  * Lagrangian boundary condition types and injection definitions.
3  *============================================================================*/
4 
5 /* VERS */
6 
7 /*
8   This file is part of Code_Saturne, a general-purpose CFD tool.
9 
10   Copyright (C) 1998-2021 EDF S.A.
11 
12   This program is free software; you can redistribute it and/or modify it under
13   the terms of the GNU General Public License as published by the Free Software
14   Foundation; either version 2 of the License, or (at your option) any later
15   version.
16 
17   This program is distributed in the hope that it will be useful, but WITHOUT
18   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
20   details.
21 
22   You should have received a copy of the GNU General Public License along with
23   this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
24   Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 */
26 
27 /*----------------------------------------------------------------------------*/
28 
29 #include "cs_defs.h"
30 
31 /*----------------------------------------------------------------------------
32  * Standard C library headers
33  *----------------------------------------------------------------------------*/
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <assert.h>
39 
40 /*----------------------------------------------------------------------------
41  * Local headers
42  *----------------------------------------------------------------------------*/
43 
44 #include "cs_headers.h"
45 
46 /*----------------------------------------------------------------------------*/
47 
48 BEGIN_C_DECLS
49 
50 /*============================================================================
51  * Local (user defined) function definitions
52  *============================================================================*/
53 
54 /*----------------------------------------------------------------------------
55  * Computation of particle injection profile.
56  *
57  * Note: if the input pointer is non-NULL, it must point to valid data
58  * when the selection function is called, so that value or structure should
59  * not be temporary (i.e. local);
60  *
61  * parameters:
62  *   zone_id     <-- id of associated mesh zone
63  *   location_id <-- id of associated mesh location
64  *   input       <-- pointer to optional (untyped) value or structure.
65  *   n_elts      <-- number of zone elements
66  *   elt_ids     <-- ids of zone elements
67  *   profile     <-- weight of a given zone element (size: n_elts)
68  *----------------------------------------------------------------------------*/
69 
70 /*! [lagr_bc_profile_func_2] */
71 static void
_injection_profile(int zone_id,int location_id,const void * input,cs_lnum_t n_elts,const cs_lnum_t elt_ids[],cs_real_t profile[])72 _injection_profile(int               zone_id,
73                    int               location_id,
74                    const void       *input,
75                    cs_lnum_t         n_elts,
76                    const cs_lnum_t   elt_ids[],
77                    cs_real_t         profile[])
78 {
79   const cs_real_3_t  *b_face_coords
80     = (const cs_real_3_t *)cs_glob_mesh_quantities->b_face_cog;
81 
82   const int itmx = 8;
83 
84   /* Data initializations with experimental measurements
85      --------------------------------------------------- */
86 
87   /* transverse coordinate */
88 
89   cs_real_t zi[] = {0.e-3, 1.e-3, 1.5e-3, 2.0e-3, 2.5e-3, 3.0e-3, 3.5e-3,
90                     4.0e-3, 4.5e-3, 5.0e-3};
91 
92   /* particle volume fraction */
93 
94   cs_real_t lvf[] = {0.377e-4, 2.236e-4, 3.014e-4, 4.306e-4, 5.689e-4,
95                      8.567e-4, 7.099e-4, 4.520e-4, 2.184e-4, 0.377e-4};
96 
97   /* vertical mean velocity of the particles */
98 
99   cs_real_t ui[] = {5.544, 8.827, 9.068, 9.169, 8.923, 8.295, 7.151, 6.048,
100                     4.785, 5.544};
101 
102   /* Loop en elements
103      ---------------- */
104 
105   for (cs_lnum_t ei = 0; ei < n_elts; ei++) {
106 
107     /* Face center */
108 
109     const cs_lnum_t face_id = elt_ids[ei];
110 
111     const cs_real_t z = b_face_coords[face_id][2];
112 
113     /* Interpolation */
114 
115     int i = 0;
116 
117     if (z > zi[0]) {
118       for (i = 0; i < itmx; i++) {
119         if (z >= zi[i] && z < zi[i+1])
120           break;
121       }
122     }
123 
124     /* Compute volume fraction and statistical weight */
125 
126     cs_real_t up = ui[i] +(z-zi[i])*(ui[i+1]-ui[i])/(zi[i+1]-zi[i]);
127     cs_real_t lvfp = lvf[i] + (z-zi[i])*(lvf[i+1]-lvf[i])/(zi[i+1]-zi[i]);
128 
129     /* number of particles in the cell */
130 
131     profile[ei] = lvfp * up;
132   }
133 }
134 /*! [lagr_bc_profile_func_2] */
135 
136 /*============================================================================
137  * User function definitions
138  *============================================================================*/
139 
140 /*----------------------------------------------------------------------------*/
141 /*!
142  * \brief Define particle boundary conditions.
143  *
144  * This is used for the definition of inlet and other boundaries,
145  * based on predefined boundary zones (\ref cs_zone_t).
146  *
147  * \param[in] bc_type    type of the boundary faces
148  */
149 /*----------------------------------------------------------------------------*/
150 
151 void
cs_user_lagr_boundary_conditions(const int bc_type[])152 cs_user_lagr_boundary_conditions(const int  bc_type[])
153 {
154   /*! [lagr_bc_variables] */
155   cs_lagr_zone_data_t *lagr_bcs = cs_lagr_get_boundary_conditions();
156   /*! [lagr_bc_variables] */
157 
158   /* Zone types
159      ========== */
160 
161   /* For every boundary zone, we define the associated type:
162 
163        CS_LAGR_INLET     -> zone of particle inlet
164        CS_LAGR_OUTLET    -> particle outlet
165        CS_LAGR_REBOUND   -> rebound of the particles
166        CS_LAGR_DEPO1     -> definitive deposition
167        CS_LAGR_DEPO2     -> definitive deposition, but the particle remains
168                             in memory (useful only if iensi2 = 1)
169        CS_LAGR_DEPO_DLVO -> deposition of the particle with DLVO forces
170        CS_LAGR_FOULING   -> fouling (coal only physical_model = 2)
171        CS_LAGR_SYM       -> symmetry condition for the particles (zero flux)
172 
173  */
174 
175   /* define zone types */
176 
177   /*! [lagr_bc_define_type_1] */
178   {
179      const cs_zone_t  *z;
180      int n_zones = cs_boundary_zone_n_zones();
181 
182      /* default: rebound for all types */
183      for (int z_id = 0; z_id < n_zones; z_id++) {
184        lagr_bcs->zone_type[z_id] = CS_LAGR_REBOUND;
185      }
186 
187      /* inlet and outlet for specified zones */
188      z = cs_boundary_zone_by_name("inlet");
189      lagr_bcs->zone_type[z->id] = CS_LAGR_INLET;
190 
191      z = cs_boundary_zone_by_name("outlet");
192      lagr_bcs->zone_type[z->id] = CS_LAGR_OUTLET;
193   }
194   /*! [lagr_bc_define_type_1] */
195 
196   /* Injection per particle set into the calculation domain
197      ====================================================== */
198 
199   /* For every injection (usually inlet) zone,
200      we provide the following information:
201 
202      *   n_inject: number of particles injected per set and per zone
203      *   injection_frequency: injection frequency. If injection_frequency = 0,
204                               then the injection occurs only at the first
205                               absolute iteration.
206 
207      *   injection_profile_func: optional pointer to profile definition
208      *   injection_profile_input: associated input, or NULL
209 
210      *   cluster: number of the group to which the particle belongs
211                   (only if one wishes to calculate statistics per group)
212 
213      *   velocity_profile: type of condition on the velocity
214               = -1 imposed flow velocity
215               =  0 imposed velocity along the normal direction of the
216                     boundary face, with norm equal to velocity[0] (m/s)
217               =  1 imposed velocity: we prescribe velocity[0] (m/s)
218                                                   velocity[1] (m/s)
219                                                   velocity[2] (m/s)
220               =  2 user-defined profile
221 
222      *   temperature_profile: type of temperature condition
223               = 0 fluid temperature
224               = 1 imposed temperature: we prescribe the temperature
225 
226      *   density
227 
228      *   coal_number: number of the coal of the particle
229                       (only if physical_model = 2) */
230 
231   /* Access an injection set for selected zone
232      (created automatically if not previously accessed) */
233 
234   /*! [lagr_bc_define_injection_1] */
235   {
236     const cs_zone_t  *z = cs_boundary_zone_by_name("inlet");
237     int set_id = 0;
238     cs_lagr_injection_set_t *zis
239       = cs_lagr_get_injection_set(lagr_bcs, z->id, set_id);
240 
241     /* Now define parameters for this class and set */
242 
243     zis->n_inject = 100;
244     zis->injection_frequency = 1;
245 
246     /* Assign other attributes (could be done through the GUI) */
247 
248     if (cs_glob_lagr_model->n_stat_classes > 0)
249       zis->cluster = set_id + 1;
250 
251     zis->velocity_profile = 0;
252     zis->velocity_magnitude = 1.1;
253 
254     zis->stat_weight = 1.0;
255     zis->flow_rate = 0.0;
256 
257     /* Mean value and standard deviation of the diameter */
258     zis->diameter = 5e-05;
259     zis->diameter_variance = 0.0;
260 
261     /* Density */
262 
263     zis->density = 2500.0;
264 
265     zis->fouling_index = 100.0;
266 
267     /* Temperature and Cp */
268 
269     if (cs_glob_lagr_specific_physics->itpvar == 1) {
270       zis->temperature_profile = 1;
271       zis->temperature = 20.0;
272 
273       zis->cp = 1400.;
274       zis->emissivity = 0.7;
275     }
276 
277   }
278   /*! [lagr_bc_define_injection_1] */
279 
280   /*! [lagr_bc_define_injection_2] */
281   {
282     const cs_zone_t  *z = cs_boundary_zone_by_name("inlet");
283     int set_id = 1;
284     cs_lagr_injection_set_t *zis
285       = cs_lagr_get_injection_set(lagr_bcs, z->id, set_id);
286 
287     /* Assign injection profile function */
288 
289     zis->injection_profile_func = _injection_profile;
290     zis->injection_profile_input = NULL; /* default */
291 
292   }
293   /*! [lagr_bc_define_injection_2] */
294 
295   /* same procedure for additional injections at other zones or sets... */
296 }
297 
298 /*----------------------------------------------------------------------------*/
299 /*!
300  * \brief Handling of a particle interaction with a boundary of type
301  *        \ref CS_LAGR_BC_USER.
302  *
303  * In this example, the particle is simply deposited and marked for
304  * elimination.
305  *
306  * \param[in, out]  particles       pointer to particle set
307  * \param[in]       p_id            particle id
308  * \param[in]       face_id         boundary face id
309  * \param[in]       face_norm       unit face (or face subdivision) normal
310  * \param[in]       c_intersect     coordinates of intersection with the face
311  * \param[in]       t_intersect     relative distance (in [0, 1]) of the
312  *                                  intersection point with the face relative
313  *                                  to the initial trajectory segment
314  * \param[in]       b_zone_id       boundary zone id of the matching face
315  * \param[in, out]  event_flag      event flag in case events are available
316  * \param[in, out]  tracking_state  particle tracking state
317  */
318 /*----------------------------------------------------------------------------*/
319 
320 void
cs_lagr_user_boundary_interaction(cs_lagr_particle_set_t * particles,cs_lnum_t p_id,cs_lnum_t face_id,const cs_real_t face_norm[3],const cs_real_t c_intersect[3],cs_real_t t_intersect,int b_zone_id,int * event_flag,cs_lagr_tracking_state_t * tracking_state)321 cs_lagr_user_boundary_interaction(cs_lagr_particle_set_t    *particles,
322                                   cs_lnum_t                  p_id,
323                                   cs_lnum_t                  face_id,
324                                   const cs_real_t            face_norm[3],
325                                   const cs_real_t            c_intersect[3],
326                                   cs_real_t                  t_intersect,
327                                   int                        b_zone_id,
328                                   int                       *event_flag,
329                                   cs_lagr_tracking_state_t  *tracking_state)
330 {
331   /* Update deposition-related counter */
332 
333   /*! [update] */
334 
335 # pragma omp atomic
336   particles->n_part_dep += 1;
337 
338 # pragma omp atomic
339   particles->weight_dep += cs_lagr_particles_get_real(particles,
340                                                       p_id,
341                                                       CS_LAGR_STAT_WEIGHT);
342 
343   /* Mark particle as deposited and update its coordinates */
344 
345   cs_lagr_particles_set_flag(particles, p_id, CS_LAGR_PART_DEPOSITED);
346 
347   cs_real_t  *particle_coord
348     = cs_lagr_particles_attr(particles, p_id, CS_LAGR_COORDS);
349   for (int k = 0; k < 3; k++)
350     particle_coord[k] = c_intersect[k];
351 
352   /* Update event and particle state */
353 
354   *event_flag = *event_flag | (CS_EVENT_OUTFLOW | CS_EVENT_DEPOSITION);
355   *tracking_state = CS_LAGR_PART_OUT;
356 
357   /*! [update] */
358 
359 }
360 
361 /*----------------------------------------------------------------------------*/
362 
363 END_C_DECLS
364