1 /*============================================================================
2  * Functions to handle extended definitions of quantities
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 /*----------------------------------------------------------------------------
28  * Standard C library headers
29  *----------------------------------------------------------------------------*/
30 
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <assert.h>
35 
36 /*----------------------------------------------------------------------------
37  *  Local headers
38  *----------------------------------------------------------------------------*/
39 
40 #include "bft_mem.h"
41 
42 #include "cs_field.h"
43 #include "cs_flag.h"
44 #include "cs_log.h"
45 #include "cs_mesh_location.h"
46 
47 /*----------------------------------------------------------------------------
48  * Header for the current file
49  *----------------------------------------------------------------------------*/
50 
51 #include "cs_xdef.h"
52 
53 /*----------------------------------------------------------------------------*/
54 
55 BEGIN_C_DECLS
56 
57 /*=============================================================================
58  * Additional doxygen documentation
59  *============================================================================*/
60 
61  /*!
62    \file cs_xdef.c
63 
64    \brief Functions to handle extended definitions of quantities thanks to the
65           cs_xdef_t structures.
66 
67  */
68 
69 /*=============================================================================
70  * Local Macro definitions and structure definitions
71  *============================================================================*/
72 
73 #define CS_XDEF_DBG  0
74 
75 /*============================================================================
76  * Global static variables
77  *============================================================================*/
78 
79 static const char *_xdef_type_name[]
80   = {"CS_XDEF_BY_ANALYTIC_FUNCTION",
81      "CS_XDEF_BY_ARRAY",
82      "CS_XDEF_BY_DOF_FUNCTION",
83      "CS_XDEF_BY_FIELD",
84      "CS_XDEF_BY_FUNCTION",
85      "CS_XDEF_BY_QOV",
86      "CS_XDEF_BY_SUB_DEFINITIONS",
87      "CS_XDEF_BY_TIME_FUNCTION",
88      "CS_XDEF_BY_VALUE",
89      "out of range"};
90 
91 /*============================================================================
92  * Private function prototypes
93  *============================================================================*/
94 
95 /*============================================================================
96  * Public function prototypes
97  *============================================================================*/
98 
99 /*----------------------------------------------------------------------------*/
100 /*!
101  * \brief  Allocate and initialize a new cs_xdef_t structure based on volumic
102  *         elements
103  *
104  * \param[in]  type        type of definition
105  * \param[in]  dim         dimension of the values to define
106  * \param[in]  z_id        volume zone id
107  * \param[in]  state       flag to know if this uniform, cellwise, steady...
108  * \param[in]  meta        metadata associated to this description
109  * \param[in]  context     pointer to a structure
110  *
111  * \return a pointer to the new cs_xdef_t structure
112  */
113 /*----------------------------------------------------------------------------*/
114 
115 cs_xdef_t *
cs_xdef_volume_create(cs_xdef_type_t type,int dim,int z_id,cs_flag_t state,cs_flag_t meta,void * context)116 cs_xdef_volume_create(cs_xdef_type_t           type,
117                       int                      dim,
118                       int                      z_id,
119                       cs_flag_t                state,
120                       cs_flag_t                meta,
121                       void                    *context)
122 {
123   cs_xdef_t  *d = NULL;
124 
125   BFT_MALLOC(d, 1, cs_xdef_t);
126 
127   d->type = type;
128   d->support = CS_XDEF_SUPPORT_VOLUME;
129   d->dim = dim;
130   d->z_id = z_id;
131   d->state = state;
132   d->meta = meta;
133   d->qtype = CS_QUADRATURE_BARY; /* default value */
134 
135   /* Now define the context pointer */
136   switch (type) {
137 
138   case CS_XDEF_BY_VALUE:
139     {
140       double  *_context = (double *)context;
141       BFT_MALLOC(d->context, dim, double);
142 
143       double  *_context_cpy = (double *)d->context;
144       for (int i = 0; i < dim; i++) _context_cpy[i] = _context[i];
145 
146       /* Update state flag */
147       d->state |= CS_FLAG_STATE_UNIFORM | CS_FLAG_STATE_CELLWISE;
148     }
149     break;
150 
151   case CS_XDEF_BY_ANALYTIC_FUNCTION:
152     {
153       cs_xdef_analytic_context_t  *a = (cs_xdef_analytic_context_t *)context;
154       cs_xdef_analytic_context_t  *b = NULL;
155 
156       BFT_MALLOC(b, 1, cs_xdef_analytic_context_t);
157       assert(a->z_id == z_id);
158       b->z_id = a->z_id;
159       b->func = a->func;
160       b->input = a->input;
161       b->free_input = a->free_input;
162 
163       d->context = b;
164     }
165     break;
166 
167   case CS_XDEF_BY_DOF_FUNCTION:
168     {
169       cs_xdef_dof_context_t  *a = (cs_xdef_dof_context_t *)context;
170       cs_xdef_dof_context_t  *b = NULL;
171 
172       BFT_MALLOC(b, 1, cs_xdef_dof_context_t);
173       assert(a->z_id == z_id);
174       b->z_id = a->z_id;
175       b->func = a->func;
176       b->loc = a->loc;
177       b->input = a->input;
178       b->free_input = a->free_input;
179 
180       d->context = b;
181     }
182     break;
183 
184   case CS_XDEF_BY_TIME_FUNCTION:
185     {
186       cs_xdef_time_func_context_t  *a = (cs_xdef_time_func_context_t *)context;
187       cs_xdef_time_func_context_t  *b = NULL;
188 
189       BFT_MALLOC(b, 1, cs_xdef_time_func_context_t);
190       b->func = a->func;
191       b->input = a->input;
192       b->free_input = a->free_input;
193 
194       d->context = b;
195     }
196     break;
197 
198   case CS_XDEF_BY_ARRAY:
199     {
200       cs_xdef_array_context_t  *a = (cs_xdef_array_context_t *)context;
201       cs_xdef_array_context_t  *b = NULL;
202 
203       BFT_MALLOC(b, 1, cs_xdef_array_context_t);
204       assert(a->z_id == z_id);
205       b->z_id = a->z_id;
206       b->stride = a->stride;
207       b->loc = a->loc;
208       b->values = a->values;
209       b->is_owner = a->is_owner;
210       b->index = a->index;
211 
212       /* Update state flag */
213       if (cs_flag_test(b->loc, cs_flag_primal_cell) ||
214           cs_flag_test(b->loc, cs_flag_dual_face_byc))
215         d->state |= CS_FLAG_STATE_CELLWISE;
216 
217       d->context = b;
218     }
219     break;
220 
221   case CS_XDEF_BY_FIELD:
222     {
223       cs_field_t  *f = (cs_field_t *)context;
224 
225       d->context = f;
226       assert(f != NULL);
227 
228       const cs_mesh_location_type_t  loc_type =
229         cs_mesh_location_get_type(f->location_id);
230 
231       /* Update state flag */
232       switch(loc_type) {
233 
234       case CS_MESH_LOCATION_CELLS:
235         d->state |= CS_FLAG_STATE_CELLWISE;
236         d->meta |= CS_FLAG_FULL_LOC;
237         break;
238       case CS_MESH_LOCATION_VERTICES:
239         d->meta |= CS_FLAG_FULL_LOC;
240         break;
241 
242       default:
243         break; /* Nothing to do */
244       }
245 
246     }
247     break;
248 
249   case CS_XDEF_BY_QOV:
250     {
251       double  *_context = (double *)context;
252 
253       BFT_MALLOC(d->context, 1, double);
254 
255       double *_context_cpy = (double *)d->context;
256       _context_cpy[0] = _context[0];
257     }
258     break;
259 
260   default: /* More generic functions e.g. CS_XDEF_BY_FUNCTION */
261     d->context = context;  /* remark: context is used as an input structure.
262                               The lifecycle of this pointer is not managed by
263                               the current cs_xdef_t structure */
264     break;
265   }
266 
267   return d;
268 }
269 
270 /*----------------------------------------------------------------------------*/
271 /*!
272  * \brief  Allocate and initialize a new cs_xdef_t structure based on boundary
273  *         elements
274  *
275  * \param[in]  type       type of definition
276  * \param[in]  dim        dimension of the values to define
277  * \param[in]  z_id       volume zone id
278  * \param[in]  state      flag to know if this uniform, cellwise, steady...
279  * \param[in]  meta       metadata associated to this description
280  * \param[in]  context    pointer to a structure
281  *
282  * \return a pointer to the new cs_xdef_t structure
283  */
284 /*----------------------------------------------------------------------------*/
285 
286 cs_xdef_t *
cs_xdef_boundary_create(cs_xdef_type_t type,int dim,int z_id,cs_flag_t state,cs_flag_t meta,void * context)287 cs_xdef_boundary_create(cs_xdef_type_t    type,
288                         int               dim,
289                         int               z_id,
290                         cs_flag_t         state,
291                         cs_flag_t         meta,
292                         void             *context)
293 {
294   cs_xdef_t  *d = NULL;
295 
296   BFT_MALLOC(d, 1, cs_xdef_t);
297 
298   d->type = type;
299   d->support = CS_XDEF_SUPPORT_BOUNDARY;
300   d->dim = dim;
301   d->z_id = z_id;
302   d->state = state;
303   d->meta = meta;
304   d->qtype = CS_QUADRATURE_BARY; /* default value */
305 
306   switch (type) {
307 
308   case CS_XDEF_BY_VALUE:
309     {
310       double  *_context = (double *)context;
311 
312       BFT_MALLOC(d->context, dim, double);
313 
314       double  *_context_cpy = (double *)d->context;
315       for (int i = 0; i < dim; i++) _context_cpy[i] = _context[i];
316 
317       /* Update state flag */
318       d->state |= CS_FLAG_STATE_UNIFORM | CS_FLAG_STATE_FACEWISE;
319     }
320     break;
321 
322   case CS_XDEF_BY_ANALYTIC_FUNCTION:
323     {
324       cs_xdef_analytic_context_t  *a = (cs_xdef_analytic_context_t *)context;
325       cs_xdef_analytic_context_t  *b = NULL;
326 
327       BFT_MALLOC(b, 1, cs_xdef_analytic_context_t);
328       assert(a->z_id == z_id);
329       b->z_id = a->z_id;
330       b->func = a->func;
331       b->input = a->input;
332       b->free_input = a->free_input;
333 
334       d->context = b;
335     }
336     break;
337 
338   case CS_XDEF_BY_DOF_FUNCTION:
339     {
340       cs_xdef_dof_context_t  *a = (cs_xdef_dof_context_t *)context;
341       cs_xdef_dof_context_t  *b = NULL;
342 
343       BFT_MALLOC(b, 1, cs_xdef_dof_context_t);
344       b->func = a->func;
345       b->loc = a->loc;
346       b->input = a->input;
347       b->free_input = a->free_input;
348 
349       d->context = b;
350     }
351     break;
352 
353   case CS_XDEF_BY_ARRAY:
354     {
355       cs_xdef_array_context_t  *a = (cs_xdef_array_context_t *)context;
356       cs_xdef_array_context_t  *b = NULL;
357 
358       BFT_MALLOC(b, 1, cs_xdef_array_context_t);
359       b->stride = a->stride;
360       b->loc = a->loc;
361       b->values = a->values;
362       b->is_owner = a->is_owner;
363       b->index = a->index;
364 
365       d->context = b;
366 
367       /* Update state flag */
368       if (cs_flag_test(b->loc, cs_flag_primal_face))
369         d->state |= CS_FLAG_STATE_FACEWISE;
370     }
371     break;
372 
373   case CS_XDEF_BY_FIELD:
374     {
375       cs_field_t  *f = (cs_field_t *)context;
376       assert(f != NULL);
377       d->context = f;
378 
379       const cs_mesh_location_type_t  loc_type =
380         cs_mesh_location_get_type(f->location_id);
381 
382       /* Update flags */
383       if (loc_type == CS_MESH_LOCATION_BOUNDARY_FACES) {
384         d->meta |= CS_FLAG_FULL_LOC;
385         d->state |= CS_FLAG_STATE_FACEWISE;
386       }
387       else
388         bft_error(__FILE__, __LINE__, 0,
389                   " %s: Definition by field on the boundary rely on a mesh"
390                   " location defined at boundary faces.", __func__);
391     }
392     break;
393 
394   case CS_XDEF_BY_QOV:
395     {
396       double  *_context = (double *)context;
397 
398       BFT_MALLOC(d->context, 1, double);
399 
400       double  *_context_cpy = (double *)d->context;
401       _context_cpy[0] = _context[0];
402 
403       /* Update state flag */
404       d->state |= CS_FLAG_STATE_UNIFORM | CS_FLAG_STATE_FACEWISE;
405     }
406     break;
407 
408   default: /* More generic functions e.g. CS_XDEF_BY_FUNCTION */
409     d->context = context;   /* remark: context is used as an input structure.
410                                The lifecycle of this pointer is not managed by
411                                the current cs_xdef_t structure */
412     break;
413 
414   }
415 
416   return d;
417 }
418 
419 /*----------------------------------------------------------------------------*/
420 /*!
421  * \brief  Allocate and initialize a new cs_xdef_t structure for setting the
422  *         time step
423  *
424  * \param[in]  type       type of definition
425  * \param[in]  state      flag to know if this uniform, cellwise, steady...
426  * \param[in]  meta       metadata associated to this description
427  * \param[in]  context    pointer to a structure storing the parameters (cast
428  *                        on-the-fly according to the type of definition)
429  *
430  * \return a pointer to the new cs_xdef_t structure
431  */
432 /*----------------------------------------------------------------------------*/
433 
434 cs_xdef_t *
cs_xdef_timestep_create(cs_xdef_type_t type,cs_flag_t state,cs_flag_t meta,void * context)435 cs_xdef_timestep_create(cs_xdef_type_t       type,
436                         cs_flag_t            state,
437                         cs_flag_t            meta,
438                         void                *context)
439 {
440   cs_xdef_t  *d = NULL;
441 
442   BFT_MALLOC(d, 1, cs_xdef_t);
443 
444   d->type = type;
445   d->support = CS_XDEF_SUPPORT_TIME;
446   d->dim = 1;
447   d->z_id = -1;                  /* no associated zone */
448   d->state = state;
449   d->meta = meta;
450   d->qtype = CS_QUADRATURE_NONE; /* default value */
451 
452   switch (type) {
453 
454   case CS_XDEF_BY_VALUE:
455     {
456       double  *_context = (double *)context;
457 
458       BFT_MALLOC(d->context, 1, double);
459 
460       double  *_context_cpy = (double *)d->context;
461       _context_cpy[0] = _context[0];
462 
463       /* Update state flag */
464       d->state |= CS_FLAG_STATE_UNIFORM | CS_FLAG_STATE_STEADY;
465     }
466     break;
467 
468   case CS_XDEF_BY_TIME_FUNCTION:
469     {
470       cs_xdef_time_func_context_t *a = (cs_xdef_time_func_context_t *)context;
471       cs_xdef_time_func_context_t *b = NULL;
472 
473       BFT_MALLOC(b, 1, cs_xdef_time_func_context_t);
474       b->func = a->func;
475       b->input = a->input;
476       b->free_input = a->free_input;
477 
478       d->state |= CS_FLAG_STATE_UNIFORM;
479       d->context = b;
480     }
481     break;
482 
483   default:
484     d->context = context;   /* remark: context is used as an input structure.
485                                The lifecycle of this pointer is not managed by
486                                the current cs_xdef_t structure */
487     break;
488   }
489 
490   return d;
491 }
492 
493 /*----------------------------------------------------------------------------*/
494 /*!
495  * \brief  Free a cs_xdef_t structure
496  *
497  * \param[in, out] d    pointer to a cs_xdef_t structure
498  *
499  * \return NULL
500  */
501 /*----------------------------------------------------------------------------*/
502 
503 cs_xdef_t *
cs_xdef_free(cs_xdef_t * d)504 cs_xdef_free(cs_xdef_t     *d)
505 {
506   if (d == NULL)
507     return d;
508 
509   switch (d->type) {
510 
511   case CS_XDEF_BY_ARRAY:
512     {
513       cs_xdef_array_context_t  *a = (cs_xdef_array_context_t *)d->context;
514       if (a->is_owner)
515         BFT_FREE(a->values);
516       BFT_FREE(d->context);
517     }
518     break;
519 
520   case CS_XDEF_BY_ANALYTIC_FUNCTION:
521     {
522       cs_xdef_analytic_context_t *c = (cs_xdef_analytic_context_t *)d->context;
523 
524       if (c->free_input != NULL)
525         c->input = c->free_input(c->input);
526 
527       BFT_FREE(d->context);
528     }
529     break;
530 
531   case CS_XDEF_BY_DOF_FUNCTION:
532     {
533       cs_xdef_dof_context_t *c = (cs_xdef_dof_context_t *)d->context;
534 
535       if (c->free_input != NULL)
536         c->input = c->free_input(c->input);
537 
538       BFT_FREE(d->context);
539     }
540     break;
541 
542   case CS_XDEF_BY_TIME_FUNCTION:
543     {
544       cs_xdef_time_func_context_t *c =
545         (cs_xdef_time_func_context_t *)d->context;
546 
547       if (c->free_input != NULL)
548         c->input = c->free_input(c->input);
549 
550       BFT_FREE(d->context);
551     }
552     break;
553 
554   case CS_XDEF_BY_VALUE:
555   case CS_XDEF_BY_QOV:
556     BFT_FREE(d->context);
557     break;
558 
559   default:
560     break; /* Nothing special to do e.g. CS_XDEF_BY_FUNCTION */
561   }
562 
563   BFT_FREE(d);
564 
565   return NULL;
566 }
567 
568 /*----------------------------------------------------------------------------*/
569 /*!
570  * \brief  copy a cs_xdef_t structure
571  *
572  * \param[in]  src    pointer to a cs_xdef_t structure to copy
573  *
574  * \return a pointer to a new allocated cs_xdef_t structure
575  */
576 /*----------------------------------------------------------------------------*/
577 
578 cs_xdef_t *
cs_xdef_copy(cs_xdef_t * src)579 cs_xdef_copy(cs_xdef_t     *src)
580 {
581   cs_xdef_t  *cpy = NULL;
582   if (src == NULL)
583     return cpy;
584 
585   /* In the case of a definition by array where the structure is not owner
586      one sets the copy to be owner of the array in order to avoid a memory
587      leak */
588 
589   switch (src->support) {
590 
591   case CS_XDEF_SUPPORT_VOLUME:
592     cpy = cs_xdef_volume_create(src->type,
593                                 src->dim,
594                                 src->z_id,
595                                 src->state,
596                                 src->meta,
597                                 src->context);
598     break;
599 
600   case CS_XDEF_SUPPORT_TIME:
601     cpy = cs_xdef_timestep_create(src->type,
602                                   src->state,
603                                   src->meta,
604                                   src->context);
605     break;
606 
607   case CS_XDEF_SUPPORT_BOUNDARY:
608     cpy = cs_xdef_boundary_create(src->type,
609                                   src->dim,
610                                   src->z_id,
611                                   src->state,
612                                   src->meta,
613                                   src->context);
614     break;
615 
616   default:
617     bft_error(__FILE__, __LINE__, 0, " %s: Invalid case", __func__);
618 
619   }
620 
621   cpy->qtype = src->qtype;
622 
623   return cpy;
624 }
625 
626 /*----------------------------------------------------------------------------*/
627 /*!
628  * \brief In the case of a definition by an analytic function, a time function
629  *        or a function relying on degrees of freedom (DoFs), this function
630  *        allows one to set a more or less complex input data structure.  This
631  *        call should be done before the first evaluation call of the
632  *        associated cs_xdef_t structure.
633  *
634  * \param[in, out]  d         pointer to a cs_xdef_t structure
635  * \param[in]       input     pointer to an input structure
636  */
637 /*----------------------------------------------------------------------------*/
638 
639 void
cs_xdef_set_input_context(cs_xdef_t * d,void * input)640 cs_xdef_set_input_context(cs_xdef_t       *d,
641                           void            *input)
642 {
643   if (d == NULL)
644     return;
645 
646   switch (d->type) {
647 
648   case CS_XDEF_BY_ANALYTIC_FUNCTION:
649     {
650       cs_xdef_analytic_context_t *c = (cs_xdef_analytic_context_t *)d->context;
651 
652       c->input = input;
653     }
654     break;
655 
656   case CS_XDEF_BY_DOF_FUNCTION:
657     {
658       cs_xdef_dof_context_t *c = (cs_xdef_dof_context_t *)d->context;
659 
660       c->input = input;
661     }
662     break;
663 
664   case CS_XDEF_BY_TIME_FUNCTION:
665     {
666       cs_xdef_time_func_context_t *c =
667         (cs_xdef_time_func_context_t *)d->context;
668 
669       c->input = input;
670     }
671     break;
672 
673   default:
674     cs_base_warn(__FILE__, __LINE__);
675     cs_log_printf(CS_LOG_DEFAULT,
676                   " %s: Setting a free input function is ignored.\n"
677                   " The type of definition is not compatible.", __func__);
678     break; /* Nothing special to do */
679 
680   } /* End of switch */
681 }
682 
683 /*----------------------------------------------------------------------------*/
684 /*!
685  * \brief In case of a definition by an analytic function, a time function or a
686  *        function relying on degrees of freedom (DoFs). One can set a function
687  *        to free a complex input data structure (please refer to \ref
688  *        cs_xdef_free_input_t) for more details.
689  *
690  * \param[in, out]  d             pointer to a cs_xdef_t structure
691  * \param[in]       free_input    pointer to a function which free the input
692  *                                structure
693  */
694 /*----------------------------------------------------------------------------*/
695 
696 void
cs_xdef_set_free_input_function(cs_xdef_t * d,cs_xdef_free_input_t * free_input)697 cs_xdef_set_free_input_function(cs_xdef_t               *d,
698                                 cs_xdef_free_input_t    *free_input)
699 {
700   if (d == NULL)
701     return;
702 
703   switch (d->type) {
704 
705   case CS_XDEF_BY_ANALYTIC_FUNCTION:
706     {
707       cs_xdef_analytic_context_t *c = (cs_xdef_analytic_context_t *)d->context;
708 
709       c->free_input = free_input;
710     }
711     break;
712 
713   case CS_XDEF_BY_DOF_FUNCTION:
714     {
715       cs_xdef_dof_context_t *c = (cs_xdef_dof_context_t *)d->context;
716 
717       c->free_input = free_input;
718     }
719     break;
720 
721   case CS_XDEF_BY_TIME_FUNCTION:
722     {
723       cs_xdef_time_func_context_t *c =
724         (cs_xdef_time_func_context_t *)d->context;
725 
726       c->free_input = free_input;
727     }
728     break;
729 
730   default:
731     cs_base_warn(__FILE__, __LINE__);
732     cs_log_printf(CS_LOG_DEFAULT,
733                   " %s: Setting a free input function is ignored.\n"
734                   " The type of definition is not compatible.", __func__);
735     break; /* Nothing special to do */
736 
737   } /* End of switch */
738 }
739 
740 /*----------------------------------------------------------------------------*/
741 /*!
742  * \brief  In case of definition by array, set the array after having added
743  *         this definition
744  *
745  * \param[in, out]  d          pointer to a cs_xdef_t structure
746  * \param[in]       is_owner   manage or not the lifecycle of the array values
747  * \param[in]       array      values
748  */
749 /*----------------------------------------------------------------------------*/
750 
751 void
cs_xdef_set_array(cs_xdef_t * d,bool is_owner,cs_real_t * array)752 cs_xdef_set_array(cs_xdef_t     *d,
753                   bool           is_owner,
754                   cs_real_t     *array)
755 {
756   if (d == NULL)
757     return;
758 
759   if (d->type != CS_XDEF_BY_ARRAY)
760     bft_error(__FILE__, __LINE__, 0,
761               "%s: The given cs_xdef_t structure should be defined by array.",
762               __func__);
763 
764   cs_xdef_array_context_t  *a = (cs_xdef_array_context_t *)d->context;
765 
766   /* An array is already assigned and one manages the lifecycle */
767   if (a->is_owner && a->values != NULL)
768     BFT_FREE(a->values);
769 
770   /* Set the new values */
771   a->is_owner = is_owner;
772   a->values = array;
773 }
774 
775 /*----------------------------------------------------------------------------*/
776 /*!
777  * \brief  In case of definition by array, set the index to get access to the
778  *         array values.
779  *
780  * \param[in, out]  d             pointer to a cs_xdef_t structure
781  * \param[in]       array_index   index on array values
782  */
783 /*----------------------------------------------------------------------------*/
784 
785 void
cs_xdef_set_array_index(cs_xdef_t * d,cs_lnum_t * array_index)786 cs_xdef_set_array_index(cs_xdef_t     *d,
787                         cs_lnum_t     *array_index)
788 {
789   if (d == NULL)
790     return;
791 
792   if (d->type != CS_XDEF_BY_ARRAY)
793     bft_error(__FILE__, __LINE__, 0,
794               "%s: The given cs_xdef_t structure should be defined by array.",
795               __func__);
796 
797   cs_xdef_array_context_t  *ai = (cs_xdef_array_context_t *)d->context;
798 
799   ai->index = array_index;
800 }
801 
802 /*----------------------------------------------------------------------------*/
803 /*!
804  * \brief  Set the type of quadrature to use for evaluating the given
805  *         description
806  *
807  * \param[in, out]  d       pointer to a cs_xdef_t structure
808  * \param[in]       qtype   type of quadrature
809  */
810 /*----------------------------------------------------------------------------*/
811 
812 void
cs_xdef_set_quadrature(cs_xdef_t * d,cs_quadrature_type_t qtype)813 cs_xdef_set_quadrature(cs_xdef_t              *d,
814                        cs_quadrature_type_t    qtype)
815 {
816   if (d == NULL)
817     return;
818 
819   d->qtype = qtype;
820 }
821 
822 /*----------------------------------------------------------------------------*/
823 /*!
824  * \brief  Get the type of quadrature to use for evaluating the given
825  *         description
826  *
827  * \param[in]  d       pointer to a cs_xdef_t structure
828  *
829  * \return the type of quadrature
830  */
831 /*----------------------------------------------------------------------------*/
832 
833 cs_quadrature_type_t
cs_xdef_get_quadrature(cs_xdef_t * d)834 cs_xdef_get_quadrature(cs_xdef_t     *d)
835 {
836   if (d == NULL)
837     return CS_QUADRATURE_NONE;
838 
839   return  d->qtype;
840 }
841 
842 /*----------------------------------------------------------------------------*/
843 /*!
844  * \brief  Retrieve the flag dedicated to the state
845  *
846  * \param[in] d    pointer to a cs_xdef_t structure
847  *
848  * \return the value of the flag
849  */
850 /*----------------------------------------------------------------------------*/
851 
852 cs_xdef_type_t
cs_xdef_get_type(const cs_xdef_t * d)853 cs_xdef_get_type(const cs_xdef_t     *d)
854 {
855   if (d == NULL)
856     return CS_N_XDEF_TYPES;
857   else
858     return d->type;
859 }
860 
861 /*----------------------------------------------------------------------------*/
862 /*!
863  * \brief  Retrieve the flag dedicated to the state
864  *
865  * \param[in] d    pointer to a cs_xdef_t structure
866  *
867  * \return the value of the flag
868  */
869 /*----------------------------------------------------------------------------*/
870 
871 cs_flag_t
cs_xdef_get_state_flag(const cs_xdef_t * d)872 cs_xdef_get_state_flag(const cs_xdef_t     *d)
873 {
874   if (d == NULL)
875     return 0;
876   else
877     return d->state;
878 }
879 
880 /*----------------------------------------------------------------------------*/
881 /*!
882  * \brief  Output the settings related to a cs_xdef_t structure
883  *
884  * \param[in] prefix    optional string
885  * \param[in] d         pointer to a cs_xdef_t structure
886  */
887 /*----------------------------------------------------------------------------*/
888 
889 void
cs_xdef_log(const char * prefix,const cs_xdef_t * d)890 cs_xdef_log(const char          *prefix,
891             const cs_xdef_t     *d)
892 {
893   if (d == NULL)
894     return;
895 
896   bool  is_uniform = false, is_steady = false, is_cellwise = false;
897   if (d->state & CS_FLAG_STATE_UNIFORM)  is_uniform = true;
898   if (d->state & CS_FLAG_STATE_STEADY)   is_steady = true;
899   if (d->state & CS_FLAG_STATE_CELLWISE) is_cellwise = true;
900 
901   const char  *_p;
902   const char _empty_prefix[2] = "";
903   if (prefix == NULL)
904     _p = _empty_prefix;
905   else
906     _p = prefix;
907 
908   cs_log_printf(CS_LOG_SETUP,
909                 "%s | Uniform %s Cellwise %s Steady %s Meta: %u\n",
910                 _p, cs_base_strtf(is_uniform), cs_base_strtf(is_cellwise),
911                 cs_base_strtf(is_steady), d->meta);
912 
913   /* Which support */
914   /* ============= */
915 
916   if (d->support == CS_XDEF_SUPPORT_VOLUME) {
917 
918     const cs_zone_t  *z = cs_volume_zone_by_id(d->z_id);
919     assert(z != NULL);
920     cs_log_printf(CS_LOG_SETUP, "%s | Support:   volume | Zone: %s (id:%5d)\n",
921                   _p, z->name, z->id);
922 
923   }
924   else if (d->support == CS_XDEF_SUPPORT_BOUNDARY) {
925 
926     const cs_zone_t  *z = cs_boundary_zone_by_id(d->z_id);
927     assert(z != NULL);
928     cs_log_printf(CS_LOG_SETUP, "%s | Support: boundary | Zone: %s (id:%5d)\n",
929                   _p, z->name, z->id);
930 
931   }
932   else if (d->support == CS_XDEF_SUPPORT_TIME)
933     cs_log_printf(CS_LOG_SETUP, "%s | Support: time\n", _p);
934 
935   /* Type of definition */
936   /* ================== */
937 
938   switch (d->type) {
939 
940   case CS_XDEF_BY_ANALYTIC_FUNCTION:
941     cs_log_printf(CS_LOG_SETUP, "%s | Definition by an analytical function\n",
942                   _p);
943     break;
944 
945   case CS_XDEF_BY_DOF_FUNCTION:
946     cs_log_printf(CS_LOG_SETUP, "%s | Definition by a DoF function\n", _p);
947     break;
948 
949   case CS_XDEF_BY_ARRAY:
950     cs_log_printf(CS_LOG_SETUP, "%s | Definition by an array\n", _p);
951     break;
952 
953   case CS_XDEF_BY_FIELD:
954     {
955       cs_field_t  *f = (cs_field_t *)d->context;
956 
957       if (f == NULL)
958         bft_error(__FILE__, __LINE__, 0,
959                   " Field pointer is set to NULL in a definition by field");
960 
961       cs_log_printf(CS_LOG_SETUP, "%s | Definition by the field \"%s\"\n",
962                     _p, f->name);
963     }
964     break;
965 
966   case CS_XDEF_BY_FUNCTION:
967     cs_log_printf(CS_LOG_SETUP, "%s | Definition by function\n", _p);
968     break;
969 
970   case CS_XDEF_BY_QOV:
971     cs_log_printf(CS_LOG_SETUP,
972                   "%s | Definition by a quantity over a volume\n", _p);
973     break;
974 
975   case CS_XDEF_BY_SUB_DEFINITIONS:
976     cs_log_printf(CS_LOG_SETUP, "%s | Definition by sub-definitions\n", _p);
977     break;
978 
979   case CS_XDEF_BY_TIME_FUNCTION:
980     cs_log_printf(CS_LOG_SETUP, "%s | Definition by a time function\n", _p);
981     break;
982 
983   case CS_XDEF_BY_VALUE:
984     {
985       cs_real_t *values = (cs_real_t *)d->context;
986 
987       if (d->dim == 1)
988         cs_log_printf(CS_LOG_SETUP, "%s | Definition by_value: % 5.3e\n",
989                       _p, values[0]);
990       else if (d->dim == 3)
991         cs_log_printf(CS_LOG_SETUP, "%s | Definition by_value:"
992                       " [% 5.3e, % 5.3e, % 5.3e]\n",
993                       _p, values[0], values[1], values[2]);
994       else if (d->dim == 9)
995         cs_log_printf(CS_LOG_SETUP, "%s | Definition by_value:"
996                       " [[% 4.2e, % 4.2e, % 4.2e], [% 4.2e, % 4.2e, % 4.2e],"
997                       " [% 4.2e, % 4.2e, % 4.2e]]\n",
998                       _p, values[0], values[1], values[2], values[3], values[4],
999                       values[5], values[6], values[7], values[8]);
1000       else
1001         bft_error(__FILE__, __LINE__, 0,
1002                   " %s: Invalid case. dim = %d (expected 3, 6 or 9)\n",
1003                   __func__, d->dim);
1004     }
1005     break; /* BY_VALUE */
1006 
1007   default:
1008     bft_error(__FILE__, __LINE__, 0, _("%s: Invalid type of description."),
1009               __func__);
1010     break;
1011 
1012   } /* switch on def_type */
1013 
1014   cs_log_printf(CS_LOG_SETUP, "%s | Quadrature: %s\n",
1015                 _p, cs_quadrature_get_type_name(d->qtype));
1016 
1017 }
1018 
1019 /*----------------------------------------------------------------------------*/
1020 /*!
1021  * \brief  Retrieve a pointer to the cs_xdef_type's name string
1022  *
1023  * \param[in] xdef_type  type to query
1024  *
1025  * \return a pointer to mathing name string
1026  */
1027 /*----------------------------------------------------------------------------*/
1028 
1029 const char *
cs_xdef_type_get_name(cs_xdef_type_t xdef_type)1030 cs_xdef_type_get_name(cs_xdef_type_t  xdef_type)
1031 {
1032   if (xdef_type < 0 || xdef_type >= CS_N_XDEF_TYPES)
1033     xdef_type = CS_N_XDEF_TYPES;
1034 
1035   return _xdef_type_name[xdef_type];
1036 }
1037 
1038 /*----------------------------------------------------------------------------*/
1039 
1040 END_C_DECLS
1041