1 /*============================================================================
2  * Lagrangian particle event model
3  *============================================================================*/
4 
5 /*
6   This file is part of Code_Saturne, a general-purpose CFD tool.
7 
8   Copyright (C) 1998-2021 EDF S.A.
9 
10   This program is free software; you can redistribute it and/or modify it under
11   the terms of the GNU General Public License as published by the Free Software
12   Foundation; either version 2 of the License, or (at your option) any later
13   version.
14 
15   This program is distributed in the hope that it will be useful, but WITHOUT
16   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18   details.
19 
20   You should have received a copy of the GNU General Public License along with
21   this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22   Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24 
25 /*----------------------------------------------------------------------------*/
26 
27 #include "cs_defs.h"
28 
29 /*----------------------------------------------------------------------------
30  * Standard C library headers
31  *----------------------------------------------------------------------------*/
32 
33 #include <limits.h>
34 #include <stdio.h>
35 #include <stddef.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <math.h>
39 #include <ctype.h>
40 #include <float.h>
41 #include <assert.h>
42 
43 /*----------------------------------------------------------------------------
44  *  Local headers
45  *----------------------------------------------------------------------------*/
46 
47 #include "bft_printf.h"
48 #include "bft_error.h"
49 #include "bft_mem.h"
50 
51 #include "fvm_periodicity.h"
52 
53 #include "cs_base.h"
54 #include "cs_math.h"
55 #include "cs_mesh_quantities.h"
56 #include "cs_order.h"
57 #include "cs_parall.h"
58 #include "cs_timer_stats.h"
59 
60 #include "cs_lagr.h"
61 #include "cs_lagr_particle.h"
62 
63 /*----------------------------------------------------------------------------
64  *  Header for the current file
65  *----------------------------------------------------------------------------*/
66 
67 #include "cs_lagr_event.h"
68 
69 /*----------------------------------------------------------------------------*/
70 
71 BEGIN_C_DECLS
72 
73 /*=============================================================================
74  * Additional doxygen documentation
75  *============================================================================*/
76 
77 /*!
78   \file cs_lagr_event.c
79         Particle event management.
80 
81 Particle events allow keeping track of particle events suh as boundary
82 interactions using a structure and API similar to that used for particles.
83 
84 Particles events could actually be stored as particle data, given the
85 necessary additional attributes defined here (i.e. using a different
86 attribute map), and could be refactored in the future based on feedback.
87 
88 As of now, it was chosen to use an independent structure, so as to avoid
89 confusion regarding the more restricted uses and (temporary) lifetime
90 of particle events, which should need to be maintained only as a buffer
91 mechanism for event-based statistics.
92 
93 */
94 
95 /*! \cond DOXYGEN_SHOULD_SKIP_THIS */
96 
97 /*=============================================================================
98  * Local Macro definitions
99  *============================================================================*/
100 
101 #define  N_GEOL 13
102 #define  CS_LAGR_MIN_COMM_BUF_SIZE  8
103 
104 /*=============================================================================
105  * Local Enumeration definitions
106  *============================================================================*/
107 
108 /* keys to sort attributes by type. */
109 
110 typedef enum {
111   CS_LAGR_P_NULLV,
112   CS_LAGR_P_RV,
113   CS_LAGR_P_IV,
114 } _array_map_id_t;
115 
116 /*============================================================================
117  * Local structure definitions
118  *============================================================================*/
119 
120 /* Private data associated to each particle event */
121 /* -----------------------------------------------*/
122 
123 /* Event data value */
124 /*------------------*/
125 
126 union cs_lagr_value_t {
127   cs_lnum_t      l; /* v_lnum_t */
128   cs_gnum_t      g; /* v_gnum_t */
129   cs_real_t      f; /* v_real_t */
130 };
131 
132 /*============================================================================
133  * Static global variables
134  *============================================================================*/
135 
136 /* Enumerator names */
137 /* Enumerator names */
138 
139 const char *_event_attribute_name[] = {
140   "flag",
141   "cell_id",
142   "face_id",
143   "velocity_post",
144   "<none>"};
145 
146 /* Global particle event attributes map */
147 
148 static cs_lagr_event_attribute_map_t  *_e_attr_map = NULL;
149 
150 /* Quick mapping from particle attributes to event attributes
151    to allow for quick copy from particle to event */
152 
153 static int   _n_mapped_part_attr = 0;
154 static int  *_mapped_part_attr = NULL;
155 
156 static cs_lagr_event_set_t  *_boundary_events = NULL;
157 
158 /*============================================================================
159  * Global variables
160  *============================================================================*/
161 
162 /*=============================================================================
163  * Private function definitions
164  *============================================================================*/
165 
166 /*----------------------------------------------------------------------------*
167  * Compute new extents to ensure alignment of data
168  *
169  * returns:
170  *   padded extents ensuring alignement
171  *----------------------------------------------------------------------------*/
172 
173 static size_t
_align_extents(size_t size)174 _align_extents(size_t  size)
175 {
176   size_t retval = size;
177 
178   size_t align_size = sizeof(union cs_lagr_value_t);
179 
180   size_t r = size % align_size;
181   if (r > 0)
182     retval += (align_size - r);
183 
184   return retval;
185 }
186 
187 /*----------------------------------------------------------------------------*
188  * Map particle event attributes for a given configuration.
189  *
190  * parameters:
191  *   attr_keys   <-> keys to sort attributes by Fortran array and index
192  *                   for each attribute: array, index in array, count
193  *
194  * returns:
195  *   pointer to structure mapping particle event attributes
196  *----------------------------------------------------------------------------*/
197 
198 static cs_lagr_event_attribute_map_t *
_create_attr_map(cs_lnum_t attr_keys[CS_LAGR_N_E_ATTRIBUTES][3])199 _create_attr_map(cs_lnum_t attr_keys[CS_LAGR_N_E_ATTRIBUTES][3])
200 {
201   cs_lagr_event_attribute_t attr;
202   cs_lnum_t *order;
203 
204   cs_lagr_event_attribute_map_t  *e_am;
205 
206   BFT_MALLOC(e_am, 1, cs_lagr_event_attribute_map_t);
207 
208   e_am->lb = 0;
209   e_am->extents = e_am->lb;
210 
211   for (attr = 0; attr < CS_LAGR_N_E_ATTRIBUTES; attr++) {
212     e_am->size[attr] = 0;
213     e_am->datatype[attr] = CS_REAL_TYPE;
214     e_am->displ[attr] = -1;
215     e_am->count[attr] = 1;
216   }
217 
218   BFT_MALLOC(order, CS_LAGR_N_E_ATTRIBUTES, cs_lnum_t);
219 
220   cs_order_lnum_allocated_s(NULL,
221                             (const cs_lnum_t *)attr_keys,
222                             3,
223                             order,
224                             CS_LAGR_N_E_ATTRIBUTES);
225 
226   int array_prev = 0;
227 
228   /* Now loop on ordered attributes */
229 
230   for (int i = 0; i < CS_LAGR_N_E_ATTRIBUTES; i++) {
231 
232     cs_datatype_t datatype = CS_REAL_TYPE;
233 
234     attr = order[i];
235 
236     e_am->datatype[attr] = CS_DATATYPE_NULL;
237     e_am->displ[attr] =-1;
238     e_am->count[attr] = 0;
239 
240     if (attr_keys[attr][0] < 1) continue;
241 
242     /* Behavior depending on array */
243 
244     switch(attr_keys[attr][0]) {
245     case CS_LAGR_P_RV:
246       break;
247     case CS_LAGR_P_IV:
248       datatype = CS_LNUM_TYPE;
249       break;
250     default:
251       continue;
252     }
253 
254     /* Add padding for alignment when changing array */
255 
256     if (attr_keys[attr][0] != array_prev) {
257       e_am->extents = _align_extents(e_am->extents);
258       array_prev = attr_keys[attr][0];
259     }
260 
261     /* Add attribute to map */
262 
263     e_am->displ[attr] = e_am->extents;
264     e_am->count[attr] = attr_keys[attr][2];
265     e_am->datatype[attr] = datatype;
266     e_am->size[attr] =   e_am->count[attr]
267                        * cs_datatype_size[e_am->datatype[attr]];
268 
269     e_am->extents += e_am->size[attr];
270 
271   }
272 
273   e_am->extents = _align_extents(e_am->extents);
274 
275   BFT_FREE(order);
276 
277   return e_am;
278 }
279 
280 /*----------------------------------------------------------------------------*
281  * Free particle event attributes for a given configuration.
282  *----------------------------------------------------------------------------*/
283 
284 static void
_destroy_attr_map(cs_lagr_event_attribute_map_t ** e_am)285 _destroy_attr_map(cs_lagr_event_attribute_map_t  **e_am)
286 {
287   if (*e_am != NULL) {
288     BFT_FREE(*e_am);
289   }
290 }
291 
292 /*----------------------------------------------------------------------------
293  * Allocate a cs_lagr_particle_event_set_t structure.
294  *
295  * parameters:
296  *   n_events_max <-- local max. number of particles
297  *   e_am         <-- particle event attributes map
298  *
299  * returns:
300  *   a new allocated cs_lagr_event_set_t structure
301  *----------------------------------------------------------------------------*/
302 
303 static cs_lagr_event_set_t *
_create_event_set(cs_lnum_t n_events_max,const cs_lagr_event_attribute_map_t * e_am)304 _create_event_set(cs_lnum_t                             n_events_max,
305                   const cs_lagr_event_attribute_map_t  *e_am)
306 
307 {
308   cs_lagr_event_set_t  *new_set = NULL;
309 
310   if (n_events_max == 0)
311     return NULL;
312 
313   BFT_MALLOC(new_set, 1, cs_lagr_event_set_t);
314 
315   BFT_MALLOC(new_set->e_buffer, n_events_max * e_am->extents, unsigned char);
316 
317   new_set->n_events     = 0;
318   new_set->n_events_max = n_events_max;
319 
320   assert(n_events_max >= 1);
321 
322   new_set->e_am = e_am;
323 
324   return new_set;
325 }
326 
327 /*----------------------------------------------------------------------------
328  * Dump an events structure
329  *
330  * parameter
331  *   particles   <-- cs_lagr_event_set_t structure to dump
332  *   particle_id <-- id of particle to dump
333  *----------------------------------------------------------------------------*/
334 
335 static void
_dump_event(const cs_lagr_event_set_t * events,cs_lnum_t event_id)336 _dump_event(const cs_lagr_event_set_t  *events,
337             cs_lnum_t                   event_id)
338 {
339   const cs_lagr_event_attribute_map_t *am = events->e_am;
340 
341   bft_printf("  event: %lu\n", (unsigned long)event_id);
342 
343   bft_printf("    values:\n");
344 
345   for (cs_lagr_event_attribute_t attr = 0;
346        attr < CS_LAGR_N_E_ATTRIBUTES;
347        attr++) {
348     if (am->count[attr] > 0) {
349       const char *attr_name = cs_lagr_event_get_attr_name(attr);
350       switch (am->datatype[attr]) {
351       case CS_LNUM_TYPE:
352         {
353           const cs_lnum_t *v
354             = cs_lagr_events_attr_const(events, event_id, attr);
355           bft_printf("      %24s: %10ld\n", attr_name, (long)v[0]);
356           for (int i = 1; i < am->count[attr]; i++)
357             bft_printf("      %24s: %10ld\n", " ", (long)v[i]);
358         }
359         break;
360       case CS_REAL_TYPE:
361         {
362           const cs_real_t *v
363             = cs_lagr_events_attr_const(events, event_id, attr);
364           bft_printf("      %24s: %10.3g\n", attr_name, v[0]);
365           for (int i = 1; i < am->count[attr]; i++)
366             bft_printf("      %24s: %10.3g\n", " ", v[i]);
367         }
368         break;
369       default:
370         break;
371       }
372     }
373   }
374   bft_printf("\n");
375 }
376 
377 /*! (DOXYGEN_SHOULD_SKIP_THIS) \endcond */
378 
379 /*============================================================================
380  * Public function definitions
381  *============================================================================*/
382 
383 /*----------------------------------------------------------------------------*/
384 /*!
385  * \brief Define particle map based on defined options.
386  *
387  * This function should only be called after
388  * \ref cs_lagr_particle_attr_initialize,
389  * as it may use elements from the main particle attributes map.
390  */
391 /*----------------------------------------------------------------------------*/
392 
393 void
cs_lagr_event_initialize(void)394 cs_lagr_event_initialize(void)
395 {
396   int  i;
397 
398   int loc_count = 0;
399 
400   cs_lnum_t attr_keys[CS_LAGR_N_E_ATTRIBUTES][3];
401 
402   /* Initialize global parameter relative to the lagrangian module */
403 
404   /* Set indexes */
405 
406   for (i = 0; i < CS_LAGR_N_E_ATTRIBUTES; i++) {
407     attr_keys[i][0] = CS_LAGR_P_NULLV;
408     attr_keys[i][1] = 0;
409     attr_keys[i][2] = 0;
410   }
411 
412   /* Copy some selected attributes from particle data */
413 
414   cs_lagr_attribute_t default_p_attrs[]
415     = {CS_LAGR_STAT_WEIGHT,
416        CS_LAGR_RESIDENCE_TIME,
417        CS_LAGR_MASS,
418        CS_LAGR_DIAMETER,
419        CS_LAGR_SHAPE,
420        CS_LAGR_ORIENTATION,
421        CS_LAGR_QUATERNION,
422        CS_LAGR_RADII,
423        CS_LAGR_ANGULAR_VEL,
424        CS_LAGR_EULER,
425        CS_LAGR_SHAPE_PARAM,
426        CS_LAGR_TAUP_AUX,
427        CS_LAGR_COORDS,
428        CS_LAGR_VELOCITY,
429        CS_LAGR_YPLUS,
430        CS_LAGR_INTERF,
431        CS_LAGR_MARKO_VALUE,
432        CS_LAGR_FOULING_INDEX,
433        CS_LAGR_TEMPERATURE,
434        CS_LAGR_FLUID_TEMPERATURE,
435        CS_LAGR_CP,
436        CS_LAGR_WATER_MASS,
437        CS_LAGR_COAL_MASS,
438        CS_LAGR_COKE_MASS,
439        CS_LAGR_SHRINKING_DIAMETER,
440        CS_LAGR_STAT_CLASS,
441        CS_LAGR_USER};
442 
443   _n_mapped_part_attr = 0;
444 
445   int n_attrs = sizeof(default_p_attrs) / sizeof(cs_lagr_attribute_t);
446 
447   const cs_lagr_attribute_map_t *p_am = cs_lagr_particle_get_attr_map();
448 
449   for (i = 0; i < n_attrs; i++) {
450     int j = default_p_attrs[i];
451     int count = p_am->count[0][j];
452     if (count > 0) {
453       if (p_am->datatype[j] == CS_REAL_TYPE)
454         attr_keys[j][0] = CS_LAGR_P_RV;
455       else if (p_am->datatype[j] == CS_LNUM_TYPE)
456         attr_keys[j][0] = CS_LAGR_P_IV;
457       if (attr_keys[j][0] != CS_DATATYPE_NULL) {
458         attr_keys[j][1] = ++loc_count;
459         attr_keys[j][2] = count;
460         _n_mapped_part_attr += 1;
461       }
462     }
463   }
464 
465   BFT_REALLOC(_mapped_part_attr, _n_mapped_part_attr, int);
466   _n_mapped_part_attr = 0;
467 
468   for (i = 0; i < n_attrs; i++) {
469     int j = default_p_attrs[i];
470     if (attr_keys[j][0] != CS_DATATYPE_NULL) {
471       _mapped_part_attr[_n_mapped_part_attr] = j;
472       _n_mapped_part_attr += 1;
473     }
474   }
475 
476   /* Now handle event-specific attributes */
477 
478   attr_keys[CS_LAGR_E_FLAG][0] = CS_LAGR_P_IV;
479   attr_keys[CS_LAGR_E_FLAG][1] = ++loc_count;
480   attr_keys[CS_LAGR_E_FLAG][2] = 1;
481 
482   attr_keys[CS_LAGR_E_CELL_ID][0] = CS_LAGR_P_IV;
483   attr_keys[CS_LAGR_E_CELL_ID][1] = ++loc_count;
484   attr_keys[CS_LAGR_E_CELL_ID][2] = 1;
485 
486   attr_keys[CS_LAGR_E_FACE_ID][0] = CS_LAGR_P_IV;
487   attr_keys[CS_LAGR_E_FACE_ID][1] = ++loc_count;
488   attr_keys[CS_LAGR_E_FACE_ID][2] = 1;
489 
490   attr_keys[CS_LAGR_E_VELOCITY][0] = CS_LAGR_P_RV;
491   attr_keys[CS_LAGR_E_VELOCITY][1] = ++loc_count;
492   attr_keys[CS_LAGR_E_VELOCITY][2] = 3;
493 
494   /* Default count of 1 */
495 
496   for (i = 0; i < CS_LAGR_N_E_ATTRIBUTES; i++) {
497     if (attr_keys[i][1] > 0 && attr_keys[i][2] == 0)
498       attr_keys[i][2] = 1;
499     else if (attr_keys[i][1] < 1)
500       attr_keys[i][0] = 0;
501   }
502 
503   /* Build mappings
504      (in the future, they should be created first, then marked,
505      then built) */
506 
507   _e_attr_map = _create_attr_map(attr_keys);
508 }
509 
510 /*----------------------------------------------------------------------------*/
511 /*!
512  * \brief Destroy main particle set and map if they exist.
513  */
514 /*----------------------------------------------------------------------------*/
515 
516 void
cs_lagr_event_finalize(void)517 cs_lagr_event_finalize(void)
518 {
519   if (_boundary_events != NULL)
520     cs_lagr_event_set_destroy(&_boundary_events);
521 
522   BFT_FREE(_mapped_part_attr);
523   _n_mapped_part_attr = 0;
524 
525   _destroy_attr_map(&_e_attr_map);
526 }
527 
528 /*----------------------------------------------------------------------------*/
529 /*!
530  * \brief  Return const pointer to the main particle event attribute
531  *         map structure.
532  *
533  * \return pointer to current particle event attrbute map, or NULL
534  */
535 /*----------------------------------------------------------------------------*/
536 
537 const cs_lagr_event_attribute_map_t *
cs_lagr_event_get_attr_map(void)538 cs_lagr_event_get_attr_map(void)
539 {
540   const cs_lagr_event_attribute_map_t *e_am = _e_attr_map;
541   return e_am;
542 }
543 
544 /*----------------------------------------------------------------------------*/
545 /*!
546  * \brief  Return name associated with a given attribute.
547  *
548  * \param[in]   attr   event attribute
549  */
550 /*----------------------------------------------------------------------------*/
551 
552 const char *
cs_lagr_event_get_attr_name(cs_lagr_event_attribute_t attr)553 cs_lagr_event_get_attr_name(cs_lagr_event_attribute_t   attr)
554 {
555   const char *retval = _event_attribute_name[  CS_LAGR_N_E_ATTRIBUTES
556                                              - CS_LAGR_N_ATTRIBUTES];
557 
558   if (attr >= 0) {
559     if ((int)attr < CS_LAGR_N_ATTRIBUTES)
560       retval = cs_lagr_attribute_name[attr];
561     else {
562       if (attr < CS_LAGR_N_E_ATTRIBUTES)
563         retval = _event_attribute_name[attr - CS_LAGR_N_ATTRIBUTES];
564     }
565   }
566 
567   return retval;
568 }
569 
570 /*----------------------------------------------------------------------------*/
571 /*!
572  * Create a cs_lagr_event_set_t structure.
573  *
574  * \return pointer to event set
575  */
576 /*----------------------------------------------------------------------------*/
577 
578 cs_lagr_event_set_t  *
cs_lagr_event_set_create(void)579 cs_lagr_event_set_create(void)
580 {
581   cs_lagr_event_set_t  *events = _create_event_set(256, _e_attr_map);
582 
583 #if 0 && defined(DEBUG) && !defined(NDEBUG)
584   bft_printf("\n EVENT SET AFTER CREATION\n");
585   cs_lagr_event_set_dump(events);
586 #endif
587 
588   return events;
589 }
590 
591 /*----------------------------------------------------------------------------*/
592 /*!
593  * Destroy a cs_lagr_event_set_t structure.
594  *
595  * \param[in, out]  events  pointer to pointer to event set to destroy
596  */
597 /*----------------------------------------------------------------------------*/
598 
599 void
cs_lagr_event_set_destroy(cs_lagr_event_set_t ** events)600 cs_lagr_event_set_destroy(cs_lagr_event_set_t  **events)
601 {
602   if (events != NULL) {
603 
604     cs_lagr_event_set_t *_set = *events;
605     BFT_FREE(_set->e_buffer);
606 
607     BFT_FREE(*events);
608   }
609 }
610 
611 /*----------------------------------------------------------------------------*/
612 /*!
613  * \brief Get data extents for a given particle event attribute.
614  *
615  * For attributes not currently present, the displacement and data
616  * size should be -1 and 0 respectively.
617  *
618  * \param[in]   events     associated event set
619  * \param[in]   attr       event attribute
620  * \param[out]  extents    size (in bytes) of event structure, or NULL
621  * \param[out]  size       size (in bytes) of attribute in event structure,
622  *                         or NULL
623  * \param[out]  displ      displacement (in bytes) in event structure,
624  *                         or NULL
625  * \param[out]  datatype   datatype of associated attribute, or NULL
626  * \param[out]  count      number of type values associated with attribute,
627  *                         or NULL
628  */
629 /*----------------------------------------------------------------------------*/
630 
631 void
cs_lagr_event_get_attr_info(const cs_lagr_event_set_t * events,cs_lagr_event_attribute_t attr,size_t * extents,size_t * size,ptrdiff_t * displ,cs_datatype_t * datatype,int * count)632 cs_lagr_event_get_attr_info(const cs_lagr_event_set_t   *events,
633                             cs_lagr_event_attribute_t    attr,
634                             size_t                      *extents,
635                             size_t                      *size,
636                             ptrdiff_t                   *displ,
637                             cs_datatype_t               *datatype,
638                             int                         *count)
639 {
640   if (extents)
641     *extents = events->e_am->extents;
642   if (size)
643     *size = events->e_am->size[attr];
644   if (displ)
645     *displ = events->e_am->displ[attr];
646   if (datatype)
647     *datatype = events->e_am->datatype[attr];
648   if (count)
649     *count = events->e_am->count[attr];
650 }
651 
652 /*----------------------------------------------------------------------------*/
653 /*!
654  * \brief Check if an event attribute is in a valid range.
655  *
656  * If this is not the case, a fatal error is provoked.
657 
658  * \param[in]   attr       event attribute
659  */
660 /*----------------------------------------------------------------------------*/
661 
662 void
cs_lagr_event_attr_in_range(int attr)663 cs_lagr_event_attr_in_range(int  attr)
664 {
665   if (attr < 0 || attr >= CS_LAGR_N_E_ATTRIBUTES)
666     bft_error(__FILE__, __LINE__,0,
667               _("Out-of range attribute type: %d"),
668               (int)attr);
669 }
670 
671 /*----------------------------------------------------------------------------
672  * Resize event set buffers if needed.
673  *
674  * \param[in, out]  event_set  pointer to event set
675  * \param[in]       minimum required
676  *----------------------------------------------------------------------------*/
677 
678 void
cs_lagr_event_set_resize(cs_lagr_event_set_t * event_set,cs_lnum_t min_size)679 cs_lagr_event_set_resize(cs_lagr_event_set_t  *event_set,
680                          cs_lnum_t             min_size)
681 {
682   if (min_size == event_set->n_events_max)
683     return;
684 
685   assert(min_size >= event_set->n_events);
686 
687   event_set->n_events_max = min_size;
688 
689   BFT_REALLOC(event_set->e_buffer,
690               event_set->n_events_max * event_set->e_am->extents,
691               unsigned char);
692 }
693 
694 /*----------------------------------------------------------------------------*/
695 /*!
696  * \brief Dump a cs_lagr_event_set_t structure
697  *
698  * \param[in]  events  cs_lagr_event_set_t structure to dump
699  */
700 /*----------------------------------------------------------------------------*/
701 
702 void
cs_lagr_event_set_dump(const cs_lagr_event_set_t * events)703 cs_lagr_event_set_dump(const cs_lagr_event_set_t  *events)
704 {
705   if (events != NULL) {
706 
707     bft_printf("Particle events set\n");
708     bft_printf("-------------------\n");
709     bft_printf("  n_events:      %10ld\n", (long)events->n_events);
710     bft_printf("  n_events_max:  %10ld\n", (long)events->n_events_max);
711 
712     bft_printf_flush();
713 
714     for (cs_lnum_t i = 0; i < events->n_events; i++) {
715       _dump_event(events, i);
716     }
717 
718   }
719   bft_printf_flush();
720 }
721 
722 /*----------------------------------------------------------------------------
723  * Resize event set buffers if needed.
724  *
725  * \param[in, out]  events       pointer to event set
726  * \param[in, out]  particles    pointer to particle set
727  * \param[in]       event_id     event id
728  * \param[in]       particle_id  particle id
729  *----------------------------------------------------------------------------*/
730 
731 void
cs_lagr_event_init_from_particle(cs_lagr_event_set_t * events,cs_lagr_particle_set_t * particles,cs_lnum_t event_id,cs_lnum_t particle_id)732 cs_lagr_event_init_from_particle(cs_lagr_event_set_t     *events,
733                                  cs_lagr_particle_set_t  *particles,
734                                  cs_lnum_t                event_id,
735                                  cs_lnum_t                particle_id)
736 {
737   memset(events->e_buffer + events->e_am->extents*event_id,
738          0,
739          events->e_am->extents);
740 
741   for (cs_lnum_t i = 0; i < _n_mapped_part_attr; i++) {
742     int attr = _mapped_part_attr[i];
743 
744     const unsigned char *p_attr = cs_lagr_particles_attr(particles,
745                                                          particle_id,
746                                                          attr);
747 
748     unsigned char *e_attr = cs_lagr_events_attr(events,
749                                                 event_id,
750                                                 attr);
751 
752     size_t size = particles->p_am->size[attr];
753 
754     for (size_t j = 0; j < size; j++)
755       e_attr[j] = p_attr[j];
756   }
757 
758   cs_lnum_t cell_id = cs_lagr_particles_get_lnum(particles, particle_id,
759                                                  CS_LAGR_CELL_ID);
760   cs_lagr_events_set_lnum(events,
761                           event_id,
762                           CS_LAGR_E_CELL_ID,
763                           cell_id);
764 }
765 
766 /*----------------------------------------------------------------------------*/
767 /*!
768  * Return a cs_lagr_event_set_t structure for particle/boundary interactions.
769  *
770  * The event set is created if not present yet.
771  *
772  * This event set is automatically freed and destroyed at the end of the
773  * computation.
774  *
775  * \return pointer to event set
776  */
777 /*----------------------------------------------------------------------------*/
778 
779 cs_lagr_event_set_t  *
cs_lagr_event_set_boundary_interaction(void)780 cs_lagr_event_set_boundary_interaction(void)
781 {
782   if (_boundary_events == NULL)
783     _boundary_events = _create_event_set(256, _e_attr_map);
784 
785   return _boundary_events;
786 }
787 
788 /*----------------------------------------------------------------------------*/
789 
790 END_C_DECLS
791