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