/*============================================================================
*
* Code_Saturne version 1.3
* ------------------------
*
*
* This file is part of the Code_Saturne Kernel, element of the
* Code_Saturne CFD tool.
*
* Copyright (C) 1998-2007 EDF S.A., France
*
* contact: saturne-support@edf.fr
*
* The Code_Saturne Kernel is free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* The Code_Saturne Kernel is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the Code_Saturne Kernel; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*
*============================================================================*/
/*============================================================================
* Définitions, variables globales, et fonctions associées au post traitement
*============================================================================*/
/* includes système */
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Includes BFT */
#include <bft_config.h>
#include <bft_mem.h>
#include <bft_printf.h>
/* Includes FVM */
#include <fvm_nodal.h>
#include <fvm_writer.h>
/* Includes librairie */
#include "cs_base.h"
#include "cs_maillage.h"
#include "cs_maillage_connect.h"
#include "cs_post.h"
#ifdef __cplusplus
extern "C" {
#if 0
} /* Fausse accolade pour ramener l'auto-indentation d'Emacs à la colonne 0 */
#endif
#endif /* __cplusplus */
/*============================================================================
* Définitions d'énumerations
*============================================================================*/
/*----------------------------------------------------------------------------
* Type de support de maillage
*----------------------------------------------------------------------------*/
typedef enum {
CS_POST_SUPPORT_CEL, /* Valeurs associées aux cellules */
CS_POST_SUPPORT_FAC_INT, /* Valeurs associées aux faces internes */
CS_POST_SUPPORT_FAC_BRD, /* Valeurs associées aux faces de bord */
CS_POST_SUPPORT_SOM /* Valeurs associées aux sommets */
} cs_post_support_t;
/*============================================================================
* Structures locales
*============================================================================*/
/* Structure définissant un "writer" : cet objet correspond au choix d'un
* nom de cas, de répertoire, et de format, ainsi qu'un indicateur précisant
* si les maillages associés doivent dépendre ou non du temps, et la
* fréquence de sortie par défaut pour les variables associées. */
struct _cs_post_writer_t {
cs_int_t id; /* Identificateur (< 0 pour writer
standard ou développeur, > 0 pour
writer utilisateur */
cs_int_t freq_sortie; /* Fréquence de sortie par défaut
associée */
cs_bool_t ecr_depl; /* Ecriture d'un champ déplacement
si vrai */
int actif; /* 0 si pas de sortie au pas de
temps courant, 1 en cas de sortie */
fvm_writer_t *writer; /* Gestionnaire d'écriture associé */
};
/* Structure définissant un maillage de post traitement ; cet objet
* gère le lien entre un tel maillage et les "writers" associés. */
struct _cs_post_maillage_t {
int id; /* Identificateur (< 0 pour maillage
standard ou développeur, > 0 pour
maillage utilisateur */
int ind_ent[3]; /* Présence de cellules (ind_ent[0],
de faces internes (ind_ent[1]),
ou de faces de bord (ind_ent[2])
sur un processeur au moins */
int alias; /* Si > -1, indice dans le tableau
des maillages de post traitement
du premier maillage partageant
le même maillage externe */
int nbr_writers; /* Nombre de gestionnaires de sortie */
int *ind_writer; /* Tableau des indices des
* gestionnaires de sortie associés */
int nt_ecr; /* Numéro du pas de temps de la
dernière écriture (-1 avant la
première écriture) */
cs_int_t nbr_fac; /* Nombre de faces internes associées */
cs_int_t nbr_fbr; /* Nombre de faces de bord associées */
const fvm_nodal_t *maillage_ext; /* Maillage externe associé */
fvm_nodal_t *_maillage_ext; /* Maillage externe associé, si
propriétaire */
fvm_writer_time_dep_t ind_mod_min; /* Indicateur de possibilité de
modification au cours du temps */
fvm_writer_time_dep_t ind_mod_max; /* Indicateur de possibilité de
modification au cours du temps */
};
/*============================================================================
* Variables globales statiques
*============================================================================*/
/* Tableau de sauvegarde des coordonnées initiales des sommets */
static cs_bool_t cs_glob_post_deformable = CS_FALSE;
static cs_real_t *cs_glob_post_coo_som_ini = NULL;
/* Tableau des maillages externes associés aux post-traitements */
/* (maillages, -1 et -2 réservés, donc numérotation commence -2)*/
static int cs_glob_post_num_maillage_min = -2;
static int cs_glob_post_nbr_maillages = 0;
static int cs_glob_post_nbr_maillages_max = 0;
static cs_post_maillage_t *cs_glob_post_maillages = NULL;
/* Tableau des writers d'écriture associés aux post-traitements */
static int cs_glob_post_nbr_writers = 0;
static int cs_glob_post_nbr_writers_max = 0;
static cs_post_writer_t *cs_glob_post_writers = NULL;
/* Tableau des fonctions et instances enregistrés */
static int cs_glob_post_nbr_var_tp = 0;
static int cs_glob_post_nbr_var_tp_max = 0;
static cs_post_var_temporelle_t **cs_glob_post_f_var_tp = NULL;
static int *cs_glob_post_i_var_tp = NULL;
/*============================================================================
* Définitions de macros
*============================================================================*/
/*============================================================================
* Prototypes de fonctions privées
*============================================================================*/
/*----------------------------------------------------------------------------
* Conversion d'un type de données cs_post_type_t en type fvm_datatype_t.
*----------------------------------------------------------------------------*/
static fvm_datatype_t _cs_post_cnv_datatype
(
cs_post_type_t type_cs
);
/*----------------------------------------------------------------------------
* Recherche de l'indice d'un writer associé à un numéro donné.
*----------------------------------------------------------------------------*/
static int _cs_post_ind_writer
(
const cs_int_t id_writer /* --> numéro du writer */
);
/*----------------------------------------------------------------------------
* Recherche de l'indice d'un maillage de post traitement associé à un
* numéro donné.
*----------------------------------------------------------------------------*/
static int _cs_post_ind_maillage
(
const cs_int_t nummai /* --> numéro du maillage externe associé */
);
/*----------------------------------------------------------------------------
* Ajout d'un maillage de post traitement et initialisation de base,
* et renvoi d'un pointeur sur la structure associée
*----------------------------------------------------------------------------*/
static cs_post_maillage_t * _cs_post_ajoute_maillage
(
const cs_int_t id_maillage /* --> numéro du maillage demandé */
);
/*----------------------------------------------------------------------------
* Création d'un maillage de post traitement ; les listes de cellules ou
* faces à extraire sont triées en sortie, qu'elles le soient déjà en entrée
* ou non.
*
* La liste des cellules associées n'est nécessaire que si le nombre
* de cellules à extraire est strictement supérieur à 0 et inférieur au
* nombre de cellules du maillage.
*
* Les listes de faces ne sont prises en compte que si le nombre de cellules
* à extraire est nul ; si le nombre de faces de bord à extraire est égal au
* nombre de faces de bord du maillage global, et le nombre de faces internes
* à extraire est nul, alors on extrait par défaut le maillage de bord, et la
* liste des faces de bord associée n'est donc pas nécessaire.
*----------------------------------------------------------------------------*/
static void _cs_post_definit_maillage
(
cs_post_maillage_t *const maillage_post, /* <-> maillage post à compléter */
const char *const nom_maillage, /* --> nom du maillage externe */
const cs_int_t nbr_cel, /* --> nombre de cellules */
const cs_int_t nbr_fac, /* --> nombre de faces internes */
const cs_int_t nbr_fbr, /* --> nombre de faces de bord */
cs_int_t liste_cel[], /* <-> liste des cellules */
cs_int_t liste_fac[], /* <-> liste des faces internes */
cs_int_t liste_fbr[] /* <-> liste des faces de bord */
);
/*----------------------------------------------------------------------------
* Mise à jour en cas d'alias des critères de modification au cours du temps
* des maillages en fonction des propriétés des writers qui lui
* sont associés :
*
* La topologie d'un maillage ne pourra pas être modifiée si le critère
* de modification minimal résultant est trop faible (i.e. si l'un des
* writers associés ne permet pas la redéfinition de la topologie du maillage).
*
* Les coordonnées des sommets et la connectivité ne pourront être libérés
* de la mémoire si la critère de modification maximal résultant est trop
* élevé (i.e. si l'un des writers associés permet l'évolution du maillage
* en temps, et nécessite donc sa réécriture).
*----------------------------------------------------------------------------*/
static void _cs_post_ind_mod_alias
(
const int indmai /* --> indice du maillage post en cours */
);
/*----------------------------------------------------------------------------
* Découpage des polygones ou polyèdres en éléments simples si nécessaire.
*----------------------------------------------------------------------------*/
static void _cs_post_divise_poly
(
cs_post_maillage_t *const maillage_post, /* --> maillage ext. associé */
const cs_post_writer_t *const writer /* --> writer associé */
);
/*----------------------------------------------------------------------------
* Ecriture d'un maillage de post traitement en fonction des "writers".
*----------------------------------------------------------------------------*/
static void _cs_post_ecrit_maillage
(
cs_post_maillage_t *const maillage_post,
const cs_int_t nt_cur_abs, /* --> numéro de pas de temps */
const cs_real_t t_cur_abs /* --> temps physique courant */
);
/*----------------------------------------------------------------------------
* Assemblage des valeurs d'une variable définie sur une combinaison de
* faces de bord et de faces internes (sans indirection) en un tableau
* défini sur un ensemble unique de faces.
*
* La variable résultante n'est pas entrelacée.
*----------------------------------------------------------------------------*/
static void _cs_post_assmb_var_faces
(
const fvm_nodal_t *const maillage_ext, /* --> maillage externe */
const cs_int_t nbr_fac, /* --> nb faces internes */
const cs_int_t nbr_fbr, /* --> nb faces bord */
const int dim_var, /* --> dim. variable */
const fvm_interlace_t interlace, /* --> indic. entrelacage */
const cs_real_t var_fac[], /* --> valeurs faces int. */
const cs_real_t var_fbr[], /* --> valeurs faces bord */
cs_real_t var_tmp[] /* <-- valeurs assemblées */
);
/*----------------------------------------------------------------------------
* Transformation d'un tableau d'indicateurs (marqueurs) en liste ;
* renvoie la taille effective de la liste.
*----------------------------------------------------------------------------*/
static cs_int_t _cs_post_ind_vers_liste
(
cs_int_t nbr, /* <-> taille indicateur */
cs_int_t liste[] /* <-> indicateur, puis liste */
);
/*----------------------------------------------------------------------------
* Boucle sur les maillages de post traitement pour écriture des variables
*----------------------------------------------------------------------------*/
static void _cs_post_ecrit_deplacements
(
const cs_int_t nt_cur_abs, /* --> numéro de pas de temps courant */
const cs_real_t t_cur_abs /* --> valeur du temps physique associé */
);
/*============================================================================
* Prototypes de fonctions Fortran appellées
*============================================================================*/
/*----------------------------------------------------------------------------
* Fonction développeur pour la sortie de variables sur un maillage post
*----------------------------------------------------------------------------*/
void CS_PROCF (dvvpst, DVVPST)
(
const cs_int_t *const idbia0, /* --> numéro 1ère case libre dans IA */
const cs_int_t *const idbra0, /* --> numéro 1ère case libre dans RA */
const cs_int_t *const nummai, /* --> numéro du maillage post */
const cs_int_t *const ndim, /* --> dimension de l'espace */
const cs_int_t *const ncelet, /* --> nombre de cellules étendu */
const cs_int_t *const ncel, /* --> nombre de cellules */
const cs_int_t *const nfac, /* --> nombre de faces internes */
const cs_int_t *const nfabor, /* --> nombre de faces de bord */
const cs_int_t *const nfml, /* --> nombre de familles */
const cs_int_t *const nprfml, /* --> nombre de proprietes des familles */
const cs_int_t *const nnod, /* --> nombre de sommets */
const cs_int_t *const lndfac, /* --> longueur de nodfac */
const cs_int_t *const lndfbr, /* --> longueur de nodfbr */
const cs_int_t *const ncelbr, /* --> nombre de cellules de bord */
const cs_int_t *const nvar, /* --> nombre de variables */
const cs_int_t *const nscal, /* --> nombre de scalaires */
const cs_int_t *const nphas, /* --> nombre de phases */
const cs_int_t *const nvlsta, /* --> nombre de variables stat. (lagr) */
const cs_int_t *const nvisbr, /* --> nombre de variables stat. (lagr) */
const cs_int_t *const ncelps, /* --> nombre de cellules post */
const cs_int_t *const nfacps, /* --> nombre de faces internes post */
const cs_int_t *const nfbrps, /* --> nombre de faces de bord post */
const cs_int_t *const nideve, /* --> longueur du tableau idevel[] */
const cs_int_t *const nrdeve, /* --> longueur du tableau rdevel[] */
const cs_int_t *const nituse, /* --> longueur du tableau ituser[] */
const cs_int_t *const nrtuse, /* --> longueur du tableau rtuser[] */
const cs_int_t itypps[], /* --> indicateur (0 ou 1) de présence */
/* de cellules, faces internes et bord */
const cs_int_t ifacel[], /* --> connect. faces internes / cellules */
const cs_int_t ifabor[], /* --> connect. faces de bord / cellules */
const cs_int_t ifmfbr[], /* --> liste des familles des faces bord */
const cs_int_t ifmcel[], /* --> liste des familles des cellules */
const cs_int_t iprfml[], /* --> liste des propriétés des familles */
const cs_int_t ipnfac[], /* --> rang ds nodfac 1er sommet faces int */
const cs_int_t nodfac[], /* --> numéro des sommets des faces int */
const cs_int_t ipnfbr[], /* --> rang ds nodfbr 1er sommt faces brd */
const cs_int_t nodfbr[], /* --> numéro des sommets des faces bord */
const cs_int_t lstcel[], /* --> liste des cellules post */
const cs_int_t lstfac[], /* --> liste des faces internes post */
const cs_int_t lstfbr[], /* --> liste des faces de bord post */
const cs_int_t idevel[], /* --> tab. complémentaire développeur */
const cs_int_t ituser[], /* --> tab. complémentaire utilisateur */
const cs_int_t ia[], /* --> macro-tableau entier */
const cs_real_t xyzcen[], /* --> c.d.g. des cellules */
const cs_real_t surfac[], /* --> surfaces des faces internes */
const cs_real_t surfbo[], /* --> surfaces des faces de bord */
const cs_real_t cdgfac[], /* --> c.d.g. des faces internes */
const cs_real_t cdgfbo[], /* --> c.d.g. des faces de bord */
const cs_real_t xyznod[], /* --> coordonnées des sommets */
const cs_real_t volume[], /* --> volumes des cellules */
const cs_real_t dt[], /* --> pas de temps */
const cs_real_t rtpa[], /* --> variables aux cellules (préc.) */
const cs_real_t rtp[], /* --> variables aux cellules */
const cs_real_t propce[], /* --> propriétés physiques cellules */
const cs_real_t propfa[], /* --> propriétés physiques aux faces */
const cs_real_t propfb[], /* --> propriétés physiques faces bord */
const cs_real_t coefa[], /* --> cond. limites aux faces de bord */
const cs_real_t coefb[], /* --> cond. limites aux faces de bord */
const cs_real_t statce[], /* --> moy. statistiques (Lagrangien) */
const cs_real_t stativ[], /* --> var. statistiques (Lagrangien) */
const cs_real_t statfb[], /* --> moy. statistiques (Lagrangien) */
const cs_real_t valcel[], /* --- vals. aux cellules post */
const cs_real_t valfac[], /* --- vals. aux faces internes post */
const cs_real_t valfbr[], /* --- vals. aux faces de bord post */
const cs_real_t rdevel[], /* --> tab. complémentaire développeur */
const cs_real_t rtuser[], /* --> tab. complémentaire utilisateur */
const cs_real_t ra[] /* --> macro-tableau réel */
);
/*----------------------------------------------------------------------------
* Fonction utilisateur pour la modification d'un maillage post
*----------------------------------------------------------------------------*/
void CS_PROCF (usmpst, USMPST)
(
const cs_int_t *const idbia0, /* --> numéro 1ère case libre dans IA */
const cs_int_t *const idbra0, /* --> numéro 1ère case libre dans RA */
const cs_int_t *const nummai, /* --> numéro du maillage post */
const cs_int_t *const ndim, /* --> dimension de l'espace */
const cs_int_t *const ncelet, /* --> nombre de cellules étendu */
const cs_int_t *const ncel, /* --> nombre de cellules */
const cs_int_t *const nfac, /* --> nombre de faces internes */
const cs_int_t *const nfabor, /* --> nombre de faces de bord */
const cs_int_t *const nfml, /* --> nombre de familles */
const cs_int_t *const nprfml, /* --> nombre de proprietes des familles */
const cs_int_t *const nnod, /* --> nombre de sommets */
const cs_int_t *const lndfac, /* --> longueur de nodfac */
const cs_int_t *const lndfbr, /* --> longueur de nodfbr */
const cs_int_t *const ncelbr, /* --> nombre de cellules de bord */
const cs_int_t *const nvar, /* --> nombre de variables */
const cs_int_t *const nscal, /* --> nombre de scalaires */
const cs_int_t *const nphas, /* --> nombre de phases */
const cs_int_t *const nvlsta, /* --> nombre de variables stat. (lagr) */
const cs_int_t *const ncelps, /* --> nombre de cellules post */
const cs_int_t *const nfacps, /* --> nombre de faces internes post */
const cs_int_t *const nfbrps, /* --> nombre de faces de bord post */
const cs_int_t *const nideve, /* --> longueur du tableau idevel[] */
const cs_int_t *const nrdeve, /* --> longueur du tableau rdevel[] */
const cs_int_t *const nituse, /* --> longueur du tableau ituser[] */
const cs_int_t *const nrtuse, /* --> longueur du tableau rtuser[] */
cs_int_t *const imodif, /* <-- 0 si maillage non modifié, 1 sinon */
const cs_int_t itypps[], /* --> indicateur (0 ou 1) de présence */
/* de cellules, faces internes et bord */
const cs_int_t ifacel[], /* --> connect. faces internes / cellules */
const cs_int_t ifabor[], /* --> connect. faces de bord / cellules */
const cs_int_t ifmfbr[], /* --> liste des familles des faces bord */
const cs_int_t ifmcel[], /* --> liste des familles des cellules */
const cs_int_t iprfml[], /* --> liste des propriétés des familles */
const cs_int_t ipnfac[], /* --> rang ds nodfac 1er sommet faces int */
const cs_int_t nodfac[], /* --> numéro des sommets des faces int */
const cs_int_t ipnfbr[], /* --> rang ds nodfbr 1er sommt faces brd */
const cs_int_t nodfbr[], /* --> numéro des sommets des faces bord */
const cs_int_t lstcel[], /* --> liste des cellules post */
const cs_int_t lstfac[], /* --> liste des faces internes post */
const cs_int_t lstfbr[], /* --> liste des faces de bord post */
const cs_int_t idevel[], /* --> tab. complémentaire développeur */
const cs_int_t ituser[], /* --> tab. complémentaire utilisateur */
const cs_int_t ia[], /* --> macro-tableau entier */
const cs_real_t xyzcen[], /* --> c.d.g. des cellules */
const cs_real_t surfac[], /* --> surfaces des faces internes */
const cs_real_t surfbo[], /* --> surfaces des faces de bord */
const cs_real_t cdgfac[], /* --> c.d.g. des faces internes */
const cs_real_t cdgfbo[], /* --> c.d.g. des faces de bord */
const cs_real_t xyznod[], /* --> coordonnées des sommets */
const cs_real_t volume[], /* --> volumes des cellules */
const cs_real_t dt[], /* --> pas de temps */
const cs_real_t rtpa[], /* --> variables aux cellules (préc.) */
const cs_real_t rtp[], /* --> variables aux cellules */
const cs_real_t propce[], /* --> propriétés physiques cellules */
const cs_real_t propfa[], /* --> propriétés physiques aux faces */
const cs_real_t propfb[], /* --> propriétés physiques faces bord */
const cs_real_t coefa[], /* --> cond. limites aux faces de bord */
const cs_real_t coefb[], /* --> cond. limites aux faces de bord */
const cs_real_t statce[], /* --> moy. statistiques (Lagrangien) */
const cs_real_t valcel[], /* --- vals. aux cellules post */
const cs_real_t valfac[], /* --- vals. aux faces internes post */
const cs_real_t valfbr[], /* --- vals. aux faces de bord post */
const cs_real_t rdevel[], /* --> tab. complémentaire développeur */
const cs_real_t rtuser[], /* --> tab. complémentaire utilisateur */
const cs_real_t ra[] /* --> macro-tableau réel */
);
/*----------------------------------------------------------------------------
* Fonction utilisateur pour la sortie de variables sur un maillage post
*----------------------------------------------------------------------------*/
void CS_PROCF (usvpst, USVPST)
(
const cs_int_t *const idbia0, /* --> numéro 1ère case libre dans IA */
const cs_int_t *const idbra0, /* --> numéro 1ère case libre dans RA */
const cs_int_t *const nummai, /* --> numéro du maillage post */
const cs_int_t *const ndim, /* --> dimension de l'espace */
const cs_int_t *const ncelet, /* --> nombre de cellules étendu */
const cs_int_t *const ncel, /* --> nombre de cellules */
const cs_int_t *const nfac, /* --> nombre de faces internes */
const cs_int_t *const nfabor, /* --> nombre de faces de bord */
const cs_int_t *const nfml, /* --> nombre de familles */
const cs_int_t *const nprfml, /* --> nombre de proprietes des familles */
const cs_int_t *const nnod, /* --> nombre de sommets */
const cs_int_t *const lndfac, /* --> longueur de nodfac */
const cs_int_t *const lndfbr, /* --> longueur de nodfbr */
const cs_int_t *const ncelbr, /* --> nombre de cellules de bord */
const cs_int_t *const nvar, /* --> nombre de variables */
const cs_int_t *const nscal, /* --> nombre de scalaires */
const cs_int_t *const nphas, /* --> nombre de phases */
const cs_int_t *const nvlsta, /* --> nombre de variables stat. (lagr) */
const cs_int_t *const ncelps, /* --> nombre de cellules post */
const cs_int_t *const nfacps, /* --> nombre de faces internes post */
const cs_int_t *const nfbrps, /* --> nombre de faces de bord post */
const cs_int_t *const nideve, /* --> longueur du tableau idevel[] */
const cs_int_t *const nrdeve, /* --> longueur du tableau rdevel[] */
const cs_int_t *const nituse, /* --> longueur du tableau ituser[] */
const cs_int_t *const nrtuse, /* --> longueur du tableau rtuser[] */
const cs_int_t itypps[], /* --> indicateur (0 ou 1) de présence */
/* de cellules, faces internes et bord */
const cs_int_t ifacel[], /* --> connect. faces internes / cellules */
const cs_int_t ifabor[], /* --> connect. faces de bord / cellules */
const cs_int_t ifmfbr[], /* --> liste des familles des faces bord */
const cs_int_t ifmcel[], /* --> liste des familles des cellules */
const cs_int_t iprfml[], /* --> liste des propriétés des familles */
const cs_int_t ipnfac[], /* --> rang ds nodfac 1er sommet faces int */
const cs_int_t nodfac[], /* --> numéro des sommets des faces int */
const cs_int_t ipnfbr[], /* --> rang ds nodfbr 1er sommt faces brd */
const cs_int_t nodfbr[], /* --> numéro des sommets des faces bord */
const cs_int_t lstcel[], /* --> liste des cellules post */
const cs_int_t lstfac[], /* --> liste des faces internes post */
const cs_int_t lstfbr[], /* --> liste des faces de bord post */
const cs_int_t idevel[], /* --> tab. complémentaire développeur */
const cs_int_t ituser[], /* --> tab. complémentaire utilisateur */
const cs_int_t ia[], /* --> macro-tableau entier */
const cs_real_t xyzcen[], /* --> c.d.g. des cellules */
const cs_real_t surfac[], /* --> surfaces des faces internes */
const cs_real_t surfbo[], /* --> surfaces des faces de bord */
const cs_real_t cdgfac[], /* --> c.d.g. des faces internes */
const cs_real_t cdgfbo[], /* --> c.d.g. des faces de bord */
const cs_real_t xyznod[], /* --> coordonnées des sommets */
const cs_real_t volume[], /* --> volumes des cellules */
const cs_real_t dt[], /* --> pas de temps */
const cs_real_t rtpa[], /* --> variables aux cellules (préc.) */
const cs_real_t rtp[], /* --> variables aux cellules */
const cs_real_t propce[], /* --> propriétés physiques cellules */
const cs_real_t propfa[], /* --> propriétés physiques aux faces */
const cs_real_t propfb[], /* --> propriétés physiques faces bord */
const cs_real_t coefa[], /* --> cond. limites aux faces de bord */
const cs_real_t coefb[], /* --> cond. limites aux faces de bord */
const cs_real_t statce[], /* --> moy. statistiques (Lagrangien) */
const cs_real_t valcel[], /* --- vals. aux cellules post */
const cs_real_t valfac[], /* --- vals. aux faces internes post */
const cs_real_t valfbr[], /* --- vals. aux faces de bord post */
const cs_real_t rdevel[], /* --> tab. complémentaire développeur */
const cs_real_t rtuser[], /* --> tab. complémentaire utilisateur */
const cs_real_t ra[] /* --> macro-tableau réel */
);
/*----------------------------------------------------------------------------
* Fonction récupèrant les paramètres contenus dans les commons FORTRAN qui
* sont utiles à l'initialisation du post-traitement.
*----------------------------------------------------------------------------*/
void CS_PROCF (inipst, INIPST)
(
const cs_int_t *const ichrvl, /* --> indic. de post du volume fluide */
const cs_int_t *const ichrbo, /* --> indic. de post des faces de bord */
const cs_int_t *const ichrsy, /* --> indic. de post des faces de bord */
/* couplées avec Syrthes */
const cs_int_t *const ipstmd, /* --> indic. de maillage déformable */
/* 0 : pas de déformation */
/* 1 : déformation des maillages post */
/* 2 : écriture d'un champ déplacement */
const cs_int_t *const ntchr, /* --> fréquence des sorties post */
const char *const fmtchr, /* --> nom du format de post-traitement */
const char *const optchr /* --> options du format de post */
);
/*============================================================================
* Fonctions publiques pour l'API Fortran
*============================================================================*/
/*----------------------------------------------------------------------------
* Création d'un "writer" à partir des données du Fortran.
*
* Interface Fortran : utiliser PSTCWR (voir cs_post_util.F)
*----------------------------------------------------------------------------*/
void CS_PROCF (pstcw1, PSTCW1)
(
const cs_int_t *const numwri, /* --> numéro du writer à créer
* < 0 pour writer réservé,
* > 0 pour writer utilisateur) */
const char *const nomcas, /* --> nom du cas associé */
const char *const nomrep, /* --> nom de répertoire associé */
const char *const nomfmt, /* --> nom de format associé */
const char *const optfmt, /* --> options associées au format */
const cs_int_t *const lnmcas, /* --> longueur du nom du cas */
const cs_int_t *const lnmrep, /* --> longueur du nom du répertoire */
const cs_int_t *const lnmfmt, /* --> longueur du nom du format */
const cs_int_t *const lopfmt, /* --> longueur des options du format */
const cs_int_t *const indmod, /* --> 0 si figé, 1 si déformable,
* 2 si topologie change */
const cs_int_t *const ntchr /* --> fréquence de sortie par défaut */
CS_ARGF_SUPP_CHAINE /* (arguments 'longueur' éventuels,
Fortran, inutilisés lors de
l'appel mais placés par de
nombreux compilateurs) */
)
{
/* variables locales */
char *nom_cas;
char *nom_rep;
char *nom_format;
char *opt_format;
/* Conversion des chaînes de caractères Fortran en chaînes C */
nom_cas = cs_base_chaine_f_vers_c_cree(nomcas, *lnmcas);
nom_rep = cs_base_chaine_f_vers_c_cree(nomrep, *lnmrep);
nom_format = cs_base_chaine_f_vers_c_cree(nomfmt, *lnmfmt);
opt_format = cs_base_chaine_f_vers_c_cree(optfmt, *lopfmt);
/* Traitement principal */
cs_post_ajoute_writer(*numwri,
nom_cas,
nom_rep,
nom_format,
opt_format,
*indmod,
*ntchr);
/* Libération des chaînes C temporaires */
nom_cas = cs_base_chaine_f_vers_c_detruit(nom_cas);
nom_rep = cs_base_chaine_f_vers_c_detruit(nom_rep);
nom_format = cs_base_chaine_f_vers_c_detruit(nom_format);
opt_format = cs_base_chaine_f_vers_c_detruit(opt_format);
}
/*----------------------------------------------------------------------------
* Création d'un maillage de post traitement à partir des données du
* Fortran.
*
* Interface Fortran : utiliser PSTCMA (voir cs_post_util.F)
*----------------------------------------------------------------------------*/
void CS_PROCF (pstcm1, PSTCM1)
(
const cs_int_t *const nummai, /* --> numéro du maillage à créer (< 0 pour
* maillage standard ou développeur,
* > 0 pour maillage utilisateur) */
const char *const nommai, /* --> nom du maillage externe */
const cs_int_t *const lnmmai, /* --> longueur du nom du maillage */
const cs_int_t *const nbrcel, /* --> nombre de cellules */
const cs_int_t *const nbrfac, /* --> nombre de faces internes */
const cs_int_t *const nbrfbr, /* --> nombre de faces de bord */
cs_int_t lstcel[], /* <-> liste des cellules */
cs_int_t lstfac[], /* <-> liste des faces internes */
cs_int_t lstfbr[] /* <-> liste des faces de bord */
CS_ARGF_SUPP_CHAINE /* (arguments 'longueur' éventuels,
Fortran, inutilisés lors de
l'appel mais placés par de
nombreux compilateurs) */
)
{
/* variables locales */
char *nom_maillage;
/* Conversion des chaînes de caractères Fortran en chaînes C */
nom_maillage = cs_base_chaine_f_vers_c_cree(nommai, *lnmmai);
/* Traitement principal */
cs_post_ajoute_maillage(*nummai,
nom_maillage,
*nbrcel,
*nbrfac,
*nbrfbr,
lstcel,
lstfac,
lstfbr);
/* Libération des chaînes C temporaires */
nom_maillage = cs_base_chaine_f_vers_c_detruit(nom_maillage);
}
/*----------------------------------------------------------------------------
* Création d'un alias sur un maillage de post traitement.
*
* Interface Fortran :
*
* SUBROUTINE PSTALM (NUMMAI, NUMWRI)
* *****************
*
* INTEGER NUMMAI : --> : Numéro de l'alias à créer
* INTEGER NUMREF : --> : Numéro du maillage externe associé
*----------------------------------------------------------------------------*/
void CS_PROCF (pstalm, PSTALM)
(
const cs_int_t *nummai, /* --> numéro de l'alias à créer */
const cs_int_t *numref /* --> numéro du maillage associe */
)
{
cs_post_alias_maillage(*nummai, *numref);
}
/*----------------------------------------------------------------------------
* Association d'un "writer" à un maillage pour le post traitement.
*
* Interface Fortran :
*
* SUBROUTINE PSTASS (NUMMAI, NUMWRI)
* *****************
*
* INTEGER NUMMAI : --> : Numéro du maillage externe associé
* INTEGER NUMWRI : --> : Numéro du writer
*----------------------------------------------------------------------------*/
void CS_PROCF (pstass, PSTASS)
(
const cs_int_t *nummai, /* --> numéro du maillage externe associé */
const cs_int_t *numwri /* --> numéro du writer */
)
{
cs_post_associe(*nummai, *numwri);
}
/*----------------------------------------------------------------------------
* Mise à jour de l'indicateur "actif" ou "inactif" des "writers" en
* fonction du pas de temps et de leur fréquence de sortie par défaut.
*
* Interface Fortran :
*
* SUBROUTINE PSTNTC (NTCABS)
* *****************
*
* INTEGER NTCABS : --> : Numéro du pas de temps
*----------------------------------------------------------------------------*/
void CS_PROCF (pstntc, PSTNTC)
(
const cs_int_t *ntcabs /* --> numéro de pas de temps associé */
)
{
cs_post_activer_selon_defaut(*ntcabs);
}
/*----------------------------------------------------------------------------
* Forcer de l'indicateur "actif" ou "inactif" d'un "writers" spécifique
* ou de l'ensemble des "writers" pour le pas de temps en cours.
*
* Interface Fortran :
*
* SUBROUTINE PSTACT (NTCABS, TTCABS)
* *****************
*
* INTEGER NUMWRI : --> : Numéro du writer, ou 0 pour forcer
* : : simultanément tous les writers
* INTEGER INDACT : --> : 0 pour désactiver, 1 pour activer
*----------------------------------------------------------------------------*/
void CS_PROCF (pstact, PSTACT)
(
const cs_int_t *numwri, /* --> numéro du writer, ou 0 pour forcer
* simultanément tous les writers */
const cs_int_t *indact /* --> 0 pour désactiver, 1 pour activer */
)
{
cs_post_activer_writer(*numwri,
*indact);
}
/*----------------------------------------------------------------------------
* Ecriture des maillages de post traitement en fonction des gestionnaires
* de sortie associés.
*
* Interface Fortran :
*
* SUBROUTINE PSTEMA (NTCABS, TTCABS)
* *****************
*
* INTEGER NTCABS : --> : Numéro du pas de temps
* DOUBLE PRECISION TTCABS : --> : Temps physique associé
*----------------------------------------------------------------------------*/
void CS_PROCF (pstema, PSTEMA)
(
const cs_int_t *ntcabs, /* --> numéro de pas de temps associé */
const cs_real_t *ttcabs /* --> valeur du pas de temps associé */
)
{
cs_post_ecrit_maillages(*ntcabs, *ttcabs);
}
/*----------------------------------------------------------------------------
* Boucle sur les maillages de post traitement pour écriture des variables
*----------------------------------------------------------------------------*/
void CS_PROCF (pstvar, PSTVAR)
(
const cs_int_t *const idbia0, /* --> numéro 1ère case libre dans IA */
const cs_int_t *const idbra0, /* --> numéro 1ère case libre dans RA */
const cs_int_t *const ndim, /* --> dimension de l'espace */
const cs_int_t *const ntcabs, /* --> numéro de pas de temps courant */
const cs_int_t *const ncelet, /* --> nombre de cellules étendu */
const cs_int_t *const ncel, /* --> nombre de cellules */
const cs_int_t *const nfac, /* --> nombre de faces internes */
const cs_int_t *const nfabor, /* --> nombre de faces de bord */
const cs_int_t *const nfml, /* --> nombre de familles */
const cs_int_t *const nprfml, /* --> nombre de proprietes des familles*/
const cs_int_t *const nnod, /* --> nombre de noeuds */
const cs_int_t *const lndfac, /* --> longueur de nodfac */
const cs_int_t *const lndfbr, /* --> longueur de nodfbr */
const cs_int_t *const ncelbr, /* --> nombre de cellules de bord */
const cs_int_t *const nvar, /* --> nombre de variables */
const cs_int_t *const nscal, /* --> nombre de scalaires */
const cs_int_t *const nphas, /* --> nombre de phases */
const cs_int_t *const nvlsta, /* --> nombre de variables stat. (lagr) */
const cs_int_t *const nvisbr, /* --> nombre de variables stat. (lagr) */
const cs_int_t *const nideve, /* --> longueur du tableau idevel[] */
const cs_int_t *const nrdeve, /* --> longueur du tableau rdevel[] */
const cs_int_t *const nituse, /* --> longueur du tableau ituser[] */
const cs_int_t *const nrtuse, /* --> longueur du tableau rtuser[] */
const cs_int_t ifacel[], /* --> liste des faces internes */
const cs_int_t ifabor[], /* --> liste des faces de bord */
const cs_int_t ifmfbr[], /* --> liste des familles des faces bord*/
const cs_int_t ifmcel[], /* --> liste des familles des cellules */
const cs_int_t iprfml[], /* --> liste des proprietes des familles*/
const cs_int_t ipnfac[], /* --> rg ds nodfac 1er sommet faces int*/
const cs_int_t nodfac[], /* --> numero des sommets des faces int.*/
const cs_int_t ipnfbr[], /* --> rg ds nodfbr 1er sommet faces brd*/
const cs_int_t nodfbr[], /* --> numéro des sommets des faces bord*/
const cs_int_t idevel[], /* --> tab. complémentaire développeur */
const cs_int_t ituser[], /* --> tab. complémentaire utilisateur */
const cs_int_t ia[], /* --> macro-tableau entier */
const cs_real_t *const ttcabs, /* --> temps courant absolu */
const cs_real_t xyzcen[], /* --> c.d.g. des cellules */
const cs_real_t surfac[], /* --> surfaces des faces internes */
const cs_real_t surfbo[], /* --> surfaces des faces de bord */
const cs_real_t cdgfac[], /* --> c.d.g. des faces internes */
const cs_real_t cdgfbo[], /* --> c.d.g. des faces de bord */
const cs_real_t xyznod[], /* --> coordonnees des sommets */
const cs_real_t volume[], /* --> volumes des cellules */
const cs_real_t dt[], /* --> pas de temps */
const cs_real_t rtpa[], /* --> variables aux cellules (préc.) */
const cs_real_t rtp[], /* --> variables aux cellules */
const cs_real_t propce[], /* --> propriétés physiques cellules */
const cs_real_t propfa[], /* --> propriétés physiques aux faces */
const cs_real_t propfb[], /* --> propriétés physiques faces bord */
const cs_real_t coefa[], /* --> cond. limites aux faces de bord */
const cs_real_t coefb[], /* --> cond. limites aux faces de bord */
const cs_real_t statce[], /* --> moyennes statistiques (Lagrangien*/
const cs_real_t stativ[], /* --> variances statistiques (Lagrangie*/
const cs_real_t statfb[], /* --> moyennes statistiques (Lagrangien*/
const cs_real_t rdevel[], /* --> tab. complémentaire développeur */
const cs_real_t rtuser[], /* --> tab. complémentaire utilisateur */
const cs_real_t ra[] /* --> macro-tableau réel */
)
{
/* variables locales */
int i, j, k;
int dim_ent;
cs_int_t itypps[3];
cs_int_t ind_cel, ind_fac, dec_num_fbr;
cs_int_t nbr_ent, nbr_ent_max;
cs_int_t nummai, imodif;
cs_bool_t actif;
cs_post_maillage_t *maillage_post;
cs_post_writer_t *writer;
cs_int_t nbr_cel, nbr_fac, nbr_fbr;
cs_int_t *liste_cel, *liste_fac, *liste_fbr;
cs_int_t *num_ent_parent = NULL;
cs_real_t *var_trav = NULL;
cs_real_t *var_cel = NULL;
cs_real_t *var_fac = NULL;
cs_real_t *var_fbr = NULL;
/* Boucle sur les writers pour vérifier si l'on a quelque chose à faire */
/*----------------------------------------------------------------------*/
for (j = 0 ; j < cs_glob_post_nbr_writers ; j++) {
writer = cs_glob_post_writers + j;
if (writer->actif == 1)
break;
}
if (j == cs_glob_post_nbr_writers)
return;
/* Modification éventuelle des définitions des maillages post */
/*------------------------------------------------------------*/
nbr_ent_max = 0;
for (i = 0 ; i < cs_glob_post_nbr_maillages ; i++) {
maillage_post = cs_glob_post_maillages + i;
actif = CS_FALSE;
for (j = 0 ; j < maillage_post->nbr_writers ; j++) {
writer = cs_glob_post_writers + maillage_post->ind_writer[j];
if (writer->actif == 1)
actif = CS_TRUE;
}
/* Maillage utilisateur modifiable, non alias, actif à ce pas de temps */
if ( actif == CS_TRUE
&& maillage_post->alias < 0
&& maillage_post->id > 0
&& maillage_post->ind_mod_min == FVM_WRITER_TRANSIENT_CONNECT) {
const fvm_nodal_t * maillage_ext = maillage_post->maillage_ext;
dim_ent = fvm_nodal_get_max_entity_dim(maillage_ext);
nbr_ent = fvm_nodal_get_n_entities(maillage_ext, dim_ent);
if (nbr_ent > nbr_ent_max) {
nbr_ent_max = nbr_ent;
BFT_REALLOC(num_ent_parent, nbr_ent_max, cs_int_t);
}
nummai = maillage_post->id;
/* Récupération des listes d'entités correspondantes */
fvm_nodal_get_parent_num(maillage_ext, dim_ent, num_ent_parent);
for (k = 0 ; k < 3 ; k++)
itypps[k] = maillage_post->ind_ent[k];
/* On surdimensionne ici les listes, l'utilisateur pouvant
en remplir une partie arbitraire */
BFT_MALLOC(liste_cel, cs_glob_maillage->nbr_cel, cs_int_t);
BFT_MALLOC(liste_fac, cs_glob_maillage->nbr_fac, cs_int_t);
BFT_MALLOC(liste_fbr, cs_glob_maillage->nbr_fbr, cs_int_t);
nbr_cel = 0;
nbr_fac = 0;
nbr_fbr = 0;
/* Mise à zéro des listes */
if (dim_ent == 3)
for (ind_cel = 0 ; ind_cel < cs_glob_maillage->nbr_cel ; ind_cel++)
liste_cel[ind_cel] = 0;
else if (dim_ent == 2) {
for (ind_fac = 0 ; ind_fac < cs_glob_maillage->nbr_fbr ; ind_fac++)
liste_fbr[ind_fac] = 0;
for (ind_fac = 0 ; ind_fac < cs_glob_maillage->nbr_fac ; ind_fac++)
liste_fac[ind_fac] = 0;
}
/* Si les éléments du maillage FVM sont découpés, un même numéro
parent peut apparaître plusieurs fois ; On utilise donc une
logique par indicateur. */
if (dim_ent == 3) {
for (ind_cel = 0 ; ind_cel < nbr_ent ; ind_cel++)
liste_cel[num_ent_parent[ind_cel] - 1] = 1;
}
/* Pour les faces, les numéros de faces internes "parentes"
connus par FVM décalés du nombre total de faces de bord
(c.f. construction dans cs_maillage_extrait...()) */
else if (dim_ent == 2) {
dec_num_fbr = cs_glob_maillage->nbr_fbr;
for (ind_fac = 0 ; ind_fac < nbr_ent ; ind_fac++) {
if (num_ent_parent[ind_fac] > dec_num_fbr)
liste_fac[num_ent_parent[ind_fac] - dec_num_fbr - 1] = 1;
else
liste_fbr[num_ent_parent[ind_fac] - 1] = 1;
}
}
/* Transformation des indicateurs en listes */
if (dim_ent == 3) {
nbr_cel = _cs_post_ind_vers_liste(cs_glob_maillage->nbr_cel,
liste_cel);
}
else if (dim_ent == 2) {
nbr_fac = _cs_post_ind_vers_liste(cs_glob_maillage->nbr_fac,
liste_fac);
nbr_fbr = _cs_post_ind_vers_liste(cs_glob_maillage->nbr_fbr,
liste_fbr);
}
/* Modification de la définition du maillage par l'utilisateur */
imodif = 0;
CS_PROCF(usmpst, USMPST) (idbia0, idbra0, &nummai,
ndim, ncelet, ncel, nfac, nfabor, nfml, nprfml,
nnod, lndfac, lndfbr, ncelbr,
nvar, nscal, nphas, nvlsta,
&nbr_cel, &nbr_fac, &nbr_fbr,
nideve, nrdeve, nituse, nrtuse, &imodif,
itypps, ifacel, ifabor, ifmfbr, ifmcel, iprfml,
ipnfac, nodfac, ipnfbr, nodfbr,
liste_cel, liste_fac, liste_fbr,
idevel, ituser, ia,
xyzcen, surfac, surfbo, cdgfac, cdgfbo, xyznod,
volume, dt, rtpa, rtp, propce, propfa, propfb,
coefa, coefb, statce,
var_cel, var_fac, var_fbr,
rdevel, rtuser, ra);
if (imodif > 0)
cs_post_modifie_maillage(maillage_post->id,
nbr_cel,
nbr_fac,
nbr_fbr,
liste_cel,
liste_fac,
liste_fbr);
BFT_FREE(liste_cel);
BFT_FREE(liste_fac);
BFT_FREE(liste_fbr);
}
}
/* On s'assure maintenant de la synchronisation des alias */
for (i = 0 ; i < cs_glob_post_nbr_maillages ; i++) {
maillage_post = cs_glob_post_maillages + i;
if (maillage_post->alias > -1) {
const cs_post_maillage_t *maillage_ref;
maillage_ref = cs_glob_post_maillages + maillage_post->alias;
for (j = 0 ; j < 3 ; j++)
maillage_post->ind_ent[j] = maillage_ref->ind_ent[j];
maillage_post->nbr_fac = maillage_ref->nbr_fac;
maillage_post->nbr_fbr = maillage_ref->nbr_fbr;
}
}
/* Sortie des maillages ou champs de déplacement des sommets si nécessaire */
/*-------------------------------------------------------------------------*/
cs_post_ecrit_maillages(*ntcabs, *ttcabs);
if (cs_glob_post_deformable == CS_TRUE)
_cs_post_ecrit_deplacements(*ntcabs, *ttcabs);
/* Sorties des variables réalisés par des traitements enregistrés */
/*----------------------------------------------------------------*/
for (i = 0; i < cs_glob_post_nbr_var_tp; i++) {
cs_glob_post_f_var_tp[i](cs_glob_post_i_var_tp[i],
*ntcabs,
*ttcabs);
}
/* Sortie des variables associées aux maillages de post traitement */
/*-----------------------------------------------------------------*/
/* nbr_ent_max déja initialisé avant et au cours de la
modification éventuelle des définitions de maillages post,
et num_ent_parent alloué si nbr_ent_max > 0 */
BFT_MALLOC(var_trav, nbr_ent_max * 3, cs_real_t);
/* Boucle principale sur les maillages de post traitment */
for (i = 0 ; i < cs_glob_post_nbr_maillages ; i++) {
maillage_post = cs_glob_post_maillages + i;
actif = CS_FALSE;
for (j = 0 ; j < maillage_post->nbr_writers ; j++) {
writer = cs_glob_post_writers + maillage_post->ind_writer[j];
if (writer->actif == 1)
actif = CS_TRUE;
}
/* Si le maillage est actif à ce pas de temps */
/*--------------------------------------------*/
if (actif == CS_TRUE) {
const fvm_nodal_t * maillage_ext = maillage_post->maillage_ext;
dim_ent = fvm_nodal_get_max_entity_dim(maillage_ext);
nbr_ent = fvm_nodal_get_n_entities(maillage_ext, dim_ent);
if (nbr_ent > nbr_ent_max) {
nbr_ent_max = nbr_ent;
BFT_REALLOC(var_trav, nbr_ent_max * 3, cs_real_t);
BFT_REALLOC(num_ent_parent, nbr_ent_max, cs_int_t);
}
nummai = maillage_post->id;
/* Récupération des listes d'entités correspondantes */
fvm_nodal_get_parent_num(maillage_ext, dim_ent, num_ent_parent);
for (k = 0 ; k < 3 ; k++)
itypps[k] = maillage_post->ind_ent[k];
/* On peut sortir des variables pour ce pas de temps */
/*---------------------------------------------------*/
nbr_cel = 0;
nbr_fac = 0;
nbr_fbr = 0;
liste_cel = NULL;
liste_fac = NULL;
liste_fbr = NULL;
/* Ici, les listes sont dimensionnées au plus juste, et on pointe
sur le tableau rempli par fvm_nodal_get_parent_num() si possible. */
if (dim_ent == 3) {
nbr_cel = nbr_ent;
liste_cel = num_ent_parent;
}
/* Les numéros de faces internes "parentes" connus par FVM
sont décalés du nombre total de faces de bord */
else if (dim_ent == 2 && nbr_ent > 0) {
dec_num_fbr = cs_glob_maillage->nbr_fbr;
for (ind_fac = 0 ; ind_fac < nbr_ent ; ind_fac++) {
if (num_ent_parent[ind_fac] > dec_num_fbr)
nbr_fac++;
else
nbr_fbr++;
}
/* faces de bord seulement : numéros faces parentes FVM adaptés */
if (nbr_fac == 0) {
liste_fbr = num_ent_parent;
}
/* faces internes seulement : numéros faces parentes FVM décalés */
else if (nbr_fbr == 0) {
for (ind_fac = 0 ; ind_fac < nbr_ent ; ind_fac++)
num_ent_parent[ind_fac] -= dec_num_fbr;
liste_fac = num_ent_parent;
}
/* faces internes et de bord : numéros à séparer */
else {
BFT_MALLOC(liste_fac, nbr_fac, cs_int_t);
BFT_MALLOC(liste_fbr, nbr_fbr, cs_int_t);
nbr_fac = 0, nbr_fbr = 0;
for (ind_fac = 0 ; ind_fac < nbr_ent ; ind_fac++) {
if (num_ent_parent[ind_fac] > dec_num_fbr)
liste_fac[nbr_fac++] = num_ent_parent[ind_fac] - dec_num_fbr;
else
liste_fbr[nbr_fbr++] = num_ent_parent[ind_fac];
}
}
/* Dans tous les cas, mise à jour du nombre de faces internes
et faces de bord (utile en cas de découpage du maillage FVM)
pour les fonctions appellées par celle-ci */
maillage_post->nbr_fac = nbr_fac;
maillage_post->nbr_fbr = nbr_fbr;
}
/* Pointeurs sur tableaux d'assemblage des variables,
mis à NULL si inutiles (afin de provoquer si possible
une erreur immédiate en cas de mauvaise utilisation) */
var_cel = var_trav;
var_fac = var_cel + (nbr_cel * 3);
var_fbr = var_fac + (nbr_fac * 3);
if (nbr_cel == 0)
var_cel = NULL;
if (nbr_fac == 0)
var_fac = NULL;
if (nbr_fbr == 0)
var_fbr = NULL;
/* Post traitement automatique des variables */
if (nummai < 0)
CS_PROCF(dvvpst, DVVPST) (idbia0, idbra0, &nummai,
ndim, ncelet, ncel, nfac, nfabor, nfml, nprfml,
nnod, lndfac, lndfbr, ncelbr,
nvar, nscal, nphas, nvlsta, nvisbr,
&nbr_cel, &nbr_fac, &nbr_fbr,
nideve, nrdeve, nituse, nrtuse,
itypps, ifacel, ifabor, ifmfbr, ifmcel, iprfml,
ipnfac, nodfac, ipnfbr, nodfbr,
liste_cel, liste_fac, liste_fbr,
idevel, ituser, ia,
xyzcen, surfac, surfbo, cdgfac, cdgfbo, xyznod,
volume, dt, rtpa, rtp, propce, propfa, propfb,
coefa, coefb, statce, stativ , statfb ,
var_cel, var_fac, var_fbr,
rdevel, rtuser, ra);
/* Appel Fortran utilisateur pour post traitement des variables */
CS_PROCF(usvpst, USVPST) (idbia0, idbra0, &nummai,
ndim, ncelet, ncel, nfac, nfabor, nfml, nprfml,
nnod, lndfac, lndfbr, ncelbr,
nvar, nscal, nphas, nvlsta,
&nbr_cel, &nbr_fac, &nbr_fbr,
nideve, nrdeve, nituse, nrtuse,
itypps, ifacel, ifabor, ifmfbr, ifmcel, iprfml,
ipnfac, nodfac, ipnfbr, nodfbr,
liste_cel, liste_fac, liste_fbr,
idevel, ituser, ia,
xyzcen, surfac, surfbo, cdgfac, cdgfbo, xyznod,
volume, dt, rtpa, rtp, propce, propfa, propfb,
coefa, coefb, statce,
var_cel, var_fac, var_fbr,
rdevel, rtuser, ra);
/* En cas de mélange de faces internes et de bord, tableaux
supplémentaires alloués, à libérer */
if (liste_fac != NULL && liste_fbr != NULL) {
BFT_FREE(liste_fac);
BFT_FREE(liste_fbr);
}
}
}
/* Libération mémoire */
BFT_FREE(num_ent_parent);
BFT_FREE(var_trav);
}
/*----------------------------------------------------------------------------
* Sortie d'un champ de post traitement défini sur les cellules ou faces
* d'un maillage en fonction des "writers" associés.
*
* Interface Fortran : utiliser PSTEVA (voir cs_post_util.F)
*----------------------------------------------------------------------------*/
void CS_PROCF (pstev1, PSTEV1)
(
const cs_int_t *const nummai, /* --> numéro du maillage associé */
const char *const nomvar, /* --> nom de la variable */
const cs_int_t *const lnmvar, /* --> longueur du nom de la variable */
const cs_int_t *const idimt, /* --> 1 pour scalaire, 3 pour vecteur */
const cs_int_t *const ientla, /* --> si vecteur, 1 si valeurs
* entrelacées, 0 sinon */
const cs_int_t *const ivarpr, /* --> 1 si variable définie sur
* maillage "parent", 0 si variable
* restreinte au maillage post */
const cs_int_t *const ntcabs, /* --> numéro de pas de temps associé */
const cs_real_t *const ttcabs, /* --> valeur du pas de temps associé */
const cs_real_t varcel[], /* --> valeurs aux cellules */
const cs_real_t varfac[], /* --> valeurs aux faces internes */
const cs_real_t varfbr[] /* --> valeurs aux faces de bord */
CS_ARGF_SUPP_CHAINE /* (arguments 'longueur' éventuels,
Fortran, inutilisés lors de
l'appel mais placés par de
nombreux compilateurs) */
)
{
char *nom_var;
cs_bool_t var_parent;
cs_bool_t entrelace;
if (*ivarpr == 1)
var_parent = CS_TRUE;
else if (*ivarpr == 0)
var_parent = CS_FALSE;
else
bft_error(__FILE__, __LINE__, 0,
_("L'argument IVARPR du sous-programme PSTEVA doit être\n"
"égal à 0 ou 1, et non %d.\n"), (int)(*ivarpr));
if (*ientla == 0)
entrelace = CS_FALSE;
else if (*ientla == 1)
entrelace = CS_TRUE;
else
bft_error(__FILE__, __LINE__, 0,
_("L'argument IENTLA du sous-programme PSTEVA doit être\n"
"égal à 0 ou 1, et non %d.\n"), (int)(*ientla));
/* Conversion des chaînes de caractères Fortran en chaînes C */
nom_var = cs_base_chaine_f_vers_c_cree(nomvar, *lnmvar);
/* Traitement principal */
cs_post_ecrit_var(*nummai,
nom_var,
*idimt,
entrelace,
var_parent,
CS_POST_TYPE_cs_real_t,
*ntcabs,
*ttcabs,
varcel,
varfac,
varfbr);
/* Libération des tableaux C temporaires */
nom_var = cs_base_chaine_f_vers_c_detruit(nom_var);
}
/*----------------------------------------------------------------------------
* Prise en compte de la renumérotation des faces et faces de bord
* dans les liens de "parenté" des maillages post.
*
* Cette fonction ne doit être appellée qu'une fois, après la renumérotation
* évuentuelle des faces, pour adapter les maillages post existants.
* Des nouveaux maillages post seront automatiquement basés sur la
* "bonne" numérotation, par construction.
*
* Interface Fortran :
*
* SUBROUTINE PSTRNM
* *****************
*----------------------------------------------------------------------------*/
void CS_PROCF (pstrnm, PSTRNM)
(
void
)
{
cs_post_renum_faces();
}
/*============================================================================
* Fonctions publiques
*============================================================================*/
/*----------------------------------------------------------------------------
* Création d'un "writer" ; cet objet correspond au choix d'un nom de cas,
* de répertoire, et de format, ainsi qu'un indicateur précisant si les
* maillages associés doivent dépendre ou non du temps, et la fréquence de
* sortie par défaut pour les variables associées.
*----------------------------------------------------------------------------*/
void cs_post_ajoute_writer
(
cs_int_t id_writer, /* --> numéro du writer à créer
* (< 0 pour writer réservé,
* > 0 pour writer utilisateur) */
const char *const nom_cas, /* --> nom du cas associé */
const char *const nom_rep, /* --> nom de répertoire associé */
const char *const nom_fmt, /* --> nom de format associé */
const char *const opt_fmt, /* --> options associées au format */
cs_int_t ind_mod, /* --> 0 si figé, 1 si déformable,
* 2 si topologie change, +10 pour
* ajouter un champ déplacement */
cs_int_t frequence /* --> fréquence de sortie par défaut */
)
{
/* variables locales */
int i;
cs_post_writer_t *writer = NULL;
fvm_writer_time_dep_t dep_temps = FVM_WRITER_FIXED_MESH;
/* Vérification que le numéro demandé est disponible */
if (id_writer == 0)
bft_error(__FILE__, __LINE__, 0,
_("Le numéro de gestionnaire de post traitement demandé\n"
"doit être < 0 (réservé) ou > 0 (utilisateur).\n"));
for (i = 0 ; i < cs_glob_post_nbr_writers ; i++) {
if ((cs_glob_post_writers + i)->id == id_writer)
bft_error(__FILE__, __LINE__, 0,
_("Le numéro de gestionnaire de post traitement demandé\n"
"(%d) a déjà été affecté.\n"), (int)id_writer);
}
/* Redimensionnement du tableau global des writers */
if (cs_glob_post_nbr_writers == cs_glob_post_nbr_writers_max) {
if (cs_glob_post_nbr_writers_max == 0)
cs_glob_post_nbr_writers_max = 4;
else
cs_glob_post_nbr_writers_max *= 2;
BFT_REALLOC(cs_glob_post_writers,
cs_glob_post_nbr_writers_max,
cs_post_writer_t);
}
cs_glob_post_nbr_writers += 1;
/* Affectation du writer nouvellement créé à la structure */
writer = cs_glob_post_writers + cs_glob_post_nbr_writers - 1;
writer->id = id_writer;
writer->freq_sortie = frequence;
writer->ecr_depl = CS_FALSE;
writer->actif = 0;
if (ind_mod >= 10) {
writer->ecr_depl = CS_TRUE;
ind_mod -= 10;
}
if (ind_mod == 1)
dep_temps = FVM_WRITER_TRANSIENT_COORDS;
else if (ind_mod >= 2)
dep_temps = FVM_WRITER_TRANSIENT_CONNECT;
writer->writer = fvm_writer_init(nom_cas,
nom_rep,
nom_fmt,
opt_fmt,
dep_temps);
}
/*----------------------------------------------------------------------------
* Création d'un maillage de post traitement ; les listes de cellules ou
* faces à extraire sont triées en sortie, qu'elles le soient déjà en entrée
* ou non.
*
* La liste des cellules associées n'est nécessaire que si le nombre
* de cellules à extraire est strictement supérieur à 0 et inférieur au
* nombre de cellules du maillage.
*
* Les listes de faces ne sont prises en compte que si le nombre de cellules
* à extraire est nul ; si le nombre de faces de bord à extraire est égal au
* nombre de faces de bord du maillage global, et le nombre de faces internes
* à extraire est nul, alors on extrait par défaut le maillage de bord, et la
* liste des faces de bord associées n'est donc pas nécessaire.
*----------------------------------------------------------------------------*/
void cs_post_ajoute_maillage
(
const cs_int_t id_maillage, /* --> numéro du maillage à créer
* (< 0 pour maillage réservé,
* > 0 pour maillage utilisateur) */
const char *const nom_maillage, /* --> nom du maillage externe */
const cs_int_t nbr_cel, /* --> nombre de cellules */
const cs_int_t nbr_fac, /* --> nombre de faces internes */
const cs_int_t nbr_fbr, /* --> nombre de faces de bord */
cs_int_t liste_cel[], /* <-> liste des cellules */
cs_int_t liste_fac[], /* <-> liste des faces internes */
cs_int_t liste_fbr[] /* <-> liste des faces de bord */
)
{
/* variables locales */
cs_post_maillage_t *maillage_post = NULL;
/* Ajout et initialisation de la structure de base */
maillage_post = _cs_post_ajoute_maillage(id_maillage);
/* Création du maillage et affectation à la structure */
_cs_post_definit_maillage(maillage_post,
nom_maillage,
nbr_cel,
nbr_fac,
nbr_fbr,
liste_cel,
liste_fac,
liste_fbr);
}
/*----------------------------------------------------------------------------
* Création d'un maillage de post traitement par association d'un maillage
* externe existant.
*
* Si le maillage externe n'est plus destiné à être utilisé par ailleurs,
* on peut choisir d'en transférer la propriété au maillage de post traitement,
* qui gèrera alors son cycle de vie selon ses seuls besoins.
*
* Si le maillage externe doit continuer à être partagé, on devra veiller
* à maintenir la cohérence entre ce maillage et le posttraitement au cours
* du temps.
*----------------------------------------------------------------------------*/
void cs_post_ajoute_maillage_existant
(
cs_int_t id_maillage, /* --> numéro du maillage à créer
* (< 0 pour maillage réservé,
* > 0 pour maillage utilisateur) */
fvm_nodal_t *const maillage_ext, /* --> maillage externe */
cs_bool_t transferer /* --> indique si l'on transfère la
* propriété du maillage externe
au maillage de post traitement */
)
{
/* variables locales */
int i;
int indic_glob[3];
cs_int_t dec_num_fbr, ind_fac;
int indic_loc[3] = {1, 1, 1}; /* Indicateurs 0 à 2 "inversés" par
rapport aux autres pour pouvoir
utiliser un même appel à
MPI_Allreduce(..., MPI_MIN, ...) */
int dim_ent = 0;
cs_bool_t maj_ind_ent = CS_FALSE;
fvm_lnum_t nbr_ent = 0;
fvm_lnum_t *num_ent_parent = NULL;
cs_post_maillage_t *maillage_post = NULL;
/* Ajout et initialisation de la structure de base */
maillage_post = _cs_post_ajoute_maillage(id_maillage);
/* Affectation du maillage à la structure */
maillage_post->maillage_ext = maillage_ext;
if (transferer == CS_TRUE)
maillage_post->_maillage_ext = maillage_ext;
/* Calcul du nombre de cellules et/ou de faces */
dim_ent = fvm_nodal_get_max_entity_dim(maillage_ext);
nbr_ent = fvm_nodal_get_n_entities(maillage_ext, dim_ent);
if (dim_ent == 3 && nbr_ent > 0)
indic_loc[0] = 0;
else if (dim_ent == 2 && nbr_ent > 0) {
BFT_MALLOC(num_ent_parent, nbr_ent, cs_int_t);
fvm_nodal_get_parent_num(maillage_ext, dim_ent, num_ent_parent);
dec_num_fbr = cs_glob_maillage->nbr_fbr;
for (ind_fac = 0 ; ind_fac < nbr_ent ; ind_fac++) {
if (num_ent_parent[ind_fac] > dec_num_fbr)
maillage_post->nbr_fac += 1;
else
maillage_post->nbr_fbr += 1;
}
BFT_FREE(num_ent_parent);
if (maillage_post->nbr_fac > 0)
indic_loc[1] = 0;
else if (maillage_post->nbr_fbr > 0)
indic_loc[2] = 0;
}
for (i = 0 ; i < 3 ; i++)
indic_glob[i] = indic_loc[i];
#if defined(_CS_HAVE_MPI)
if (cs_glob_base_nbr > 1)
MPI_Allreduce (indic_loc, indic_glob, 3, MPI_INT, MPI_MIN,
cs_glob_base_mpi_comm);
#endif
/* Indicateurs globaux de présence de types de mailles
on ne met à jour que si le maillage n'est pas totalement vide
(pour des maillages dépendant du temps, vides à certains instants,
on veut pouvoir connaître le dernier type de maille contenu
dans USMPST) */
for (i = 0 ; i < 3 ; i++) {
if (indic_glob[i] == 0)
maj_ind_ent = CS_TRUE;
}
if (maj_ind_ent == CS_TRUE) {
for (i = 0 ; i < 3 ; i++) {
if (indic_glob[i] == 0) /* Logique indic_glob 0 à 2 inversée */
maillage_post->ind_ent[i] = 1; /* (c.f. remarque ci-dessus) */
else
maillage_post->ind_ent[i] = 0;
}
}
/* Indicateurs de modification min et max inversés initialement,
seront recalculés lors des associations maillages - post-traitements */
maillage_post->ind_mod_min = FVM_WRITER_TRANSIENT_CONNECT;
maillage_post->ind_mod_max = FVM_WRITER_FIXED_MESH;
}
/*----------------------------------------------------------------------------
* Création d'un alias sur un maillage de post traitement.
*
* Un alias permet d'associer un numéro supplémentaire à un maillage de
* post traitement déjà défini, et donc de lui associer d'autres
* "writers" qu'au maillage initial ; ceci permet par exemple d'écrire
* un jeu de variables principales tous les n1 pas de temps dans un
* jeu de données de post traitement, et de sortir quelques variables
* spécifiques tous les n2 pas de temps dans un autre jeu de données
* de post traitement, sans nécessiter de duplication du maillage support.
*
* Un alias est donc traité en tout point comme le maillage principal
* associé ; en particulier, si la définition de l'un est modifié, celle
* de l'autre l'est aussi.
*
* Il est impossible d'associer un alias à un autre alias (cela n'aurait
* pas d'utilité), mais on peut associer plusieurs alias à un maillage.
*----------------------------------------------------------------------------*/
void cs_post_alias_maillage
(
const cs_int_t id_alias, /* --> numéro de l'alias à créer
* (< 0 pour alias réservé,
* > 0 pour alias utilisateur) */
const cs_int_t id_maillage /* --> numéro du maillage associé */
)
{
/* variables locales */
int indref, j;
cs_post_maillage_t *maillage_post = NULL;
cs_post_maillage_t *maillage_ref = NULL;
/* Vérifications initiales */
indref = _cs_post_ind_maillage(id_maillage);
maillage_ref = cs_glob_post_maillages + indref;
if (maillage_ref->alias > -1)
bft_error(__FILE__, __LINE__, 0,
_("Le maillage %d ne peut être un alias du maillage %d,\n"
"qui est lui-même déjà un alias du maillage %d.\n"),
(int)id_alias, (int)id_maillage,
(int)((cs_glob_post_maillages + maillage_ref->alias)->id));
/* Ajout et initialisation de la structure de base */
maillage_post = _cs_post_ajoute_maillage(id_alias);
/* On réactualise maillage_ref, car on a pu déplacer l'adresse
de cs_glob_pos_maillages en le réallouant */
maillage_ref = cs_glob_post_maillages + indref;
/* Liens avec le maillage de référence */
maillage_post->alias = indref;
maillage_post->maillage_ext = maillage_ref->maillage_ext;
maillage_post->ind_mod_min = maillage_ref->ind_mod_min;
maillage_post->ind_mod_max = maillage_ref->ind_mod_max;
for (j = 0 ; j < 3 ; j++)
maillage_post->ind_ent[j] = maillage_ref->ind_ent[j];
maillage_post->nbr_fac = maillage_ref->nbr_fac;
maillage_post->nbr_fbr = maillage_ref->nbr_fbr;
}
/*----------------------------------------------------------------------------
* Vérifie l'existence d'un "writer" associé à un numéro donné.
*----------------------------------------------------------------------------*/
cs_bool_t cs_post_existe_writer
(
const cs_int_t numwri /* --> numéro du writer associé */
)
{
/* variables locales */
int indwri;
cs_post_writer_t *writer = NULL;
/* Recherche du writer demandé */
for (indwri = 0 ; indwri < cs_glob_post_nbr_writers ; indwri++) {
writer = cs_glob_post_writers + indwri;
if (writer->id == numwri)
return CS_TRUE;
}
return CS_FALSE;
}
/*----------------------------------------------------------------------------
* Vérifie l'existence d'un maillage de post traitement associé à un
* numéro donné.
*----------------------------------------------------------------------------*/
cs_bool_t cs_post_existe_maillage
(
const cs_int_t nummai /* --> numéro du maillage externe associé */
)
{
/* variables locales */
int indmai;
cs_post_maillage_t *maillage_post = NULL;
/* Recherche du maillage demandé */
for (indmai = 0 ; indmai < cs_glob_post_nbr_maillages ; indmai++) {
maillage_post = cs_glob_post_maillages + indmai;
if (maillage_post->id == nummai)
return CS_TRUE;
}
return CS_FALSE;
}
/*----------------------------------------------------------------------------
* Modification d'un maillage de post traitement existant.
*
* Il s'agit ici de modifier les listes de cellules ou faces du maillage,
* par exemple pour faire évoluer une coupe en fonction des zones
* "intéressantes (il n'est pas nécessaire de recourir à cette fonction
* si le maillage se déforme simplement).
*----------------------------------------------------------------------------*/
void cs_post_modifie_maillage
(
const cs_int_t id_maillage, /* --> numéro du writer à créer
* (< 0 pour maillage réservé,
* > 0 pour maillage utilisateur) */
const cs_int_t nbr_cel, /* --> nombre de cellules */
const cs_int_t nbr_fac, /* --> nombre de faces internes */
const cs_int_t nbr_fbr, /* --> nombre de faces de bord */
cs_int_t liste_cel[], /* <-> liste des cellules */
cs_int_t liste_fac[], /* <-> liste des faces internes */
cs_int_t liste_fbr[] /* <-> liste des faces de bord */
)
{
/* variables locales */
int i, indmai;
char *nom_maillage = NULL;
cs_post_maillage_t *maillage_post = NULL;
cs_post_writer_t *writer = NULL;
/* Récupération de la structure de base
(sortie si l'on n'est pas propriétaire du maillage) */
indmai = _cs_post_ind_maillage(id_maillage);
maillage_post = cs_glob_post_maillages + indmai;
if (maillage_post->_maillage_ext == NULL)
return;
/* Remplacement de la structure de base */
BFT_MALLOC(nom_maillage,
strlen(fvm_nodal_get_name(maillage_post->maillage_ext)) + 1,
char);
strcpy(nom_maillage, fvm_nodal_get_name(maillage_post->maillage_ext));
fvm_nodal_destroy(maillage_post->_maillage_ext);
maillage_post->maillage_ext = NULL;
_cs_post_definit_maillage(maillage_post,
nom_maillage,
nbr_cel,
nbr_fac,
nbr_fbr,
liste_cel,
liste_fac,
liste_fbr);
BFT_FREE(nom_maillage);
/* Mise à jour des alias éventuels */
for (i = 0 ; i < cs_glob_post_nbr_maillages ; i++) {
if ((cs_glob_post_maillages + i)->alias == indmai)
(cs_glob_post_maillages + i)->maillage_ext
= maillage_post->maillage_ext;
}
/* Découpage des polygones ou polyèdres en éléments simples */
for (i = 0 ; i < maillage_post->nbr_writers ; i++) {
writer = cs_glob_post_writers + maillage_post->ind_writer[i];
_cs_post_divise_poly(maillage_post, writer);
}
}
/*----------------------------------------------------------------------------
* Récupération du prochain numéro de maillage standard ou développeur
* disponible (basé sur le plus petit numéro négatif présent -1).
*----------------------------------------------------------------------------*/
cs_int_t cs_post_ret_num_maillage_libre
(
void
)
{
return (cs_glob_post_num_maillage_min - 1);
}
/*----------------------------------------------------------------------------
* Association d'un "writer" à un maillage pour le post traitement.
*----------------------------------------------------------------------------*/
void cs_post_associe
(
const cs_int_t id_maillage, /* --> numéro du maillage externe associé */
const cs_int_t id_writer /* --> numéro du writer */
)
{
int i;
int indmai, indgep;
fvm_writer_time_dep_t ind_mod;
cs_post_maillage_t *maillage_post = NULL;
cs_post_writer_t *writer = NULL;
/* Recherche du maillage et writer demandés */
indmai = _cs_post_ind_maillage(id_maillage);
indgep = _cs_post_ind_writer(id_writer);
maillage_post = cs_glob_post_maillages + indmai;
/* On vérifie que le writer n'est pas déjà associé */
for (i = 0 ; i < maillage_post->nbr_writers ; i++) {
if (maillage_post->ind_writer[i] == indgep)
break;
}
/* Si le writer n'est pas déjà associé, on l'associe */
if (i >= maillage_post->nbr_writers) {
maillage_post->nbr_writers += 1;
BFT_REALLOC(maillage_post->ind_writer,
maillage_post->nbr_writers,
cs_int_t);
maillage_post->ind_writer[maillage_post->nbr_writers - 1] = indgep;
maillage_post->nt_ecr = - 1;
/* Mise à jour de la structure */
writer = cs_glob_post_writers + indgep;
ind_mod = fvm_writer_get_time_dep(writer->writer);
if (ind_mod < maillage_post->ind_mod_min)
maillage_post->ind_mod_min = ind_mod;
if (ind_mod > maillage_post->ind_mod_max)
maillage_post->ind_mod_max = ind_mod;
_cs_post_ind_mod_alias(indmai);
/* Si l'on doit calculer le champ déplacement des sommets, on devra
sauvegarder les coordonnées initiales des sommets */
if ( cs_glob_post_deformable == CS_FALSE
&& cs_glob_post_coo_som_ini == NULL
&& writer->ecr_depl == CS_TRUE) {
cs_maillage_t *maillage = cs_glob_maillage;
if (maillage->nbr_som > 0) {
BFT_MALLOC(cs_glob_post_coo_som_ini,
maillage->nbr_som * 3,
cs_real_t);
memcpy(cs_glob_post_coo_som_ini,
maillage->coo_som,
maillage->nbr_som * 3 * sizeof(cs_real_t));
}
cs_glob_post_deformable = CS_TRUE;
}
/* Découpage des polygones ou polyèdres en éléments simples */
_cs_post_divise_poly(maillage_post, writer);
}
}
/*----------------------------------------------------------------------------
* Mise à jour de l'indicateur "actif" ou "inactif" des "writers" en
* fonction du pas de temps et de leur fréquence de sortie par défaut.
*----------------------------------------------------------------------------*/
void cs_post_activer_selon_defaut
(
const cs_int_t nt_cur_abs /* --> numéro de pas de temps courant */
)
{
int i;
cs_post_writer_t *writer;
for (i = 0 ; i < cs_glob_post_nbr_writers ; i++) {
writer = cs_glob_post_writers + i;
if (writer->freq_sortie > 0) {
if (nt_cur_abs % (writer->freq_sortie) == 0)
writer->actif = 1;
else
writer->actif = 0;
}
else
writer->actif = 0;
}
}
/*----------------------------------------------------------------------------
* Forcer de l'indicateur "actif" ou "inactif" d'un "writers" spécifique
* ou de l'ensemble des "writers" pour le pas de temps en cours.
*----------------------------------------------------------------------------*/
void cs_post_activer_writer
(
const cs_int_t id_writer, /* --> numéro du writer,ou 0 pour forcer
* simultanément tous les writers */
const cs_int_t activer /* --> 0 pour désactiver, 1 pour activer */
)
{
int i;
cs_post_writer_t *writer;
if (id_writer != 0) {
i = _cs_post_ind_writer(id_writer);
writer = cs_glob_post_writers + i;
writer->actif = (activer > 0) ? 1 : 0;
}
else {
for (i = 0 ; i < cs_glob_post_nbr_writers ; i++) {
writer = cs_glob_post_writers + i;
writer->actif = (activer > 0) ? 1 : 0;
}
}
}
/*----------------------------------------------------------------------------
* Ecriture des maillages de post traitement en fonction des "writers"
* associés.
*----------------------------------------------------------------------------*/
void cs_post_ecrit_maillages
(
const cs_int_t nt_cur_abs, /* --> numéro de pas de temps courant */
const cs_real_t t_cur_abs /* --> valeur du temps physique associé */
)
{
int i;
cs_post_maillage_t *maillage_post;
/* Boucles sur les maillages et "writers" */
for (i = 0 ; i < cs_glob_post_nbr_maillages ; i++) {
maillage_post = cs_glob_post_maillages + i;
_cs_post_ecrit_maillage(maillage_post,
nt_cur_abs,
t_cur_abs);
}
}
/*----------------------------------------------------------------------------
* Sortie d'un champ de post traitement défini sur les cellules ou faces
* d'un maillage en fonction des "writers" associés.
*----------------------------------------------------------------------------*/
void cs_post_ecrit_var
(
cs_int_t id_maillage, /* --> numéro du maillage post associé */
const char *nom_var, /* --> nom de la variable */
cs_int_t dim_var, /* --> 1 pour scalaire, 3 pour vecteur */
cs_bool_t entrelace, /* --> si vecteur, vrai si valeurs
* entrelacées, faux sinon */
cs_bool_t var_parent, /* --> vrai si valeurs définies sur
* maillage "parent", faux si
* restreintes au maillage post */
cs_post_type_t var_type, /* --> type de données associé */
cs_int_t nt_cur_abs, /* --> numéro de pas de temps courant */
cs_real_t t_cur_abs, /* --> valeur du temps physique */
const void *var_cel, /* --> valeurs aux cellules */
const void *var_fac, /* --> valeurs aux faces internes */
const void *var_fbr /* --> valeurs aux faces de bord */
)
{
cs_int_t i;
int indmai;
cs_post_maillage_t *maillage_post;
cs_post_writer_t *writer;
fvm_interlace_t interlace;
fvm_datatype_t datatype;
size_t dec_ptr = 0;
int nbr_listes_parents = 0;
fvm_lnum_t dec_num_parent[2] = {0, 0};
cs_real_t *var_tmp = NULL;
const void *var_ptr[2*9] = {NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL};
/* Initialisations */
indmai = _cs_post_ind_maillage(id_maillage);
maillage_post = cs_glob_post_maillages + indmai;
if (entrelace == CS_TRUE)
interlace = FVM_INTERLACE;
else
interlace = FVM_NO_INTERLACE;
datatype = _cs_post_cnv_datatype(var_type);
/* Affectation du tableau approprié à FVM pour la sortie */
/* Cas des cellules */
/*------------------*/
if (maillage_post->ind_ent[CS_POST_SUPPORT_CEL] == 1) {
if (var_parent == CS_TRUE) {
nbr_listes_parents = 1;
dec_num_parent[0] = 0;
}
else
nbr_listes_parents = 0;
var_ptr[0] = var_cel;
if (entrelace == CS_FALSE) {
if (var_parent == CS_TRUE)
dec_ptr = cs_glob_maillage->nbr_cel_etendu;
else
dec_ptr = fvm_nodal_get_n_entities(maillage_post->maillage_ext, 3);
dec_ptr *= fvm_datatype_size[datatype];
for (i = 1 ; i < dim_var ; i++)
var_ptr[i] = ((const char *)var_cel) + i*dec_ptr;
}
}
/* Cas des faces */
/*---------------*/
else if ( maillage_post->ind_ent[CS_POST_SUPPORT_FAC_INT] == 1
|| maillage_post->ind_ent[CS_POST_SUPPORT_FAC_BRD] == 1) {
/* En cas d'indirection, il suffit de positionner les pointeurs */
if (var_parent == CS_TRUE) {
nbr_listes_parents = 2;
dec_num_parent[0] = 0;
dec_num_parent[1] = cs_glob_maillage->nbr_fbr;
if (maillage_post->ind_ent[CS_POST_SUPPORT_FAC_BRD] == 1) {
if (entrelace == CS_FALSE) {
dec_ptr = cs_glob_maillage->nbr_fbr * fvm_datatype_size[datatype];
for (i = 0 ; i < dim_var ; i++)
var_ptr[i] = ((const char *)var_fbr) + i*dec_ptr;
}
else
var_ptr[0] = var_fbr;
}
if (maillage_post->ind_ent[CS_POST_SUPPORT_FAC_INT] == 1) {
if (entrelace == CS_FALSE) {
dec_ptr = cs_glob_maillage->nbr_fac * fvm_datatype_size[datatype];
for (i = 0 ; i < dim_var ; i++)
var_ptr[dim_var + i] = ((const char *)var_fac) + i*dec_ptr;
}
else
var_ptr[1] = var_fac;
}
}
/* Sans indirection, on doit repasser d'une variable définie sur deux
listes de faces à une variable définie sur une liste */
else {
nbr_listes_parents = 0;
if (maillage_post->ind_ent[CS_POST_SUPPORT_FAC_BRD] == 1) {
/* Cas où la variable est définie à la fois sur des faces de
bord et des faces internes : on doit repasser à une liste
unique, étant donné que l'on n'utilise pas l'indirection */
if (maillage_post->ind_ent[CS_POST_SUPPORT_FAC_INT] == 1) {
BFT_MALLOC(var_tmp,
( maillage_post->nbr_fac
+ maillage_post->nbr_fbr) * dim_var,
cs_real_t);
_cs_post_assmb_var_faces(maillage_post->maillage_ext,
maillage_post->nbr_fac,
maillage_post->nbr_fbr,
dim_var,
interlace,
var_fac,
var_fbr,
var_tmp);
interlace = FVM_NO_INTERLACE;
dec_ptr = fvm_datatype_size[datatype] * ( maillage_post->nbr_fac
+ maillage_post->nbr_fbr);
for (i = 0 ; i < dim_var ; i++)
var_ptr[i] = ((char *)var_tmp) + i*dec_ptr;
}
/* Cas où l'on a que des faces de bord */
else {
if (entrelace == CS_FALSE) {
dec_ptr = fvm_datatype_size[datatype] * maillage_post->nbr_fbr;
for (i = 0 ; i < dim_var ; i++)
var_ptr[i] = ((const char *)var_fbr) + i*dec_ptr;
}
else
var_ptr[0] = var_fbr;
}
}
/* Cas où l'on a que des faces internes */
else if (maillage_post->ind_ent[CS_POST_SUPPORT_FAC_INT] == 1) {
if (entrelace == CS_FALSE) {
dec_ptr = fvm_datatype_size[datatype] * maillage_post->nbr_fac;
for (i = 0 ; i < dim_var ; i++)
var_ptr[i] = ((const char *)var_fac) + i*dec_ptr;
}
else
var_ptr[0] = var_fac;
}
}
}
/* Sortie effective : boucle sur les writers */
/*-------------------------------------------*/
for (i = 0 ; i < maillage_post->nbr_writers ; i++) {
writer = cs_glob_post_writers + maillage_post->ind_writer[i];
if (writer->actif == 1)
fvm_writer_export_field(writer->writer,
maillage_post->maillage_ext,
nom_var,
FVM_WRITER_PER_ELEMENT,
dim_var,
interlace,
nbr_listes_parents,
dec_num_parent,
datatype,
(int)nt_cur_abs,
(double)t_cur_abs,
(const void * *)var_ptr);
}
/* Libération mémoire (si faces internes et de bord simultanées) */
if (var_tmp != NULL)
BFT_FREE(var_tmp);
}
/*----------------------------------------------------------------------------
* Sortie d'un champ de post traitement défini sur les sommets
* d'un maillage en fonction des "writers" associés.
*----------------------------------------------------------------------------*/
void cs_post_ecrit_var_som
(
cs_int_t id_maillage, /* --> numéro du maillage post associé */
const char *nom_var, /* --> nom de la variable */
cs_int_t dim_var, /* --> 1 pour scalaire, 3 pour vecteur */
cs_bool_t entrelace, /* --> si vecteur, vrai si valeurs
* entrelacées, faux sinon */
cs_bool_t var_parent, /* --> vrai si valeurs définies sur
* maillage "parent", faux si
* restreintes au maillage post */
cs_post_type_t var_type, /* --> type de données associé */
cs_int_t nt_cur_abs, /* --> numéro de pas de temps courant */
cs_real_t t_cur_abs, /* --> valeur du temps physique */
const void *var_som /* --> valeurs aux sommets */
)
{
cs_int_t i;
int indmai;
cs_post_maillage_t *maillage_post;
cs_post_writer_t *writer;
fvm_interlace_t interlace;
fvm_datatype_t datatype;
size_t dec_ptr = 0;
int nbr_listes_parents = 0;
fvm_lnum_t dec_num_parent[1] = {0};
const void *var_ptr[9] = {NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL};
/* Initialisations */
indmai = _cs_post_ind_maillage(id_maillage);
maillage_post = cs_glob_post_maillages + indmai;
if (entrelace == CS_TRUE)
interlace = FVM_INTERLACE;
else
interlace = FVM_NO_INTERLACE;
assert( sizeof(cs_real_t) == sizeof(double)
|| sizeof(cs_real_t) == sizeof(float));
datatype = _cs_post_cnv_datatype(var_type);
/* Affectation du tableau approprié à FVM pour la sortie */
if (var_parent == CS_TRUE)
nbr_listes_parents = 1;
else
nbr_listes_parents = 0;
var_ptr[0] = var_som;
if (entrelace == CS_FALSE) {
if (var_parent == CS_TRUE)
dec_ptr = cs_glob_maillage->nbr_som;
else
dec_ptr = fvm_nodal_get_n_entities(maillage_post->maillage_ext, 0)
* fvm_datatype_size[datatype];
for (i = 1 ; i < dim_var ; i++)
var_ptr[i] = ((const char *)var_som) + i*dec_ptr;
}
/* Sortie effective : boucle sur les writers */
/*-------------------------------------------*/
for (i = 0 ; i < maillage_post->nbr_writers ; i++) {
writer = cs_glob_post_writers + maillage_post->ind_writer[i];
if (writer->actif == 1)
fvm_writer_export_field(writer->writer,
maillage_post->maillage_ext,
nom_var,
FVM_WRITER_PER_NODE,
dim_var,
interlace,
nbr_listes_parents,
dec_num_parent,
datatype,
(int)nt_cur_abs,
(double)t_cur_abs,
(const void * *)var_ptr);
}
}
/*----------------------------------------------------------------------------
* Prise en compte de la renumérotation des faces et faces de bord
* dans les liens de "parenté" des maillages post.
*
* Cette fonction ne doit être appellée qu'une fois, après la renumérotation
* évuentuelle des faces, pour adapter les maillages post existants.
* Des nouveaux maillages post seront automatiquement basés sur la
* "bonne" numérotation, par construction.
*----------------------------------------------------------------------------*/
void cs_post_renum_faces
(
void
)
{
int i;
cs_int_t ifac;
cs_int_t nbr_ent;
cs_int_t *renum_ent_parent = NULL;
cs_bool_t a_traiter = CS_FALSE;
cs_post_maillage_t *maillage_post;
const cs_maillage_t *maillage = cs_glob_maillage;
/* Boucles sur les maillages */
for (i = 0 ; i < cs_glob_post_nbr_maillages ; i++) {
maillage_post = cs_glob_post_maillages + i;
if ( maillage_post->ind_ent[CS_POST_SUPPORT_FAC_INT] > 0
|| maillage_post->ind_ent[CS_POST_SUPPORT_FAC_BRD] > 0) {
a_traiter = CS_TRUE;
}
}
if (a_traiter == CS_TRUE) {
/* Préparation de la renumérotation */
nbr_ent = maillage->nbr_fac + maillage->nbr_fbr;
BFT_MALLOC(renum_ent_parent, nbr_ent, cs_int_t);
if (maillage->num_fbr_ini == NULL) {
for (ifac = 0 ; ifac < maillage->nbr_fbr ; ifac++)
renum_ent_parent[ifac] = ifac + 1;
}
else {
for (ifac = 0 ; ifac < maillage->nbr_fbr ; ifac++)
renum_ent_parent[maillage->num_fbr_ini[ifac] - 1] = ifac + 1;
}
if (maillage->num_fac_ini == NULL) {
for (ifac = 0, i = maillage->nbr_fbr ;
ifac < maillage->nbr_fac ;
ifac++, i++)
renum_ent_parent[maillage->nbr_fbr + ifac]
= maillage->nbr_fbr + ifac + 1;
}
else {
for (ifac = 0, i = maillage->nbr_fbr ;
ifac < maillage->nbr_fac ;
ifac++, i++)
renum_ent_parent[maillage->nbr_fbr + maillage->num_fac_ini[ifac] - 1]
= maillage->nbr_fbr + ifac + 1;
}
/* Modification effective */
for (i = 0 ; i < cs_glob_post_nbr_maillages ; i++) {
maillage_post = cs_glob_post_maillages + i;
if ( maillage_post->_maillage_ext != NULL
&& ( maillage_post->ind_ent[CS_POST_SUPPORT_FAC_INT] > 0
|| maillage_post->ind_ent[CS_POST_SUPPORT_FAC_BRD] > 0)) {
fvm_nodal_change_parent_num(maillage_post->_maillage_ext,
renum_ent_parent,
2);
}
}
BFT_FREE(renum_ent_parent);
}
}
/*----------------------------------------------------------------------------
* Destruction des structures associées aux post traitements
*----------------------------------------------------------------------------*/
void cs_post_detruit
(
void
)
{
int i;
cs_post_maillage_t *maillage_post = NULL;
/* Chronométrages */
for (i = 0 ; i < cs_glob_post_nbr_writers ; i++) {
double m_wtime = 0.0, m_cpu_time = 0.0, c_wtime = 0.0, c_cpu_time = 0.;
fvm_writer_get_times((cs_glob_post_writers + i)->writer,
&m_wtime, &m_cpu_time, &c_wtime, &c_cpu_time);
bft_printf(_("\n"
"Bilan des écritures de \"%s\" (%s) :\n\n"
" Temps CPU pour les maillages : %12.3f\n"
" Temps CPU pour les champs : %12.3f\n\n"
" Temps écoulé pour les maillages : %12.3f\n"
" Temps écoulé pour les champs : %12.3f\n"),
fvm_writer_get_name((cs_glob_post_writers + i)->writer),
fvm_writer_get_format((cs_glob_post_writers + i)->writer),
m_cpu_time, c_cpu_time, m_wtime, c_wtime);
}
/* Coordonnées initiales si maillage déformable) */
if (cs_glob_post_coo_som_ini != NULL)
BFT_FREE(cs_glob_post_coo_som_ini);
/* Maillages externes */
for (i = 0 ; i < cs_glob_post_nbr_maillages ; i++) {
maillage_post = cs_glob_post_maillages + i;
if (maillage_post->_maillage_ext != NULL)
fvm_nodal_destroy(maillage_post->_maillage_ext);
BFT_FREE(maillage_post->ind_writer);
}
BFT_FREE(cs_glob_post_maillages);
cs_glob_post_num_maillage_min = -2;
cs_glob_post_nbr_maillages = 0;
cs_glob_post_nbr_maillages_max = 0;
/* Writers */
for (i = 0 ; i < cs_glob_post_nbr_writers ; i++)
fvm_writer_finalize((cs_glob_post_writers + i)->writer);
BFT_FREE(cs_glob_post_writers);
cs_glob_post_nbr_writers = 0;
cs_glob_post_nbr_writers_max = 0;
/* Traitements enregistrés si nécessaire */
if (cs_glob_post_nbr_var_tp_max > 0) {
BFT_FREE(cs_glob_post_f_var_tp);
BFT_FREE(cs_glob_post_i_var_tp);
}
}
/*----------------------------------------------------------------------------
* Initialisation du post-traitement principal
*----------------------------------------------------------------------------*/
void cs_post_init_pcp
(
void
)
{
/* Valeurs par défaut */
cs_int_t indic_vol = -1, indic_brd = -1, indic_syr = -1;
cs_int_t indic_mod = -1;
char fmtchr[32 + 1] = "";
char optchr[96 + 1] = "";
cs_int_t ntchr = -1;
const char nomcas[] = "chr";
const char nomrep_ens[] = "chr.ensight";
const char nomrep_def[] = ".";
const char *nomrep = NULL;
cs_int_t id_maillage = -1;
const cs_int_t id_writer = -1; /* Numéro du writer par défaut */
/* Récupération des paramètres contenus dans les COMMONS Fortran */
CS_PROCF(inipst, INIPST)(&indic_vol,
&indic_brd,
&indic_syr,
&indic_mod,
&ntchr,
fmtchr,
optchr);
fmtchr[32] = '\0';
optchr[64] = '\0';
if (indic_vol == 0 && indic_brd == 0)
return;
/* Création du writer par défaut */
if (fmtchr[0] == 'e' || fmtchr[0] == 'E')
nomrep = nomrep_ens;
else
nomrep = nomrep_def;
cs_post_ajoute_writer(id_writer,
nomcas,
nomrep,
fmtchr,
optchr,
indic_mod,
ntchr);
/* Définition des maillages de post-traitement */
if (cs_glob_maillage->nbr_fac > 0 || cs_glob_maillage->nbr_fbr > 0) {
/*
Si on dispose de la connectivité faces -> sommets, on
peut reconstruire la connectivité nodale pour le post
traitement (mécanisme usuel).
*/
if (indic_vol > 0) { /* Maillage volumique */
id_maillage = -1; /* Numéro de maillage réservé */
cs_post_ajoute_maillage(id_maillage,
_("Volume fluide"),
cs_glob_maillage->nbr_cel,
0,
0,
NULL,
NULL,
NULL);
cs_post_associe(id_maillage, id_writer);
}
if (indic_brd > 0) { /* Maillage de peau */
id_maillage = -2; /* Numéro de maillage réservé */
cs_post_ajoute_maillage(id_maillage,
_("Bord"),
0,
0,
cs_glob_maillage->nbr_fbr,
NULL,
NULL,
NULL);
cs_post_associe(id_maillage, id_writer);
}
} /* Fin if cs_glob_maillage->nbr_fac > 0 || cs_glob_maillage->nbr_fbr > 0 */
/*
Si on ne dispose pas de la connectivité faces -> sommets, on
ne peut pas reconstruire la connectivité nodale, donc on doit
l'obtenir par un autre moyen.
Ceci ne doit se produire que lorsqu'on a lu directement certains
maillages au format solcom, dans quel cas la connectivité
nodale a déja été lue et affectée à un maillage post
(voir LETGEO et cs_maillage_solcom_lit).
*/
else if (indic_vol > 0) {
id_maillage = -1;
if (cs_post_existe_maillage(id_maillage))
cs_post_associe(id_maillage, id_writer);
}
}
/*----------------------------------------------------------------------------
* Ajout d'un traitement de variable temporelle à l'appel de PSTVAR.
*
* L'identificateur d'instance associé à la fonction permet d'ajouter
* une même fonction plusieurs fois, avec un identificateur différent
* permettant à la fonction de sélectionner un sous-traitement.
*----------------------------------------------------------------------------*/
void cs_post_ajoute_var_temporelle
(
cs_post_var_temporelle_t *fonction, /* Fonction associée */
cs_int_t id_instance /* Indentificateur d'instance
associé à la fonction */
)
{
/* Redimensionnement du tableau des traitements enregistrés si nécessaire */
if (cs_glob_post_nbr_var_tp <= cs_glob_post_nbr_var_tp_max) {
if (cs_glob_post_nbr_var_tp_max == 0)
cs_glob_post_nbr_var_tp_max = 8;
else
cs_glob_post_nbr_var_tp_max *= 2;
BFT_REALLOC(cs_glob_post_f_var_tp,
cs_glob_post_nbr_var_tp_max,
cs_post_var_temporelle_t *);
BFT_REALLOC(cs_glob_post_i_var_tp, cs_glob_post_nbr_var_tp_max, cs_int_t);
}
/* Ajout du traitement */
cs_glob_post_f_var_tp[cs_glob_post_nbr_var_tp] = fonction;
cs_glob_post_i_var_tp[cs_glob_post_nbr_var_tp] = id_instance;
cs_glob_post_nbr_var_tp += 1;
}
/*============================================================================
* Fonctions privées
*============================================================================*/
/*----------------------------------------------------------------------------
* Conversion d'un type de données cs_post_type_t en type fvm_datatype_t.
*----------------------------------------------------------------------------*/
static fvm_datatype_t _cs_post_cnv_datatype
(
cs_post_type_t type_cs
)
{
fvm_datatype_t type_fvm = FVM_DATATYPE_NULL;
switch(type_cs) {
case CS_POST_TYPE_cs_int_t:
if (sizeof(cs_int_t) == 4)
type_fvm = FVM_INT32;
else if (sizeof(cs_int_t) == 8)
type_fvm = FVM_INT64;
break;
case CS_POST_TYPE_cs_real_t:
if (sizeof(cs_real_t) == sizeof(double))
type_fvm = FVM_DOUBLE;
else if (sizeof(cs_real_t) == sizeof(float))
type_fvm = FVM_FLOAT;
break;
case CS_POST_TYPE_int:
if (sizeof(int) == 4)
type_fvm = FVM_INT32;
else if (sizeof(int) == 8)
type_fvm = FVM_INT64;
break;
case CS_POST_TYPE_float:
type_fvm = FVM_FLOAT;
break;
case CS_POST_TYPE_double:
type_fvm = FVM_DOUBLE;
break;
default:
assert(0);
}
return type_fvm;
}
/*----------------------------------------------------------------------------
* Recherche de l'indice d'un writer associé à un numéro donné.
*----------------------------------------------------------------------------*/
static int _cs_post_ind_writer
(
const cs_int_t id_writer /* --> numéro du writer */
)
{
cs_int_t indgep;
cs_post_writer_t *writer = NULL;
/* Recherche du writer demandé */
for (indgep = 0 ; indgep < cs_glob_post_nbr_writers ; indgep++) {
writer = cs_glob_post_writers + indgep;
if (writer->id == id_writer)
break;
}
if (indgep >= cs_glob_post_nbr_writers)
bft_error(__FILE__, __LINE__, 0,
_("Le gestionnaire de post traitement numéro %d demandé\n"
"n'est pas défini.\n"), (int)(id_writer));
return indgep;
}
/*----------------------------------------------------------------------------
* Recherche de l'indice d'un maillage de post traitement associé à un
* numéro donné.
*----------------------------------------------------------------------------*/
static int _cs_post_ind_maillage
(
const cs_int_t nummai /* --> numéro du maillage externe associé */
)
{
int indmai;
cs_post_maillage_t *maillage_post = NULL;
/* Recherche du maillage demandé */
for (indmai = 0 ; indmai < cs_glob_post_nbr_maillages ; indmai++) {
maillage_post = cs_glob_post_maillages + indmai;
if (maillage_post->id == nummai)
break;
}
if (indmai >= cs_glob_post_nbr_maillages)
bft_error(__FILE__, __LINE__, 0,
_("Le maillage de post traitement numéro %d demandé\n"
"n'est pas défini.\n"), (int)nummai);
return indmai;
}
/*----------------------------------------------------------------------------
* Ajout d'un maillage de post traitement et initialisation de base,
* et renvoi d'un pointeur sur la structure associée
*----------------------------------------------------------------------------*/
static cs_post_maillage_t * _cs_post_ajoute_maillage
(
const cs_int_t id_maillage /* --> numéro du maillage demandé */
)
{
/* variables locales */
int i, j;
cs_post_maillage_t *maillage_post = NULL;
/* Vérification que le numéro demandé est disponible */
if (id_maillage == 0)
bft_error(__FILE__, __LINE__, 0,
_("Le numéro de maillage de post traitement demandé\n"
"doit être < 0 (réservé) ou > 0 (utilisateur).\n"));
for (i = 0 ; i < cs_glob_post_nbr_maillages ; i++) {
if ((cs_glob_post_maillages + i)->id == id_maillage)
bft_error(__FILE__, __LINE__, 0,
_("Le numéro de maillage de post traitement demandé\n"
"(%d) a déjà été affecté.\n"), (int)id_maillage);
}
/* Redimensionnement du tableau global des maillages externes */
if (cs_glob_post_nbr_maillages == cs_glob_post_nbr_maillages_max) {
if (cs_glob_post_nbr_maillages_max == 0)
cs_glob_post_nbr_maillages_max = 8;
else
cs_glob_post_nbr_maillages_max *= 2;
BFT_REALLOC(cs_glob_post_maillages,
cs_glob_post_nbr_maillages_max,
cs_post_maillage_t);
}
cs_glob_post_nbr_maillages += 1;
if (id_maillage < cs_glob_post_num_maillage_min)
cs_glob_post_num_maillage_min = id_maillage;
/* Affectation du maillage nouvellement crée à la structure */
maillage_post = cs_glob_post_maillages + cs_glob_post_nbr_maillages - 1;
maillage_post->id = id_maillage;
maillage_post->alias = -1;
maillage_post->nbr_writers = 0;
maillage_post->ind_writer = NULL;
maillage_post->nt_ecr = -1;
for (j = 0 ; j < 3 ; j++)
maillage_post->ind_ent[j] = 0;
maillage_post->nbr_fac = 0;
maillage_post->nbr_fbr = 0;
maillage_post->maillage_ext = NULL;
maillage_post->_maillage_ext = NULL;
/* Indicateurs de modification min et max inversés initialement,
seront recalculés lors des associations maillages - post-traitements */
maillage_post->ind_mod_min = FVM_WRITER_TRANSIENT_CONNECT;
maillage_post->ind_mod_max = FVM_WRITER_FIXED_MESH;
return maillage_post;
}
/*----------------------------------------------------------------------------
* Création d'un maillage de post traitement ; les listes de cellules ou
* faces à extraire sont triées en sortie, qu'elles le soient déjà en entrée
* ou non.
*
* La liste des cellules associées n'est nécessaire que si le nombre
* de cellules à extraire est strictement supérieur à 0 et inférieur au
* nombre de cellules du maillage.
*
* Les listes de faces ne sont prises en compte que si le nombre de cellules
* à extraire est nul ; si le nombre de faces de bord à extraire est égal au
* nombre de faces de bord du maillage global, et le nombre de faces internes
* à extraire est nul, alors on extrait par défaut le maillage de bord, et la
* liste des faces de bord associée n'est donc pas nécessaire.
*----------------------------------------------------------------------------*/
static void _cs_post_definit_maillage
(
cs_post_maillage_t *const maillage_post, /* <-> maillage post à compléter */
const char *const nom_maillage, /* --> nom du maillage externe */
const cs_int_t nbr_cel, /* --> nombre de cellules */
const cs_int_t nbr_fac, /* --> nombre de faces internes */
const cs_int_t nbr_fbr, /* --> nombre de faces de bord */
cs_int_t liste_cel[], /* <-> liste des cellules */
cs_int_t liste_fac[], /* <-> liste des faces internes */
cs_int_t liste_fbr[] /* <-> liste des faces de bord */
)
{
/* variables locales */
int i;
int indic_glob[5];
int indic_loc[5] = {1, 1, 1, 0, 0}; /* Indicateurs 0 à 2 "inversés" par
rapport aux autres pour pouvoir
utiliser un même appel à
MPI_Allreduce(..., MPI_MIN, ...) */
fvm_nodal_t *maillage_ext = NULL;
cs_bool_t maj_ind_ent = CS_FALSE;
/* Indicateurs:
0 : 0 si cellules, 1 si pas de cellules,
1 : 0 si faces internes, 1 si pas de faces internes,
2 : 0 si faces de bord, 1 si pas de faces de bord,
3 : 1 si toutes les cellules sont sélectionnées,
4 : 1 si toutes les faces de bord et aucune face interne sélectionnées */
if (nbr_cel > 0)
indic_loc[0] = 0;
else {
if (nbr_fac > 0)
indic_loc[1] = 0;
if (nbr_fbr > 0)
indic_loc[2] = 0;
}
if (nbr_cel >= cs_glob_maillage->nbr_cel)
indic_loc[3] = 1;
else
indic_loc[3] = 0;
if ( nbr_fbr >= cs_glob_maillage->nbr_fbr
&& nbr_fac == 0)
indic_loc[4] = 1;
else
indic_loc[4] = 0;
for (i = 0 ; i < 5 ; i++)
indic_glob[i] = indic_loc[i];
#if defined(_CS_HAVE_MPI)
if (cs_glob_base_nbr > 1)
MPI_Allreduce (indic_loc, indic_glob, 5, MPI_INT, MPI_MIN,
cs_glob_base_mpi_comm);
#endif
/* Création de la structure associée */
if (indic_glob[0] == 0) {
if (indic_glob[3] == 1)
maillage_ext = cs_maillage_extrait_cel_nodal(cs_glob_maillage,
nom_maillage,
cs_glob_maillage->nbr_cel,
NULL);
else
maillage_ext = cs_maillage_extrait_cel_nodal(cs_glob_maillage,
nom_maillage,
nbr_cel,
liste_cel);
}
else {
if (indic_glob[4] == 1)
maillage_ext = cs_maillage_extrait_fac_nodal(cs_glob_maillage,
nom_maillage,
0,
cs_glob_maillage->nbr_fbr,
NULL,
NULL);
else
maillage_ext = cs_maillage_extrait_fac_nodal(cs_glob_maillage,
nom_maillage,
nbr_fac,
nbr_fbr,
liste_fac,
liste_fbr);
}
/* Indicateurs globaux de présence de types de mailles ;
on ne met à jour que si le maillage n'est pas totalement vide
(pour des maillages dépendant du temps, vides à certains instants,
on veut pouvoir connaître le dernier type de maille contenu
dans USMPST) */
for (i = 0 ; i < 3 ; i++) {
if (indic_glob[i] == 0)
maj_ind_ent = CS_TRUE;
}
if (maj_ind_ent == CS_TRUE) {
for (i = 0 ; i < 3 ; i++) {
if (indic_glob[i] == 0) /* Logique indic_glob 0 à 2 inversée */
maillage_post->ind_ent[i] = 1; /* (c.f. remarque ci-dessus) */
else
maillage_post->ind_ent[i] = 0;
}
}
/* Dimensions locales */
maillage_post->nbr_fac = nbr_fac;
maillage_post->nbr_fbr = nbr_fbr;
/* Lien sur le maillage nouvellement créé */
maillage_post->maillage_ext = maillage_ext;
maillage_post->_maillage_ext = maillage_ext;
}
/*----------------------------------------------------------------------------
* Mise à jour en cas d'alias des critères de modification au cours du temps
* des maillages en fonction des propriétés des writers qui lui
* sont associés :
*
* La topologie d'un maillage ne pourra pas être modifiée si le critère
* de modification minimal résultant est trop faible (i.e. si l'un des
* writers associés ne permet pas la redéfinition de la topologie du maillage).
*
* Les coordonnées des sommets et la connectivité ne pourront être libérés
* de la mémoire si la critère de modification maximal résultant est trop
* élevé (i.e. si l'un des writers associés permet l'évolution du maillage
* en temps, et nécessite donc sa réécriture).
*----------------------------------------------------------------------------*/
static void _cs_post_ind_mod_alias
(
const int indmai /* --> indice du maillage post en cours */
)
{
int i;
cs_post_maillage_t *maillage_post = NULL;
cs_post_maillage_t *maillage_ref = NULL;
/* Mise à jour référence */
maillage_post = cs_glob_post_maillages + indmai;
if (maillage_post->alias > -1) {
maillage_ref = cs_glob_post_maillages + maillage_post->alias;
if (maillage_post->ind_mod_min < maillage_ref->ind_mod_min)
maillage_ref->ind_mod_min = maillage_post->ind_mod_min;
if (maillage_post->ind_mod_max < maillage_ref->ind_mod_max)
maillage_ref->ind_mod_max = maillage_post->ind_mod_max;
}
/* Mise à jour alias) */
for (i = 0 ; i < cs_glob_post_nbr_maillages ; i++) {
maillage_post = cs_glob_post_maillages + i;
if (maillage_post->alias > -1) {
maillage_ref = cs_glob_post_maillages + maillage_post->alias;
if (maillage_post->ind_mod_min > maillage_ref->ind_mod_min)
maillage_post->ind_mod_min = maillage_ref->ind_mod_min;
if (maillage_post->ind_mod_max > maillage_ref->ind_mod_max)
maillage_post->ind_mod_max = maillage_ref->ind_mod_max;
}
}
}
/*----------------------------------------------------------------------------
* Découpage des polygones ou polyèdres en éléments simples si nécessaire.
*----------------------------------------------------------------------------*/
static void _cs_post_divise_poly
(
cs_post_maillage_t *const maillage_post, /* --> maillage ext. associé */
const cs_post_writer_t *const writer /* --> writer associé */
)
{
/* Découpage des polygones ou polyèdres en éléments simples */
if (fvm_writer_needs_tesselation(writer->writer,
maillage_post->maillage_ext,
FVM_CELL_POLY) > 0)
fvm_nodal_tesselate(maillage_post->_maillage_ext,
FVM_CELL_POLY,
NULL);
if (fvm_writer_needs_tesselation(writer->writer,
maillage_post->maillage_ext,
FVM_FACE_POLY) > 0)
fvm_nodal_tesselate(maillage_post->_maillage_ext,
FVM_FACE_POLY,
NULL);
}
/*----------------------------------------------------------------------------
* Ecriture d'un maillage de post traitement en fonction des "writers".
*----------------------------------------------------------------------------*/
static void _cs_post_ecrit_maillage
(
cs_post_maillage_t *const maillage_post,
const cs_int_t nt_cur_abs, /* --> numéro de pas de temps */
const cs_real_t t_cur_abs /* --> temps physique courant */
)
{
int j;
cs_bool_t ecrire_maillage;
cs_post_writer_t *writer;
fvm_writer_time_dep_t dep_temps;
/* Boucles sur les "writers" */
for (j = 0 ; j < maillage_post->nbr_writers ; j++) {
writer = cs_glob_post_writers + maillage_post->ind_writer[j];
dep_temps = fvm_writer_get_time_dep(writer->writer);
ecrire_maillage = CS_FALSE;
if (dep_temps == FVM_WRITER_FIXED_MESH) {
if (maillage_post->nt_ecr < 0)
ecrire_maillage = CS_TRUE;
}
else {
if (maillage_post->nt_ecr < nt_cur_abs && writer->actif == 1)
ecrire_maillage = CS_TRUE;
}
if (ecrire_maillage == CS_TRUE) {
fvm_writer_set_mesh_time(writer->writer, nt_cur_abs, t_cur_abs);
fvm_writer_export_nodal(writer->writer, maillage_post->maillage_ext);
}
}
if (ecrire_maillage == CS_TRUE)
maillage_post->nt_ecr = nt_cur_abs;
if ( maillage_post->ind_mod_max == FVM_WRITER_FIXED_MESH
&& maillage_post->_maillage_ext != NULL)
fvm_nodal_reduce(maillage_post->_maillage_ext, 0);
}
/*----------------------------------------------------------------------------
* Assemblage des valeurs d'une variable définie sur une combinaison de
* faces de bord et de faces internes (sans indirection) en un tableau
* défini sur un ensemble unique de faces.
*
* La variable résultante n'est pas entrelacée.
*----------------------------------------------------------------------------*/
static void _cs_post_assmb_var_faces
(
const fvm_nodal_t *const maillage_ext, /* --> maillage externe */
const cs_int_t nbr_fac, /* --> nb faces internes */
const cs_int_t nbr_fbr, /* --> nb faces bord */
const int dim_var, /* --> dim. variable */
const fvm_interlace_t interlace, /* --> indic. entrelacage */
const cs_real_t var_fac[], /* --> valeurs faces int. */
const cs_real_t var_fbr[], /* --> valeurs faces bord */
cs_real_t var_tmp[] /* <-- valeurs assemblées */
)
{
cs_int_t i, j, pas_1, pas_2;
cs_int_t nbr_ent = nbr_fac + nbr_fbr;
assert(maillage_ext != NULL);
/* La variable est définie sur les faces internes et faces de bord
du maillage de post traitement, et a été construite à partir
des listes de faces internes et de bord correspondantes */
/* Contribution des faces de bord */
if (interlace == FVM_INTERLACE) {
pas_1 = dim_var;
pas_2 = 1;
}
else {
pas_1 = 1;
pas_2 = nbr_fbr;
}
for (i = 0 ; i < nbr_fbr ; i++) {
for (j = 0 ; j < dim_var ; j++)
var_tmp[i + j*nbr_ent] = var_fbr[i*pas_1 + j*pas_2];
}
/* Contribution des faces internes */
if (interlace == FVM_INTERLACE) {
pas_1 = dim_var;
pas_2 = 1;
}
else {
pas_1 = 1;
pas_2 = nbr_fac;
}
for (i = 0 ; i < nbr_fac ; i++) {
for (j = 0 ; j < dim_var ; j++)
var_tmp[i + nbr_fbr + j*nbr_ent] = var_fac[i*pas_1 + j*pas_2];
}
}
/*----------------------------------------------------------------------------
* Transformation d'un tableau d'indicateurs (marqueurs) en liste ;
* renvoie la taille effective de la liste.
*----------------------------------------------------------------------------*/
static cs_int_t _cs_post_ind_vers_liste
(
cs_int_t nbr, /* <-> taille indicateur */
cs_int_t liste[] /* <-> indicateur, puis liste */
)
{
cs_int_t cpt, ind;
for (cpt = 0, ind = 0 ; ind < nbr ; ind++) {
if (liste[ind] != 0) {
liste[ind] = 0;
liste[cpt++] = ind + 1;
}
}
return cpt;
}
/*----------------------------------------------------------------------------
* Boucle sur les maillages de post traitement pour écriture des variables
*----------------------------------------------------------------------------*/
static void _cs_post_ecrit_deplacements
(
const cs_int_t nt_cur_abs, /* --> numéro de pas de temps courant */
const cs_real_t t_cur_abs /* --> valeur du temps physique associé */
)
{
/* variables locales */
int i, j;
cs_int_t k;
cs_post_maillage_t *maillage_post;
cs_post_writer_t *writer;
cs_int_t nbr_val;
fvm_lnum_t dec_num_parent[1] = {0};
cs_real_t *deplacements = NULL;
fvm_datatype_t datatype;
const cs_maillage_t *maillage = cs_glob_maillage;
const cs_real_t *var_ptr[1] = {NULL};
/* Boucle sur les writers pour vérifier si l'on a quelque chose à faire */
/*----------------------------------------------------------------------*/
if (cs_glob_post_deformable == CS_FALSE)
return;
for (j = 0 ; j < cs_glob_post_nbr_writers ; j++) {
writer = cs_glob_post_writers + j;
if (writer->actif == 1 && writer->ecr_depl == CS_TRUE)
break;
}
if (j == cs_glob_post_nbr_writers)
return;
/* Calcul du champ de déformation principal */
/*------------------------------------------*/
nbr_val = maillage->nbr_som * 3;
BFT_MALLOC(deplacements, nbr_val, cs_real_t);
assert(maillage->nbr_som == 0 || cs_glob_post_coo_som_ini != NULL);
for (k = 0; k < nbr_val; k++)
deplacements[k] = maillage->coo_som[k] - cs_glob_post_coo_som_ini[k];
/* Préparation du post traitement */
/*--------------------------------*/
if (sizeof(cs_real_t) == sizeof(double))
datatype = FVM_DOUBLE;
else if (sizeof(cs_real_t) == sizeof(float))
datatype = FVM_FLOAT;
var_ptr[0] = deplacements;
/* Boucle sur les maillages pour l'écriture des déplacements */
/*-----------------------------------------------------------*/
for (i = 0 ; i < cs_glob_post_nbr_maillages ; i++) {
maillage_post = cs_glob_post_maillages + i;
for (j = 0 ; j < maillage_post->nbr_writers ; j++) {
writer = cs_glob_post_writers + maillage_post->ind_writer[j];
if (writer->actif == 1 && writer->ecr_depl == CS_TRUE) {
fvm_writer_export_field(writer->writer,
maillage_post->maillage_ext,
_("displacement"),
FVM_WRITER_PER_NODE,
3,
FVM_INTERLACE,
1,
dec_num_parent,
datatype,
(int)nt_cur_abs,
(double)t_cur_abs,
(const void * *)var_ptr);
}
}
}
/* Libération mémoire */
BFT_FREE(deplacements);
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
syntax highlighted by Code2HTML, v. 0.9.1