/*============================================================================ * * 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 #include #include #include #include /* Includes BFT */ #include #include #include /* Includes FVM */ #include #include /* 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 */