* SATUTILS PROCEDUR FANDEUR 13/03/25 21:15:00 7446 ************************************************************************ * NOM : SATUTILS * DESCRIPTION : * * * * LANGAGE : GIBIANE-CAST3M * AUTEUR : Gilles BERNARD - MICHEL (CEA/DEN/DM2S/SFME/LTMF) * mél : gbm@semt2.smts.cea.fr ********************************************************************** * VERSION : v1, 25/12/2006, version initiale * HISTORIQUE : v1, 25/12/2006, création * HISTORIQUE : * HISTORIQUE : ************************************************************************ * Prière de PRENDRE LE TEMPS de compléter les commentaires * en cas de modification de ce sous-programme afin de faciliter * la maintenance ! ************************************************************************ * ************************************************************************* 'SI' ('EGA' roro LICODINI) ; 'ARGUMENT' SATUR*'TABLE' ; * GBM INITIALISE CORRECT TRACE ET FLUX * ----------------------------------------------------------------- * * RECUPERATION DES CONDITIONS INITIALES OU DU DERNIER PAS CALCULE * * ----------------------------------------------------------------- * * * TEMPS 'SI' ( 'NON' ('EXISTE' SATUR 'TEMPS' ) ) ; SATUR.'TEMPS' = 'TABLE' ; SATUR.'TEMPS'. 0 = 0. ; 'FINSI' ; * CHARGE 'SI' ( 'NON' ('EXISTE' SATUR 'CHARGE' ) ) ; 'ERREUR' 'Indice CHARGE absent de la table de données.' ; 'FINSI' ; * FLUX * La présence de l'indice FLUX est obligatoire. * Tests des tailles de tables IND1 = 'INDEX' ( SATUR . 'TEMPS' ) ; IND3 = 'INDEX' ( SATUR . 'CHARGE' ) ; 'SI' ( LIN1 'NEG' LIN3 ) ; 'ERREUR' 'FINSI' ; * Tests des indices de tables IPO1 = 0 ; 'REPETER' BOU1 LIN1 ; IPO1 = IPO1 + 1 ; LAST1 = IND1 . IPO1 ; LAST3 = IND3 . IPO1 ; 'SI' ( 'NEG' LAST1 LAST3 ) ; 'ERREUR' 'Indices des tables TEMPS et CHARGE incohérents.' ; 'FINSI' ; 'FIN' BOU1 ; * Récupération des inconnues initiales TPSINI = SATUR . 'TEMPS' . LAST1 ; CHRG = SATUR . 'CHARGE' . LAST1 ; 'SI' (EXISTE SATUR 'TRACE_CHARGE') ; *GBM METTRE A JOUR INITIALISATION - TRES IMPORTANT SI (EXISTE SATUR . 'TRACE_CHARGE' LAST1) ; TRH = SATUR . 'TRACE_CHARGE' . LAST1 ; SINON ; SATUR . 'TRACE_CHARGE' . LAST1 = TRH ; FINSI ; 'SINON' ; SATUR . 'TRACE_CHARGE' = table ; SATUR . 'TRACE_CHARGE' . LAST1 = TRH ; 'FINSI' ; 'RESPRO' TPSINI CHRG TRH FLU0 LAST1 ; 'FINSI' ; *********************************************************************** 'SI' ('EGA' roro LIMODELE) ; 'ARGUMENT' SATUR*'TABLE' ; * 'SI' ( 'EXISTE' SATUR 'MODELE' ) ; 'SINON' ; 'ERREUR' 'Le modèle doit contenir une formulation DARCY' ; 'FINSI' ; ABMC = 'ABS' MCHYB ; 'RESPRO' MDMH MCHYB VHYB MAILSOM MAILCENT ABMC ; 'FINSI' ; *********************************************************************** 'SI' ('EGA' roro LIPHYSIK) ; 'ARGUMENT' SATUR*'TABLE' ; * COEF_EMMAGASINEMENT 'SI' ( 'EXISTE' SATUR 'COEF_EMMAGASINEMENT') ; COFEMMAG = SATUR.'COEF_EMMAGASINEMENT' ; 'ERREUR' ('CHAINE' 'Le coefficient d emmagasinement doit etre' 'FINSI' ; 'NATURE' 'DISCRET' ; 'FINSI' ; 'SINON' ; 'FINSI' ; * PESANTEUR * Valeur de l'accélération de la pesanteur L_GRAV = 'EXISTE' SATUR 'FORCE_GRAVITE' ; 'SI' L_GRAV ; RHOWG = SATUR . 'FORCE_GRAVITE' ; 'SINON' ; RHOWG = 0.D0 ; 'FINSI' ; 'SI' ( 'EXISTE' SATUR 'AXE_G') ; GAXE = SATUR.'AXE_G' ; * normalisation de GAXE 'SI' (NORGAXE 'NEG' 0.) ; 'SI' (NDIME 'EGA' 3) ; 'FINSI' ; 'SINON' ; * GBM PENSE DOIT ETRE FAUX - A VOIR XAXE YAXE ZAXE = 0. 0. 0. ; 'FINSI' ; 'SINON' ; 'SI' (NDIME 'EGA' 2) ; XAXE YAXE = 0. 1. ; 'SINON' ; XAXE YAXE ZAXE = 0. 0. 1. ; 'FINSI' ; 'FINSI' ; 'SI' (NDIME 'EGA' 3) ; DAXE = (XAXE YAXE ZAXE) ; 'SINON' ; DAXE = (XAXE YAXE) ; 'FINSI' ; * CONVERSION_CHARGE * Facteur de convertion de l'unité d'expression de la charge vers des * Pascals. Par défaut, on suppose que les pressions sont en Pascal. 'SI' ('EXISTE' SATUR 'CONVERSION_CHARGE') ; CONVH = SATUR.'CONVERSION_CHARGE' ; 'SINON' ; CONVH = 1. ; 'FINSI' ; 'RESPRO' COFEMMAG L_GRAV RHOWG DAXE CONVH ; 'FINSI' ; ************************************************************************** * Procédure d'affichage 'SI' ('EGA' roro AFFICH) ; TPS*'FLOTTANT' TPSANC*'FLOTTANT' DELTAT*'FLOTTANT' DTI*'FLOTTANT' debug*'LOGIQUE' ; 'SI' debug ; * Affichage de l'en-tête de messages, complété à chaque itération 'MESS' ' ' ; 'SI' (('EGA' IPAL 1) 'ET' ('EGA' ITRANSI 1)) ; '+' (DELTAT) ; 'SINON' ; * rendre cet affichage optionnel 'temps (s) : ' TPS '=' TPSANC '+' DELTAT ; 'FINSI' ; '------------------------------------------------') ; '------------------------------------------------') ; 'SINON' ; * Affichage de temps en cours 'FINSI' ; 'FINSI' ; ************************************************************************* 'SI' ('EGA' roro KALSAT) ; PNS*'CHPOINT'; * GBM REGARDER SI PAS MEILLEURE BOUCLE QUAND TOUTES MEMES LOIS MAIS UN * COEF PAR ZONE *- calcul teneur en eau, saturation et premier terme capacité capillaire * Attention, la teneur calculée utilise une porosité constante au cours * du pas de temps. SAT = 0. ; TEN = 0. ; NBDS = 0 ; NOMT = 'CHAINE' LOIS.'INDEX'.&BB ; LOI1 = LOIS . NOMT ; MOD1 = LOI1 . 'MODELE' ; * réduction de la pression au sous-domaine (local) * calcul teneur et saturation * SATL TENL CAPL= ('TEXTE' NOMHT) LOI1 PNSL ; * * récupération porosité *- Calcul capacité capillaire = d teneur / d h * méthode de la corde ** avec la séparation en pression minimale : * PNSL2 = PNSL '-' LOI1.'PREC' ; * SATL2 TENL2 = ('TEXTE' nmproc) LOI1 PNSL2 ; ** Dérivation * CAP1 = TENL2 '-' TENL ; * CAP2 = 'ABS' (CAP1 '/' LOI1.'PREC') ; * La capacité est nulle à saturation : MP1 = 'MASQUE' PNSL 'INFERIEUR' 0. ; CAPL = CAPL '*' MP ; * ON EST ICI * nombre de faces/centres désaturés : nbds = nbds + ('ENTIER' ('MAXIMUM' ('RESULT' MP))) ; * concaténation * GBM a changé CENTRE en NIVEAU sur SAT !!!!!!!! 'DETRUIT' PNSL ; 'DETRUIT' SATL ; 'DETRUIT' TENL ; 'DETRUIT' PORL ; * 'DETRUIT' PNSL2 ; * 'DETRUIT' SATL2 ; * 'DETRUIT' TENL2 ; * 'DETRUIT' CAP1 ; * 'DETRUIT' CAP2 ; 'DETRUIT' MP1 ; 'DETRUIT' MP ; 'DETRUIT' CAPL ; 'FIN' BB ; 'RESPRO' nbds SAT TEN CAPA PORO1 ; 'FINSI' ; *********************************************************************** 'SI' ('EGA' roro KALSOT) ; PNS*'CHPOINT' ; * GBM REGARDER SI PAS MEILLEURE BOUCLE QUAND TOUTES MEMES LOIS MAIS UN * COEF PAR ZONE *- calcul teneur en eau, saturation et premier terme capacité capillaire * Attention, la teneur calculée utilise une porosité constante au cours * du pas de temps. * GBM AU LIEU DE LA BOUCLE ON POURRAIT PLUTOT CONCATENER AU * niveau des lois les coef et appliquer directement au champ * c'est la proc NOM_HT qui ferait ce qu'il faut, tout le reste * est faisable en creant des champs adéquats de coef. *-- Calcul teneur en eau, saturation et capacité capillaire nbds = 0 ; TEN = 0. ; SAT = 0. ; NOMT = 'CHAINE' LOIS.'INDEX'.&BB ; LOI1 = LOIS . NOMT ; MOD1 = LOI1 . 'MODELE' ; * pression et teneur en eau actuelles réduites au sous-domaine : * PNS pression en eau SATL TENL CAPL = ('TEXTE' NOMHT) LOI1 PNSL ; * concaténation teneur et saturation ** Détermination des zones saturées : ** GBM - attention test fouareux sur les inférieurs - pas précis MP1 = 'MASQUE' PNSL 'INFERIEUR' -1.D-15 ; ** La capacité est nulle à saturation : ** GBM la remise à 0 est elle nécessaire ???????? ** le calcul de Cap2 devrait aboutir naturellement à cela * sinon C que le schéma n'est pas stable CAPL = CAPL '*' MP ; * GBM application du "decentrement" * nombre de faces/centres désaturés : * fouareux car peut etre sur les traces ou sommet * il faut faire sur pression et non trace de pression * GBM GBM GBM nbds = nbds + ('ENTIER' ('MAXIMUM' ('RESULT' MP))) ; * concaténation capacité 'DETRUIT' PNSL ; 'DETRUIT' SATL ; 'DETRUIT' TENL ; 'DETRUIT' CAPL ; 'DETRUIT' MP ; 'DETRUIT' MP1 ; 'FIN' BB ; 'RESPRO' nbds SAT TEN CAPA ; 'FINSI' ; ************************************************************************ 'SI' ('EGA' roro LILOIPER) ; 'ARGUMENT' SATUR*'TABLE' ; 'SI' ('NON' ('EXISTE' SATUR 'LOI_PERMEABILITE')) ; 'ERREUR' 'La table LOI_PERMEABILITE est absente' ; 'FINSI' ; LOIP = 'TABLE' SATUR.'LOI_PERMEABILITE' ; 'SI' ('NON' ('EXISTE' LOIP 'SOUSTYPE')) ; 'ERREUR' 'La table LOI_PERMEABILITE n a pas de soustype' ; mess ' MUALEM, BURDINE, MUALEM_BURDINE,BROOKS_COREY,' ; 'FINSI' ; * Gestion des sous-zones éventuelles 'SI' ('EGA' LOIP.'SOUSTYPE' 'MULTIZONE') ; * Il y a plusieurs lois suivant les zones. * On crée l'index qui permettra de parcourir les zones * et on en retranche l'indice contenant le mot 'SOUSTYPE' * De cette façon, il ne reste dans l'index que les sous-zones, * et pas d'indice parasite. 'SI' ('NON' ('EXISTE' LOIP 'INDEX')) ; LOIP.'INDEX' = 'INDEX' LOIP ; 'FINSI' ; 'REPETER' bcl dd ; i = &bcl ; 'SI' ('EGA' LOIP.'INDEX'.i 'SOUSTYPE') ; * on écrase cet indice par les suivants : 'SI' (i < dd) ; 'REPETER' bcl2 (dd - i) ; j = i + &bcl2 ; LOIP.'INDEX'.(j-1) = LOIP.'INDEX'.j ; 'FIN' bcl2 ; 'FINSI' ; * en oubliant le dernier 'OUBLIER' (LOIP.'INDEX') dd ; 'QUITTER' bcl ; 'FINSI' ; 'FIN' bcl ; * On parcourt toutes les sous-lois LOI1 = LOIP . NOMT ; * nom de la zone LOI1.'NOMZONE' = 'CHAINE' NOMT ; * sous-type 'SI' ('NON' ('EXISTE' LOI1 'SOUSTYPE')) ; 'ERREUR' ('CHAINE' 'La soustable ' NOMT ' de LOI_PERMEABILITE na pas de soustype'); mess ' MUALEM_BURDINE,BROOKS_COREY,' ; 'FINSI' ; 'SI' (('NEG' LOI1.'SOUSTYPE' 'PUISSANCE') 'ET' ('NEG' LOI1.'SOUSTYPE' 'EXPONENTIELLE') 'ET' ('NEG' LOI1.'SOUSTYPE' 'LOGARITMIQUE') 'ET' ('NEG' LOI1.'SOUSTYPE' 'MUALEM') 'ET' ('NEG' LOI1.'SOUSTYPE' 'BURDINE') 'ET' ('NEG' LOI1.'SOUSTYPE' 'MUALEM_BURDINE') 'ET' ('NEG' LOI1.'SOUSTYPE' 'BROOKS_COREY') 'ET' ('NEG' LOI1.'SOUSTYPE' 'PERSONNELLE')) ; 'ERREUR' 'SOUSTYPE de loi inconnu' ; 'FINSI' ; * nom procédure 'SI' ('EGA' LOI1.'SOUSTYPE' 'PERSONNELLE') ; 'SI' ('NON' ('EXISTE' LOI1 'NOM_PROCEDURE')) ; 'ERREUR' 'Il manque le nom de la procédure personnelle de' ' perméabilité pour la zone ' NOMT ; 'FINSI' ; 'SINON' ; * nom de la procédure standard 'FINSI' ; * modèle 'SI' ('NON' ('EXISTE' LOI1 'MODELE')) ; 'ERREUR' ('CHAINE' 'Il manque le MODELE ' 'FINSI' ; 'FIN' BB ; 'SINON' ; * Il y a une seule loi pour tout le domaine * on imite la structure d'une sous-loi pour généraliser * nom de la zone * on recopie coefficients et paramètres, et on crée un index idtmp = 'INDEX' LOIP ; LOIP.NOMT = 'TABLE' ; 'SI' ('NEG' id NOMT) ; LOIP.NOMT.id = LOIP.id ; 'FINSI' ; 'FIN' bcl ; LOIP.'INDEX' = 'TABLE' ; NZONE = 1 ; * sous-type 'SI' (('NEG' LOIp . 'SOUSTYPE' 'PUISSANCE') 'ET' ('NEG' LOIp . 'SOUSTYPE' 'EXPONENTIELLE') 'ET' ('NEG' LOIp . 'SOUSTYPE' 'LOGARITMIQUE') 'ET' ('NEG' LOIp . 'SOUSTYPE' 'MUALEM') 'ET' ('NEG' LOIp . 'SOUSTYPE' 'BURDINE') 'ET' ('NEG' LOIp . 'SOUSTYPE' 'MUALEM_BURDINE') 'ET' ('NEG' LOIp . 'SOUSTYPE' 'BROOKS_COREY') 'ET' ('NEG' LOIp . 'SOUSTYPE' 'PERSONNELLE')) ; 'ERREUR' 'SOUSTYPE de loi inconnu' ; 'FINSI' ; * nom procédure 'SI' ('EGA' LOIP.'SOUSTYPE' 'PERSONNELLE') ; 'SI' ('NON' ('EXISTE' LOIP 'NOM_PROCEDURE')) ; 'ERREUR' 'Il manque le nom de la procédure personnelle de' ' perméabilité pour la zone ' NOMT ; 'FINSI' ; 'SINON' ; 'FINSI' ; * modèle LOIP.NOMT.'MODELE' = MDMH ; 'FINSI' ; 'RESPRO' LOIP ; 'FINSI' ; *********************************************************************** 'SI' ('EGA' roro 'LILOISAT') ; 'SI' ('NON' ('EXISTE' SATUR 'LOI_SATURATION')) ; 'ERREUR' 'La table LOI_SATURATION est absente' ; 'FINSI' ; LOIS = 'TABLE' SATUR.'LOI_SATURATION' ; 'SI' ('NON' ('EXISTE' LOIS 'SOUSTYPE')) ; 'ERREUR' 'La table LOI_SATURATION n a pas de soustype' ; 'FINSI' ; LOISAT = 'CHAINE' LOIS.'SOUSTYPE' ; * Gestion des sous-zones éventuelles 'SI' ('EGA' LOISAT 'MULTIZONE') ; * Il y a plusieurs lois suivant les zones. * On crée l'index qui permettra de parcourir les zones * et on en retranche l'indice contenant le mot 'SOUSTYPE' * De cette façon, il ne reste dans l'index que les sous-zones, * et pas d'indice parasite. 'SI' ('NON' ('EXISTE' LOIS 'INDEX')) ; LOIS.'INDEX' = 'INDEX' LOIS ; 'FINSI' ; 'REPETER' bcl dd ; i = &bcl ; 'SI' ('EGA' LOIS.'INDEX'.i 'SOUSTYPE') ; * on écrase cet indice par les suivants : 'SI' (i < dd) ; 'REPETER' bcl2 (dd - i) ; j = i + &bcl2 ; LOIS.'INDEX'.(j-1) = LOIS.'INDEX'.j ; 'FIN' bcl2 ; 'FINSI' ; * en oubliant le dernier 'OUBLIER' (LOIS.'INDEX') dd ; 'QUITTER' bcl ; 'FINSI' ; 'FIN' bcl ; * On parcourt toutes les sous-lois * CS NOMT = 'MOT' LOIS.'INDEX'.&BB ; NOMT = LOIS.'INDEX'.&BB ; LOI1 = LOIS . NOMT ; * nom de la zone LOI1.'NOMZONE' = 'CHAINE' NOMT ; * sous-type 'SI' ('NON' ('EXISTE' LOI1 'SOUSTYPE')) ; 'ERREUR' ('CHAINE' 'La soustable ' NOMT ' de LOI_SATURATION na pas de soustype') ; 'FINSI' ; LOISAT1 = 'CHAINE' LOI1.'SOUSTYPE' ; 'SI' (('NEG' LOISAT1 'VAN_GENUCHTEN') 'ET' ('NEG' LOISAT1 'EXPONENTIELLE') 'ET' ('NEG' LOISAT1 'LOGARITHMIQUE') 'ET' ('NEG' LOISAT1 'PERSONNELLE')) ; 'ERREUR' 'SOUSTYPE de loi inconnu' ; 'FINSI' ; * nom procédure 'SI' ('EGA' LOISAT1 'PERSONNELLE') ; 'SI' ('NON' ('EXISTE' LOI1 'NOM_PROCEDURE')) ; 'ERREUR' 'Il manque le nom de la procédure personnelle de' ' saturation pour la zone ' NOMT ; 'FINSI' ; 'SINON' ; * nom de la procédure standard 'FINSI' ; * modèle 'SI' ('NON' ('EXISTE' LOI1 'MODELE')) ; 'ERREUR' ('CHAINE' 'Il manque le MODELE' 'FINSI' ; 'FIN' BB ; 'SINON' ; * Il y a une seule loi pour tout le domaine * on imite la structure d'une sous-loi pour généraliser * nom de la zone * on recopie coefficients et paramètres, et on crée un index idtmp = 'INDEX' LOIS ; LOIS.NOMT = 'TABLE' ; 'SI' ('NEG' id NOMT) ; LOIS.NOMT.id = LOIS.id ; 'FINSI' ; 'FIN' bcl ; LOIS.'INDEX' = 'TABLE' ; NZONE = 1 ; * sous-type 'SI' (('NEG' LOISAT 'VAN_GENUCHTEN') 'ET' ('NEG' LOISAT 'EXPONENTIELLE') 'ET' ('NEG' LOISAT 'LOGARITHMIQUE') 'ET' ('NEG' LOISAT 'PERSONNELLE')) ; 'MESS' 'soustype actuel' LOISAT ; 'ERREUR' 'SOUSTYPE de loi inconnu' ; 'FINSI' ; * nom procédure 'SI' ('EGA' LOISAT 'PERSONNELLE') ; 'SI' ('NON' ('EXISTE' LOIS 'NOM_PROCEDURE')) ; 'ERREUR' 'Il manque le nom de la procédure personnelle de' ' saturation pour la zone ' NOMT ; * 'SINON' ; LOIS.NOMT.'NOM_PROCEDURE'= LOIS.'NOM_PROCEDURE' ; 'FINSI' ; 'SINON' ; * nom de la procédure standard 'FINSI' ; * modèle LOIS.NOMT.'MODELE' = MDMH ; 'FINSI' ; 'RESPRO' LOIS ; 'FINSI' ; *********************************************************************** *********************************************************************** *--------------------------------------------------------------------* * RECUPERATION DES DONNEES NUMERIQUES * *--------------------------------------------------------------------* 'SI' ('EGA' roro LIPARANU) ; * * HOMOGENEISATION 'SI' ('NON' ('EXISTE' SATUR 'HOMOGENEISATION')) ; NIVEAU = 'TEXTE' (CHAINE 'CENTRE') ; NIVEAU = CHAINE 'CENTRE' ; 'SINON' ; 'SI' ('EGA' SATUR.'HOMOGENEISATION' 'CENTRE') ; NIVEAU = 'TEXTE' ('CHAINE' 'CENTRE') ; NIVEAU = 'CHAINE' 'CENTRE' ; 'SINON' ; 'SI' ('EGA' SATUR.'HOMOGENEISATION' 'DECENTRE') ; NIVEAU = 'TEXTE' ('CHAINE' 'MSOMMET') ; NIVEAU = 'CHAINE' 'MSOMMET' ; 'SINON' ; 'SI' ('EGA' SATUR.'HOMOGENEISATION' 'TRACE') ; * NIVEAU = 'CHAINE' 'FACE' ; 'SINON' ; 'ERREUR' 'la méthode d homogénisation n est pas reconnue' ; 'FINSI' ; 'FINSI' ; 'FINSI' ; 'FINSI' ; * THETA 'SI' ( 'EXISTE' SATUR 'THETA' ) ; TETA = SATUR . 'THETA' ; 'SINON' ; TETA = 1.D0 ; 'FINSI' ; * NPAS 'SI' ( 'EXISTE' SATUR 'NPAS' ) ; NPAS0 = SATUR . 'NPAS' ; 'SINON' ; * 'SI' ( SATUR.'HYDRO_MECA' ) ; ** cas du couplage avec la méca, Darcysat sert de façon incrémentale * NPAS0 = 1 ; * 'SINON' ; * boucle infinie (arrêtée par TEMPS_FINAL) NPAS0 = 0 ; * 'FINSI' ; 'FINSI' ; * SOUS RELAX 'SI' ('NON' ('EXISTE' SATUR 'SOUS_RELAXATION')) ; SATUR.'SOUS_RELAXATION' = 1. ; 'FINSI' ; * NITER 'SI' ( 'EXISTE' SATUR 'NITER' ) ; NITER0 = SATUR . 'NITER' ; 'SINON' ; NITER0 = 10 ; 'FINSI' ; * RESIDU_MAX 'SI' ( 'EXISTE' SATUR 'RESIDU_MAX' ) ; ERR0 = SATUR . 'RESIDU_MAX' ; 'SINON' ; ERR0 = 1.D-4 ; 'FINSI' ; CFL0 = 1.D0 ; * ITMAXI * nb max d'itérations non linéaires 'SI' ( 'EXISTE' SATUR 'ITMAX') ; itmaxi = SATUR . 'ITMAX' ; 'SINON' ; itmaxi = 40 ; 'FINSI' ; * XI * coefficient de pénalisation à utiliser éventuellement * La pénalisation a priorité sur la réduction de pas de temps. OKPENAL = 'EXISTE' SATUR 'XI' ; 'SI' OKPENAL ; cofpenal = SATUR . 'XI' ; NPENALDT = 2 ; * seront inutilisés mais plus pratique pour les sorties COFDIV = 1.D0 ; NMAXDT = 2 ; 'SINON' ; * COFDIV * astuce par défaut : on divise le pas de temps, * d'un facteur COFDIV et un nombre NMAXDT maximum de fois. 'SI' ('EXISTE' SATUR 'COFDIV') ; COFDIV = SATUR.'COFDIV' ; 'SINON' ; COFDIV = 0.5 ; 'FINSI' ; * NMAXDT 'SI' ('EXISTE' SATUR 'NMAXDT') ; NMAXDT = SATUR.'NMAXDT' ; 'SINON' ; NMAXDT = 6 ; 'FINSI' ; NPENALDT = NMAXDT ; * pas de penalisation cofpenal = 0.D0 ; 'FINSI' ; 'SI' ('NON' ('EXISTE' SATUR 'TYPDISCRETISATION' )) ; * On choisit VF par défaut SATUR . 'TYPDISCRETISATION' = 'VF' ; 'FINSI' ; 'SI' ( ('EGA' SATUR . 'TYPDISCRETISATION' 'VF') 'ET' ('EGA' SATUR . 'HOMOGENEISATION' 'TRACE') ) ; 'ERREUR' 'méthode d homogénisation imcompatible avec les VF' ; 'FINSI' ; 'RESPRO' NIVEAU TETA NPAS0 NITER0 ERR0 CFL0 ITMAXI OKPENAL cofpenal npenaldt cofdiv nmaxdt ; *'RESPRO' NIVEAU; 'FINSI' ; *********************************************************************** 'SI' ('EGA' roro LITABTPS) ; 'ARGUMENT' SATUR*'TABLE' TPSI*'FLOTTANT' debug*'LOGIQUE' NPAS0*'ENTIER'; tmin = TPSI ; DTAUTO = FAUX ; 'SI' ('EXISTE' SATUR 'TEMPS_CALCULES') ; * Si les temps calculés sont spécifiés, on en déduit le temps final * et le pas de temps initial LTCALCUL = 'ORDONNER' (SATUR.'TEMPS_CALCULES') ; * détermination du 1er indice de temps à calculer > TPSINI * c'est le prochain temps à calculer TPS = LTCALCUL(ICAL) 'REPETER' bouc1 DCAL ; ICAL = &bouc1 ; 'SI' (tps > TPSINI) ; 'QUITTER' bouc1 ; 'FINSI' ; 'FIN' bouc1 ; NPAS0 = DCAL - ICAL + 1 ; DELTAT = TPS - TPSINI ; 'SI' ('EXISTE' SATUR 'TEMPS_FINAL'); 'SI' (SATUR.'TEMPS_FINAL' < ('MAXIMUM' LTCALCUL)) ; TFINAL = SATUR.'TEMPS_FINAL' ; 'SI' debug ; mess 'Le calcul sera conduit jusqu a TEMPS_FINAL, malgré que' ' la liste TEMPS_CALCULES aille au-delà' ; 'FINSI' ; 'SINON' ; TFINAL = 'MAXIMUM' LTCALCUL ; 'SI' debug ; mess 'indice TEMPS_FINAL ignoré car supérieur ou égal au ' 'dernier temps spécifié par TEMPS_CALCULES'; 'FINSI' ; 'FINSI' ; 'SINON' ; TFINAL = 'MAXIMUM' LTCALCUL ; 'FINSI' ; 'SI' ('EXISTE' SATUR 'DT_INITIAL'); 'SI' debug ; mess 'indice DT_INITIAL ignoré, car on respecte TEMPS_CALCULES'; 'FINSI' ; 'FINSI' ; 'SINON' ; * Sinon, on a besoin du temps final pour savoir où s'arrêter 'SI' ('EXISTE' SATUR 'TEMPS_FINAL'); TFINAL = SATUR . 'TEMPS_FINAL' ; 'SINON' ; 'ERREUR' 'Renseigner TEMPS_FINAL si TEMPS_CALCULES laissé libre '; 'FINSI' ; 'SI' ('EXISTE' SATUR 'DT_INITIAL'); DELTAT = SATUR .'DT_INITIAL'; 'SINON' ; * pas de temps calculé automatiquement plus tard * DELTAT inutil mais initialisé pour sortie plus simple DELTAT = 0.D0; DTAUTO = VRAI ; 'FINSI' ; * parametre inutils mais pour sortie unifiee. Leur valeur est * toutefois non pipot au cas où on s'en servirait. DCAL = 0.D0; ICAL = 0; 'FINSI' ; 'SI' ( 'EXISTE' SATUR 'TEMPS_SAUVES' ) ; TPSOR = 'ORDONNER' (SATUR . 'TEMPS_SAUVES') ; ISOR = 0 ; IOK1 = FAUX ; 'REPETER' BOU3 DSOR ; ISOR = ISOR + 1 ; 'SI' ( ( tmin '<' (TEMS - 1.e-6) ) 'ET' ( TEMS '<EG' (TFINAL + 1.e-6)) ) ; IOK1 = VRAI ; 'QUITTER' BOU3 ; 'FINSI' ; 'FIN' BOU3 ; 'SI' ('NON' IOK1) ; 'ERREUR' 'FINSI' ; 'SINON' ; ISOR = 0; DSOR = 0; * on met le temps final dans liste tps sortie - GBM tester 'FINSI' ; 'RESPRO' DCAL LTCALCUL DTAUTO ICAL tmin NPAS0 DELTAT TFINAL isor tpsor dsor ; 'FINSI' ; *********************************************************************** 'SI' ('EGA' roro REKAPITU) ; 'ARGUMENT' SATUR*'TABLE' L_GRAV*'LOGIQUE' rhowg*'FLOTTANT' DAXE*'POINT' convh*'FLOTTANT' cfl0*'FLOTTANT' teta*'FLOTTANT' LAST1*'ENTIER' debug*'LOGIQUE' ; 'SI' debug ; 'SAUTER' 1 'LIGNE' ; 'MESS' 'Modélisation Darcy Eléments Finis Mixtes Hybrides' ' en transitoire en milieu saturé et non-saturé.' ; 'MESS' '-------------------------------------------------' '-----------------------------------------------' ; 'SAUTER' 1 'LIGNE' ; 'MESS' ' | d t |' ; 'MESS' ' | |' ; 'MESS' ; 'MESS' 'avec :' ; 'MESS' ' d, dérivée ronde ' ; 'MESS' ' ' ; 'MESS' 'Données présentes en entrée : ' ; 'SI' ( 'EXISTE' SATUR 'SOURCE' ) ; 'MESS' ' Ce problème comporte un terme source' ; 'FINSI' ; 'SI' L_GRAV ; 'MESS' ' Ce problème comporte un effet gravitationnel ' XAXE = 'COORDONNEE' 1 DAXE ; YAXE = 'COORDONNEE' 2 DAXE ; 'SI' (NDIME 'EGA' 2) ; 'MESS' ' Direction de l axe de pesanteur :' ; ' ->') ; 'SINON' ; ZAXE = 'COORDONNEE' 3 DAXE ; 'MESS' ' Direction de l axe de pesanteur :' ; ' -> ->' ) ; 'FINSI' ; 'SINON' ; 'MESS' ' Ce problème est SANS effet gravitationnel' ; 'FINSI' ; 'SI' ('EGA' CONVH 1.) ; 'MESS' ' Les pressions sont exprimées en Pascal' ; 'SINON' ; 'MESS' ' Les pressions sont exprimées en Pascal/' 'FINSI' ; 'SI' ( 'EXISTE' SATUR 'COEF_EMMAGASINEMENT' ) ; 'MESS' ' Ce problème comporte un coefficient d emmagasinement' ; 'SINON' ; 'MESS' ' Ce problème est SANS coefficient d emmagasinement' ; 'FINSI' ; 'SI' ( 'EXISTE' SATUR 'XI' ) ; 'MESS' ' Paramètre de pénalisation : ' SATUR.'XI' ; 'FINSI' ; 'MESS' ' Relaxation : ' SATUR.'SOUS_RELAXATION' ; 'MESS' SATUR.'HOMOGENEISATION' ; 'MESS' ' ' ; 'MESS' ' Valeur de THETA, parametre du schéma diffusif : ' TETA ; 'FINSI' ; 'MESSAGE' 'hihihihiihih ' roro; 'SI' (LAST1 > 0) ; 'MESSAGE' roro ; 'MESS' 'Reprise de calcul au pas : ' LAST1 ; 'FINSI' ; 'MESS' ' ' ; 'FINSI' ; *********************************************************************** 'SI' ('EGA' roro SAVRESU) ; 'ARGUMENT' SATUR*'TABLE' TPSOR/'LISTREEL' ISOR*'ENTIER' TPSANC*'FLOTTANT' TPS*'FLOTTANT' ISAUV*'ENTIER' DELTAT*'FLOTTANT' TRHANC*'CHPOINT' TRH*'CHPOINT' CHRGANC*'CHPOINT' CHRG*'CHPOINT' TENANC*'CHPOINT' TEN*'CHPOINT' PNSANC*'CHPOINT' PNS*'CHPOINT' SATANC*'CHPOINT' SAT*'CHPOINT' FLUANC*'CHPOINT' nnind*'ENTIER' MDMH*'MMODEL' ; 'SI' ( 'EXISTE' SATUR 'TEMPS_SAUVES' ) ; * Sauvegarde de tous les temps intermédiaires, s'il y en a : 'REPETER' BOU9 ; 'SI' (isauv < 0) ; * sauvegarde initiale isauv = isauv + 1 ; DTEM = ( TPS - TEMS ) / DELTAT ; UNMO = 1. - DTEM ; * 'SI' ('NON' (SATUR.'HYDRO_MECA')) ; * Lorsque DARCYSAT est appellé par PASAPAS, c'est PASAPAS qui * sauvegarde le temps calculé, sinon, c'est DARCYSAT. SATUR.'TEMPS' .isauv = TEMS ; * 'FINSI' ; * SATUR. 'PRESSION' .isauv = RECENTRE * ('COLI' PNSANC DTEM PNS UNMO) MDMH NIVEAU ; SATUR. 'PRESSION' .isauv = 'COLI' PNSANC DTEM PNS UNMO ; ISOR = ISOR + 1 ; 'FINSI' ; 'SI' ((TPSANC '<' TEMS) 'ET' (TEMS '<EG' TPS)) ; isauv = isauv + 1 ; DTEM = ( TPS - TEMS ) / DELTAT ; UNMO = 1. - DTEM ; * 'SI' ('NON' (SATUR.'HYDRO_MECA')) ; * Lorsque DARCYSAT est appellé par PASAPAS, c'est PASAPAS qui * sauvegarde le temps calculé, sinon, c'est DARCYSAT. SATUR.'TEMPS' .isauv = TEMS ; * 'FINSI' ; * SATUR. 'PRESSION' .isauv = RECENTRE * ('COLI' PNSANC DTEM PNS UNMO) MDMH NIVEAU ; SATUR. 'PRESSION' .isauv = 'COLI' PNSANC DTEM PNS UNMO ; ISOR = ISOR + 1 ; 'SINON' ; 'QUITTER' BOU9 ; 'FINSI' ; 'SI' ( ISOR '>' DSOR ) ; ISOR = DSOR ; 'QUITTER' BOU9 ; 'FINSI' ; 'FIN' BOU9 ; * on ne sauvegarde le nb d'itérations de Picard que si les temps * de sauvegarde correspondent à des temps calculés. 'SINON' ; isauv = isauv + 1 ; SATUR. 'TEMPS' . isauv = TPS ; SATUR. 'TRACE_CHARGE' . isauv = TRH ; SATUR. 'CHARGE' . isauv = CHRG ; * correction pas de recentrage de la pression dejà au centre SATUR. 'PRESSION' . isauv = PNS ; 'FINSI' ; * on met de côté les temps effectivement calculés 'RESPRO' ISOR ISAUV ; 'FINSI' ; *********************************************************************** 'SI' ('EGA' roro TESARRET) ; 'ARGUMENT' ipen*'ENTIER' npen*'ENTIER' ila*'ENTIER' ilin*'ENTIER' delt*'FLOTTANT' maxx*'FLOTTANT' okpen*'LOGIQUE' cofpe*'FLOTTANT' CFLL*'FLOTTANT' COFD*'FLOTTANT' debg*'LOGIQUE' SATUR*'TABLE' tpss*'FLOTTANT' ; * ipen indice de boucle penalisation * npen nbmax de boucle penalisation * ila+1 ILAST + 1 indice boucle tps * ilin indice de boucle LINEAR point fixe * delt pas de tps * maxx maximum residu de equation a resoudre * okpen vrai si penalisation * penn vrai si on effectue concretement une penalisation * au cours du pas traité * cofpe coef de penalisation devant d/dt * cfll cfl de Benet * COFD coef de diminution des pas de temps * debg vrai si messages affichés * SATUR table du calcul * tpss temps en cours 'SI' (ipen < npen) ; 'SI' debg ; ', résidu :' maxx ' delta t : ' delt ; 'FINSI' ; 'SI' OKPEN ; * pénalisation PENN = VRAI ; 'SI' debg ; 'MESS' ' on relance le calcul avec le coef. de ' ' pénalisation XI :' cofpe ; 'FINSI' ; 'SINON' ; * diminution du pas de temps CFLL = CFLL * COFD ; delt = DELT * COFD ; 'SI' debg ; 'MESS' ' on relance le calcul en contractant le pas de ' 'FINSI' ; 'FINSI' ; 'SINON' ; * si vraiment on ne veut pas converger, on le dit et on continue 'SI' debg ; txt = 'CHAINE' 'Non convergence, meme avec ' ; 'SI' OKPEN ; txt = 'CHAINE' txt 'pénalisation' ; 'SINON' ; txt = 'CHAINE' txt 'division du pas de temps par ' (COFD ** (-1. * (npen - 1))) ; 'FINSI' ; mess txt ; mess 'On passe au temps suivant, instationnaire faux.' ; 'FINSI' ; 'FINSI' ; * on sauvegarde les temps où on a usé d'artifice (pénal ou division dt) 'RESPRO' delt CFLL ; 'FINSI' ; *********************************************************************** 'SI' ('EGA' roro TRONKP) ; 'ARGUMENT' MDMH*'MMODEL' CHRG*'CHPOINT' TRH*'CHPOINT' CONVH*'FLOTTANT' ; TP1 = TR1 ; 'SINON' ; 'SI' ('EGA' NIVEAU CENTRE) ; TP1 = P1 ; SINON ; 'SI' ('EXISTE' SATUR 'TRACE_IMPOSE') ; rchpo1 rchpo2 rchelem1 = PENT MDMH 'CENTRE' 'EULESCAL' 'NOLIMITE' 'CLIM' charimpo; * TP1 = 'ELNO' MDMH CHRG 'VOLUMF' rchpo1 rchpo2 ; 'SINON' ; rchpo1 rchpo2 rchelem1 = PENT MDMH 'CENTRE' 'EULESCAL' 'NOLIMITE' * TP1 = 'ELNO' MDMH CHRG 'VOLUMF' rchpo1 rchpo2 ; rchpo1 rchpo2 ; 'FINSI' ; 'FINSI' ; 'FINSI' ; 'SI' L_GRAV ; P1 = P1 '-' ( RHOWG / CONVH * ZCC ) ; TP1 = TP1 '-' ( RHOWG / CONVH * ZFF ) ; 'FINSI' ; 'FINSI' ; 'SI' ('EGA' NIVEAU 'MSOMMET') ; 'SINON' ; 'SINON' ; 'FINSI' ; 'FINSI' ; * GBM P1 charge avec unité differente - PNS idem tronquée * P1 ne devrait en théorie plus servir après nettoyage de la proc. 'RESPRO' PNS ; 'FINSI' ; *********************************************************************** 'SI' ('EGA' roro YNTGFLUX) ; 'ARGUMENT' SATUR*'TABLE' ; startflu = 1.D30 ; startsou = 1.D30 ; startmix = 1.D30 ; * integrale des cond de flux * CL de type Neumann : FLUX_IMPOSE 'SI' ( 'EXISTE' SATUR 'FLUX_IMPOSE' ) ; FLUIMP = SATUR . 'FLUX_IMPOSE' ; 'SI' (('EGA' (SATUR . 'TYPDISCRETISATION') 'VF') 'OU' (('EGA' (SATUR . 'TYPDISCRETISATION') 'EFMH') 'ET' ('EGA' teta 1.D0))) ; * On écrit les flux sous forme intégrale sauf en explicite et * kranck-Nickholson pour EFMH 'FINSI' ; 'SINON' ; FLUIMP = 0.D0 ; 'FINSI' ; * CL de type mixte : MIXTES * GBM IL Y AURA MODIF CAR HYDRAU PURE 'SI' ( 'EXISTE' SATUR 'FLUMIXTE' ) ; FLUMIX = SATUR . 'FLUMIXTE' . 'VAL' ; 'SI' (('EGA' (SATUR . 'TYPDISCRETISATION') 'VF') 'OU' (('EGA' (SATUR . 'TYPDISCRETISATION') 'EFMH') 'ET' ('EGA' teta 1.D0))) ; * On écrit les flux sous forme intégrale sauf en explicite et * kranck-Nickholson pour EFMH 'FINSI' ; 'SINON' ; FLUMIX = 0.D0 ; 'FINSI' ; 'SI' ( 'EXISTE' SATUR 'SOURCE' ) ; TERSOU = SATUR . 'SOURCE' ; * on crée une evolution intégrée temporellement pour assurer la * conservation lors de liste de pas de temps de chargement differente * des temps de discrétisation 'FINSI' ; 'RESPRO' startflu startmix startsou FLUIMP FLUMIX TERSOU ; 'FINSI' ; *********************************************************************** 'SI' ('EGA' roro YNYTDT) ; 'ARGUMENT' MMDD*'MMODEL' FLU0*'CHPOINT' ABBM*'MCHAML' VVOL*'CHPOINT' CFFL*'FLOTTANT' deb*'LOGIQUE' daut*'LOGIQUE' DELTAT*'FLOTTANT' TERSCS/'CHPOINT' ; 'SI' (deb 'OU' daut) ; TERSCS = 0.D0 * FLU0 ; 'FINSI' ; * GBM MODIFIE MDMH EN MMDD * temps qu'il faut pour remplir une maille avec ce débit moyen : DTI = ((('MAXIMUM' ('ABS' ('RESULT' IDT))) '/' ('MAXIMUM' ('RESULT' VVOL))) + 1.D-15) ** -1. ; * on s'aligne sur la cinétique la plus rapide : DTI = ('ABS' DTI) ; * TEmps pour remplir 1/300 eme du domaine. * 300 peut etre le nombre de pas viser. * inclure la quantité d'eau présente dans le bilan de remplissage * On considere minimum 50 mailles dans une direction plus * le nombre moyen de mailles par direction DTI = DTI '/' nnpas ; 'SINON' ; * GBM mettre deltat en arg. C juste pour affichage ce truc. DTI = DELTAT / CFFL ; 'FINSI' ; * pas de temps automatique : 'SI' (daut) ; * GBM * DELTAT = 'MINIMUM' ('PROG' DTI (DELTAT * 1.2D0)) ; * DELTAT = DELTAT * CFFL ; (DELTAT * 1.1D0)) ; * DELTAT = DELTAT * CFFL ; 'SI' ('EGA' DELTAT 0.D0 1.D-15) ; * GBM - on prend un très petit pas de temps pour initialiser les * flux - TESTER 0.D0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DELTAT = 1.D-15 ; 'FINSI' ; 'FINSI' ; 'SI' daut ; 'MESSAGE' 'Pas de temps calculé automatiquement.' ; 'FINSI' ; 'RESPRO' DELTAT DTI ; 'FINSI' ; *********************************************************************** 'SI' ('EGA' roro YNYTYAL) ; 'ARGUMENT' SATUR*'TABLE' TETA*'FLOTTANT' ; SATUR. 'PRESSION' = 'TABLE' ; SATUR. 'TH2O' = 'TABLE' ; SATUR. 'SATURATION' = 'TABLE' ; * Liste des temps où il aura fallu user de pénalisation : * sauvegarde du nombre d'itérations pour chaque pas de temps : * Liste des temps calculés a posteriori * Initialisation des tables la proc TRANGEOL * Indicateur les recalculs de matrices à effectuer * A virer quand procedure 1 pas incluse TABMODI = TABLE ; TABMODI . 'POROSITE' = VRAI ; TABMODI . 'CONVECTI' = VRAI ; TABMODI . 'DELTAT' = VRAI ; TABMODI . 'COEF_LIN' = VRAI ; TABMODI . 'DIFFUSIV' = VRAI ; * CHCLIM = 'TABLE' ; GEOL1 = 'TABLE' ; * l'option abandon indique qu'en dessous de 10**-13 pour la concentr * et pour des sources ou flux n'impliquant pas des variation de C * superieurs à 10**-16 on sort 0 sans calcul 'SI' ('EXISTE' SATUR 'SEUILCALC') ; GEOL1 . 'ABANDON' = VRAI ; GEOL1 . 'SEUILCALC' = SATUR . 'SEUILCALC' ; 'SINON' ; GEOL1 . 'ABANDON' = FAUX ; GEOL1 . 'SEUILCALC' = 1.D-30 ; 'FINSI' ; GEOL1 . 'NUM_PECLET' = 2.D0 ; 'SINON' ; 'FINSI' ; 'SI' ('EXISTE' SATUR 'TYPDISCRETISATION' ) ; GEOL1 . 'TYPDISCRETISATION' = SATUR . 'TYPDISCRETISATION' ; 'SINON' ; GEOL1 . 'TYPDISCRETISATION' = 'VF' ; 'FINSI' ; GEOL1 . 'THETA_DIFFUSION' = TETA ; * GBM inutile car pas de convection GEOL1 . 'THETA_CONVECTION' = 1.D0 ; GEOL1 . 'DECENTREMENT' = FAUX ; GEOL1 . 'MODIFICATI' = TABMODI ; 'RESPRO' CHCLIM GEOL1 TABMODI ; 'FINSI' ; *********************************************************************** 'FINPROC' ;
© Cast3M 2003 - Tous droits réservés.
Mentions légales