/*************************************************************************************************************************************/ /* */ /* M A R C H E A L E A T O I R E D A N S L ' E S P A C E T R I D I M E N S I O N N E L */ /* A V E C I N T E R A C T I O N E N T R E L E S P A R T I C U L E S */ /* L E T O U T E T A N T D A N S U N M I L I E U D E P R O P A G A T I O N : */ /* */ /* */ /* Author of '$xrk/rdn_walk.41$K' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 1997??????????). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* I N T E R F A C E ' listG ' : */ /* */ /* */ /* :Debut_listG: */ /* :Fin_listG: */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D I R E C T I V E S S P E C I F I Q U E S D E C O M P I L A T I O N : */ /* */ /*************************************************************************************************************************************/ @define PRAGMA_CL_____MODULE_NON_OPTIMISABLE /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* F I C H I E R S D ' I N C L U D E S : */ /* */ /*************************************************************************************************************************************/ #include INCLUDES_BASE /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N S D E B A S E E T U N I V E R S E L L E S : */ /* */ /*************************************************************************************************************************************/ #include xrk/attractor.11.I" /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* 3 */ /* D E F I N I T I O N D E L ' E S P A C E P H Y S I Q U E D A N S R ( D E B U T ) : */ /* */ /* */ /* Nota : */ /* */ /* Les extrema des coordonnees {x,y,z} */ /* ainsi que ceux de leurs differentielles */ /* {dx,dy,dz} sont fixees un peu arbitrairement */ /* et sans etre parametrees. */ /* */ /* */ /*************************************************************************************************************************************/ #define hXmin_ESPACE \ PARE(-1.0) #define hYmin_ESPACE \ PARE(-1.0) #define hZmin_ESPACE \ PARE(-1.0) /* Definition du "coin" inferieur-gauche-arriere de l'espace physique. */ #define hXmax_ESPACE \ PARE(1.0) #define hYmax_ESPACE \ PARE(1.0) #define hZmax_ESPACE \ PARE(1.0) /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* 3 */ /* D E F I N I T I O N D E L ' E S P A C E P H Y S I Q U E D A N S R ( D E B U T ) : */ /* */ /*************************************************************************************************************************************/ #include xrk/attractor.12.I" #define dXmin_ESPACE \ FLOT__NOIR #define dYmin_ESPACE \ FLOT__NOIR #define dZmin_ESPACE \ FLOT__NOIR /* Definition des minima des differentielles {dx,dy,dz}. */ #define dXmax_ESPACE \ FLOT__BLANC #define dYmax_ESPACE \ FLOT__BLANC #define dZmax_ESPACE \ FLOT__BLANC /* Definition des maxima des differentielles {dx,dy,dz}. */ #include xrk/attractor.1D.I" /* Formules de renormalisation des differentielles dans [0,1] ; elles sont utilisees lorsque */ /* la production d'images en couleurs est demandee (voir 'visualiser_en_RVB'). */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E S D I F F E R E N T S E S P A C E S E T D E L ' E F F E T D E B R U M E : */ /* */ /*************************************************************************************************************************************/ #include xrk/attractor.13.I" /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* A I D E A U C A D R A G E D E S I M A G E S : */ /* */ /*************************************************************************************************************************************/ #include xrk/attractor.1C.I" DONNEES_DE_RECHERCHE_DES_EXTREMA_DES_COORDONNEES_ET_DES_DERIVEES /* Definition des extrema des coordonnees et des derivees. On notera bien l'absence de */ /* point-virgule apres 'DONNEES_DE_RECHERCHE_DES_EXTREMA_DES_COORDONNEES_ET_DES_DERIVEES'. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* G E N E R A T I O N D E S I M A G E S : */ /* */ /*************************************************************************************************************************************/ #include xrv/champs_5.14.I" /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N S G E N E R A L E S R E L A T I V E S A L A V I S U A L I S A T I O N : */ /* */ /*************************************************************************************************************************************/ #define nombre_de_corps \ nombre_d_iterations \ /* ATTENTION, a ne pas confondre : */ \ /* */ \ /* 1-'nombre_de_periodes_de_la_simulation' qui definit finalement le nombre d'images que */ \ /* l'on va generer et qui conditionne toutes les listes (sans exception...) definies par */ \ /* 'fTRANSFORMAT_31(...)', et */ \ /* */ \ /* 2-'nombre_d_iterations' qui definit le nombre de particules visualisees dans chaque */ \ /* image ; les listes relatives aux particules sont definies elles-aussi a l'aide de la */ \ /* procedure 'dTRANSFORMAT_31(...)' ce qui signifie que 'nombre_d_iterations' est limite */ \ /* par 'NOMBRE_MAXIMAL_DE_PERIODES_DE_LA_SIMULATION'... */ \ /* */ #define DCT \ FRA1(FRA10(FU)) DEFV(Local,DEFV(Float,INIT(dct,DCT))); /* Definition de 'dt'. */ #include xrk/attractor.14.I" #define NOMBRE_MAXIMAL_DE_POINTS_GERABLES \ MIN2(NOMBRE_MAXIMAL_DE_POINTS_VISUALISABLES,NOMBRE_MAXIMAL_DE_PERIODES_DE_LA_SIMULATION) \ /* Cette constante permet de gerer d'une facon homogene les listes de dimension */ \ /* 'nombre_de_periodes_de_la_simulation' comme celles de dimension 'nombre_d_iterations'. */ /* ATTENTION, a ne pas confondre : */ /* */ /* 1-'nombre_de_periodes_de_la_simulation' qui definit finalement le nombre d'images que */ /* l'on va generer et qui conditionne toutes les listes (sans exception...) definies par */ /* 'fTRANSFORMAT_31(...)', et */ /* */ /* 2-'nombre_d_iterations' qui definit le nombre de particules visualisees dans chaque */ /* image ; les listes relatives aux particules sont definies elles-aussi a l'aide de la */ /* procedure 'dTRANSFORMAT_31(...)' ce qui signifie que 'nombre_d_iterations' est limite */ /* par 'NOMBRE_MAXIMAL_DE_PERIODES_DE_LA_SIMULATION'... */ /* */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* F O N C T I O N D E M E M O R I S A T I O N D U P O I N T C O U R A N T : */ /* */ /*************************************************************************************************************************************/ #include xrk/attractor.16.I" #define RAYON_DE_VISUALISATION \ FRA5(FRA10(mhXYZlongueur_ESPACE)) DEFV(Local,DEFV(Float,INIT(rayon_de_visualisation,RAYON_DE_VISUALISATION))); /* Rayon du disque materialisant une iteration. */ BFonctionI DEFV(Local,DEFV(FonctionI,memorisation_1_point_07(AXf,AYf,AZf,AdXf,AdYf,AdZf,numero_de_l_iteration_courante))) DEFV(Argument,DEFV(Float,AXf)); DEFV(Argument,DEFV(Float,AYf)); DEFV(Argument,DEFV(Float,AZf)); /* Definition de la position {x,y,z} de l'iteration courante. */ DEFV(Argument,DEFV(Float,AdXf)); DEFV(Argument,DEFV(Float,AdYf)); DEFV(Argument,DEFV(Float,AdZf)); /* Definition des differentielles {dx,dy,dz} de la position de l'iteration courante. */ DEFV(Argument,DEFV(Int,numero_de_l_iteration_courante)); /* Numero de l'iteration courante afin d'attenuer eventuellement la luminance des points */ /* materialisant chaque iteration en fonction de leur numero (les premieres iterations etant */ /* plus sombres, et les dernieres etant plus lumineuses). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock #include xrk/attractor.15.I" INIT_ERROR; /*..............................................................................................................................*/ MEMORISATION_DU_POINT_COURANT(X_DERIVEE_DANS_01(AdXf) ,Y_DERIVEE_DANS_01(AdYf) ,Z_DERIVEE_DANS_01(AdZf) ); /* Memorisation du point courant en Noir et Blanc ou en Couleurs, mais uniquement s'il est */ /* visible en fonction des conditions de visualisation... */ RETU_ERROR; Eblock EFonctionI BFonctionI DEFV(Local,DEFV(FonctionI,memorisation_d_un_point_grave(AXf,AYf,AZf,AdXf,AdYf,AdZf,masse,VXf,VYf,VZf,numero_de_l_iteration_courante))) DEFV(Argument,DEFV(Float,AXf)); DEFV(Argument,DEFV(Float,AYf)); DEFV(Argument,DEFV(Float,AZf)); /* Definition de la position {x,y,z} de l'iteration courante. */ DEFV(Argument,DEFV(Float,AdXf)); DEFV(Argument,DEFV(Float,AdYf)); DEFV(Argument,DEFV(Float,AdZf)); /* Definition des differentielles {dx,dy,dz} de la position de l'iteration courante. */ DEFV(Argument,DEFV(Float,masse)); /* Masse de l'iteration courante... */ DEFV(Argument,DEFV(Float,VXf)); DEFV(Argument,DEFV(Float,VYf)); DEFV(Argument,DEFV(Float,VZf)); /* Definition de la vitesse (Vx,Vy,Vz) de l'iteration courante. */ DEFV(Argument,DEFV(Int,numero_de_l_iteration_courante)); /* Numero de l'iteration courante afin d'attenuer eventuellement la luminance des points */ /* materialisant chaque iteration en fonction de leur numero (les premieres iterations etant */ /* plus sombres, et les dernieres etant plus lumineuses). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock #include xrk/attractor.15.I" INIT_ERROR; /*..............................................................................................................................*/ DEFINITION_DE_LA_VITESSE_DE_LA_SPHERE_COURANTE(VXf,VYf,VZf); /* Memorisation de la vitesse du point courant. */ DEFINITION_DE_LA_MASSE_DE_LA_SPHERE_COURANTE(masse); /* Memorisation de la masse du point courant. */ CALS(memorisation_1_point_07(AXf,AYf,AZf ,AdXf,AdYf,AdZf ,numero_de_l_iteration_courante ) ); /* Memorisation du point courant en Noir et Blanc ou en Couleurs, mais uniquement s'il est */ /* visible en fonction des conditions de visualisation... */ RETU_ERROR; Eblock EFonctionI /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* F O N C T I O N S D E V I S U A L I S A T I O N E T D ' I N T E R P O L A T I O N : */ /* */ /*************************************************************************************************************************************/ #define __VERSION__PERMETTRE_L_UTILISATION_D_UN_FOND \ /* Afin de permettre la mise en place d'un fond pour chaque image generee (definition */ \ /* deplacee ici le 20030313150921). D'autre part 'PERMETTRE_L_UTILISATION_D_UN_FOND' */ \ /* a ete change en '__VERSION__PERMETTRE_L_UTILISATION_D_UN_FOND' le 20030313145928 */ \ /* afin de permettre sa recuperation dans 'v $xcc/cpp$Z _VERSION_'. */ #include xrk/attractor.17.I" #include xrv/particule.31.I" #define VISUALISER_L_ENSEMBLE_DES_INSTANTS \ FAUX DEFV(Local,DEFV(Logical,INIT(visualiser_l_ensemble_des_instants,VISUALISER_L_ENSEMBLE_DES_INSTANTS))); /* Doit-on visualiser l'ensemble des instants ('VRAI') ou bien uniquement l'instant */ /* precedent ('FAUX'). */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E L ' I N V E R S I O N D U P R O C E S S U S : */ /* */ /*************************************************************************************************************************************/ #define INVERSER_LE_PROCESSUS \ FAUX DEFV(Local,DEFV(Logical,INIT(inverser_le_processus,INVERSER_LE_PROCESSUS))); /* Doit-on inverser le processus a un certain instant ('VRAI') ou pas ('FAUX') ; lorsque */ /* 'IL_FAUT(inverser_le_processus)', c'est 'periode_d_inversion_du_processus' qui definit */ /* la periode d'inversion... */ #define PERIODE_D_INVERSION_DU_PROCESSUS \ MOINS_L_INFINI DEFV(Local,DEFV(Int,INIT(periode_d_inversion_du_processus,PERIODE_D_INVERSION_DU_PROCESSUS))); /* Donne le numero de la periode ou toutes les vitesses seront arbitrairement inversees. */ /* Lorsqu'il n'y a aucun processus aleatoires actifs, cela permet de voir si l'on revient */ /* aux conditions initiales aux environ de 'DOUB(periode_d_inversion_du_processus)'... */ /* En fait, cela ne doit pas fonctionner systematiquement car, en effet, il y a le phenomene */ /* de collisions : on ne decrete pas qu'il y a collision lorsque les particules s'eloignent */ /* les unes des autres (cas par exemple des conditions initiales) ; en inversant pour chaque */ /* particule les vitesses, les particules vont donc se rapprocher les unes des autres, et */ /* on risque donc de decreter des collisions qui n'avaient pas eu lieu a l'aller... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E L A M A R C H E A L E A T O I R E : */ /* */ /* */ /* Definition : */ /* */ /* Soit la famille {C ,C ,...,C } de 'N' */ /* 1 2 N */ /* corps. A chaque pas de temps, et en coordonnees */ /* spheriques, les coordonnees de ceux-ci sont */ /* translatees a l'aide de trois increments en */ /* 'theta', 'phi' et 'rho'. */ /* */ /* */ /*************************************************************************************************************************************/ #define LIMITER_AUTOMATIQUEMENT_TENTATIVES_RECHERCHE_BONNE_PERTURBATION \ VRAI DEFV(Local,DEFV(Logical,INIT(limiter_automatiquement_tentatives_recherche_bonne_perturbation ,LIMITER_AUTOMATIQUEMENT_TENTATIVES_RECHERCHE_BONNE_PERTURBATION ) ) ); #define NOMBRE_MAXIMAL_DE_TENTATIVES_DE_RECHERCHE_D_UNE_BONNE_PERTURBATION \ CENT DEFV(Local,DEFV(Int,INIT(nombre_maximal_de_tentatives_de_recherche_d_une_bonne_perturbation ,NOMBRE_MAXIMAL_DE_TENTATIVES_DE_RECHERCHE_D_UNE_BONNE_PERTURBATION ) ) ); /* Lors de la recherche d'une vitesse perturbee satisfaisant aux contraintes imposees (dues */ /* au champ de force et a la distance maximale par rapport a l'origine), lorsque celles-ci */ /* ne peuvent etre satisfaites, il faut imposer un nombre maximal de tentatives afin de ne */ /* pas boucler. Ce nombre peut etre calcule automatiquement a partir des parametres, ou bien */ /* etre impose arbitrairement (l'etat implicite est 'VRAI' afin d'assurer la compatibilite */ /* avec les anciennes sequences generees avant le 1995110200). */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E S C O N S T A N T E S D U P R O B L E M E : */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E S L I S T E S D E S C R I P T I V E S I N I T I A L E S D E S C O R P S : */ /* */ /*************************************************************************************************************************************/ /* ATTENTION, a ne pas confondre : */ /* */ /* 1-'nombre_de_periodes_de_la_simulation' qui definit finalement le nombre d'images que */ /* l'on va generer et qui conditionne toutes les listes (sans exception...) definies par */ /* 'fTRANSFORMAT_31(...)', et */ /* */ /* 2-'nombre_d_iterations' qui definit le nombre de particules visualisees dans chaque */ /* image ; les listes relatives aux particules sont definies elles-aussi a l'aide de la */ /* procedure 'dTRANSFORMAT_31(...)' ce qui signifie que 'nombre_d_iterations' est limite */ /* par 'NOMBRE_MAXIMAL_DE_PERIODES_DE_LA_SIMULATION'... */ /* */ dfTRANSFORMAT_31(liste_initiale_des_DATE_DE_NAISSANCE,fichier_LISTE_DATE_DE_NAISSANCE,DATE_DE_NAISSANCE_IMPLICITE,INSTANT_INITIAL) /* Definition des fichiers de listes de dates de naissance. */ dfTRANSFORMAT_31(liste_initiale_des_X,fichier_LISTE_X,X_IMPLICITE,Xcentre_ESPACE) dfTRANSFORMAT_31(liste_initiale_des_Y,fichier_LISTE_Y,Y_IMPLICITE,Ycentre_ESPACE) dfTRANSFORMAT_31(liste_initiale_des_Z,fichier_LISTE_Z,Z_IMPLICITE,hZmin_ESPACE) /* Definition des fichiers de listes de coordonnees. */ /* Pour les coordonnees implicites, on notera l'utilisation de 'hZmin_ESPACE' et non */ /* pas de 'Zcentre_ESPACE' comme le voudrait la logique ; ceci est du au fait que cette */ /* derniere valeur interferait malheureusement avec la position de l'observateur dans le */ /* cube de visualisation, et rendrait invisible les particules... */ dfTRANSFORMAT_31(liste_initiale_des_VX,fichier_LISTE_VX,VX_IMPLICITE,FZERO) dfTRANSFORMAT_31(liste_initiale_des_VY,fichier_LISTE_VY,VY_IMPLICITE,FZERO) dfTRANSFORMAT_31(liste_initiale_des_VZ,fichier_LISTE_VZ,VZ_IMPLICITE,FZERO) /* Definition des fichiers de listes de vitesses. */ dfTRANSFORMAT_31(liste_initiale_des_MINIMUM_DELTA_RHO ,fichier_LISTE_MINIMUM_DELTA_RHO ,MINIMUM_DELTA_RHO_IMPLICITE ,NEGA(FRA4(FRA10(mhXYZlongueur_ESPACE))) ) dfTRANSFORMAT_31(liste_initiale_des_MAXIMUM_DELTA_RHO ,fichier_LISTE_MAXIMUM_DELTA_RHO ,MAXIMUM_DELTA_RHO_IMPLICITE ,NEUT(FRA4(FRA10(mhXYZlongueur_ESPACE))) ) /* Definition des fichiers de listes de variations des 'rho's. */ dfTRANSFORMAT_31(liste_initiale_des_MINIMUM_N_PHI,fichier_LISTE_MINIMUM_N_PHI,MINIMUM_N_PHI_IMPLICITE,NEGA(DEUX)) dfTRANSFORMAT_31(liste_initiale_des_MAXIMUM_N_PHI,fichier_LISTE_MAXIMUM_N_PHI,MAXIMUM_N_PHI_IMPLICITE,NEUT(DEUX)) dfTRANSFORMAT_31(liste_initiale_des_DELTA_PHI,fichier_LISTE_DELTA_PHI,DELTA_PHI_IMPLICITE,PI_SUR_2) /* Definition des fichiers de listes de variations des 'phi's (ou "longitude"). */ /* */ /* ATTENTION, par la suite, les quantites du type 'MINIMUM_N_?' et 'MAXIMUM_N_?' sont */ /* traitees comme des quantites entieres (en particulier, on fait des 'ARRO(...)' sur les */ /* nombres aleatoires 'variation_de_phi' et 'variation_de_theta' qu'elles permettent de */ /* generer...). */ dfTRANSFORMAT_31(liste_initiale_des_MINIMUM_N_THETA,fichier_LISTE_MINIMUM_N_THETA,MINIMUM_N_THETA_IMPLICITE,NEGA(DEUX)) dfTRANSFORMAT_31(liste_initiale_des_MAXIMUM_N_THETA,fichier_LISTE_MAXIMUM_N_THETA,MAXIMUM_N_THETA_IMPLICITE,NEUT(DEUX)) dfTRANSFORMAT_31(liste_initiale_des_DELTA_THETA,fichier_LISTE_DELTA_THETA,DELTA_THETA_IMPLICITE,PI_SUR_2) /* Definition des fichiers de listes de variations des 'theta's (ou "distance polaire"). */ dfTRANSFORMAT_31(liste_initiale_des_DISTANCE_MAXIMALE ,fichier_LISTE_DISTANCE_MAXIMALE ,DISTANCE_MAXIMALE_IMPLICITE ,MOIT(mhXYZlongueur_ESPACE) ) /* Definition des fichiers de listes de distances maximales. */ dfTRANSFORMAT_31(liste_initiale_des_STABILITE,fichier_LISTE_STABILITE,STABILITE_IMPLICITE,HUIT) /* Definition des fichiers de listes de stabilite (la "stabilite" donne le nombre de */ /* periodes pendant lequel un corps ne changera pas de direction). */ dfTRANSFORMAT_31(liste_initiale_des_RAYON,fichier_LISTE_RAYON,RAYON_IMPLICITE,RAYON_DE_VISUALISATION) /* Definition du fichier de liste des rayons. */ /* */ /* ATTENTION, le rayon est en unite d'ecran [0,1]. */ dfTRANSFORMAT_31(liste_initiale_des_RAYON_D_INTERACTION ,fichier_LISTE_RAYON_D_INTERACTION ,RAYON_D_INTERACTION_IMPLICITE ,RAYON_DE_VISUALISATION ) /* Definition du fichier de liste des rayons d'interaction (introduit le 19980115090818). */ /* Le 19980213090623, je suis passe de 'RAYON_D_INTERACTION_IMPLICITE' ayant la valeur */ /* 'FRA4(FRA10(FU))' a 'FACTEUR_DU_RAYON_D_INTERACTION_IMPLICITE' valant 'FU' car c'est */ /* plus logique de definir l'interaction en fonction du rayon des particules et non pas */ /* de facon absolue. Le 19980224182217, je suis en fait revenu a la notion anterieure car, */ /* en effet, sur des sequences du type : */ /* */ /* xivPdf 11 2 / 003073_003584 */ /* */ /* qui sont generees par superposition des trajectoires filiformes et de cometes. Il est */ /* donc imperatif de faire les deux calculs dans les memes conditions, meme si les rayons */ /* de visualisation sont differents... */ dfTRANSFORMAT_31(liste_initiale_des_ROUGE,fichier_LISTE_ROUGE,ROUGE_IMPLICITE,BLANC) dfTRANSFORMAT_31(liste_initiale_des_VERTE,fichier_LISTE_VERTE,VERTE_IMPLICITE,BLANC) dfTRANSFORMAT_31(liste_initiale_des_BLEUE,fichier_LISTE_BLEUE,BLEUE_IMPLICITE,BLANC) /* Definition des fichiers de listes de couleurs. */ /* */ /* ATTENTION, les couleurs des points a visualiser doivent etre definies ainsi : */ /* */ /* ROUGE E [NOIR,BLANC] */ /* VERTE E [NOIR,BLANC] */ /* BLEUE E [NOIR,BLANC] */ /* */ dfTRANSFORMAT_31(liste_initiale_des_MASSE,fichier_LISTE_MASSE,MASSE_IMPLICITE,FU) /* Definition du fichier de liste des masses. */ #define NOMBRE_DE_PAS_DE_TEMPS_PAR_PERIODE \ GRO1(GRO1(UN)) DEFV(Local,DEFV(Int,INIT(nombre_de_pas_de_temps_par_periode,NOMBRE_DE_PAS_DE_TEMPS_PAR_PERIODE))); /* Definition du nombre de pas de temps que l'on effectue pour une periode (c'est-a-dire */ /* entre deux images calculees). On notera que lorsqu'il y a prise en compte de phenomenes */ /* telle la reflexion ou la refraction, il est essentiel que le pas de temps ait une valeur */ /* telle que l'on ne manque pas des details petits des champs. On aura interet alors a */ /* utiliser un petit pas de temps et un nombre de pas de temps par periode important. */ #include xrv/particule.21.I" /* ATTENTION, a ne pas confondre : */ /* */ /* 1-'nombre_de_periodes_de_la_simulation' qui definit finalement le nombre d'images que */ /* l'on va generer et qui conditionne toutes les listes (sans exception...) definies par */ /* 'fTRANSFORMAT_31(...)', et */ /* */ /* 2-'nombre_d_iterations' qui definit le nombre de particules visualisees dans chaque */ /* image ; les listes relatives aux particules sont definies elles-aussi a l'aide de la */ /* procedure 'dTRANSFORMAT_31(...)' ce qui signifie que 'nombre_d_iterations' est limite */ /* par 'NOMBRE_MAXIMAL_DE_PERIODES_DE_LA_SIMULATION'... */ /* */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E S L I S T E S D E S C R I P T I V E S C O U R A N T E S D E S C O R P S : */ /* */ /*************************************************************************************************************************************/ DEFV(Float,DdTb1(POINTERf ,liste_des_dates_de_naissance ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); DEFV(pointF_3D,DdTb1(POINTERs ,liste_des_coordonnees_a_l_instant_initial ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); DEFV(deltaF_3D,DdTb1(POINTERs ,liste_des_vitesses_a_l_instant_initial ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); /* Definition de l'instant initial. */ DEFV(pointF_3D,DdTb1(POINTERs ,liste_des_coordonnees_a_l_instant_precedent ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); /* Definition de l'instant precedent. */ DEFV(deltaF_3D,DdTb1(POINTERs ,liste_des_vitesses_a_l_instant_courant ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); DEFV(pointF_3D,DdTb1(POINTERs ,liste_des_coordonnees_a_l_instant_courant ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); DEFV(Int,DdTb1(POINTERi ,liste_des_stabilites_a_l_instant_courant ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); DEFV(Logical,DdTb1(POINTERl ,liste_des_blocages_a_l_instant_courant ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); DEFV(Logical,DdTb1(POINTERl ,liste_des_reflexions_a_l_instant_courant ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); DEFV(Logical,DdTb1(POINTERl ,liste_des_refractions_a_l_instant_courant ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); DEFV(genere_Float,DdTb1(POINTERf ,liste_des_niveaux_locaux_a_l_instant_courant ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); DEFV(Positive,DdTb1(POINTERi ,liste_des_compteurs_de_collisions_a_l_instant_courant ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); DEFV(Positive,DdTb1(POINTERi ,liste_des_compteurs_de_reflexions_a_l_instant_courant ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); DEFV(Positive,DdTb1(POINTERi ,liste_des_compteurs_de_refractions_a_l_instant_courant ,nombre_de_corps ,ADRESSE_NON_ENCORE_DEFINIE ) ); /* Definition de l'instant courant. */ DEFV(pointF_3D,DdTb2(POINTERs ,liste_des_coordonnees_cumule_sur_toute_la_duree ,nombre_de_corps ,nombre_de_periodes_de_la_simulation ,ADRESSE_NON_ENCORE_DEFINIE ) ); /* Definition de l'ensemble des instants cumules. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E L ' I N T E G R A T I O N D U S Y S T E M E */ /* D ' E Q U A T I O N S D I F F E R E N T I E L L E S : */ /* */ /*************************************************************************************************************************************/ #include xrk/integr.2B.vv.I" /* Uniquement afin de definir {cx,cy,cz}. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* A C C E S A U X L I S T E S : */ /* */ /*************************************************************************************************************************************/ #define DERNIER_POINT_DES_LISTES \ LSTX(PREMIER_POINT_DES_LISTES,nombre_de_corps) \ /* Definition du dernier point des listes. */ #define ACCES_DATES_DE_NAISSANCE(corps) \ IdTb1(liste_des_dates_de_naissance \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_COORDONNEES_INITIALES(corps) \ IdTb1(liste_des_coordonnees_a_l_instant_initial \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_VITESSE_INITIALE(corps) \ IdTb1(liste_des_vitesses_a_l_instant_initial \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) /* Acces aux caracteristiques du corps de numero donne 'corps' dans sa position initiale. */ #define ACCES_COORDONNEES_PRECEDENTES(corps) \ IdTb1(liste_des_coordonnees_a_l_instant_precedent \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) /* Definition de l'instant precedent. */ #define ACCES_VITESSE_COURANTE(corps) \ IdTb1(liste_des_vitesses_a_l_instant_courant \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_COORDONNEES_COURANTES(corps) \ IdTb1(liste_des_coordonnees_a_l_instant_courant \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_STABILITES_COURANTES(corps) \ IdTb1(liste_des_stabilites_a_l_instant_courant \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_BLOCAGES_COURANTS(corps) \ IdTb1(liste_des_blocages_a_l_instant_courant \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_REFLEXIONS_COURANTS(corps) \ IdTb1(liste_des_reflexions_a_l_instant_courant \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_REFRACTIONS_COURANTS(corps) \ IdTb1(liste_des_refractions_a_l_instant_courant \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_NIVEAUX_LOCAUX_COURANTS(corps) \ IdTb1(liste_des_niveaux_locaux_a_l_instant_courant \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_COMPTEURS_COLLISIONS_COURANTS(corps) \ IdTb1(liste_des_compteurs_de_collisions_a_l_instant_courant \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_COMPTEURS_REFLEXIONS_COURANTS(corps) \ IdTb1(liste_des_compteurs_de_reflexions_a_l_instant_courant \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_COMPTEURS_REFRACTIONS_COURANTS(corps) \ IdTb1(liste_des_compteurs_de_refractions_a_l_instant_courant \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_MASSES(corps) \ IdTb1(liste_initiale_des_MASSE \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) /* Acces aux caracteristiques du corps de numero donne 'corps' dans sa position courante. */ #define ACCES_COORDONNEES_CUMULEES(corps,periode) \ IdTb2(liste_des_coordonnees_cumule_sur_toute_la_duree \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ,INDX(periode,NUMERO_DE_LA_PREMIERE_PERIODE_DE_LA_SIMULATION) \ ,nombre_de_periodes_de_la_simulation \ ) /* Acces aux coordonnees sur l'ensemble de la simulation. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D U P O I N T D E R E F E R E N C E C O U R A N T : */ /* */ /*************************************************************************************************************************************/ #include xrr/N_corps.11.I" /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* A C C E S A U N A L B U M : */ /* */ /*************************************************************************************************************************************/ #include xrk/rdn_walk.31.I" /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D ' U N C H A M P D E F O R C E T R I D I M E N S I O N N E L : */ /* */ /*************************************************************************************************************************************/ dfTRANSFORMAT_31(liste_initiale_des_BORNE_INFERIEURE_DE_L_OUVERTURE ,fichier_LISTE_BORNE_INFERIEURE_DE_L_OUVERTURE ,BORNE_INFERIEURE_DE_L_OUVERTURE_IMPLICITE ,FZERO ) dfTRANSFORMAT_31(liste_initiale_des_BORNE_SUPERIEURE_DE_L_OUVERTURE ,fichier_LISTE_BORNE_SUPERIEURE_DE_L_OUVERTURE ,BORNE_SUPERIEURE_DE_L_OUVERTURE_IMPLICITE ,PI ) /* Definition du segment [inf,sup] dans lequel doit se trouver l'angle entre la vitesse */ /* perturbee et le gradient du champ de force pour que le deplacement aleatoire soit */ /* accepte. */ #define UTILISER_UN_CHAMP_DE_FORCE \ FAUX DEFV(Local,DEFV(Logical,INIT(utiliser_un_champ_de_force,UTILISER_UN_CHAMP_DE_FORCE))); /* Indique s'il faut contraindre le generateur par un champ de force defini par un album */ /* d'images ('VRAI') ou pas ('FAUX') auquel cas on n'utilise que 'LISTE_DISTANCE_MAXIMALE'. */ #define F_nPASX \ QUATRE #define F_nPASY \ QUATRE #define F_nPASZ \ UN DEFV(Local,DEFV(Int,INIT(F_NpasX,F_nPASX))); DEFV(Local,DEFV(Int,INIT(F_NpasY,F_nPASY))); DEFV(Local,DEFV(Int,INIT(F_NpasZ,F_nPASZ))); /* Indique les demi-dimensions (en nombre de points) des volumes elementaires du champ */ /* de force dans lequel on calcule le gradient. */ #define ADAPTER_LES_F_nPAS \ FAUX DEFV(Local,DEFV(Logical,INIT(adapter_les_F_nPAS,ADAPTER_LES_F_nPAS))); /* Indique si les 'F_Npas?' doivent etre adaptes automatiquement en fonction du mouvement */ /* de chaque particule ('VRAI') ou bien utilises tel quels ('FAUX'). */ #include xci/sequence.01.I" /* ATTENTION, on definit ainsi le symbole 'DERNIERE_IMAGE' qui ne sert a rien ici, puisque */ /* c'est en effet 'Zmax' qui joue ce role... */ DEFV(Local,DEFV(Int,INIT(F_premiere_coupe,PREMIERE_IMAGE))); /* Numero de la premiere coupe du champ de force. */ DEFV(Local,DEFV(Int,INIT(F_pas_des_coupes,PAS_DES_IMAGES))); /* Pas de passage d'un numero de coupe a une autre. */ DEFV(Local,DEFV(Int,INIT(F_nombre_de_chiffres_pour_le_champ,NOMBRE_DE_CHIFFRES))); /* Nombre de chiffres codant le numero des coupes de la serie... */ #define F_ATTENDRE_LES_IMAGES_INEXISTANTES \ VRAI DEFV(Local,DEFV(Logical,INIT(F_attendre_les_images_inexistantes,F_ATTENDRE_LES_IMAGES_INEXISTANTES))); /* Indique si les images inexistantes constituent une erreur ('FAUX'), ou bien si cela est */ /* normal ('VRAI'), ce qui signifie qu'elles n'ont pas encore ete calculee... */ #define F_PERIODISER_X \ FAUX #define F_PERIODISER_Y \ FAUX #define F_PERIODISER_Z \ FAUX DEFV(Local,DEFV(Logical,INIT(F_periodiser_X,F_PERIODISER_X))); DEFV(Local,DEFV(Logical,INIT(F_periodiser_Y,F_PERIODISER_Y))); DEFV(Local,DEFV(Logical,INIT(F_periodiser_Z,F_PERIODISER_Z))); /* Indique si l'espace [Xmin,Xmax]x[Ymin,Ymax]x[Zmin,Zmax] est periodique ('VRAI') ou pas */ /* ('FAUX'). */ #define F_SYMETRISER_X \ FAUX #define F_SYMETRISER_Y \ FAUX #define F_SYMETRISER_Z \ FAUX DEFV(Local,DEFV(Logical,INIT(F_symetriser_X,F_SYMETRISER_X))); DEFV(Local,DEFV(Logical,INIT(F_symetriser_Y,F_SYMETRISER_Y))); DEFV(Local,DEFV(Logical,INIT(F_symetriser_Z,F_SYMETRISER_Z))); /* Indique si l'espace [Xmin,Xmax]x[Ymin,Ymax]x[Zmin,Zmax] est symetrique ('VRAI') ou pas */ /* ('FAUX'). Ceci a ete introduit le 20050721095220... */ #define F_PROLONGER_X \ FAUX #define F_PROLONGER_Y \ FAUX #define F_PROLONGER_Z \ FAUX DEFV(Local,DEFV(Logical,INIT(F_prolonger_X,F_PROLONGER_X))); DEFV(Local,DEFV(Logical,INIT(F_prolonger_Y,F_PROLONGER_Y))); DEFV(Local,DEFV(Logical,INIT(F_prolonger_Z,F_PROLONGER_Z))); /* Indique si l'espace [Xmin,Xmax]x[Ymin,Ymax]x[Zmin,Zmax] doit etre prolonge a l'exterieur */ /* comme il est au bord ('VRAI') ou pas ('FAUX'). */ #define F_NIVEAU_HORS_DU_CHAMP_DE_FORCE \ NIVEAU_HORS_ECRAN DEFV(Local,DEFV(genere_p,INIT(F_niveau_hors_du_champ_de_force,F_NIVEAU_HORS_DU_CHAMP_DE_FORCE))); /* Valeur a forcer a l'exterieur du champ de force, lorsqu'il ne faut ni periodiser, ni */ /* prolonger... */ #define F_NIVEAU_INITIAL_DU_CHAMP_DE_FORCE \ BLANC DEFV(Local,DEFV(genere_p,INIT(F_niveau_initial_du_champ_de_force,F_NIVEAU_INITIAL_DU_CHAMP_DE_FORCE))); /* Valeur pour initialiser eventuellement le champ de force dans 'ACCES_ALBUM(...)'. */ #define PRENDRE_LA_PREMIERE_DIRECTION_TROUVEE \ VRAI DEFV(Local,DEFV(Logical,INIT(prendre_la_premiere_direction_trouvee,PRENDRE_LA_PREMIERE_DIRECTION_TROUVEE))); /* Si cet indicateur est 'VRAI', des que l'on a trouve une direction perturbee qui colle */ /* au mieux avec le gradient, on la garde. S'il est 'FAUX', un tirage au sort determine */ /* si on la conserve ou si on continue a chercher... */ #define NOMBRE_D_ITERATIONS_SI_ON_NE_PREND_PAS_LA_PREMIERE_DIRECTION_TROUVEE \ UN DEFV(Local,DEFV(Positive,INIT(nombre_d_iterations_si_on_ne_prend_pas_la_premiere_direction_trouvee ,NOMBRE_D_ITERATIONS_SI_ON_NE_PREND_PAS_LA_PREMIERE_DIRECTION_TROUVEE ) ) ); /* Nombre de "selecteur"s a generer lorsque l'on ne prend pas la premiere direction trouvee. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D U M I L I E U D E P R O P A G A T I O N : */ /* */ /*************************************************************************************************************************************/ #define UTILISER_UN_MILIEU_DE_PROPAGATION \ FAUX DEFV(Local,DEFV(Logical,INIT(utiliser_un_milieu_de_propagation,UTILISER_UN_MILIEU_DE_PROPAGATION))); /* Indique si la propagation a lieu dans un milieu "optique" ('VRAI') ou pas ('FAUX') ; on */ /* appel "milieu optique" un milieu ou vont avoir lieu des phenomenes de reflexion et de */ /* refraction. */ #define IL_PEUT_Y_AVOIR_REFLEXION \ VRAI DEFV(Local,DEFV(Logical,INIT(il_peut_y_avoir_reflexion,IL_PEUT_Y_AVOIR_REFLEXION))); /* Indique si la reflexion est possible ('VRAI') ou pas ('FAUX'). */ #define IL_PEUT_Y_AVOIR_REFRACTION \ VRAI DEFV(Local,DEFV(Logical,INIT(il_peut_y_avoir_refraction,IL_PEUT_Y_AVOIR_REFRACTION))); /* Indique si la refraction est possible ('VRAI') ou pas ('FAUX'). */ #define ANGLE_INFERIEUR_DU_CONE_DE_REFLEXION \ GRO1(PI_SUR_2) #define ANGLE_SUPERIEUR_DU_CONE_DE_REFLEXION \ GRO3(PI_SUR_2) DEFV(Local,DEFV(Float,INIT(angle_inferieur_du_cone_de_reflexion,ANGLE_INFERIEUR_DU_CONE_DE_REFLEXION))); DEFV(Local,DEFV(Float,INIT(angle_superieur_du_cone_de_reflexion,ANGLE_SUPERIEUR_DU_CONE_DE_REFLEXION))); /* Definition du cone a l'interieur duquel il y a reflexion... */ #define MODULER_LA_VITESSE_LORS_D_UNE_REFRACTION \ FAUX DEFV(Local,DEFV(Logical,INIT(moduler_la_vitesse_lors_d_une_refraction,MODULER_LA_VITESSE_LORS_D_UNE_REFRACTION))); /* Indique lorsque 'EST_VRAI(il_peut_y_avoir_refraction)' si la vitesse des particules */ /* doit etre modulee par l'indice de refraction comme le veulent les lois de l'optique */ /* ('VRAI') ou pas ('FAUX'), ce qui permet alors d'eviter des pseudo-immobilisations */ /* lorsque les rapports d'indice sont trop eleves... */ #define FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION \ FU #define TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION \ FZERO DEFV(Local,DEFV(Float,INIT(facteur_vitesse_OX2_refraction_reflexion,FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION))); DEFV(Local,DEFV(Float,INIT(translation_vitesse_OX2_refraction_reflexion,TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION))); dfTRANSFORMAT_31(liste_initiale_des_FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION ,fichier_LISTE_FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION ,FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION_IMPLICITE ,FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION ) dfTRANSFORMAT_31(liste_initiale_des_TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION ,fichier_LISTE_TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION ,TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION_IMPLICITE ,TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION ) #define ACCES_FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION(corps) \ IdTb1(liste_initiale_des_FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION(corps) \ IdTb1(liste_initiale_des_TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_FACTEUR_VITESSE_OX2(corps) \ ACCES_FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION(corps) #define ACCES_TRANSLATION_VITESSE_OX2(corps) \ ACCES_TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION(corps) /* Facteurs multiplicatif et additif relatifs a la composante 'OX2' d'une vitesse apres une */ /* reflexion ou une refraction. Cette composante est aussi appelee "normale" car elle est */ /* alignee avec le Gradient, c'est-a-dire donc orthogonale au plan de reflexion/refraction. */ /* Ils vont permettre de simuler des echanges d'energie avec le milieu. Ceci a ete introduit */ /* le 19980909093853. */ #define FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION \ FU #define TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION \ FZERO DEFV(Local,DEFV(Float,INIT(facteur_vitesse_OZ2_refraction_reflexion,FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION))); DEFV(Local,DEFV(Float,INIT(translation_vitesse_OZ2_refraction_reflexion,TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION))); dfTRANSFORMAT_31(liste_initiale_des_FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION ,fichier_LISTE_FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION ,FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION_IMPLICITE ,FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION ) dfTRANSFORMAT_31(liste_initiale_des_TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION ,fichier_LISTE_TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION ,TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION_IMPLICITE ,TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION ) #define ACCES_FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION(corps) \ IdTb1(liste_initiale_des_FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION(corps) \ IdTb1(liste_initiale_des_TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION \ ,INDX(corps,PREMIER_POINT_DES_LISTES) \ ,nombre_de_corps \ ) #define ACCES_FACTEUR_VITESSE_OZ2(corps) \ ACCES_FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION(corps) #define ACCES_TRANSLATION_VITESSE_OZ2(corps) \ ACCES_TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION(corps) /* Facteurs multiplicatif et additif relatifs a la composante 'OZ2' d'une vitesse apres une */ /* reflexion ou une refraction. Cette composante est aussi appelee "tangentielle" car elle */ /* est dans le plan de reflexion/refraction. */ /* Ils vont permettre de simuler des echanges d'energie avec le milieu. Ceci a ete introduit */ /* le 19980909093853. */ #define CALCULER_LA_MOYENNE_DES_Mgradient_3x3x3_tri_dimensionnel \ VRAI DEFV(Local,DEFV(Logical,INIT(calculer_la_moyenne_des_Mgradient_3x3x3_tri_dimensionnel ,CALCULER_LA_MOYENNE_DES_Mgradient_3x3x3_tri_dimensionnel ) ) ); /* Indique si l'on doit calculer la moyenne des gradients 3x3x3 ('VRAI') ou bien la moyenne */ /* des {Rho,Phi,Theta} des gradients 3x3x3, puis reconstituer a partir de la un gradient */ /* moyen ('FAUX'). Cette option a ete introduite le 20010326161323 apres experiences faites */ /* grace a 'v $xiii/di_image$FON IFgradient_simplifie_____evaluer_le_gradient_local_moyen' */ /* via 'v $xci/gradient.02$K'. Le comportement anterieur a cette date correspond a la */ /* valeur 'VRAI' de cette options. ATTENTION : cette methode a un gros defaut. */ /* En effet, les petites imprecisions sur {Phi,Theta} peuvent provoquer des anomalies ; par */ /* exemple, dans une simulation bidimensionnelle a 'Z' constant, les particules peuvent */ /* ainsi s'echapper de leur plan 'Z' de depart. Ce probleme est evidemment cause par les */ /* passages des coordonnees cartesiennes aux coordonnees spheriques, puis retour (cela peut */ /* etre vu grace au programme 'v $xtKi/CartSph3D.01$K'). Ce probleme est corrigeable */ /* approximativement via 'seuil_de_Mgradient_local_tri_dimensionnel_?' ci-apres. */ /* */ /* On notera au passage qu'un plan de coordonnee 'Z' constante a un 'Theta' egal a pi/2. */ #define SEUIL_DE_Mgradient_local_tri_dimensionnel_X \ FZERO #define SEUIL_DE_Mgradient_local_tri_dimensionnel_Y \ FZERO #define SEUIL_DE_Mgradient_local_tri_dimensionnel_Z \ tgEPSILON /* ATTENTION, les valeurs par defaut {FZERO,FZERO,tgEPSILON} correspondent a une utilisation */ /* bidimensionnelle {OX,OY} du programme... */ DEFV(Local,DEFV(Float,INIT(seuil_de_Mgradient_local_tri_dimensionnel_X,SEUIL_DE_Mgradient_local_tri_dimensionnel_X))); DEFV(Local,DEFV(Float,INIT(seuil_de_Mgradient_local_tri_dimensionnel_Y,SEUIL_DE_Mgradient_local_tri_dimensionnel_Y))); DEFV(Local,DEFV(Float,INIT(seuil_de_Mgradient_local_tri_dimensionnel_Z,SEUIL_DE_Mgradient_local_tri_dimensionnel_Z))); /* Si 'IL_NE_FAUT_PAS(calculer_la_moyenne_des_Mgradient_3x3x3_tri_dimensionnel)', donne le */ /* seuil en deca duquel les composantes du gradient calcule a partir des valeurs moyennes */ /* de {Rho,Phi,Theta} sont annulees car considerees comme trop petites. On notera qu'une */ /* valeur nulle retablit ces defauts (introduit le 20010328100529). */ #define ARRONDIR_PAR_DEFAUT_LES_COORDONNEES_DU_M_GRADIENT \ VRAI DEFV(Local,DEFV(Logical,INIT(arrondir_par_defaut_les_coordonnees_du_M_gradient,ARRONDIR_PAR_DEFAUT_LES_COORDONNEES_DU_M_GRADIENT))); /* Indique si l'arrondi dans le calcul des coordonnees {X,Y,Z} est par defaut ('VRAI') ou */ /* a la plus proche valeur entiere ('FAUX'). */ #define AFFINER_LE_MAILLAGE_DE_CALCUL_DU_M_GRADIENT \ FAUX DEFV(Local,DEFV(Logical,INIT(affiner_le_maillage_de_calcul_du_M_gradient,AFFINER_LE_MAILLAGE_DE_CALCUL_DU_M_GRADIENT))); /* Indique si le maillage de calcul du 'M-Gradient' doit etre affine ('VRAI') ou pas */ /* ('FAUX'). En effet, le milieu de propagation peut contenir des "details" trop fins */ /* par rapport au deplacement d'une particule pendant le temps 'dct'. Cela se voit, par */ /* exemple, dans la sequence : */ /* */ /* xivPdf 11 1 / 023323_023834 */ /* */ /* sur l'image '023508' ou une particule (blanchatre) rencontre la pointe qui "rentre" */ /* dans l'ensemble de Mandelbrot sur la portie positive de l'axe Reel. */ #define CALCULER_UN_M_GRADIENT_TRIDIMENSIONNEL_SIMPLIFIE \ FAUX DEFV(Local,DEFV(Logical,INIT(calculer_un_M_gradient_tridimensionnel_simplifie,CALCULER_UN_M_GRADIENT_TRIDIMENSIONNEL_SIMPLIFIE))); /* Indique lorsque 'IL_NE_FAUT_PAS(affiner_le_maillage_de_calcul_du_M_gradient)' si le */ /* calcul du 'M-Gradient' est simplifie, c'est-a-dire 3 fois monodimensionnel ('VRAI') */ /* ou reellement tridimensionnel ('FAUX'). */ /* */ /* Lorsque 'IL_FAUT(calculer_un_M_gradient_tridimensionnel_simplifie)', le gradient */ /* obtenu est tres approximatif et son "inclinaison" est tres quantifiee ; par exemple, */ /* en mode bidimensionnel, il a tendance a s'aligner parallelement aux axes de coordonnees */ /* lorsque le milieu de propagation est homogene et surtout binaire. C'est ce phenomene */ /* qui explique par exemple le collage d'une particule sur l'image '024416' de la sequence : */ /* */ /* xivPdf 11 1 / 024347_024858 */ /* */ /* Cette particule est celle qui est pratiquement le plus haut sur l'image. Pour elle le */ /* gradient fut tres certainement calcule horizontal, alors que sa vitesse incidente etait */ /* pratiquement verticale, mais faisant un angle inferieur a pi/2 avec ce gradient. Dans */ /* ces conditions, on decrete qu'il y a refraction, d'ou le collage apparent (en fait, de */ /* par le rapport enorme des indices de refraction, la vitesse est considerablement reduite */ /* d'ou cet effet de pseudo-immobilisation). */ /* */ /* Le 19971222111857, 'CALCULER_UN_M_GRADIENT_TRIDIMENSIONNEL_SIMPLIFIE' est passe de la */ /* valeur 'VRAI' a la valeur 'FAUX'. */ /* */ /* On notera que la conjonction de 'IL_FAUT(adapter_les_M_nPAS)' et de */ /* 'IL_NE_FAUT_PAS(calculer_un_M_gradient_tridimensionnel_simplifie)' permet de lutter */ /* contre un phenomene "classique" qui consiste apres une REFLEXION a faire une REFRACTION */ /* qui peut etre consideree comme l'inverse ; en effet, on voit le gradient oppose de celui */ /* de la REFLEXION. La solution est donc d'adapter les pas... */ #define M_GRADIENT_TRIDIMENSIONNEL_NON_SIMPLIFIE_FILTRER \ VRAI DEFV(Local,DEFV(Logical,INIT(M_gradient_tridimensionnel_non_simplifie_filtrer ,M_GRADIENT_TRIDIMENSIONNEL_NON_SIMPLIFIE_FILTRER ) ) ); /* La valeur implicite est passee de 'FAUX' a 'VRAI' le 19980302151517. */ #define M_GRADIENT_TRIDIMENSIONNEL_NON_SIMPLIFIE_TOLERANCE \ GRO3(FRA4(______________BLANC_NORMALISE)) DEFV(Local,DEFV(Float,INIT(M_gradient_tridimensionnel_non_simplifie_tolerance ,FLOT__NIVEAU_UNDEF ) ) ); /* Indique lorsque 'IL_NE_FAUT_PAS(calculer_un_M_gradient_tridimensionnel_simplifie)' si le */ /* calcul du gradient filtre les niveaux en excluant ceux qui sont trop eloignes de la */ /* moyenne ('VRAI') ou en les prenant tous ('FAUX'). La tolerance est alors utilisee pour */ /* definir l'intervalle des niveaux das [0,1] autorises a participer au calcul du gradient. */ /* */ /* ATTENTION, le 19980914135745, en preparant la sequence : */ /* */ /* xivPdf 11 2 / 029972_030483 */ /* */ /* j'ai pu constater que cela pouvait etre tres ennuyeux, meme sur des images "milieu" ne */ /* contenant que du 'NOIR' et du 'BLANC'. En effet, imaginons qu'il n'y ait, par exemple, */ /* qu'un seul point 'NOIR' ; le niveau moyen est alors tres proche de 'BLANC' et si le */ /* facteur de tolerance est inferieur a 1, le seul point 'NOIR' sera ignore lors du calcul */ /* du gradient, et celui-ci sera donc de module nul... */ /* */ /* Le 20091023085726, 'M_GRADIENT_TRIDIMENSIONNEL_NON_SIMPLIFIE_TOLERANCE' fut remplace par */ /* 'FLOT__NIVEAU_UNDEF' a cause de l'usage de '______________BLANC_NORMALISE' */ /* et donc par 'v $xiiD/definit.2$DEF ______NORMALISE_NIVEAU' qui lui-meme utilise */ /* 'v $xiiD/definit.2$DEF AXE_NIVEAUX_OUVERT_FERME'. Alors 'NIVEAU_DU_CHAMP_NOIR_et_BLANC' */ /* ne peut etre dans un 'DEFV(Local,DEFV(genere_Float,INIT(...)))' puisqu'il teste une */ /* variable... */ #define M_GRADIENT_TRIDIMENSIONNEL_NON_SIMPLIFIE_SPHERIQUE \ VRAI DEFV(Local,DEFV(Logical,INIT(M_gradient_tridimensionnel_non_simplifie_spherique ,M_GRADIENT_TRIDIMENSIONNEL_NON_SIMPLIFIE_SPHERIQUE ) ) ); /* Indique lorsque 'IL_NE_FAUT_PAS(calculer_un_M_gradient_tridimensionnel_simplifie)' si le */ /* calcul du gradient se fait dans une fenetre circulaire ('VRAI') ou carree ('FAUX'). */ /* La valeur implicite est passee de 'FAUX' a 'VRAI' le 19980302151517. */ #define PONDERER_UN_M_GRADIENT_TRIDIMENSIONNEL_NON_SIMPLIFIE \ FAUX DEFV(Local,DEFV(Logical,INIT(ponderer_un_M_gradient_tridimensionnel_non_simplifie ,PONDERER_UN_M_GRADIENT_TRIDIMENSIONNEL_NON_SIMPLIFIE ) ) ); /* Indique lorsque 'IL_NE_FAUT_PAS(calculer_un_M_gradient_tridimensionnel_simplifie)' si le */ /* calcul du gradient doit etre une somme ponderee ('VRAI') ou pas ('FAUX') des gradients */ /* elementaires. */ #define M_nPASX \ QUATRE #define M_nPASY \ QUATRE #define M_nPASZ \ UN DEFV(Local,DEFV(Int,INIT(M_NpasX,M_nPASX))); DEFV(Local,DEFV(Int,INIT(M_NpasY,M_nPASY))); DEFV(Local,DEFV(Int,INIT(M_NpasZ,M_nPASZ))); /* Indique les demi-dimensions (en nombre de points) des volumes elementaires du milieu */ /* de propagation dans lequel on calcule le gradient. */ #define ADAPTER_LES_M_nPAS \ VRAI DEFV(Local,DEFV(Logical,INIT(adapter_les_M_nPAS,ADAPTER_LES_M_nPAS))); /* Indique si les 'M_Npas?' doivent etre adaptes automatiquement en fonction du mouvement */ /* de chaque particule ('VRAI') ou bien utilises tel quels ('FAUX'). */ /* */ /* Le 19971222111857, 'ADAPTER_LES_M_nPAS' est passe de la valeur 'FAUX' a la valeur 'VRAI'. */ /* */ /* On notera que la conjonction de 'IL_FAUT(adapter_les_M_nPAS)' et de */ /* 'IL_NE_FAUT_PAS(calculer_un_M_gradient_tridimensionnel_simplifie)' permet de lutter */ /* contre un phenomene "classique" qui consiste apres une REFLEXION a faire une REFRACTION */ /* qui peut etre consideree comme l'inverse ; en effet, on voit le gradient oppose de celui */ /* de la REFLEXION. La solution est donc d'adapter les pas... */ #define EDITER_LES_MESSAGES_D_ERREUR_DU_CALCUL_DU_GRADIENT \ FAUX DEFV(Local,DEFV(Logical,INIT(editer_les_messages_d_erreur_du_calcul_du_gradient,EDITER_LES_MESSAGES_D_ERREUR_DU_CALCUL_DU_GRADIENT))); /* Indique si il faut editer les volumineux messages d'erreur possibles lors du calcul du */ /* gradient (introduit le 20150208081016). */ DEFV(Local,DEFV(Int,INIT(M_premiere_coupe,PREMIERE_IMAGE))); /* Numero de la premiere coupe du milieu de propagation. */ DEFV(Local,DEFV(Int,INIT(M_pas_des_coupes,PAS_DES_IMAGES))); /* Pas de passage d'un numero de coupe a une autre. */ DEFV(Local,DEFV(Int,INIT(M_nombre_de_chiffres_pour_le_milieu,NOMBRE_DE_CHIFFRES))); /* Nombre de chiffres codant le numero des coupes de la serie... */ #define M_ATTENDRE_LES_IMAGES_INEXISTANTES \ VRAI DEFV(Local,DEFV(Logical,INIT(M_attendre_les_images_inexistantes,M_ATTENDRE_LES_IMAGES_INEXISTANTES))); /* Indique si les images inexistantes constituent une erreur ('FAUX'), ou bien si cela est */ /* normal ('VRAI'), ce qui signifie qu'elles n'ont pas encore ete calculee... */ #define M_PERIODISER_X \ FAUX #define M_PERIODISER_Y \ FAUX #define M_PERIODISER_Z \ FAUX DEFV(Local,DEFV(Logical,INIT(M_periodiser_X,M_PERIODISER_X))); DEFV(Local,DEFV(Logical,INIT(M_periodiser_Y,M_PERIODISER_Y))); DEFV(Local,DEFV(Logical,INIT(M_periodiser_Z,M_PERIODISER_Z))); /* Indique si l'espace [Xmin,Xmax]x[Ymin,Ymax]x[Zmin,Zmax] est periodique ('VRAI') ou pas */ /* ('FAUX'). */ #define M_SYMETRISER_X \ FAUX #define M_SYMETRISER_Y \ FAUX #define M_SYMETRISER_Z \ FAUX DEFV(Local,DEFV(Logical,INIT(M_symetriser_X,M_SYMETRISER_X))); DEFV(Local,DEFV(Logical,INIT(M_symetriser_Y,M_SYMETRISER_Y))); DEFV(Local,DEFV(Logical,INIT(M_symetriser_Z,M_SYMETRISER_Z))); /* Indique si l'espace [Xmin,Xmax]x[Ymin,Ymax]x[Zmin,Zmax] est symetrique ('VRAI') ou pas */ /* ('FAUX'). Ceci a ete introduit le 20050721095220... */ #define M_PROLONGER_X \ FAUX #define M_PROLONGER_Y \ FAUX #define M_PROLONGER_Z \ FAUX DEFV(Local,DEFV(Logical,INIT(M_prolonger_X,M_PROLONGER_X))); DEFV(Local,DEFV(Logical,INIT(M_prolonger_Y,M_PROLONGER_Y))); DEFV(Local,DEFV(Logical,INIT(M_prolonger_Z,M_PROLONGER_Z))); /* Indique si l'espace [Xmin,Xmax]x[Ymin,Ymax]x[Zmin,Zmax] doit etre prolonge a l'exterieur */ /* comme il est au bord ('VRAI') ou pas ('FAUX'). */ /* ATTENTION, le 20010206095440, lors de la generation de la sequence : */ /* */ /* xivPdf 10 2 / 026509_027020 */ /* */ /* j'ai pris conscience du fait que les valeurs 'M_NIVEAU_HORS_DU_MILIEU_DE_PROPAGATION' et */ /* 'M_NIVEAU_INITIAL_DU_MILIEU_DE_PROPAGATION' etaient "inversees". J'ai donc retabli a */ /* cette date les bonnes valeurs ; il est en effet plus logique d'avoir 'BLANC' a */ /* l'interieur et 'NOIR', ce qui permet de faire de la reflexion a l'interieur du milieu, */ /* lorsque des particules vont du centre vers l'exterieur, par exemple... */ #define M_NIVEAU_HORS_DU_MILIEU_DE_PROPAGATION \ NOIR DEFV(Local,DEFV(genere_p,INIT(M_niveau_hors_du_milieu_de_propagation,M_NIVEAU_HORS_DU_MILIEU_DE_PROPAGATION))); /* Valeur a forcer a l'exterieur du milieu de propagation, lorsqu'il ne faut ni periodiser, */ /* ni prolonger... */ #define M_NIVEAU_INITIAL_DU_MILIEU_DE_PROPAGATION \ BLANC DEFV(Local,DEFV(genere_p,INIT(M_niveau_initial_du_milieu_de_propagation,M_NIVEAU_INITIAL_DU_MILIEU_DE_PROPAGATION))); /* Valeur pour initialiser eventuellement le milieu de propagation dans 'ACCES_ALBUM(...)'. */ /* ATTENTION, le 20010206095440, lors de la generation de la sequence : */ /* */ /* xivPdf 10 2 / 026509_027020 */ /* */ /* j'ai pris conscience du fait que les valeurs 'M_NIVEAU_HORS_DU_MILIEU_DE_PROPAGATION' et */ /* 'M_NIVEAU_INITIAL_DU_MILIEU_DE_PROPAGATION' etaient "inversees". J'ai donc retabli a */ /* cette date les bonnes valeurs ; il est en effet plus logique d'avoir 'BLANC' a */ /* l'interieur et 'NOIR', ce qui permet de faire de la reflexion a l'interieur du milieu, */ /* lorsque des particules vont du centre vers l'exterieur, par exemple... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E S I N T E R A C T I O N S E N T R E P A R T I C U L E S : */ /* */ /*************************************************************************************************************************************/ #define FACTEUR_DES_RAYON_D_INTERACTION \ FDU DEFV(Local,DEFV(Float,INIT(facteur_des_rayon_d_interaction,FACTEUR_DES_RAYON_D_INTERACTION))); /* Permet de moduler la somme des rayons d'interaction entre deux particules. La logique */ /* voudrait evidemment que ce facteur vaille 1. Mais a cause du rendu des particules sous */ /* la forme de spheres estompees, leur contour apparent semble beaucoup plus reduit qu'il */ /* n'est en realite ; cela s'est vu en utilisant la palette '$xiP/masque' sur les images */ /* '0005' et '0006' lors de la generation de la sequence : */ /* */ /* xivPdf 11 2 / 003073_003584 */ /* */ /* lorsque les deux particules en haut et a gauche interagissent... */ #define SEUIL_D_INTERACTION \ FZERO DEFV(Local,DEFV(Float,INIT(seuil_d_interaction,SEUIL_D_INTERACTION))); /* Indique la distance en deca de laquelle deux particules vont interagir. On notera qu'une */ /* valeur nulle inhibe a priori ce mecanisme (voir l'utilisation d'un 'IFLT(...)'). Ainsi, */ /* on espere pouvoir construire des 'DLA' (ou 'Diffusion Limited Aggregation'). Une valeur */ /* de 0.025 permet de bien simuler les collisions... */ #define GENERER_DES_DiffusionLimitedAggregation \ FAUX DEFV(Local,DEFV(Logical,INIT(generer_des_DiffusionLimitedAggregation,GENERER_DES_DiffusionLimitedAggregation))); /* Indique s'il faut generer des 'DLA' ('VRAI') ou pas ('FAUX')... */ #include xrk/rdn_walk.41.I" /* Gestion des collisions... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E S I N T E R A C T I O N S D E S P A R T I C U L E S A V E C L E M I L I E U : */ /* */ /*************************************************************************************************************************************/ #define UTILISER_UN_CHAMP_DE_PROBABILITE \ FAUX DEFV(Local,DEFV(Logical,INIT(utiliser_un_champ_de_probabilite,UTILISER_UN_CHAMP_DE_PROBABILITE))); /* Indique s'il faut contraindre les interactions par un champ de probabilite defini par */ /* un album d'images ('VRAI') ou pas ('FAUX'). */ DEFV(Local,DEFV(Int,INIT(P_premiere_coupe,PREMIERE_IMAGE))); /* Numero de la premiere coupe du champ de probabilite. */ DEFV(Local,DEFV(Int,INIT(P_pas_des_coupes,PAS_DES_IMAGES))); /* Pas de passage d'un numero de coupe a une autre. */ DEFV(Local,DEFV(Int,INIT(P_nombre_de_chiffres_pour_le_champ,NOMBRE_DE_CHIFFRES))); /* Nombre de chiffres codant le numero des coupes de la serie... */ #define P_ATTENDRE_LES_IMAGES_INEXISTANTES \ VRAI DEFV(Local,DEFV(Logical,INIT(P_attendre_les_images_inexistantes,P_ATTENDRE_LES_IMAGES_INEXISTANTES))); /* Indique si les images inexistantes constituent une erreur ('FAUX'), ou bien si cela est */ /* normal ('VRAI'), ce qui signifie qu'elles n'ont pas encore ete calculee... */ #define P_PERIODISER_X \ FAUX #define P_PERIODISER_Y \ FAUX #define P_PERIODISER_Z \ FAUX DEFV(Local,DEFV(Logical,INIT(P_periodiser_X,P_PERIODISER_X))); DEFV(Local,DEFV(Logical,INIT(P_periodiser_Y,P_PERIODISER_Y))); DEFV(Local,DEFV(Logical,INIT(P_periodiser_Z,P_PERIODISER_Z))); /* Indique si l'espace [Xmin,Xmax]x[Ymin,Ymax]x[Zmin,Zmax] est periodique ('VRAI') ou pas */ /* ('FAUX'). */ #define P_SYMETRISER_X \ FAUX #define P_SYMETRISER_Y \ FAUX #define P_SYMETRISER_Z \ FAUX DEFV(Local,DEFV(Logical,INIT(P_symetriser_X,P_SYMETRISER_X))); DEFV(Local,DEFV(Logical,INIT(P_symetriser_Y,P_SYMETRISER_Y))); DEFV(Local,DEFV(Logical,INIT(P_symetriser_Z,P_SYMETRISER_Z))); /* Indique si l'espace [Xmin,Xmax]x[Ymin,Ymax]x[Zmin,Zmax] est symetrique ('VRAI') ou pas */ /* ('FAUX'). Ceci a ete introduit le 20050721095220... */ #define P_PROLONGER_X \ FAUX #define P_PROLONGER_Y \ FAUX #define P_PROLONGER_Z \ FAUX DEFV(Local,DEFV(Logical,INIT(P_prolonger_X,P_PROLONGER_X))); DEFV(Local,DEFV(Logical,INIT(P_prolonger_Y,P_PROLONGER_Y))); DEFV(Local,DEFV(Logical,INIT(P_prolonger_Z,P_PROLONGER_Z))); /* Indique si l'espace [Xmin,Xmax]x[Ymin,Ymax]x[Zmin,Zmax] doit etre prolonge a l'exterieur */ /* comme il est au bord ('VRAI') ou pas ('FAUX'). */ #define P_NIVEAU_HORS_DU_CHAMP_DE_PROBABILITE \ NIVEAU_HORS_ECRAN DEFV(Local,DEFV(genere_p,INIT(P_niveau_hors_du_champ_de_probabilite,P_NIVEAU_HORS_DU_CHAMP_DE_PROBABILITE))); /* Valeur a forcer a l'exterieur du champ de probabilite, lorsqu'il ne faut ni periodiser, */ /* ni prolonger... */ #define P_NIVEAU_INITIAL_DU_CHAMP_DE_PROBABILITE \ BLANC DEFV(Local,DEFV(genere_p,INIT(P_niveau_initial_du_champ_de_probabilite,P_NIVEAU_INITIAL_DU_CHAMP_DE_PROBABILITE))); /* Valeur pour initialiser eventuellement le champ de probabilite dans 'ACCES_ALBUM(...)'. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E L ' E D I T I O N D E S E V E N E M E N T S : */ /* */ /*************************************************************************************************************************************/ #define EDITER_LES_EVENEMENTS \ FAUX DEFV(Local,DEFV(Logical,INIT(editer_les_evenements,EDITER_LES_EVENEMENTS))); /* Indique s'il faut editer les evenements ('VRAI') ou pas ('FAUX'). */ #define EDITION_E(action) \ Bblock \ Test(IL_FAUT(editer_les_evenements)) \ Bblock \ BLOC(action;); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Procedure d'edition conditionnelle... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E S I N I T I A L I S A T I O N S : */ /* */ /*************************************************************************************************************************************/ /* Jusqu'au 20030313150921, '__VERSION__PERMETTRE_L_UTILISATION_D_UN_FOND' etait defini */ /* ici, mais cela est contraire aux tests dont il est l'objet dans */ /* 'v $xrv/champs_5.12$I __VERSION__PERMETTRE_L_UTILISATION_D_UN_FOND' via */ /* 'v $xrk/attractor.17$I champs_5.12', d'ou son deplacement a cette date... */ #include xrk/attractor.18.I" /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M A R C H E A L E A T O I R E D A N S L ' E S P A C E T R I D I M E N S I O N N E L */ /* A V E C I N T E R A C T I O N E N T R E L E S P A R T I C U L E S */ /* L E T O U T E T A N T D A N S U N M I L I E U D E P R O P A G A T I O N : */ /* */ /*************************************************************************************************************************************/ BCommande(nombre_d_arguments,arguments) /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(CHAR,INIC(POINTERc(nom_du_champ_de_forceA),NOM_PIPE)); /* Nom de la sequence definissant le champ de force. */ DEFV(CHAR,INIC(POINTERc(F_nom_postfixe),NOM_UNDEF_VIDE)); /* Nom d'un eventuel postfixe a placer derriere <nom_du_champ_de_forceA><numero> (par */ /* exemple '$ROUGE'). */ DEFV(CHAR,INIC(POINTERc(nom_du_milieu_de_propagationA),NOM_PIPE)); /* Nom de la sequence definissant le milieu de propagation. */ DEFV(CHAR,INIC(POINTERc(M_nom_postfixe),NOM_UNDEF_VIDE)); /* Nom d'un eventuel postfixe a placer derriere <nom_du_milieu_de_propagationA><numero> (par */ /* exemple '$ROUGE'). */ DEFV(CHAR,INIC(POINTERc(nom_du_champ_de_probabiliteA),NOM_PIPE)); /* Nom de la sequence definissant le champ de probabilite. */ DEFV(CHAR,INIC(POINTERc(P_nom_postfixe),NOM_UNDEF_VIDE)); /* Nom d'un eventuel postfixe a placer derriere <nom_du_champ_de_probabiliteA><numero> (par */ /* exemple '$ROUGE'). */ DONNEES_NECESSAIRES_A_L_UTILISATION_D_UN_FOND; DEFV(Int,INIT(corpsI,UNDEF)); DEFV(Int,INIT(corpsJ,UNDEF)); DEFV(Int,INIT(corps,UNDEF)); /* Pour manipuler les listes... */ /*..............................................................................................................................*/ EGAL(Zmin,k___Zmin); EGAL(Zmax,SUCZ(Zmin)); /* Cette precaution essentielle est due a la declaration : */ /* */ /* BDEFV(album,champ_de_force); */ /* */ /* faite plus loin, et qui sinon, provoque sur 'SYSTEME_SG...' (par exemple) le message : */ /* */ /* unix: ALERT: ... - out of logical swap space during brk/sbrk ... */ /* */ /* dans '$Ferreurs'. Bien evidemment, le 'GET_ARGUMENTSv(...)' qui suit peut changer cela, */ /* et doit le faire lorsqu'un champ de force defini par plus d'une image est declare... */ /* Enfin, le 'SUCZ(...)' est destine a ce que l'axe 'OZ" ne soit pas reduit a une point... */ INITIALISATIONS_GENERALES; /* Initialisations generales faites au tout debut... */ iTRANSFORMAT_31(liste_initiale_des_DATE_DE_NAISSANCE,DATE_DE_NAISSANCE_IMPLICITE); /* Initialisation des fichiers de dates de naissance. */ iTRANSFORMAT_31(liste_initiale_des_X,X_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_Y,Y_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_Z,Z_IMPLICITE); /* Initialisation des fichiers de listes de coordonnees. */ iTRANSFORMAT_31(liste_initiale_des_VX,VX_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_VY,VY_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_VZ,VZ_IMPLICITE); /* Initialisation des fichiers de listes de vitesses implicites. */ iTRANSFORMAT_31(liste_initiale_des_MINIMUM_DELTA_RHO,MINIMUM_DELTA_RHO_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_MAXIMUM_DELTA_RHO,MAXIMUM_DELTA_RHO_IMPLICITE); /* Initialisation des fichiers de listes de variations des 'rho's. */ iTRANSFORMAT_31(liste_initiale_des_MINIMUM_N_PHI,MINIMUM_N_PHI_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_MAXIMUM_N_PHI,MAXIMUM_N_PHI_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_DELTA_PHI,DELTA_PHI_IMPLICITE); /* Initialisation des fichiers de listes de variations des 'phi's (ou "longitude"). */ iTRANSFORMAT_31(liste_initiale_des_MINIMUM_N_THETA,MINIMUM_N_THETA_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_MAXIMUM_N_THETA,MAXIMUM_N_THETA_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_DELTA_THETA,DELTA_THETA_IMPLICITE); /* Initialisation des fichiers de listes de variations des 'theta's (ou "distance polaire"). */ iTRANSFORMAT_31(liste_initiale_des_BORNE_INFERIEURE_DE_L_OUVERTURE,BORNE_INFERIEURE_DE_L_OUVERTURE_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_BORNE_SUPERIEURE_DE_L_OUVERTURE,BORNE_SUPERIEURE_DE_L_OUVERTURE_IMPLICITE); /* Initialisation des fichiers des bornes inferieures et superieures des angles entre le */ /* vecteur vitesse perturbee et le gradient du champ de force. */ iTRANSFORMAT_31(liste_initiale_des_DISTANCE_MAXIMALE,DISTANCE_MAXIMALE_IMPLICITE); /* Initialisation des fichiers de liste de distances maximales. */ iTRANSFORMAT_31(liste_initiale_des_STABILITE,STABILITE_IMPLICITE); /* Initialisation des fichiers de liste de stabilite. */ iTRANSFORMAT_31(liste_initiale_des_RAYON,RAYON_IMPLICITE); /* Initialisation du fichier de liste des rayons. */ iTRANSFORMAT_31(liste_initiale_des_RAYON_D_INTERACTION,RAYON_D_INTERACTION_IMPLICITE); /* Initialisation du fichier de liste de rayon d'interaction (introduit le 19980115090818). */ iTRANSFORMAT_31(liste_initiale_des_ROUGE,ROUGE_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_VERTE,VERTE_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_BLEUE,BLEUE_IMPLICITE); /* Initialisation des fichiers de listes de couleurs. */ iTRANSFORMAT_31(liste_initiale_des_MASSE,MASSE_IMPLICITE); /* Initialisation du fichier de liste des masses. */ iTRANSFORMAT_31(liste_initiale_des_COEFFICIENT_DE_RESTITUTION,COEFFICIENT_DE_RESTITUTION_IMPLICITE); /* Initialisation du fichier de liste de taux de restitution. */ iTRANSFORMAT_31(liste_initiale_des_FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION,FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION ,TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION_IMPLICITE ); iTRANSFORMAT_31(liste_initiale_des_FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION,FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION_IMPLICITE); iTRANSFORMAT_31(liste_initiale_des_TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION ,TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION_IMPLICITE ); /* Initialisation des facteurs et translations des vitesses "normales" et "tangentielles" */ /* apres refraction ou reflexion... */ #include xrv/champs_5.1A.I" GET_ARGUMENTSv(nombre_d_arguments ,BLOC(PROCESS_ARGUMENT_I("nombre_points=""npoints=""iterations=""corps=",nombre_de_corps /* Le 20111211100209, les parametres "nombre_points=""npoints=""iterations=" ont ete */ /* introduits par symetrie avec 'v $xrv/particule.10$K nombre_points= (par exemple...). */ ,BLOC(VIDE;) ,BLOC( Bblock PRINT_AVERTISSEMENT("'corps=' doit etre defini avant tout fichier"); Test(IFGT(nombre_de_corps,NOMBRE_MAXIMAL_DE_POINTS_GERABLES)) Bblock PRINT_ERREUR("le nombre de points a gerer est trop important"); PRINT_ERREUR("il va donc etre seuille"); CAL1(Prer2("Il vaut %d alors que le maximum est de %d\n" ,nombre_de_corps ,NOMBRE_MAXIMAL_DE_POINTS_GERABLES ) ); EGAL(nombre_de_corps,NOMBRE_MAXIMAL_DE_POINTS_GERABLES); /* Et on seuille le nombre de points... */ Eblock ATes Bblock Eblock ETes Eblock ) ); /* ATTENTION : la recuperation de 'nombre_de_corps' doit preceder les */ /* 'PROCESS_ARGUMENT_C(...)' qui suivent car ils l'utilisent. */ PROCESS_ARGUMENTS_GEOMETRIQUES; PROCESS_ARGUMENT_FICHIER("LISTE_DATE_DE_NAISSANCE=" ,fichier_LISTE_DATE_DE_NAISSANCE ,liste_initiale_des_DATE_DE_NAISSANCE ,DATE_DE_NAISSANCE_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_X=" ,fichier_LISTE_X ,liste_initiale_des_X ,X_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_Y=" ,fichier_LISTE_Y ,liste_initiale_des_Y ,Y_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_Z=" ,fichier_LISTE_Z ,liste_initiale_des_Z ,Z_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_VX=" ,fichier_LISTE_VX ,liste_initiale_des_VX ,VX_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_VY=" ,fichier_LISTE_VY ,liste_initiale_des_VY ,VY_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_VZ=" ,fichier_LISTE_VZ ,liste_initiale_des_VZ ,VZ_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_MINIMUM_DELTA_RHO=" ,fichier_LISTE_MINIMUM_DELTA_RHO ,liste_initiale_des_MINIMUM_DELTA_RHO ,MINIMUM_DELTA_RHO_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_MAXIMUM_DELTA_RHO=" ,fichier_LISTE_MAXIMUM_DELTA_RHO ,liste_initiale_des_MAXIMUM_DELTA_RHO ,MAXIMUM_DELTA_RHO_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_MINIMUM_N_PHI=" ,fichier_LISTE_MINIMUM_N_PHI ,liste_initiale_des_MINIMUM_N_PHI ,MINIMUM_N_PHI_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_MAXIMUM_N_PHI=" ,fichier_LISTE_MAXIMUM_N_PHI ,liste_initiale_des_MAXIMUM_N_PHI ,MAXIMUM_N_PHI_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_DELTA_PHI=" ,fichier_LISTE_DELTA_PHI ,liste_initiale_des_DELTA_PHI ,DELTA_PHI_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_MINIMUM_N_THETA=" ,fichier_LISTE_MINIMUM_N_THETA ,liste_initiale_des_MINIMUM_N_THETA ,MINIMUM_N_THETA_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_MAXIMUM_N_THETA=" ,fichier_LISTE_MAXIMUM_N_THETA ,liste_initiale_des_MAXIMUM_N_THETA ,MAXIMUM_N_THETA_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_DELTA_THETA=" ,fichier_LISTE_DELTA_THETA ,liste_initiale_des_DELTA_THETA ,DELTA_THETA_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_BORNE_INFERIEURE_DE_L_OUVERTURE=" ,fichier_LISTE_BORNE_INFERIEURE_DE_L_OUVERTURE ,liste_initiale_des_BORNE_INFERIEURE_DE_L_OUVERTURE ,BORNE_INFERIEURE_DE_L_OUVERTURE_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_BORNE_SUPERIEURE_DE_L_OUVERTURE=" ,fichier_LISTE_BORNE_SUPERIEURE_DE_L_OUVERTURE ,liste_initiale_des_BORNE_SUPERIEURE_DE_L_OUVERTURE ,BORNE_SUPERIEURE_DE_L_OUVERTURE_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_DISTANCE_MAXIMALE=" ,fichier_LISTE_DISTANCE_MAXIMALE ,liste_initiale_des_DISTANCE_MAXIMALE ,DISTANCE_MAXIMALE_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_STABILITE=" ,fichier_LISTE_STABILITE ,liste_initiale_des_STABILITE ,STABILITE_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_RAYON=" ,fichier_LISTE_RAYON ,liste_initiale_des_RAYON ,RAYON_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_RAYON_D_INTERACTION=" ,fichier_LISTE_RAYON_D_INTERACTION ,liste_initiale_des_RAYON_D_INTERACTION ,RAYON_D_INTERACTION_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_ROUGE=" ,fichier_LISTE_ROUGE ,liste_initiale_des_ROUGE ,ROUGE_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_VERTE=" ,fichier_LISTE_VERTE ,liste_initiale_des_VERTE ,VERTE_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_BLEUE=" ,fichier_LISTE_BLEUE ,liste_initiale_des_BLEUE ,BLEUE_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_MASSE=" ,fichier_LISTE_MASSE ,liste_initiale_des_MASSE ,MASSE_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_FICHIER("LISTE_COEFFICIENT_DE_RESTITUTION=" ,fichier_LISTE_COEFFICIENT_DE_RESTITUTION ,liste_initiale_des_COEFFICIENT_DE_RESTITUTION ,COEFFICIENT_DE_RESTITUTION_IMPLICITE ,lTRANSFORMAT_11 ); PROCESS_ARGUMENT_C("LISTE_FACTEUR_VITESSE_OX2=" ,fichier_LISTE_FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION ,BLOC(VIDE;) ,BLOC(lTRANSFORMAT_11(fichier_LISTE_FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION ,liste_initiale_des_FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION ,FACTEUR_VITESSE_OX2_REFRACTION_REFLEXION_IMPLICITE ); ) ); PROCESS_ARGUMENT_C("LISTE_TRANSLATION_VITESSE_OX2=" ,fichier_LISTE_TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION ,BLOC(VIDE;) ,BLOC(lTRANSFORMAT_11(fichier_LISTE_TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION ,liste_initiale_des_TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION ,TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION_IMPLICITE ); ) ); PROCESS_ARGUMENT_C("LISTE_FACTEUR_VITESSE_OZ2=" ,fichier_LISTE_FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION ,BLOC(VIDE;) ,BLOC(lTRANSFORMAT_11(fichier_LISTE_FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION ,liste_initiale_des_FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION ,FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION_IMPLICITE ); ) ); PROCESS_ARGUMENT_C("LISTE_TRANSLATION_VITESSE_OZ2=" ,fichier_LISTE_TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION ,BLOC(VIDE;) ,BLOC(lTRANSFORMAT_11(fichier_LISTE_TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION ,liste_initiale_des_TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION ,TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION_IMPLICITE ); ) ); GET_ARGUMENT_L("inverser=",inverser_le_processus); GET_ARGUMENT_I("periode_d_inversion=",periode_d_inversion_du_processus); GET_ARGUMENT_I("graine=""g=",graine_du_generateur_d_evenements); GET_ARGUMENT_L("affiner_rdn=",rdnIFnD_____affiner_la_generation); GET_ARGUMENT_L("iterer_rdn=",rdnIFnD_____iterer_la_generation); GET_ARGUMENT_L("automatique=",limiter_automatiquement_tentatives_recherche_bonne_perturbation); GET_ARGUMENT_I("tentatives=",nombre_maximal_de_tentatives_de_recherche_d_une_bonne_perturbation); GET_ARGUMENT_L("history=""editer_evenements=",editer_les_evenements); GET_ARGUMENT_L("force=",utiliser_un_champ_de_force); GET_ARGUMENT_L("adapter_F_nPAS=",adapter_les_F_nPAS); GET_ARGUMENT_I("FNpasX=",F_NpasX); GET_ARGUMENT_I("FNpasY=",F_NpasY); GET_ARGUMENT_I("FNpasZ=",F_NpasZ); GET_ARGUMENT_L("Fattendre=",F_attendre_les_images_inexistantes); GET_ARGUMENT_C("imageFC=""FC=",nom_du_champ_de_forceA); GET_ARGUMENT_C("Fpostfixe=",F_nom_postfixe); GET_ARGUMENT_I("Fpremiere=",F_premiere_coupe); GET_ARGUMENT_I("Fpas=",F_pas_des_coupes); GET_ARGUMENT_I("FChiffres=",F_nombre_de_chiffres_pour_le_champ); GET_ARGUMENT_L("Fperiodiser_X=",F_periodiser_X); GET_ARGUMENT_L("Fperiodiser_Y=",F_periodiser_Y); GET_ARGUMENT_L("Fperiodiser_Z=",F_periodiser_Z); GET_ARGUMENT_L("Fsymetriser_X=",F_symetriser_X); GET_ARGUMENT_L("Fsymetriser_Y=",F_symetriser_Y); GET_ARGUMENT_L("Fsymetriser_Z=",F_symetriser_Z); GET_ARGUMENT_L("Fprolonger_X=",F_prolonger_X); GET_ARGUMENT_L("Fprolonger_Y=",F_prolonger_Y); GET_ARGUMENT_L("Fprolonger_Z=",F_prolonger_Z); GET_ARGUMENT_P("Fniveau_hors_du_champ_de_force=""Fhors=",F_niveau_hors_du_champ_de_force); GET_ARGUMENT_P("Fniveau_initial_du_champ_de_force=""Finitial=",F_niveau_initial_du_champ_de_force); GET_ARGUMENT_L("premiere_direction=",prendre_la_premiere_direction_trouvee); GET_ARGUMENT_I("selecteur=",nombre_d_iterations_si_on_ne_prend_pas_la_premiere_direction_trouvee); GET_ARGUMENT_L("propagation=""milieu=",utiliser_un_milieu_de_propagation); GET_ARGUMENT_L("reflexion=",il_peut_y_avoir_reflexion); GET_ARGUMENT_L("refraction=",il_peut_y_avoir_refraction); GET_ARGUMENT_F("angle_inferieur_de_reflexion=",angle_inferieur_du_cone_de_reflexion); GET_ARGUMENT_F("angle_superieur_de_reflexion=",angle_superieur_du_cone_de_reflexion); GET_ARGUMENT_L("moduler_vitesse=",moduler_la_vitesse_lors_d_une_refraction); GET_ARGUMENT_F("AvitesseN=",facteur_vitesse_OX2_refraction_reflexion); GET_ARGUMENT_F("BvitesseN=",translation_vitesse_OX2_refraction_reflexion); GET_ARGUMENT_F("AvitesseT=",facteur_vitesse_OZ2_refraction_reflexion); GET_ARGUMENT_F("BvitesseT=",translation_vitesse_OZ2_refraction_reflexion); GET_ARGUMENT_L("moyenne_gradient=",calculer_la_moyenne_des_Mgradient_3x3x3_tri_dimensionnel); GET_ARGUMENT_F("seuil_gradientX=",seuil_de_Mgradient_local_tri_dimensionnel_X); GET_ARGUMENT_F("seuil_gradientY=",seuil_de_Mgradient_local_tri_dimensionnel_Y); GET_ARGUMENT_F("seuil_gradientZ=",seuil_de_Mgradient_local_tri_dimensionnel_Z); GET_ARGUMENT_L("M_gradient_par_defaut=",arrondir_par_defaut_les_coordonnees_du_M_gradient); GET_ARGUMENT_L("affiner_M_maillage=",affiner_le_maillage_de_calcul_du_M_gradient); GET_ARGUMENT_L("Msimplifier=",calculer_un_M_gradient_tridimensionnel_simplifie); GET_ARGUMENT_L("Mfiltrer=",M_gradient_tridimensionnel_non_simplifie_filtrer); GIT_ARGUMENT_F("Mtolerance=" ,M_gradient_tridimensionnel_non_simplifie_tolerance ,M_GRADIENT_TRIDIMENSIONNEL_NON_SIMPLIFIE_TOLERANCE ); /* Le 20091023085726, le 'GET_ARGUMENT_F(...)' a ete remplace par 'GIT_ARGUMENT_F(...)' */ /* a cause de 'v $xrk/rdn_walk.52$K 20091023085850'. ATTENTION : l'usage eventuel de */ /* l'argument "AXE_NIVEAUX_OUVERT_FERME_____compatibilite_19951221=" doit donc alors */ /* PRECEDER un eventuel "Mtolerance="... */ GET_ARGUMENT_L("Mspherique=",M_gradient_tridimensionnel_non_simplifie_spherique); GET_ARGUMENT_L("Mponderer=",ponderer_un_M_gradient_tridimensionnel_non_simplifie); GET_ARGUMENT_L("adapter_M_nPAS=",adapter_les_M_nPAS); GET_ARGUMENT_I("MNpasX=",M_NpasX); GET_ARGUMENT_I("MNpasY=",M_NpasY); GET_ARGUMENT_I("MNpasZ=",M_NpasZ); GET_ARGUMENT_L("messages_erreur_gradient=""meg=",editer_les_messages_d_erreur_du_calcul_du_gradient); /* Introduit le 20150208081016... */ GET_ARGUMENT_L("Mattendre=",M_attendre_les_images_inexistantes); GET_ARGUMENT_C("imageMC=""MC=",nom_du_milieu_de_propagationA); GET_ARGUMENT_C("Mpostfixe=",M_nom_postfixe); GET_ARGUMENT_I("Mpremiere=",M_premiere_coupe); GET_ARGUMENT_I("Mpas=",M_pas_des_coupes); GET_ARGUMENT_I("MChiffres=",M_nombre_de_chiffres_pour_le_milieu); GET_ARGUMENT_L("Mperiodiser_X=",M_periodiser_X); GET_ARGUMENT_L("Mperiodiser_Y=",M_periodiser_Y); GET_ARGUMENT_L("Mperiodiser_Z=",M_periodiser_Z); GET_ARGUMENT_L("Msymetriser_X=",M_symetriser_X); GET_ARGUMENT_L("Msymetriser_Y=",M_symetriser_Y); GET_ARGUMENT_L("Msymetriser_Z=",M_symetriser_Z); GET_ARGUMENT_L("Mprolonger_X=",M_prolonger_X); GET_ARGUMENT_L("Mprolonger_Y=",M_prolonger_Y); GET_ARGUMENT_L("Mprolonger_Z=",M_prolonger_Z); GET_ARGUMENT_P("Mniveau_hors_du_milieu_de_propagation=""Mhors=",M_niveau_hors_du_milieu_de_propagation); GET_ARGUMENT_P("Mniveau_initial_du_milieu_de_propagation=""Minitial=" ,M_niveau_initial_du_milieu_de_propagation ); GET_ARGUMENT_F("interaction=",seuil_d_interaction); GET_ARGUMENT_L("collisions=",gerer_les_collisions); GET_ARGUMENT_L("ponctuels=""chocs_ponctuels=",considerer_les_chocs_ponctuels); GET_ARGUMENT_F("facteur_d_interaction=",facteur_des_rayon_d_interaction); GET_ARGUMENT_F("restitution=""elasticite=",coefficient_de_restitution); GET_ARGUMENT_L("DLA=",generer_des_DiffusionLimitedAggregation); GET_ARGUMENT_L("probabilite=",utiliser_un_champ_de_probabilite); GET_ARGUMENT_L("Pattendre=",P_attendre_les_images_inexistantes); GET_ARGUMENT_C("imagePC=""PC=",nom_du_champ_de_probabiliteA); GET_ARGUMENT_C("Ppostfixe=",P_nom_postfixe); GET_ARGUMENT_I("Ppremiere=",P_premiere_coupe); GET_ARGUMENT_I("Ppas=",P_pas_des_coupes); GET_ARGUMENT_I("PChiffres=",P_nombre_de_chiffres_pour_le_champ); GET_ARGUMENT_L("Pperiodiser_X=",P_periodiser_X); GET_ARGUMENT_L("Pperiodiser_Y=",P_periodiser_Y); GET_ARGUMENT_L("Pperiodiser_Z=",P_periodiser_Z); GET_ARGUMENT_L("Psymetriser_X=",P_symetriser_X); GET_ARGUMENT_L("Psymetriser_Y=",P_symetriser_Y); GET_ARGUMENT_L("Psymetriser_Z=",P_symetriser_Z); GET_ARGUMENT_L("Pprolonger_X=",P_prolonger_X); GET_ARGUMENT_L("Pprolonger_Y=",P_prolonger_Y); GET_ARGUMENT_L("Pprolonger_Z=",P_prolonger_Z); GET_ARGUMENT_P("Pniveau_hors_du_champ_de_probabilite=""Phors=",P_niveau_hors_du_champ_de_probabilite); GET_ARGUMENT_P("Pniveau_initial_du_champ_de_probabilite=""Pinitial=" ,P_niveau_initial_du_champ_de_probabilite ); GET_ARGUMENT_F("dt=""dct=",dct); GET_ARGUMENT_I("nombre=",nombre_de_pas_de_temps_par_periode); PROCESS_ARGUMENTS_DE_VISUALISATION; PROCESS_ARGUMENTS_DE_VISUALISATION_DES_AXES_DE_COORDONNEES; GET_ARGUMENT_L("ensemble=",visualiser_l_ensemble_des_instants); GET_ARGUMENT_L("centrer=",definir_la_scene_par_rapport_au_centre_de_l_espace); GET_ARGUMENT_F("Xcentre=",X_centre_de_l_espace_pour_la_visualisation); GET_ARGUMENT_F("Ycentre=",Y_centre_de_l_espace_pour_la_visualisation); GET_ARGUMENT_F("Zcentre=",Z_centre_de_l_espace_pour_la_visualisation); GET_ARGUMENT_I("reference=",corps_de_reference); GET_ARGUMENT_L("derniere_position=",se_referer_a_la_derniere_position_du_corps_de_reference); GET_ARGUMENT_L("trainees=",generer_les_trainees); GET_ARGUMENT_L("renormaliser=",renormaliser_les_trainees); GET_ARGUMENT_I("mode_des_trainees=""mode=",mode_de_generation_des_trainees); GET_ARGUMENT_F("attenuation_des_trainees=",facteur_d_attenuation_des_trainees); GET_ARGUMENT_F("attenuation_des_images=",facteur_d_attenuation_des_images); ) ); #include xrv/champs_5.19.I" /* Pour eviter le message : */ /* */ /* Static function is not referenced. */ /* */ /* sur 'SYSTEME_ES9000_AIX_CC'... */ #include xrk/attractor.19.I" /* Validations et definition de l'espace physique. */ INITIALISATION_DE_LA_SYNTHESE_D_IMAGE; /* Initialisation eventuelle du calcul des trainees... */ Test(IFET(IL_FAUT(utiliser_un_milieu_de_propagation) ,IFET(EST_VRAI(il_peut_y_avoir_reflexion) ,EST_VRAI(il_peut_y_avoir_refraction) ) ) ) Bblock PRINT_ATTENTION("dans l'etat actuel, il est peu sage d'utiliser l'option 'refraction' avec l'option 'reflexion'"); /* En effet, lorsqu'une particule se deplace, une configuration de points situes devant */ /* celle-ci qui correspondrait a une reflexion, donnerait une refraction une fois qu'elle */ /* aurait ete depassee par la particule (et donc situee derriere elle). On peut ainsi */ /* provoquer de fausses refractions... */ Eblock ATes Bblock Eblock ETes Test(IFET(IL_FAUT(gerer_les_collisions) ,IL_FAUT(generer_des_DiffusionLimitedAggregation) ) ) Bblock PRINT_ATTENTION("les options 'collisions' et 'DLA' sont relativement incompatibles"); Eblock ATes Bblock Eblock ETes Test(IFET(IL_NE_FAUT_PAS(definir_la_scene_par_rapport_au_centre_de_l_espace) ,NINCff(corps_de_reference,PREMIER_POINT_DES_LISTES,nombre_de_corps) ) ) Bblock PRINT_ATTENTION("le corps de reference demande n'existe pas, on lui substitue la valeur par defaut"); EGAL(corps_de_reference,CORPS_DE_REFERENCE); Eblock ATes Bblock Eblock ETes Test(IFET(IL_FAUT(affiner_le_maillage_de_calcul_du_M_gradient) ,IL_FAUT(adapter_les_M_nPAS) ) ) Bblock PRINT_ATTENTION("les options 'affiner_M_maillage' et 'adapter_M_nPAS' sont relativement incompatibles"); /* En effet, lorsque 'IL_FAUT(adapter_les_M_nPAS)' les 'delta_?_anticipe' sont apres */ /* calcul divises par 2. Si ensuite 'IL_FAUT(affiner_le_maillage_de_calcul_du_M_gradient)' */ /* le balayage de calcul du gradient est alors 2 fois trop petit... */ Eblock ATes Bblock Eblock ETes Test(IFET(IL_FAUT(affiner_le_maillage_de_calcul_du_M_gradient) ,IL_NE_FAUT_PAS(calculer_un_M_gradient_tridimensionnel_simplifie) ) ) Bblock PRINT_ATTENTION("les options 'affiner_M_maillage' et 'Msimplifier' sont incompatibles"); Eblock ATes Bblock Eblock ETes MdTb1(liste_des_dates_de_naissance ,nombre_de_corps ,Float ,ADRESSE_NON_ENCORE_DEFINIE ); MdTb1(liste_des_coordonnees_a_l_instant_initial ,nombre_de_corps ,pointF_3D ,ADRESSE_NON_ENCORE_DEFINIE ); MdTb1(liste_des_vitesses_a_l_instant_initial ,nombre_de_corps ,deltaF_3D ,ADRESSE_NON_ENCORE_DEFINIE ); /* Definition de l'instant initial. */ MdTb1(liste_des_coordonnees_a_l_instant_precedent ,nombre_de_corps ,pointF_3D ,ADRESSE_NON_ENCORE_DEFINIE ); /* Definition de l'instant precedent. */ MdTb1(liste_des_coordonnees_a_l_instant_courant ,nombre_de_corps ,pointF_3D ,ADRESSE_NON_ENCORE_DEFINIE ); MdTb1(liste_des_vitesses_a_l_instant_courant ,nombre_de_corps ,deltaF_3D ,ADRESSE_NON_ENCORE_DEFINIE ); MdTb1(liste_des_stabilites_a_l_instant_courant ,nombre_de_corps ,Int ,ADRESSE_NON_ENCORE_DEFINIE ); MdTb1(liste_des_blocages_a_l_instant_courant ,nombre_de_corps ,Logical ,ADRESSE_NON_ENCORE_DEFINIE ); MdTb1(liste_des_reflexions_a_l_instant_courant ,nombre_de_corps ,Logical ,ADRESSE_NON_ENCORE_DEFINIE ); MdTb1(liste_des_refractions_a_l_instant_courant ,nombre_de_corps ,Logical ,ADRESSE_NON_ENCORE_DEFINIE ); MdTb1(liste_des_niveaux_locaux_a_l_instant_courant ,nombre_de_corps ,genere_Float ,ADRESSE_NON_ENCORE_DEFINIE ); MdTb1(liste_des_compteurs_de_collisions_a_l_instant_courant ,nombre_de_corps ,Positive ,ADRESSE_NON_ENCORE_DEFINIE ); MdTb1(liste_des_compteurs_de_reflexions_a_l_instant_courant ,nombre_de_corps ,Positive ,ADRESSE_NON_ENCORE_DEFINIE ); MdTb1(liste_des_compteurs_de_refractions_a_l_instant_courant ,nombre_de_corps ,Positive ,ADRESSE_NON_ENCORE_DEFINIE ); /* Definition de l'instant courant. */ MdTb2(liste_des_coordonnees_cumule_sur_toute_la_duree ,nombre_de_corps ,nombre_de_periodes_de_la_simulation ,pointF_3D ,ADRESSE_NON_ENCORE_DEFINIE ); /* Definition de l'ensemble des instants cumules. */ Test(IZGT(nombre_de_periodes_de_la_simulation)) Bblock /* Cas ou il y a au moins une periode a generer ; ce test a ete ajoute le 19980706122905 */ /* car il manquait et provoquait des anomalies sur '$LACT27' pour "np=0"... */ Komp(corps,nombre_de_corps) Bblock /* Initialisation des listes relatives aux differents corps arguments meme celles pour */ /* lesquelles cela n'a pas de sens... */ EGAL(ACCES_DATES_DE_NAISSANCE(corps),ACCES_LISTE(liste_initiale_des_DATE_DE_NAISSANCE,corps)); INITIALISATION_POINT_3D(ACCES_COORDONNEES_INITIALES(corps) ,ACCES_LISTE(liste_initiale_des_X,corps) ,ACCES_LISTE(liste_initiale_des_Y,corps) ,ACCES_LISTE(liste_initiale_des_Z,corps) ); INITIALISATION_ACCROISSEMENT_3D(ACCES_VITESSE_INITIALE(corps) ,ACCES_LISTE(liste_initiale_des_VX,corps) ,ACCES_LISTE(liste_initiale_des_VY,corps) ,ACCES_LISTE(liste_initiale_des_VZ,corps) ); TRANSFERT_POINT_3D(ACCES_COORDONNEES_PRECEDENTES(corps) ,ACCES_COORDONNEES_INITIALES(corps) ); TRANSFERT_POINT_3D(ACCES_COORDONNEES_CUMULEES(corps,NUMERO_DE_LA_PREMIERE_PERIODE_DE_LA_SIMULATION) ,ACCES_COORDONNEES_INITIALES(corps) ); TRANSFERT_POINT_3D(ACCES_COORDONNEES_COURANTES(corps) ,ACCES_COORDONNEES_INITIALES(corps) ); TRANSFERT_ACCROISSEMENT_3D(ACCES_VITESSE_COURANTE(corps) ,ACCES_VITESSE_INITIALE(corps) ); Test(IFOU(IFNE(ACCES_LISTE(liste_initiale_des_STABILITE,corps) ,INTE(ACCES_LISTE(liste_initiale_des_STABILITE,corps)) ) ,IZLE(ACCES_LISTE(liste_initiale_des_STABILITE,corps)) ) ) Bblock PRINT_ATTENTION("la 'stabilite' d'un corps n'est pas un nombre entier, ou est negative ou nulle"); CAL1(Prer1("corps=%d\n",corps)); EGAL(ACCES_STABILITES_COURANTES(corps),STABILITE_IMPLICITE); Eblock ATes Bblock EGAL(ACCES_STABILITES_COURANTES(corps),INTE(ACCES_LISTE(liste_initiale_des_STABILITE,corps))); Eblock ETes #define UN_TOUR_DE_PLUS \ UN EGAL(ACCES_STABILITES_COURANTES(corps),ADD2(ACCES_STABILITES_COURANTES(corps),UN_TOUR_DE_PLUS)); /* Et ce a cause du probleme lie a la visualisation des conditions initiales... */ EGAL(ACCES_REFLEXIONS_COURANTS(corps),FAUX); EGAL(ACCES_REFRACTIONS_COURANTS(corps),FAUX); EGAL(ACCES_NIVEAUX_LOCAUX_COURANTS(corps),NIVEAU_UNDEF); /* Et ce afin d'eviter que, par exemple, juste apres une reflexion, on considere lors du */ /* calcul du gradient qu'il y a refraction ; ceci est tout a fait possible puisqu'apres */ /* une reflexion la situation est inversee et que l'on risque donc de trouver un gradient */ /* inverse de celui qui a cause la reflexion et qui donc implique une refraction... */ CLIR(ACCES_COMPTEURS_COLLISIONS_COURANTS(corps)); CLIR(ACCES_COMPTEURS_REFLEXIONS_COURANTS(corps)); CLIR(ACCES_COMPTEURS_REFRACTIONS_COURANTS(corps)); /* Afin de compter les collisions dont 'corps' sera la victime. Ce nombre de collisions */ /* pourra etre uniquement 'ACCES_COMPTEURS_COLLISIONS_COURANTS(corps)' si l'on souhaite */ /* ne connaitre que les collisions entre les particules deux a deux ; mais cela pourra etre */ /* 'ACCES_COMPTEURS_COLLISIONS_COURANTS(corps)+ACCES_COMPTEURS_REFLEXIONS_COURANTS(corps)' */ /* si l'on compte comme "collision" celles qui ont lieu avec les discontinuites du milieu */ /* (ce qui est appele donc en fait "reflexion"). */ EGAL(ACCES_BLOCAGES_COURANTS(corps),FAUX); /* Les corps ne sont actuellement pas bloques... */ Eblock EKom Eblock ATes Bblock /* Cas ou il n'y a aucune periode a generer ; ce test a ete ajoute le 19980706122905 */ /* car il manquait et provoquait des anomalies sur '$LACT27' pour "np=0"... */ Eblock ETes begin_nouveau_block Bblock BDEFV(album,champ_de_force); /* Definition de l'album d'images dans lequel ranger le champ de force... */ BDEFV(album,milieu_de_propagation); /* Definition de l'album d'images dans lequel ranger le milieu de propagation... */ BDEFV(album,champ_de_probabilite); /* Definition de l'album d'images dans lequel ranger le champ de probabilite... */ ACCES_ALBUM(utiliser_un_champ_de_force ,champ_de_force ,nom_du_champ_de_forceA,F_nom_postfixe,F_nombre_de_chiffres_pour_le_champ ,F_attendre_les_images_inexistantes ,NE_PAS_AUTORISER_LES_SEQUENCES_INCOMPLETES_DANS_UN_ALBUM ,F_premiere_coupe,F_pas_des_coupes ,NE_PAS_INVERSER_L_ORDRE_DES_COUPES_DANS_ACCES_ALBUM ,F_niveau_initial_du_champ_de_force ); ACCES_ALBUM(utiliser_un_milieu_de_propagation ,milieu_de_propagation ,nom_du_milieu_de_propagationA,M_nom_postfixe,M_nombre_de_chiffres_pour_le_milieu ,M_attendre_les_images_inexistantes ,NE_PAS_AUTORISER_LES_SEQUENCES_INCOMPLETES_DANS_UN_ALBUM ,M_premiere_coupe,M_pas_des_coupes ,NE_PAS_INVERSER_L_ORDRE_DES_COUPES_DANS_ACCES_ALBUM ,M_niveau_initial_du_milieu_de_propagation ); ACCES_ALBUM(utiliser_un_champ_de_probabilite ,champ_de_probabilite ,nom_du_champ_de_probabiliteA,P_nom_postfixe,P_nombre_de_chiffres_pour_le_champ ,P_attendre_les_images_inexistantes ,NE_PAS_AUTORISER_LES_SEQUENCES_INCOMPLETES_DANS_UN_ALBUM ,P_premiere_coupe,P_pas_des_coupes ,NE_PAS_INVERSER_L_ORDRE_DES_COUPES_DANS_ACCES_ALBUM ,P_niveau_initial_du_champ_de_probabilite ); Komp(numero_de_la_periode_courante_de_la_simulation,nombre_de_periodes_de_la_simulation) Bblock DEFV(Int,INIT(periode,UNDEF)); /* Periode de parcours de 'ACCES_COORDONNEES_PRECEDENTES(...)' pour la visualisation... */ INITIALISATIONS_RELATIVES_A_CHAQUE_NOUVELLE_IMAGE(numero_de_la_periode_courante); /* Initialisations necessaires avant le calcul et la generation de chaque nouvelle image. */ DoIn(periode ,COND(IL_FAUT(visualiser_l_ensemble_des_instants) ,NUMERO_DE_LA_PREMIERE_PERIODE_DE_LA_SIMULATION ,numero_de_la_periode_courante_de_la_simulation ) ,numero_de_la_periode_courante_de_la_simulation ,I ) Bblock Komp(corps,nombre_de_corps) Bblock Test(IFLE(ACCES_DATES_DE_NAISSANCE(corps),temps_courant)) Bblock EGAL(rayon_de_visualisation,ACCES_LISTE(liste_initiale_des_RAYON,corps)); /* Recuperation eventuelle du rayon de chaque point... */ EGAL(cx,ASD1(ACCES_COORDONNEES_CUMULEES(corps,periode),x)); EGAL(cy,ASD1(ACCES_COORDONNEES_CUMULEES(corps,periode),y)); EGAL(cz,ASD1(ACCES_COORDONNEES_CUMULEES(corps,periode),z)); /* A cause de 'RECHERCHE_DES_EXTREMA_DES_COORDONNEES_ET_DES_DERIVEES', il est necessaire */ /* de passer par {cx,cy,cz}. */ EGAL(dcx,ACCES_LISTE(liste_initiale_des_ROUGE,corps)); EGAL(dcy,ACCES_LISTE(liste_initiale_des_VERTE,corps)); EGAL(dcz,ACCES_LISTE(liste_initiale_des_BLEUE,corps)); CALS(memorisation_d_un_point_grave(DECENTRAGE_DES_COORDONNEES(cx,X,x) ,DECENTRAGE_DES_COORDONNEES(cy,Y,y) ,DECENTRAGE_DES_COORDONNEES(cz,Z,z) ,dcx ,dcy ,dcz ,ACCES_MASSES(corps) ,ASD1(ACCES_VITESSE_COURANTE(corps),dx) ,ASD1(ACCES_VITESSE_COURANTE(corps),dy) ,ASD1(ACCES_VITESSE_COURANTE(corps),dz) ,periode ) ); /* Memorisation du corps courant, la premiere image donnant les conditions initiales... */ /* ATTENTION, jusqu'au 19980213085333, on trouvait 'corps' a la place de 'periode' ; bien */ /* que ne servant a rien, j'ai corrige cette erreur... */ /* */ /* L'edition des vitesses {vx,vy,vz} du point courant a ete ajoute le 19980630135924 */ /* afin de permettre l'edition de l'etat final d'une simulation afin que celui-ci puisse */ /* servir de conditions initiales a une autre simulation, par exemple, en ayant modifie la */ /* geometrie du milieu. ATTENTION, lors d'une telle utilisation l'etat final d'une */ /* simulation 'N' est alors strictement identique a l'etat initial de la suivante 'N+1' */ /* (heureusement...) ce qui signifie que la derniere image de la simulation 'N' et la ' */ /* premiere image de la simulation 'N+1' sont identiques et donc, cette premiere image */ /* doit etre ignoree ('v _____xivPdf_11_2/$Fnota 018098_018609'). D'autre part, dans une */ /* telle utilisation, il est difficile d'assurer la continuite des trainees ; de petits */ /* defauts peuvent apparaitre comme dans 'v _____xivPdf_11_2/$Fnota 018098_018609'. */ /* De plus, en prenant l'exemple d'un milieu {NOIR,BLANC} (le 'BLANC' designant l'interieur */ /* et le 'BLANC' designant l'exterieur), il est necessaire que le volume interieur de la */ /* simulation 'N' soit inclus dans le volume interieur de la simulation 'N+1' ; en effet, */ /* dans le cas contraire, des particules proches de la frontiere pourraient etre "ejectees" */ /* artificiellement du milieu de propagation ('BLANC') et alors le cas de ces particules */ /* devrait etre traite avant de la lancer la simulation 'N+1' ; mais qu'en faire ? */ RECHERCHE_DES_EXTREMA_DES_COORDONNEES_ET_DES_DERIVEES; /* On notera que cette recherche n'est pas conditionnee par 'editer_les_extrema', car les */ /* extrema pourraient etre utilises pour la visualisation... */ Eblock ATes Bblock Eblock ETes Eblock EKom Eblock EDoI Test(IL_FAUT(inverser_le_processus)) Bblock Test(IFEQ(numero_de_la_periode_courante_de_la_simulation,periode_d_inversion_du_processus)) Bblock /* Cas ou il faut inverser arbitrairement toutes les vitesses. Il est evident que cela n'a */ /* reellement de sens que si il n'y a aucun processus aleatoires actifs... */ Komp(corps,nombre_de_corps) Bblock INITIALISATION_ACCROISSEMENT_3D(ACCES_VITESSE_COURANTE(corps) ,NEGA(ASD1(ACCES_VITESSE_COURANTE(corps),dx)) ,NEGA(ASD1(ACCES_VITESSE_COURANTE(corps),dy)) ,NEGA(ASD1(ACCES_VITESSE_COURANTE(corps),dz)) ); /* On repart donc dans la direction inverse de la direction incidente... */ Eblock EKom Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Repe(COND(IFGT(numero_de_la_periode_courante_de_la_simulation,NUMERO_DE_LA_PREMIERE_PERIODE_DE_LA_SIMULATION) ,nombre_de_pas_de_temps_par_periode ,ADD2(nombre_de_pas_de_temps_par_periode,UN_TOUR_DE_PLUS) ) ) /* Cette precaution evitant de visualiser deux fois les conditions initiales (ce qui se */ /* voit lorsque 'nombre_de_pas_de_temps_par_periode' est egal a un...). */ Bblock Test(I3OU(IL_FAUT(utiliser_un_champ_de_force) ,IL_FAUT(utiliser_un_milieu_de_propagation) ,IL_FAUT(utiliser_un_champ_de_probabilite) ) ) Bblock Komp(corps,nombre_de_corps) Bblock Test(IFET(EST_FAUX(ACCES_BLOCAGES_COURANTS(corps)) ,IFLE(ACCES_DATES_DE_NAISSANCE(corps),temps_courant) ) ) Bblock /* Cas d'un corps non bloque et qui est vivant.. */ #define X_VITESSE \ ASD1(ACCES_VITESSE_COURANTE(corps),dx) #define Y_VITESSE \ ASD1(ACCES_VITESSE_COURANTE(corps),dy) #define Z_VITESSE \ ASD1(ACCES_VITESSE_COURANTE(corps),dz) #define X_POSITION \ ASD1(ACCES_COORDONNEES_COURANTES(corps),x) #define Y_POSITION \ ASD1(ACCES_COORDONNEES_COURANTES(corps),y) #define Z_POSITION \ ASD1(ACCES_COORDONNEES_COURANTES(corps),z) DEFV(deltaF_3D,deplacement_elementaire_dans_les_champs); INITIALISATION_ACCROISSEMENT_3D(deplacement_elementaire_dans_les_champs ,SOUS(X_PHYSIQUE_A_VISUALISATION(AXPB(X_VITESSE,dct,X_POSITION)) ,X_PHYSIQUE_A_VISUALISATION(X_POSITION) ) ,SOUS(Y_PHYSIQUE_A_VISUALISATION(AXPB(Y_VITESSE,dct,Y_POSITION)) ,Y_PHYSIQUE_A_VISUALISATION(Y_POSITION) ) ,SOUS(Z_PHYSIQUE_A_VISUALISATION(AXPB(Z_VITESSE,dct,Z_POSITION)) ,Z_PHYSIQUE_A_VISUALISATION(Z_POSITION) ) ); /* Deplacement a priori du corps courant au cours d'un pas de temps. On notera que ce */ /* calcul est fait via une difference entre la position future et la position courante */ /* car, en effet, les procedures '?_PHYSIQUE_A_VISUALISATION(...)' ne font pas qu'un simple */ /* changement d'echelle mais aussi (malheureusment...) une translation dans l'espace */ /* physique... */ #undef Z_VITESSE #undef Y_VITESSE #undef X_VITESSE #undef Z_POSITION #undef Y_POSITION #undef X_POSITION Test(IFGT(longF3D(deplacement_elementaire_dans_les_champs),FLOT(INTER_POINT))) Bblock PRINT_ATTENTION("le pas de temps est trop grand et des details des champs seront ignores"); PRINT_ATTENTION("diminuer 'dct=' et augmenter 'nombre='"); CAL1(Prer1("corps..............................=%d\n",corps)); CAL1(Prer1("longueur du deplacement elementaire=%f\n" ,longF3D(deplacement_elementaire_dans_les_champs) ) ); CAL1(Prer1("pas de temps.......................=%f\n" ,dct ) ); CAL1(Prer1("nombre de pas de temps par periode.=%d\n" ,nombre_de_pas_de_temps_par_periode ) ); /* Un exemple de probleme est la situation suivante : */ /* */ /* */ /* +++++++++++++++++++++++++++++++++++++++++++++++ */ /* ++++++++++++++++++++++++++++++++++++++++++++++ */ /* +++++++++++++++++++++++++++++++++++++++++++++ */ /* -----------------------*----------- ++++++++ */ /* . t . /++++++++ */ /* . . /++++++++ */ /* . . /++++++++ */ /* . .++++++++ */ /* . /++.+++++ */ /* . /+++++.++ */ /* . /++++++++. */ /* t-dt * /++++++++ * t+dt */ /* . /++++++++ . */ /* */ /* */ /* il y a reflexion a 't'. La trajectoire prend une direction telle que dans l'intervalle */ /* de temps [t,t+dt] on franchisse une frontiere qui n'est pas vue. Comme les champs sont */ /* definis a l'aide d'image, il convient que pendant l'intervalle de temps [t,t+dt] chaque */ /* particule ne survole pas plus d'un point d'image... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Eblock EKom Eblock ATes Bblock Eblock ETes Komp(corpsI,nombre_de_corps) Bblock Komp(corpsJ,nombre_de_corps) Bblock Test(IFET(IFLT(corpsI,corpsJ) ,IFET(IFLE(ACCES_DATES_DE_NAISSANCE(corpsI),temps_courant) ,IFLE(ACCES_DATES_DE_NAISSANCE(corpsJ),temps_courant) ) ) ) Bblock /* ATTENTION, le 19971222172717, j'ai remplace : */ /* */ /* IFNE(corpsI,corpsJ) */ /* */ /* par : */ /* */ /* IFLT(corpsI,corpsJ) */ /* */ /* car, en effet, sinon, on risque de traiter deux fois chaque couple {corpsI,corpsJ}. Cela */ /* s'est vu avec les collisions... */ DEFV(Float,INIT(distance_I_J_courante ,RpdisF3D(ACCES_COORDONNEES_COURANTES(corpsI) ,ACCES_COORDONNEES_COURANTES(corpsJ) ) ) ); /* Distance courante entre 'I' et 'J'. */ Test(IFET(IFLT(distance_I_J_courante ,seuil_d_interaction ) ,IFLT(distance_I_J_courante ,MUL2(facteur_des_rayon_d_interaction ,ADD2(ACCES_LISTE(liste_initiale_des_RAYON_D_INTERACTION,corpsI) ,ACCES_LISTE(liste_initiale_des_RAYON_D_INTERACTION,corpsJ) ) ) ) ) ) /* ATTENTION, jusqu'au 19971222185613, il y avait ici 'ACCES_COORDONNEES_PRECEDENTES(...)' */ /* au lieu de 'ACCES_COORDONNEES_COURANTES(...)' ce qui a cree des problemes de chaine de */ /* collisions apres une premiere collision entre deux particules. ATTENTION, jusqu'au */ /* 19980224182217, il y avait : */ /* */ /* ,MIN2(MUL2(ACCES_LISTE(liste_initiale_des_FACTEUR_DU_RAYON_D_INTERACTION,corpsI) */ /* ,ACCES_LISTE(liste_initiale_des_RAYON,corpsI) */ /* ) */ /* ,MUL2(ACCES_LISTE(liste_initiale_des_FACTEUR_DU_RAYON_D_INTERACTION,corpsJ) */ /* ,ACCES_LISTE(liste_initiale_des_RAYON,corpsJ) */ /* ) */ /* ) */ /* */ Bblock /* Cas ou les deux corps 'I' et 'J' sont proches l'un de l'autre : */ DEFV(Float,INIT(probabilite_d_interaction,PROBABILITE_UNITE)); DEFV(Float,INIT(seuil_de_la_probabilite_d_interaction,PROBABILITE_NULLE)); /* A priori, l'evenement est certain... */ Test(IL_FAUT(utiliser_un_champ_de_probabilite)) Bblock DEFV(Int ,INIT(X ,gX_PHYSIQUE_A_VISUALISATION(MOYE(ASD1(ACCES_COORDONNEES_COURANTES(corpsI),x) ,ASD1(ACCES_COORDONNEES_COURANTES(corpsJ),x) ) ,FZERO ) ) ); DEFV(Int ,INIT(Y ,gY_PHYSIQUE_A_VISUALISATION(MOYE(ASD1(ACCES_COORDONNEES_COURANTES(corpsI),y) ,ASD1(ACCES_COORDONNEES_COURANTES(corpsJ),y) ) ,FZERO ) ) ); DEFV(Int ,INIT(Z ,gZ_PHYSIQUE_A_VISUALISATION(MOYE(ASD1(ACCES_COORDONNEES_COURANTES(corpsI),z) ,ASD1(ACCES_COORDONNEES_COURANTES(corpsJ),z) ) ,FZERO ) ) ); /* Positionnement dans le champ de probabilite. */ EGAL(probabilite_d_interaction ,______NORMALISE_NIVEAU(FAload_point(champ_de_probabilite ,X,Y,Z ,P_periodiser_X,P_periodiser_Y,P_periodiser_Z ,P_symetriser_X,P_symetriser_Y,P_symetriser_Z ,P_prolonger_X,P_prolonger_Y,P_prolonger_Z ,P_niveau_hors_du_champ_de_probabilite ) ) ); GENERATION_D_UNE_VALEUR(seuil_de_la_probabilite_d_interaction ,PROBABILITE_NULLE ,PROBABILITE_UNITE ); /* Calcul de la probabilite locale d'interaction a "mi-chemin" entre les corps 'I' et 'J'. */ Eblock ATes Bblock Eblock ETes Test(IFGT(probabilite_d_interaction,seuil_de_la_probabilite_d_interaction)) /* Cas ou il y a interaction... */ Bblock Test(IL_FAUT(gerer_les_collisions)) Bblock DEFV(Float,INIT(distance_I_J_avant ,RpdisF3D(ACCES_COORDONNEES_PRECEDENTES(corpsI) ,ACCES_COORDONNEES_PRECEDENTES(corpsJ) ) ) ); /* Distance precedente entre 'I' et 'J'. */ Test(IFLT(distance_I_J_courante,distance_I_J_avant)) /* Ce test permet de decreter qu'il y a collision que lorsque les corps 'I' et 'J' semblent */ /* s'approcher l'un de l'autre. Le test strict 'IFLT(...)' permet de plus d'eviter des */ /* effets nefastes, par exemple, lorsque les conditions initiales imposent que tous les */ /* corps partent du meme point... */ Bblock COLLISION_ENTRE_DEUX_CORPS(corpsI,corpsJ); INCR(ACCES_COMPTEURS_COLLISIONS_COURANTS(corpsI),I); INCR(ACCES_COMPTEURS_COLLISIONS_COURANTS(corpsJ),I); /* Comptage des collisions pour 'corpsI' et 'corpsJ'. */ EDITION_E(BLOC(CAL2(Prin4("periode=%d t=%f collisions corpsI=%d corpsJ=%d\n" ,numero_de_la_periode_courante_de_la_simulation ,temps_courant ,corpsI ,corpsJ ) ); ) ); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Test(IL_FAUT(generer_des_DiffusionLimitedAggregation)) Bblock EGAL(ACCES_BLOCAGES_COURANTS(corpsI),VRAI); INITIALISATION_ACCROISSEMENT_3D(ACCES_VITESSE_COURANTE(corpsI) ,FZERO ,FZERO ,FZERO ); EGAL(ACCES_BLOCAGES_COURANTS(corpsJ),VRAI); INITIALISATION_ACCROISSEMENT_3D(ACCES_VITESSE_COURANTE(corpsJ) ,FZERO ,FZERO ,FZERO ); /* Les deux corps 'I' et 'J' etant proches l'un de l'autre, ils sont bloques. */ EDITION_E(BLOC(CAL2(Prin4("periode=%d t=%f DLA corpsI=%d corpsJ=%d\n" ,numero_de_la_periode_courante_de_la_simulation ,temps_courant ,corpsI ,corpsJ ) ); ) ); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock /* Cas ou il n'y a pas d'interaction... */ Eblock ETes Eblock ATes Bblock /* Cas ou les deux corps 'I' et 'J' sont eloignes l'un de l'autre : rien a faire... */ Eblock ETes Eblock ATes Bblock Eblock ETes Eblock EKom Eblock EKom Komp(corps,nombre_de_corps) Bblock EDITION_E(BLOC(CAL2(Prin3("periode=%d t=%f corps=%d\n" ,numero_de_la_periode_courante_de_la_simulation ,temps_courant ,corps ) ); ) ); EDITION_E(BLOC(CAL2(Prin3(" coordonnees={%+f,%+f,%+f}" ,ASD1(ACCES_COORDONNEES_COURANTES(corps),x) ,ASD1(ACCES_COORDONNEES_COURANTES(corps),y) ,ASD1(ACCES_COORDONNEES_COURANTES(corps),z) ) ); ) ); EDITION_E(BLOC(CAL2(Prin3(" vitesse={%+f,%+f,%+f}" ,ASD1(ACCES_VITESSE_COURANTE(corps),dx) ,ASD1(ACCES_VITESSE_COURANTE(corps),dy) ,ASD1(ACCES_VITESSE_COURANTE(corps),dz) ) ); ) ); EDITION_E(BLOC(CAL2(Prin3(" couleur={%+f,%+f,%+f}" ,ACCES_LISTE(liste_initiale_des_ROUGE,corps) ,ACCES_LISTE(liste_initiale_des_VERTE,corps) ,ACCES_LISTE(liste_initiale_des_BLEUE,corps) ) ); ) ); TRANSFERT_POINT_3D(ACCES_COORDONNEES_PRECEDENTES(corps) ,ACCES_COORDONNEES_COURANTES(corps) ); Test(IFET(EST_FAUX(ACCES_BLOCAGES_COURANTS(corps)) ,IFLE(ACCES_DATES_DE_NAISSANCE(corps),temps_courant) ) ) Bblock /* Cas d'un corps non bloque et qui est vivant.. */ DEFV(Int,INIT(X,UNDEF)); DEFV(Float ,INIT(Xf ,gX_PHYSIQUE_A_VISUALISATION(ASD1(ACCES_COORDONNEES_COURANTES(corps),x),FZERO) ) ); DEFV(Int,INIT(Y,UNDEF)); DEFV(Float ,INIT(Yf ,gY_PHYSIQUE_A_VISUALISATION(ASD1(ACCES_COORDONNEES_COURANTES(corps),y),FZERO) ) ); DEFV(Int,INIT(Z,UNDEF)); DEFV(Float ,INIT(Zf ,gZ_PHYSIQUE_A_VISUALISATION(ASD1(ACCES_COORDONNEES_COURANTES(corps),z),FZERO) ) ); /* Positionnement dans le milieu de propagation ou dans le champ de force. */ DEFV(Int,INIT(X_anticipe,UNDEF)); DEFV(Float ,INIT(Xf_anticipe ,gX_PHYSIQUE_A_VISUALISATION(AXPB(ASD1(ACCES_VITESSE_COURANTE(corps),dx) ,dct ,ASD1(ACCES_COORDONNEES_COURANTES(corps),x) ) ,FZERO ) ) ); DEFV(Int,INIT(Y_anticipe,UNDEF)); DEFV(Float ,INIT(Yf_anticipe ,gY_PHYSIQUE_A_VISUALISATION(AXPB(ASD1(ACCES_VITESSE_COURANTE(corps),dy) ,dct ,ASD1(ACCES_COORDONNEES_COURANTES(corps),y) ) ,FZERO ) ) ); DEFV(Int,INIT(Z_anticipe,UNDEF)); DEFV(Float ,INIT(Zf_anticipe ,gZ_PHYSIQUE_A_VISUALISATION(AXPB(ASD1(ACCES_VITESSE_COURANTE(corps),dz) ,dct ,ASD1(ACCES_COORDONNEES_COURANTES(corps),z) ) ,FZERO ) ) ); /* Anticipation de la position future du point courant afin d'evaluer les fonctions */ /* 'nPRE?(...)' et 'nSUC?(...)'. */ DEFV(Float,INIT(module_de_la_vitesse_incidente,longF3D(ACCES_VITESSE_COURANTE(corps)))); /* Module |V| du vecteur vitesse courant. */ Test(IFOU(IL_NE_FAUT_PAS(utiliser_un_milieu_de_propagation) ,IFET(IL_FAUT(utiliser_un_milieu_de_propagation) ,IL_FAUT(arrondir_par_defaut_les_coordonnees_du_M_gradient) ) ) ) Bblock EGAL(X,INTE(Xf)); EGAL(Y,INTE(Yf)); EGAL(Z,INTE(Zf)); EGAL(X_anticipe,INTE(Xf_anticipe)); EGAL(Y_anticipe,INTE(Yf_anticipe)); EGAL(Z_anticipe,INTE(Zf_anticipe)); /* Passage aux coordonnees "images". */ Eblock ATes Bblock EGAL(X,ARRI(Xf)); EGAL(Y,ARRI(Yf)); EGAL(Z,ARRI(Zf)); EGAL(X_anticipe,ARRI(Xf_anticipe)); EGAL(Y_anticipe,ARRI(Yf_anticipe)); EGAL(Z_anticipe,ARRI(Zf_anticipe)); /* Passage aux coordonnees "images" (le 19971230124439). */ Eblock ETes Test(IFET(IL_FAUT(utiliser_un_milieu_de_propagation),IZNE(module_de_la_vitesse_incidente))) Bblock DEFV(Int,INIT(Xg,X)); DEFV(Int,INIT(Yg,Y)); DEFV(Int,INIT(Zg,Z)); /* Coordonnees du point ou evaluer le gradient : on prend {X,Y,Z} a priori, mais cela */ /* pourra etre modifie si 'IL_FAUT(adapter_les_M_nPAS)' ci-apres en prenant la position */ /* moyenne entre la position courante (a 't') et la position anticipee (a 't+dt'). */ DEFV(genere_Float,INIT(niveau_central_du_pave_du_Mgradient_local_tri_dimensionnel,NIVEAU_UNDEF)); /* Valeur du champ "milieur de propagation" au centre du pave de calcul du gradient local. */ /* Ceci a ete introduit le 19971230143719, ainsi que 'ACCES_NIVEAUX_LOCAUX_COURANTS(...)' */ /* afin de savoir si pour une particule donnee ce niveau central change d'un instant a */ /* l'autre. On decide arbitrairement que s'il n'a pas change, il ne peut y avoir refraction. */ DEFV(deltaI_3D,pave_du_Mgradient_local_tri_dimensionnel); /* Pave a l'interieur duquel evaluer le gradient. */ DEFV(deltaF_3D,Mgradient_local_tri_dimensionnel); /* Gradient local (Gx,Gy,Gz) du milieu de propagation. */ DEFV(Float,INIT(module_du_Mgradient_local_tri_dimensionnel,FLOT__UNDEF)); /* Module |G| du gradient local (Gx,Gy,Gz) du milieu de propagation. */ DEFV(deltaI_3D,delta_anticipe_dans_le_milieu_de_propagation); /* Deplacement a priori exprime en coordonnees image... */ #define delta_X_anticipe \ ASD1(delta_anticipe_dans_le_milieu_de_propagation,dx) #define delta_Y_anticipe \ ASD1(delta_anticipe_dans_le_milieu_de_propagation,dy) #define delta_Z_anticipe \ ASD1(delta_anticipe_dans_le_milieu_de_propagation,dz) INITIALISATION_ACCROISSEMENT_3D(delta_anticipe_dans_le_milieu_de_propagation ,SOUS(X_anticipe,X) ,SOUS(Y_anticipe,Y) ,SOUS(Z_anticipe,Z) ); /* Deplacement anticipe de la particule courante (ne pouvant etre nul). */ Test(IL_FAUT(adapter_les_M_nPAS)) Bblock EGAL(Xg,MOYE(X,X_anticipe)); EGAL(Yg,MOYE(Y,Y_anticipe)); EGAL(Zg,MOYE(Z,Z_anticipe)); /* Coordonnees du point ou evaluer le gradient : on prend la position moyenne entre la */ /* position courante (a 't') et la position anticipee (a 't+dt'). */ INITIALISATION_ACCROISSEMENT_3D(delta_anticipe_dans_le_milieu_de_propagation ,MAX2(pasX,MOIT(ABSO(delta_X_anticipe))) ,MAX2(pasY,MOIT(ABSO(delta_Y_anticipe))) ,MAX2(pasZ,MOIT(ABSO(delta_Z_anticipe))) ); Eblock ATes Bblock Eblock ETes #define ch_M \ milieu_de_propagation #define eM_NpasX \ MUL2(COND(IL_FAUT(adapter_les_M_nPAS) \ ,DIVI(delta_X_anticipe,pasX) \ ,UN \ ) \ ,M_NpasX \ ) #define PreX(x) \ nPREX(x,eM_NpasX) #define SucX(x) \ nSUCX(x,eM_NpasX) #define eM_NpasY \ MUL2(COND(IL_FAUT(adapter_les_M_nPAS) \ ,DIVI(delta_Y_anticipe,pasY) \ ,UN \ ) \ ,M_NpasY \ ) #define PreY(y) \ nPREY(y,eM_NpasY) #define SucY(y) \ nSUCY(y,eM_NpasY) #define eM_NpasZ \ MUL2(COND(IL_FAUT(adapter_les_M_nPAS) \ ,DIVI(delta_Z_anticipe,pasZ) \ ,UN \ ) \ ,M_NpasZ \ ) #define PreZ(z) \ nPREZ(z,eM_NpasZ) #define SucZ(z) \ nSUCZ(z,eM_NpasZ) #define FALOAD_POINT(champ,x,y,z) \ ______NORMALISE_NIVEAU(FAload_point(champ \ ,x,y,z \ ,M_periodiser_X,M_periodiser_Y,M_periodiser_Z \ ,M_symetriser_X,M_symetriser_Y,M_symetriser_Z \ ,M_prolonger_X,M_prolonger_Y,M_prolonger_Z \ ,M_niveau_hors_du_milieu_de_propagation \ ) \ ) /* Pour reduire la longueur des lignes qui suivent... */ Test(IL_FAUT(affiner_le_maillage_de_calcul_du_M_gradient)) Bblock DEFV(Logical,INIT(poursuivre_l_affinage_du_maillage_de_calcul_du_M_gradient,VRAI)); /* Afin d'iterer sur l'affinage... */ DEFV(Float,INIT(FXc,FLOT(X))); DEFV(Float,INIT(FYc,FLOT(Y))); DEFV(Float,INIT(FZc,FLOT(Z))); /* Point (en flottant) a partir duquel on va chercher un gradient non nul, */ DEFV(Int,INIT(Xc,UNDEF)); DEFV(Int,INIT(Yc,UNDEF)); DEFV(Int,INIT(Zc,UNDEF)); /* Puis en entier... */ DEFV(Float,INIT(maximum_des_FpasXYZ,FLOT__UNDEF)); /* Plus grand deplacement en valeur absolu... */ DEFV(Float,INIT(distance_a_parcourir_a_priori_dans_le_milieu_de_propagation,FLOT__UNDEF)); /* Distance a parcouri a priori (c'est-a-dire s'il n'y a ni reflexion, ni refraction...). */ DEFV(Float,INIT(FpasX ,SOUS(X_PHYSIQUE_A_VISUALISATION(AXPB(ASD1(ACCES_VITESSE_COURANTE(corps),dx) ,dct ,ASD1(ACCES_COORDONNEES_COURANTES(corps) ,x ) ) ) ,X_PHYSIQUE_A_VISUALISATION(ASD1(ACCES_COORDONNEES_COURANTES(corps),x)) ) ) ); DEFV(Float,INIT(FpasY ,SOUS(Y_PHYSIQUE_A_VISUALISATION(AXPB(ASD1(ACCES_VITESSE_COURANTE(corps),dy) ,dct ,ASD1(ACCES_COORDONNEES_COURANTES(corps) ,y ) ) ) ,Y_PHYSIQUE_A_VISUALISATION(ASD1(ACCES_COORDONNEES_COURANTES(corps),y)) ) ) ); DEFV(Float,INIT(FpasZ ,SOUS(Z_PHYSIQUE_A_VISUALISATION(AXPB(ASD1(ACCES_VITESSE_COURANTE(corps),dz) ,dct ,ASD1(ACCES_COORDONNEES_COURANTES(corps) ,z ) ) ) ,Z_PHYSIQUE_A_VISUALISATION(ASD1(ACCES_COORDONNEES_COURANTES(corps),z)) ) ) ); /* Pas non entier de deplacement sur les axes dans le sens de la vitesse courante... */ EGAL(maximum_des_FpasXYZ,MAX3(ABSO(FpasX),ABSO(FpasY),ABSO(FpasZ))); EGAL(FpasX,DIVZ(FpasX,maximum_des_FpasXYZ)); EGAL(FpasY,DIVZ(FpasY,maximum_des_FpasXYZ)); EGAL(FpasZ,DIVZ(FpasZ,maximum_des_FpasXYZ)); /* Pas non entier de deplacement sur les axes dans le sens de la vitesse courante... */ EGAL(distance_a_parcourir_a_priori_dans_le_milieu_de_propagation ,longI3D(delta_anticipe_dans_le_milieu_de_propagation) ); /* Distance a parcouri a priori (c'est-a-dire s'il n'y a ni reflexion, ni refraction...). */ Tant(IL_FAUT(poursuivre_l_affinage_du_maillage_de_calcul_du_M_gradient)) Bblock EGAL(Xc,INTE(FXc)); EGAL(Yc,INTE(FYc)); EGAL(Zc,INTE(FZc)); /* Point (en entier) ou le gradient va etre calcule... */ #define PReX(x) \ nPREX(x,M_NpasX) #define SUcX(x) \ nSUCX(x,M_NpasX) #define PReY(y) \ nPREY(y,M_NpasY) #define SUcY(y) \ nSUCY(y,M_NpasY) #define PReZ(z) \ nPREZ(z,M_NpasZ) #define SUcZ(z) \ nSUCZ(z,M_NpasZ) EGAL(niveau_central_du_pave_du_Mgradient_local_tri_dimensionnel ,FALOAD_POINT(ch_M,NEUT(Xc),NEUT(Yc),NEUT(Zc)) ); INITIALISATION_ACCROISSEMENT_3D(pave_du_Mgradient_local_tri_dimensionnel ,LENG(PReX(Xc),SUcX(Xc)) ,LENG(PReY(Yc),SUcY(Yc)) ,LENG(PReZ(Zc),SUcZ(Zc)) ); /* Definition du gradient calcule... */ INITIALISATION_ACCROISSEMENT_3D(Mgradient_local_tri_dimensionnel ,DIVI(SOUS(FALOAD_POINT(ch_M,SUcX(Xc),NEUT(Yc),NEUT(Zc)) ,FALOAD_POINT(ch_M,PReX(Xc),NEUT(Yc),NEUT(Zc)) ) ,_____lNORMALISE_OX(DOUB(nPAS(M_NpasX,pasX))) ) ,DIVI(SOUS(FALOAD_POINT(ch_M,NEUT(Xc),SUcY(Yc),NEUT(Zc)) ,FALOAD_POINT(ch_M,NEUT(Xc),PReY(Yc),NEUT(Zc)) ) ,_____lNORMALISE_OY(DOUB(nPAS(M_NpasY,pasY))) ) ,DIVI(SOUS(FALOAD_POINT(ch_M,NEUT(Xc),NEUT(Yc),SUcZ(Zc)) ,FALOAD_POINT(ch_M,NEUT(Xc),NEUT(Yc),PReZ(Zc)) ) ,_____lNORMALISE_OZ(DOUB(nPAS(M_NpasZ,pasZ))) ) ); /* Calcul des trois composantes du gradient local au point {X,Y,Z} en ce qui concerne le */ /* milieu de propagation. */ #undef SUcZ #undef PReZ #undef SUcY #undef PReY #undef SUcX #undef PReX EGAL(module_du_Mgradient_local_tri_dimensionnel ,longF3D(Mgradient_local_tri_dimensionnel) ); /* Calcul du module |G| du gradient local au point courant (Xc,Yc,Zc). */ Test(IFOU(IZGT(module_du_Mgradient_local_tri_dimensionnel) ,IFGT(RdisF3D(FLOT(X),FLOT(Y),FLOT(Z) ,FXc,FYc,FZc ) ,distance_a_parcourir_a_priori_dans_le_milieu_de_propagation ) ) ) Bblock EGAL(poursuivre_l_affinage_du_maillage_de_calcul_du_M_gradient,FAUX); /* On s'arrete d'affiner soit sur le premier gradient non nul rencontre, soit lorsque l'on */ /* arrive au voisinage du point "anticipe" (en fonction de la vitesse courante et du 'dct'). */ Eblock ATes Bblock INCR(FXc,FpasX); INCR(FYc,FpasY); INCR(FZc,FpasZ); /* Deplacement le long du vecteur vitesse. */ Eblock ETes Eblock ETan EGAL(Xg,Xc); EGAL(Yg,Yc); EGAL(Zg,Zc); /* Coordonnees du point ou a ete evalue le gradient. */ Eblock ATes Bblock EGAL(niveau_central_du_pave_du_Mgradient_local_tri_dimensionnel ,FALOAD_POINT(ch_M,NEUT(Xg),NEUT(Yg),NEUT(Zg)) ); /* Definition du gradient calcule... */ Test(IL_FAUT(calculer_un_M_gradient_tridimensionnel_simplifie)) Bblock INITIALISATION_ACCROISSEMENT_3D(pave_du_Mgradient_local_tri_dimensionnel ,LENG(PreX(Xg),SucX(Xg)) ,LENG(PreY(Yg),SucY(Yg)) ,LENG(PreZ(Zg),SucZ(Zg)) ); INITIALISATION_ACCROISSEMENT_3D(Mgradient_local_tri_dimensionnel ,DIVI(SOUS(FALOAD_POINT(ch_M,SucX(Xg),NEUT(Yg),NEUT(Zg)) ,FALOAD_POINT(ch_M,PreX(Xg),NEUT(Yg),NEUT(Zg)) ) ,_____lNORMALISE_OX(DOUB(nPAS(eM_NpasX,pasX))) ) ,DIVI(SOUS(FALOAD_POINT(ch_M,NEUT(Xg),SucY(Yg),NEUT(Zg)) ,FALOAD_POINT(ch_M,NEUT(Xg),PreY(Yg),NEUT(Zg)) ) ,_____lNORMALISE_OY(DOUB(nPAS(eM_NpasY,pasY))) ) ,DIVI(SOUS(FALOAD_POINT(ch_M,NEUT(Xg),NEUT(Yg),SucZ(Zg)) ,FALOAD_POINT(ch_M,NEUT(Xg),NEUT(Yg),PreZ(Zg)) ) ,_____lNORMALISE_OZ(DOUB(nPAS(eM_NpasZ,pasZ))) ) ); /* Calcul des trois composantes du gradient local au point {X,Y,Z} en ce qui concerne le */ /* milieu de propagation. Ce calcul est fait de trois calculs monodimensionnels. */ Eblock ATes Bblock DEFV(Int,INIT(nombre_de_points_dans_le_pave,ZERO)); /* Nombre de points du volume dans lequel on va rechercher la moyenne des niveaux.. */ DEFV(genere_Float,INIT(niveau_moyen_dans_le_pave,FZERO)); /* Afin de calculer le niveau moyen dans le pave de calcul du gradient (dans [0,1]). */ DEFV(genere_Float,INIT(niveau_minimum_tolerable,FLOT__NIVEAU_UNDEF)); DEFV(genere_Float,INIT(niveau_maximum_tolerable,FLOT__NIVEAU_UNDEF)); /* Segment dans lequel on tolere les niveaux pour le calcul du gradient... */ DEFV(Int,INIT(nombre_de_points_du_Mgradient_local,ZERO)); /* Nombre de points du volume dans lequel on va moyenner des gradients "ponctuels". */ DEFV(Float,INIT(sphere_dans_le_pave_du_Mgradient_local_tri_dimensionnel,FLOT__UNDEF)); /* Afin de connaitre le diametre de la sphere inscrite dans le pave de calcul du gradient. */ DEFV(deltaF_3D,rayon_vecteur_courant); DEFV(Float,INIT(module_du_rayon_vecteur_courant,FLOT__UNDEF)); /* Rayon vecteur du point courant {X,Y,Z} et son module. */ INITIALISATION_ACCROISSEMENT_3D(pave_du_Mgradient_local_tri_dimensionnel ,LENG(PREX(PreX(Xg)),SUCX(SucX(Xg))) ,LENG(PREY(PreY(Yg)),SUCY(SucY(Yg))) ,LENG(PREZ(PreZ(Zg)),SUCZ(SucZ(Zg))) ); EGAL(sphere_dans_le_pave_du_Mgradient_local_tri_dimensionnel ,MOIT(MIN3(ASD1(pave_du_Mgradient_local_tri_dimensionnel,dx) ,ASD1(pave_du_Mgradient_local_tri_dimensionnel,dy) ,ASD1(pave_du_Mgradient_local_tri_dimensionnel,dz) ) ) ); Test(IL_FAUT(M_gradient_tridimensionnel_non_simplifie_filtrer)) Bblock begin_albumQ(DoIn,PreZ(Zg),SucZ(Zg),pasZ ,DoIn,PreY(Yg),SucY(Yg),pasY ,DoIn,PreX(Xg),SucX(Xg),pasX ) Bblock INITIALISATION_ACCROISSEMENT_3D(rayon_vecteur_courant ,FLOT(SOUS(X,Xg)) ,FLOT(SOUS(Y,Yg)) ,FLOT(SOUS(Z,Zg)) ); EGAL(module_du_rayon_vecteur_courant,longF3D(rayon_vecteur_courant)); /* Calcul du rayon vecteur du point courant {X,Y,Z} et de son module. */ Test(IFOU(IL_NE_FAUT_PAS(M_gradient_tridimensionnel_non_simplifie_spherique) ,IFET(IL_FAUT(M_gradient_tridimensionnel_non_simplifie_spherique) ,IFLE(module_du_rayon_vecteur_courant ,sphere_dans_le_pave_du_Mgradient_local_tri_dimensionnel ) ) ) ) Bblock INCR(niveau_moyen_dans_le_pave,FALOAD_POINT(ch_M,X,Y,Z)); /* Cumul des niveaux... */ INCR(nombre_de_points_dans_le_pave,I); /* Comptage des points utilises... */ Eblock ATes Bblock Eblock ETes Eblock end_albumQ(EDoI,EDoI,EDoI) Test(IZGT(nombre_de_points_dans_le_pave)) Bblock EGAL(niveau_moyen_dans_le_pave ,DIVI(niveau_moyen_dans_le_pave,FLOT(nombre_de_points_dans_le_pave)) ); /* Et normalisation du cumul des niveaux... */ Eblock ATes Bblock PRINT_ERREUR("le nombre de niveaux recuperes est nul"); CAL1(Prer1("rayon de la sphere = %+f\n" ,sphere_dans_le_pave_du_Mgradient_local_tri_dimensionnel ) ); Eblock ETes EGAL(niveau_minimum_tolerable ,SOUS(niveau_moyen_dans_le_pave ,M_gradient_tridimensionnel_non_simplifie_tolerance ) ); EGAL(niveau_maximum_tolerable ,ADD2(niveau_moyen_dans_le_pave ,M_gradient_tridimensionnel_non_simplifie_tolerance ) ); /* Definition du segment d'acceptation des niveaux qui participent au calcul du gradient. */ /* */ /* ATTENTION, le 19980914135745, en preparant la sequence : */ /* */ /* xivPdf 11 2 / 029972_030483 */ /* */ /* j'ai pu constater que cela pouvait etre tres ennuyeux, meme sur des images "milieu" ne */ /* contenant que du 'NOIR' et du 'BLANC'. En effet, imaginons qu'il n'y ait, par exemple, */ /* qu'un seul point 'NOIR' ; le niveau moyen est alors tres proche de 'BLANC' et si le */ /* facteur de tolerance est inferieur a 1, le seul point 'NOIR' sera ignore lors du calcul */ /* du gradient, et celui-ci sera donc de module nul... */ Eblock ATes Bblock Eblock ETes INITIALISATION_ACCROISSEMENT_3D(Mgradient_local_tri_dimensionnel ,FZERO ,FZERO ,FZERO ); /* Initialisation du gradient local au point (Xg,Yg,Zg). */ begin_albumQ(DoIn,PreZ(Zg),SucZ(Zg),pasZ ,DoIn,PreY(Yg),SucY(Yg),pasY ,DoIn,PreX(Xg),SucX(Xg),pasX ) /* ATTENTION, le 19971229141908, afin d'eviter les refractions parasites, j'ai essaye de */ /* mettre ici : */ /* */ /* begin_albumQ(DoIn,SUCZ(PreZ(Zg)),PREZ(SucZ(Zg)),pasZ */ /* ,DoIn,SUCY(PreY(Yg)),PREY(SucY(Yg)),pasY */ /* ,DoIn,SUCX(PreX(Xg)),PREX(SucX(Xg)),pasX */ /* ) */ /* */ /* Malheureusement, cela a provoque la perte de nombreuses reflexions. Je reviens donc a */ /* la solution anterieure... */ Bblock /* Balayage d'un volume dont le point (Xg,Yg,Zg) est le centre. */ DEFV(deltaF_3D,Mgradient_3x3x3_tri_dimensionnel); /* Gradient "ponctuel" au point courant. */ DEFV(Float,INIT(ponderation_du_Mgradient_3x3x3,FU)); /* Ponderation des gradients ponctuels lors du cumul du gradient local. */ INITIALISATION_ACCROISSEMENT_3D(rayon_vecteur_courant ,FLOT(SOUS(X,Xg)) ,FLOT(SOUS(Y,Yg)) ,FLOT(SOUS(Z,Zg)) ); EGAL(module_du_rayon_vecteur_courant,longF3D(rayon_vecteur_courant)); /* Calcul du rayon vecteur du point courant {X,Y,Z} et de son module. */ Test(IFOU(IL_NE_FAUT_PAS(M_gradient_tridimensionnel_non_simplifie_spherique) ,IFET(IL_FAUT(M_gradient_tridimensionnel_non_simplifie_spherique) ,IFLE(module_du_rayon_vecteur_courant ,sphere_dans_le_pave_du_Mgradient_local_tri_dimensionnel ) ) ) ) Bblock DEFV(genere_Float,INIT(niveau_sXnYnZ ,FALOAD_POINT(ch_M,SUCX(X),NEUT(Y),NEUT(Z)) ) ); DEFV(genere_Float,INIT(niveau_pXnYnZ ,FALOAD_POINT(ch_M,PREX(X),NEUT(Y),NEUT(Z)) ) ); DEFV(genere_Float,INIT(niveau_nXsYnZ ,FALOAD_POINT(ch_M,NEUT(X),SUCY(Y),NEUT(Z)) ) ); DEFV(genere_Float,INIT(niveau_nXpYnZ ,FALOAD_POINT(ch_M,NEUT(X),PREY(Y),NEUT(Z)) ) ); DEFV(genere_Float,INIT(niveau_nXnYsZ ,FALOAD_POINT(ch_M,NEUT(X),NEUT(Y),SUCZ(Z)) ) ); DEFV(genere_Float,INIT(niveau_nXnYpZ ,FALOAD_POINT(ch_M,NEUT(X),NEUT(Y),PREZ(Z)) ) ); /* Acces aux 6 points utiles au calcul du gradient tres tres local... */ Test(IFOU(IL_NE_FAUT_PAS(M_gradient_tridimensionnel_non_simplifie_filtrer) ,IFET(IL_FAUT(M_gradient_tridimensionnel_non_simplifie_filtrer) ,I3ET(IFET(IFINff(niveau_sXnYnZ ,niveau_minimum_tolerable ,niveau_maximum_tolerable ) ,IFINff(niveau_pXnYnZ ,niveau_minimum_tolerable ,niveau_maximum_tolerable ) ) ,IFET(IFINff(niveau_nXsYnZ ,niveau_minimum_tolerable ,niveau_maximum_tolerable ) ,IFINff(niveau_nXpYnZ ,niveau_minimum_tolerable ,niveau_maximum_tolerable ) ) ,IFET(IFINff(niveau_nXnYsZ ,niveau_minimum_tolerable ,niveau_maximum_tolerable ) ,IFINff(niveau_nXnYpZ ,niveau_minimum_tolerable ,niveau_maximum_tolerable ) ) ) ) ) ) Bblock INITIALISATION_ACCROISSEMENT_3D(Mgradient_3x3x3_tri_dimensionnel ,DIVZ(SOUS(niveau_sXnYnZ,niveau_pXnYnZ) ,_____lNORMALISE_OX(DOUB(pasX)) ) ,DIVZ(SOUS(niveau_nXsYnZ,niveau_nXpYnZ) ,_____lNORMALISE_OY(DOUB(pasY)) ) ,DIVZ(SOUS(niveau_nXnYsZ,niveau_nXnYpZ) ,_____lNORMALISE_OZ(DOUB(pasZ)) ) ); /* Gradient "ponctuel" au point courant {X,Y,Z}. */ Test(IL_FAUT(ponderer_un_M_gradient_tridimensionnel_non_simplifie)) Bblock DEFV(Float,INIT(cosinus_du_rayon_vecteur_courant,FLOT__UNDEF)); /* Cosinus de l'angle entre le rayon vecteur du point courant et le vecteur vitesse. */ Test(IZNE(module_du_rayon_vecteur_courant)) Bblock EGAL(cosinus_du_rayon_vecteur_courant ,DIVI(prdF3D(ACCES_VITESSE_COURANTE(corps) ,rayon_vecteur_courant ) ,MUL2(module_de_la_vitesse_incidente ,module_du_rayon_vecteur_courant ) ) ); /* Cosinus de l'angle entre le rayon vecteur du point courant et le vecteur vitesse. */ EGAL(ponderation_du_Mgradient_3x3x3 ,COS1(cosinus_du_rayon_vecteur_courant) ); /* La ponderation est ainsi dans [0,1] et fonction de la distance angulaire du point courant */ /* {X,Y,Z} a l'axe du vecteur vitesse (via 'cosinus(...)'). Plus cette distance est faible, */ /* et plus la ponderation est proche de 1 ; plus cette distance est elevee, et plus la */ /* ponderation est proche de 0. */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes INITIALISATION_ACCROISSEMENT_3D(Mgradient_local_tri_dimensionnel ,AXPB(ponderation_du_Mgradient_3x3x3 ,ASD1(Mgradient_3x3x3_tri_dimensionnel ,dx ) ,ASD1(Mgradient_local_tri_dimensionnel ,dx ) ) ,AXPB(ponderation_du_Mgradient_3x3x3 ,ASD1(Mgradient_3x3x3_tri_dimensionnel ,dy ) ,ASD1(Mgradient_local_tri_dimensionnel ,dy ) ) ,AXPB(ponderation_du_Mgradient_3x3x3 ,ASD1(Mgradient_3x3x3_tri_dimensionnel ,dz ) ,ASD1(Mgradient_local_tri_dimensionnel ,dz ) ) ); /* Cumul d'obtention du gradient local au point (Xg,Yg,Zg). */ INCR(nombre_de_points_du_Mgradient_local,I); /* Comptage des points utilises... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Eblock end_albumQ(EDoI,EDoI,EDoI) Test(IZGT(nombre_de_points_du_Mgradient_local)) Bblock INITIALISATION_ACCROISSEMENT_3D(Mgradient_local_tri_dimensionnel ,DIVI(ASD1(Mgradient_local_tri_dimensionnel,dx) ,FLOT(nombre_de_points_du_Mgradient_local) ) ,DIVI(ASD1(Mgradient_local_tri_dimensionnel,dy) ,FLOT(nombre_de_points_du_Mgradient_local) ) ,DIVI(ASD1(Mgradient_local_tri_dimensionnel,dz) ,FLOT(nombre_de_points_du_Mgradient_local) ) ); /* Normalisation du cumul de definition du gradient local au point (Xg,Yg,Zg). */ Eblock ATes Bblock PRINT_ERREUR("lors du filtrage, le nombre de niveaux toleres est nul"); CAL1(Prer1("rayon de la sphere = %+f\n" ,sphere_dans_le_pave_du_Mgradient_local_tri_dimensionnel ) ); CAL1(Prer3("niveaux = {moyen=%+f,minimum=%+f,maximum=%+f}\n" ,niveau_moyen_dans_le_pave ,niveau_minimum_tolerable ,niveau_maximum_tolerable ) ); Eblock ETes Eblock ETes Eblock ETes #undef FALOAD_POINT #undef SucZ #undef PreZ #undef eM_NpasZ #undef SucY #undef PreY #undef eM_NpasY #undef SucX #undef PreX #undef eM_NpasX #undef ch_M #undef delta_Z_anticipe #undef delta_Y_anticipe #undef delta_X_anticipe EGAL(module_du_Mgradient_local_tri_dimensionnel ,longF3D(Mgradient_local_tri_dimensionnel) ); /* Calcul du module |G| du gradient local au point {X,Y,Z} du milieu de propagation. */ EDITION_E(BLOC(CAL2(Prin3(" MILIEU gradient={%+f,%+f,%+f}" ,ASD1(Mgradient_local_tri_dimensionnel,dx) ,ASD1(Mgradient_local_tri_dimensionnel,dy) ,ASD1(Mgradient_local_tri_dimensionnel,dz) ) ); ) ); EDITION_E(BLOC(CAL2(Prin1(" module(gradient)=%+f" ,module_du_Mgradient_local_tri_dimensionnel ) ); ) ); EDITION_E(BLOC(CAL2(Prin3(" au point={%d,%d,%d}" ,Xg ,Yg ,Zg ) ); ) ); EDITION_E(BLOC(CAL2(Prin3(" dans un pave={%d,%d,%d}" ,ASD1(pave_du_Mgradient_local_tri_dimensionnel,dx) ,ASD1(pave_du_Mgradient_local_tri_dimensionnel,dy) ,ASD1(pave_du_Mgradient_local_tri_dimensionnel,dz) ) ); ) ); /* On notera que grace a cette edition, il est possible de generer une visualisation */ /* tridimensionnelle du milieu de propagation. En effet soit 'MILIEU(n)' la suite des */ /* images definissant ce milieu. On fera alors : */ /* */ /* $xci/dilate.01$X A=MILIEU(n) dilater=FAUX $formatI | \ */ /* $xci/eor$X A1=MILIEU(n) R=CONTOUR(n) $formatI */ /* */ /* ce qui donne le 'CONTOUR' du 'MILIEU' de propagation. Puis : */ /* */ /* $xci/liste_points$X A=CONTOUR(n) eX=VRAI eY=FAUX eNIVEAU=FAUX epoints=FAUX | \ */ /* $SE -e "s/^.*=//" \ */ /* > F1(n)$COORD_X */ /* $xci/liste_points$X A=CONTOUR(n) eX=FAUX eY=VRAI eNIVEAU=FAUX epoints=FAUX | \ */ /* $SE -e "s/^.*=//" \ */ /* > F1(n)$COORD_Y */ /* */ /* ce qui donne les 'NC' coordonnees {X,Y} de 'CONTOUR(n)'. Puis on extrait 1 coordonnee */ /* sur 'N' par : */ /* */ /* $xrv/un_sur_N.01$X ATTENTION=FAUX ne=NC fichier=F1(n)$COORD_X paquets=N | \ */ /* $SE -e "s/^.*=//" \ */ /* > F2(n)$COORD_X */ /* $xrv/un_sur_N.01$X ATTENTION=FAUX ne=NC fichier=F1(n)$COORD_Y paquets=N | \ */ /* $SE -e "s/^.*=//" \ */ /* > F2(n)$COORD_Y */ /* */ /* ce qui donne un echantillonnage regulier de 'NE' coordonnees {X,Y} de 'CONTOUR(n)'. Soit */ /* alors 'Z(n)' la coordonnee 'Z' associee a la couche 'MILIEU(n)'. Il suffit de generer : */ /* */ /* $xci/valeurs_inte$X premiere=1 derniere=NE vD=Z(n) vA=Z(n) \ */ /* > F2(n)$COORD_Z */ /* */ /* On dispose alors de trois series de fichiers {F2(n)$COORD_X,F2(n)$COORD_Y,F2(n)$COORD_Z} */ /* qui definissent de facon tridimensionnelle la frontiere du milieu de propagation. On peut */ /* alors la visualiser a l'aide de : */ /* */ /* $xrv/particule.10$X */ /* */ /* mais on peut aussi injecter {F2(n)$COORD_X,F2(n)$COORD_Y,F2(n)$COORD_Z} comme conditions */ /* initiales dans : */ /* */ /* $xrk/rdn_walk.41$X */ /* */ /* et editer ici le gradient (en ne faisant qu'une seule image, visualisant donc les */ /* conditions initiales) que l'on visualisera a son tour grace a : */ /* */ /* $xrv/particule.10$X */ /* */ /* en le materialisant, par exemple, avec le RAYON des particules... */ Test(IZGT(module_du_Mgradient_local_tri_dimensionnel)) Bblock DEFV(Float,INIT(module_de_la_vitesse_apres_reflexion_ou_refraction,FLOT__UNDEF)); /* Module |V| du vecteur vitesse apres reflexion ou refraction. */ DEFV(deltaF_3D,vecteur_directeur_OX2); DEFV(deltaF_3D,vecteur_directeur_OY2); DEFV(Float,INIT(module_du_vecteur_directeur_OY2,FLOT__UNDEF)); DEFV(deltaF_3D,vecteur_directeur_OZ2); /* Vecteurs unitaires des axes {OX2,OY2,OZ2}. */ DEFV(matrixF_3D,matrice_de_rotation_directe); DEFV(matrixF_3D,matrice_de_rotation_inverse); /* Definition de la matrice de passage {OX1,OY1,OZ1} --> {OX2,OY2,OZ2} et inverse. */ DEFV(deltaF_3D,vecteur_vitesse_incident); /* Vecteur vitesse incident exprime dans le referentiel {OX2,OY2,OZ2}. */ DEFV(deltaF_3D,vecteur_vitesse_reflechi_ou_refracte); DEFV(Float,INIT(Rho_du_vecteur_vitesse_incident,FLOT__UNDEF)); DEFV(Float,INIT(Theta_du_vecteur_vitesse_incident,FLOT__UNDEF)); /* Vecteur vitesse reflechi ou refracte exprime dans le referentiel {OX2,OY2,OZ2} et */ /* son {rho,theta} exprime dans le plan {OX2,OZ2}. */ DEFV(Float,INIT(cosinus_du_theta_incident_VG,FLOT__UNDEF)); DEFV(Float,INIT(sinus_du_theta_incident_VG,FLOT__UNDEF)); DEFV(Float,INIT(theta_incident_VG,FLOT__UNDEF)); /* Angle theta entre le vecteur vitesse incident et le gradient du milieu de propagation. */ DEFV(Float,INIT(theta_apres_reflexion_ou_refraction,FLOT__UNDEF)); /* Angle theta entre le vecteur vitesse reflechi et le gradient du milieu de propagation. */ DEFV(Float,INIT(rapport_de_l_indice_refracte_a_l_indice_incident,FU)); /* Lorsqu'il y a refraction, le module de la vitesse 'V' est divise par le rapport des */ /* indices de refraction N(refracte)/N(incident) qui est superieur a 1. Lorsqu'il y a */ /* reflexion, le module de 'V' ne change pas, d'ou cette initialisation a 1... */ TRANSFERT_ACCROISSEMENT_3D(vecteur_directeur_OX2,Mgradient_local_tri_dimensionnel); NORMALISATION_ACCROISSEMENT_3D(vecteur_directeur_OX2); PRODUIT_VECTORIEL_ACCROISSEMENT_3D(vecteur_directeur_OY2 ,ACCES_VITESSE_COURANTE(corps) ,Mgradient_local_tri_dimensionnel ); /* ATTENTION, on utilise 'ACCES_VITESSE_COURANTE(corps)' et non pas 'vecteur_directeur_OZ2' */ /* de meme que 'Mgradient_local_tri_dimensionnel' et non pas 'vecteur_directeur_OX2' car, */ /* effet, on a besoin de 'module_du_vecteur_directeur_OY2' valant le module exact du produit */ /* vectoriel de 'V' et de 'G'... */ EGAL(module_du_vecteur_directeur_OY2 ,longF3D(vecteur_directeur_OY2) ); Test(IZGT(module_du_vecteur_directeur_OY2)) Bblock /* Cas ou l'axe 'OY2' a pu etre defini... */ NORMALISATION_ACCROISSEMENT_3D(vecteur_directeur_OY2); PRODUIT_VECTORIEL_ACCROISSEMENT_3D(vecteur_directeur_OZ2 ,vecteur_directeur_OX2 ,vecteur_directeur_OY2 ); NORMALISATION_ACCROISSEMENT_3D(vecteur_directeur_OZ2); /* Definition du nouveau referentiel {OX2,OY2,OZ2} ou 'OX2' est dirige par le Gradient : */ /* */ /* --> --> */ /* I = G */ /* */ /* --> --> --> */ /* J = V /\ I */ /* */ /* --> --> --> */ /* K = I /\ J */ /* */ /* les trois vecteurs {I,J,K} etant evidemment normalises. On notera au passage que les */ /* vecteurs vitesses (incident et reflechi ou refracte) sont donc contenus dans le plan */ /* {OX2,OZ2} ce qui sera exploite par la suite lors d'un passage en coordonnees polaires */ /* et inversement... */ /* */ /* On appelera respectivement "Normale" et "Tangentielle" les composantes de la vitesse */ /* le long des axes 'OX2' et 'OZ2'. */ INITIALISATION_MATRICE_3D(matrice_de_rotation_directe ,ASD1(vecteur_directeur_OX2,dx) ,ASD1(vecteur_directeur_OX2,dy) ,ASD1(vecteur_directeur_OX2,dz) ,ASD1(vecteur_directeur_OY2,dx) ,ASD1(vecteur_directeur_OY2,dy) ,ASD1(vecteur_directeur_OY2,dz) ,ASD1(vecteur_directeur_OZ2,dx) ,ASD1(vecteur_directeur_OZ2,dy) ,ASD1(vecteur_directeur_OZ2,dz) ); INITIALISATION_MATRICE_3D(matrice_de_rotation_inverse ,ASD1(vecteur_directeur_OX2,dx) ,ASD1(vecteur_directeur_OY2,dx) ,ASD1(vecteur_directeur_OZ2,dx) ,ASD1(vecteur_directeur_OX2,dy) ,ASD1(vecteur_directeur_OY2,dy) ,ASD1(vecteur_directeur_OZ2,dy) ,ASD1(vecteur_directeur_OX2,dz) ,ASD1(vecteur_directeur_OY2,dz) ,ASD1(vecteur_directeur_OZ2,dz) ); /* Calcul de la matrice de rotation permettant de passer du referentiel {OX1,OY1,OZ1} au */ /* referentiel {OX2,OY2,OZ2} et de son inverse. */ PRODUIT_MATRICE_ACCROISSEMENT_3D(vecteur_vitesse_incident ,matrice_de_rotation_directe ,ACCES_VITESSE_COURANTE(corps) ); /* Calcul de la vitesse incidente dans le referentiel {OX2,OY2,OZ2}. */ EGAL(cosinus_du_theta_incident_VG ,DIVI(prdF3D(ACCES_VITESSE_COURANTE(corps),Mgradient_local_tri_dimensionnel) ,MUL2(module_de_la_vitesse_incidente ,module_du_Mgradient_local_tri_dimensionnel ) ) ); EGAL(sinus_du_theta_incident_VG ,DIVI(module_du_vecteur_directeur_OY2 ,MUL2(module_de_la_vitesse_incidente ,module_du_Mgradient_local_tri_dimensionnel ) ) ); EGAL(theta_incident_VG ,ATAN(sinus_du_theta_incident_VG ,cosinus_du_theta_incident_VG ) ); /* Angle theta entre le vecteur vitesse incident et le gradient du milieu de propagation. */ EGAL(theta_apres_reflexion_ou_refraction,theta_incident_VG); EGAL(rapport_de_l_indice_refracte_a_l_indice_incident,FU); /* On fait comme si il devait n'y avoir ni reflexion, ni refraction... */ Test(IFINff(theta_incident_VG ,angle_inferieur_du_cone_de_reflexion ,angle_superieur_du_cone_de_reflexion ) ) /* Dans ce cas le vecteur vitesse incident et le vecteur gradient ne vont pas dans la */ /* meme direction ; on decrete alors qu'il y a reflexion totale et donc l'index de */ /* refraction N(incident)/N(refracte) est superieur a 1. Il y a donc reflexion lorsque */ /* l'on passe d'un milieu de fort indice ('BLANC' par exemple) a un milieu de faible */ /* indice ('NOIR' par exemple). */ Bblock Test(IFET(EST_VRAI(il_peut_y_avoir_reflexion) ,TOUJOURS_VRAI ) ) Bblock /* Le 'TOUJOURS_VRAI' est la uniquement pour assurer la symetrie de ce 'Test(...)' avec */ /* celui relatif a 'il_peut_y_avoir_refraction' qui va suivre... */ EGAL(theta_apres_reflexion_ou_refraction,SOUS(PI,theta_incident_VG)); /* Angle theta entre le vecteur vitesse reflechi et le gradient du milieu de propagation. */ /* ATTENTION, on notera que les lois de l'optique donnent : */ /* */ /* G ^ */ /* * | --* */ /* * +theta | -theta * | */ /* * | * */ /* * | * */ /* * | * */ /* * | * */ /* --------------------O------------------> */ /* | */ /* | */ /* | */ /* */ /* soit : */ /* */ /* theta(reflechi) = -theta(incident), */ /* */ /* or ici, la definition de 'theta' est differente. On considere : */ /* */ /* G ^ */ /* * | --* */ /* * |pi-theta * | */ /* * |-------* */ /* * |\ * */ /* * | \ * */ /* N(incident) * | *\ ('BLANC' par exemple) */ /* --------------------O---\--------------> */ /* N(refracte) | . \ ('NOIR' par exemple) */ /* | . \theta */ /* | .\ */ /* | . */ /* | . */ /* | . V */ /* */ /* soit : */ /* */ /* theta(reflechi) = pi-theta(incident), */ /* */ EGAL(rapport_de_l_indice_refracte_a_l_indice_incident,FU); /* Le module de 'V' ne change pas lorsqu'il y a reflexion. Cette mise a 1 a deja eu lieu */ /* lors de la definition de 'rapport_de_l_indice_refracte_a_l_indice_incident', mais on */ /* le refait ici par symetrie avec le cas de la refraction qui va suivre... */ EGAL(ACCES_REFLEXIONS_COURANTS(corps),VRAI); /* Et ce afin d'eviter que, par exemple, juste apres une reflexion, on considere lors du */ /* calcul du gradient qu'il y a refraction ; ceci est tout a fait possible puisqu'apres */ /* une reflexion la situation est inversee et que l'on risque donc de trouver un gradient */ /* inverse de celui qui a cause la reflexion et qui donc implique une refraction... */ INCR(ACCES_COMPTEURS_REFLEXIONS_COURANTS(corps),I); /* Comptage des reflexions pour 'corps'. */ EDITION_E(BLOC(CAL2(Prin2(" REFLEXION thetaI=%+f thetaR=%+f" ,theta_incident_VG ,theta_apres_reflexion_ou_refraction ) ); ) ); Eblock ATes Bblock Eblock ETes EGAL(ACCES_REFRACTIONS_COURANTS(corps),FAUX); /* Et ce afin d'eviter que, par exemple, juste apres une reflexion, on considere lors du */ /* calcul du gradient qu'il y a refraction ; ceci est tout a fait possible puisqu'apres */ /* une reflexion la situation est inversee et que l'on risque donc de trouver un gradient */ /* inverse de celui qui a cause la reflexion et qui donc implique une refraction... */ Eblock ATes /* Dans ce cas le vecteur vitesse incident et le vecteur gradient vont dans la meme */ /* direction ; on decrete qu'il y a refraction et donc l'index de refraction */ /* N(incident)/N(refracte) est inferieur a 1. Il y a donc refraction lorsque */ /* l'on passe d'un milieu de faible indice ('NOIR' par exemple) a un milieu de fort */ /* indice ('BLANC' par exemple). */ Bblock Test(I3ET(EST_VRAI(il_peut_y_avoir_refraction) ,EST_FAUX(ACCES_REFLEXIONS_COURANTS(corps)) ,IFNE(ACCES_NIVEAUX_LOCAUX_COURANTS(corps) ,niveau_central_du_pave_du_Mgradient_local_tri_dimensionnel ) ) ) /* Lorsqu'il n'y a pas variation du niveau central de calcul du gradient, on decide */ /* arbitrairement qu'il ne peut y avoir de refraction. Cette methode introduite le */ /* 19971230143719 permet de lutter contre des refractions parasites que l'on decretait */ /* jusqu'a presente "en regardant" derriere les particules ; des inhomogeneites dans le */ /* milieu de propagation provoquait ce probleme. Par exemple : */ /* */ /* soit le milieu de propagation suivant (ou '000' et '255' representent respectivement */ /* le 'NOIR' et le 'BLANC') : */ /* */ /* 255 255 255 255 000 000 000 000 000 000 */ /* */ /* 255 255 255 255 000 000 000 000 000 000 */ /* */ /* 255 255 255 255 000 000 000 000 000 000 */ /* ------------------- */ /* 255 255 255|255 255 255 255 255|255 255 */ /* |+++ */ /* 255 255 255|255 255 255 255 255|255 255 */ /* | */ /* 255 255 255|255 255 255 255 255|255 255 */ /* | === */ /* 255 255 255|255 255 255 255 255|255 255 */ /* | */ /* 255 255 255|255 255 255 255 255|255 255 */ /* ------------------- */ /* 255 255 255 255 255 255 255 255 255 255 */ /* */ /* La particule est au point souligne par '===' a l'instant 't' et au point souligne par */ /* '+++' a l'instant 't+dt'. Dans les conditions de la sequence : */ /* */ /* xivPdf 11 1 / 028254_028765 */ /* */ /* il s'agit du corps '26' a la periode '41'. Le gradient du milieu de propagation y est */ /* alors calcule dans un pave 5x5x5 (materialise par un cadre carre ci-dessus). A */ /* l'instant 't' il ne voit donc pas les points de niveau '000' ; le gradient est alors */ /* d'ailleurs nul et le ne se passe rien. A l'instant 't+dt', il voit les points de niveau */ /* '000', mais malheureusement majoritairement derriere la particule (son vecteur vitesse */ /* va du point '===' au point '+++') ; par definition, cela correspond a de la refraction. */ /* Il est evident que celle-ci est evidemment parasite... */ Bblock EGAL(rapport_de_l_indice_refracte_a_l_indice_incident ,COND(IFGE(module_du_Mgradient_local_tri_dimensionnel,FU) ,NEUT(module_du_Mgradient_local_tri_dimensionnel) ,INVE(module_du_Mgradient_local_tri_dimensionnel) ) ); EGAL(theta_apres_reflexion_ou_refraction ,ASIX(DIVI(SINX(theta_incident_VG) ,rapport_de_l_indice_refracte_a_l_indice_incident ) ) ); /* Modification de l'angle 'theta' suivant les lois de l'optique : */ /* */ /* sinus(incident) N(refracte) */ /* ----------------- = ------------- > 1 */ /* sinus(refracte) N(incident) */ /* */ /* (Loi de Snell). */ /* */ /* L'indice de refraction utilise est soit le module du gradient, soit son inverse, en */ /* choisissant celui qui est superieur a 1. Les lois de l'optique donnent : */ /* */ /* On notera qu'un passage "brutal" du '$NOIR' au '$BLANC', avec les parametres par defaut, */ /* correspond a un rapport 'rapport_de_l_indice_refracte_a_l_indice_incident' de : */ /* */ /* N(refracte) */ /* ------------- = 63.875000 */ /* N(incident) */ /* */ /* ce qui est enorme... */ Test(IFINff(theta_incident_VG,NEGA(PI_SUR_2),NEUT(PI_SUR_2))) Bblock /* Lorsque 'theta' est dans [-pi/2,+pi/2], le resultat de 'ASIX(...)' qui est donne dans */ /* [-pi/2,+pi/2] est alors conserve... */ Eblock ATes Bblock EGAL(theta_apres_reflexion_ou_refraction ,SOUS(PI,theta_apres_reflexion_ou_refraction) ); /* Lorsque 'theta' n'est pas dans [-pi/2,+pi/2], le resultat de 'ASIX(...)' qui est donne */ /* [-pi/2,+pi/2] est corrige, sachant que : */ /* */ /* arcsinus(theta) = arcsinus(pi-theta). */ /* */ Eblock ETes EGAL(ACCES_REFRACTIONS_COURANTS(corps),VRAI); /* Et ce afin d'eviter que, par exemple, juste apres une reflexion, on considere lors du */ /* calcul du gradient qu'il y a refraction ; ceci est tout a fait possible puisqu'apres */ /* une reflexion la situation est inversee et que l'on risque donc de trouver un gradient */ /* inverse de celui qui a cause la reflexion et qui donc implique une refraction... */ INCR(ACCES_COMPTEURS_REFRACTIONS_COURANTS(corps),I); /* Comptage des refractions pour 'corps'. */ EDITION_E(BLOC(CAL2(Prin3(" REFRACTION thetaI=%+f thetaR=%+f indice(R/I)=%+f" ,theta_incident_VG ,theta_apres_reflexion_ou_refraction ,rapport_de_l_indice_refracte_a_l_indice_incident ) ); ) ); Test(IL_NE_FAUT_PAS(moduler_la_vitesse_lors_d_une_refraction)) Bblock EGAL(rapport_de_l_indice_refracte_a_l_indice_incident,FU); /* On annule ainsi le calcul de 'rapport_de_l_indice_refracte_a_l_indice_incident' dont la */ /* valeur a ete utile, et ce afin de ne pas modifier la vitesse de la particule, ce qui */ /* dans le cas de rapports trop grands provoque des pseudo-immobilisations... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes EGAL(ACCES_REFLEXIONS_COURANTS(corps),FAUX); /* Et ce afin d'eviter que, par exemple, juste apres une reflexion, on considere lors du */ /* calcul du gradient qu'il y a refraction ; ceci est tout a fait possible puisqu'apres */ /* une reflexion la situation est inversee et que l'on risque donc de trouver un gradient */ /* inverse de celui qui a cause la reflexion et qui donc implique une refraction... */ Eblock ETes Test(IFNE_a_peu_pres_absolu(ASD1(vecteur_vitesse_incident,dy),FZERO,GRAND_EPSILON)) Bblock PRINT_ERREUR("le vecteur vitesse n'est pas dans le plan [OX2,OZ2]"); CAL1(Prer3("gradient local = {%+f,%+f,%+f}\n" ,ASD1(Mgradient_local_tri_dimensionnel,dx) ,ASD1(Mgradient_local_tri_dimensionnel,dy) ,ASD1(Mgradient_local_tri_dimensionnel,dz) ) ); CAL1(Prer3("vecteur dans [OX1,OY1,OZ1] = {%+f,%+f,%+f}\n" ,ASD1(ACCES_VITESSE_COURANTE(corps),dx) ,ASD1(ACCES_VITESSE_COURANTE(corps),dy) ,ASD1(ACCES_VITESSE_COURANTE(corps),dz) ) ); CAL1(Prer3("matrice directe =\n {%+f,%+f,%+f}\n" ,ASD2(matrice_de_rotation_directe,cx,cx) ,ASD2(matrice_de_rotation_directe,cx,cy) ,ASD2(matrice_de_rotation_directe,cx,cz) ) ); CAL1(Prer3("{%+f,%+f,%+f}\n" ,ASD2(matrice_de_rotation_directe,cy,cx) ,ASD2(matrice_de_rotation_directe,cy,cy) ,ASD2(matrice_de_rotation_directe,cy,cz) ) ); CAL1(Prer3("{%+f,%+f,%+f}\n" ,ASD2(matrice_de_rotation_directe,cz,cx) ,ASD2(matrice_de_rotation_directe,cz,cy) ,ASD2(matrice_de_rotation_directe,cz,cz) ) ); CAL1(Prer3("vecteur dans [OX2,OY2,OZ2] = {%+f,%+f,%+f}\n" ,ASD1(vecteur_vitesse_incident,dx) ,ASD1(vecteur_vitesse_incident,dy) ,ASD1(vecteur_vitesse_incident,dz) ) ); CAL1(Prer3("matrice inverse =\n {%+f,%+f,%+f}\n" ,ASD2(matrice_de_rotation_inverse,cx,cx) ,ASD2(matrice_de_rotation_inverse,cx,cy) ,ASD2(matrice_de_rotation_inverse,cx,cz) ) ); CAL1(Prer3("{%+f,%+f,%+f}\n" ,ASD2(matrice_de_rotation_inverse,cy,cx) ,ASD2(matrice_de_rotation_inverse,cy,cy) ,ASD2(matrice_de_rotation_inverse,cy,cz) ) ); CAL1(Prer3("{%+f,%+f,%+f}\n" ,ASD2(matrice_de_rotation_inverse,cz,cx) ,ASD2(matrice_de_rotation_inverse,cz,cy) ,ASD2(matrice_de_rotation_inverse,cz,cz) ) ); Eblock ATes Bblock Eblock ETes EGAL(Rho_du_vecteur_vitesse_incident ,Rho_2D(ASD1(vecteur_vitesse_incident,dx) ,ASD1(vecteur_vitesse_incident,dz) ) ); EGAL(Theta_du_vecteur_vitesse_incident ,Theta_2D(ASD1(vecteur_vitesse_incident,dx) ,ASD1(vecteur_vitesse_incident,dz) ) ); /* Le vecteur vitesse incident, de meme que le vecteur vitesse reflechi ou refracte, sont */ /* dans le plan {OX2,OZ2} par definition. On peut donc y passer en coordonnees polaires. */ EGAL(Rho_du_vecteur_vitesse_incident ,DIVI(Rho_du_vecteur_vitesse_incident ,rapport_de_l_indice_refracte_a_l_indice_incident ) ); /* Prise en compte de l'eventuel modification du module de la vitesse 'V' (dans le cas de */ /* la refraction). */ INITIALISATION_ACCROISSEMENT_3D (vecteur_vitesse_reflechi_ou_refracte ,Xcartesienne_2D(Rho_du_vecteur_vitesse_incident ,ADD2(Theta_du_vecteur_vitesse_incident ,SOUS(theta_apres_reflexion_ou_refraction ,theta_incident_VG ) ) ) ,ASD1(vecteur_vitesse_incident,dy) ,Ycartesienne_2D(Rho_du_vecteur_vitesse_incident ,ADD2(Theta_du_vecteur_vitesse_incident ,SOUS(theta_apres_reflexion_ou_refraction ,theta_incident_VG ) ) ) ); /* Reflexion ou refraction du vecteur vitesse incident dans le referentiel {OX2,OY2,OZ2}. */ INITIALISATION_ACCROISSEMENT_3D(vecteur_vitesse_reflechi_ou_refracte ,AXPB(MUL2(facteur_vitesse_OX2_refraction_reflexion ,ACCES_FACTEUR_VITESSE_OX2(corps) ) ,ASD1(vecteur_vitesse_reflechi_ou_refracte,dx) ,ADD2(translation_vitesse_OX2_refraction_reflexion ,ACCES_TRANSLATION_VITESSE_OX2(corps) ) ) ,NEUT(ASD1(vecteur_vitesse_reflechi_ou_refracte,dy)) ,AXPB(MUL2(facteur_vitesse_OZ2_refraction_reflexion ,ACCES_FACTEUR_VITESSE_OZ2(corps) ) ,ASD1(vecteur_vitesse_reflechi_ou_refracte,dz) ,ADD2(translation_vitesse_OZ2_refraction_reflexion ,ACCES_TRANSLATION_VITESSE_OZ2(corps) ) ) ); /* Simulation eventuelle d'echange d'energie avec le milieu en agissant sur les composantes */ /* "Normale" ('OX2') et "Tangentielle" ('OZ2') du vecteur vitesse. */ PRODUIT_MATRICE_ACCROISSEMENT_3D(ACCES_VITESSE_COURANTE(corps) ,matrice_de_rotation_inverse ,vecteur_vitesse_reflechi_ou_refracte ); /* La vitesse du corps courant est donc changee en fonction, localement, de la reflexion */ /* ou de la refraction due au milieu de propagation... */ /* */ /* On notera que j'ai tente la chose suivante : */ /* */ /* --> --> */ /* --> V /\ G */ /* U = -------------- */ /* --> --> */ /* | V /\ G | */ /* */ /* donne, une fois normalise, un vecteur unitaire orthogonal au plan forme par le vecteur */ /* vitesse 'V' et le gradient local 'G' du milieu de propagation. Appelons 'R' le vecteur */ /* vitesse Reflechi ou Refracte. On a evidemment : */ /* */ /* --> --> --> --> --> */ /* R /\ G = | R |.| G |.sin(theta). U */ /* */ /* ou theta est l'angle entre 'R' et 'G' qui est donne par les lois de l'optique (Reflexion */ /* ou Refraction). De la, on peut tirer le vecteur 'R' : */ /* */ /* --> --> --> --> -1 --> */ /* R = [ | R |.| G |.sin(theta). U ] /\ G */ /* */ /* a l'aide de l'anti-produit vectoriel ('v $ximd/operator.1$FON APvect'). Malheureusement, */ /* j'ai du y renoncer le 19971204091928 car il y a indetermination dans le calcul de */ /* l'anti-produit vectoriel comme cela est explique dans 'v $ximd/operator.1$FON APvect'. */ EGAL(module_de_la_vitesse_apres_reflexion_ou_refraction ,longF3D(ACCES_VITESSE_COURANTE(corps)) ); Test(IFET(IZNE(module_de_la_vitesse_apres_reflexion_ou_refraction) ,IFLE(module_de_la_vitesse_apres_reflexion_ou_refraction,pEPSILON) ) ) Bblock PRINT_ERREUR("un vecteur vitesse est trop petit, sans etre nul"); CAL1(Prer1("il s'agit du corps %d\n" ,corps ) ); CAL1(Prer3("vitesse = {%+f,%+f,%+f}\n" ,ASD1(ACCES_VITESSE_COURANTE(corps),dx) ,ASD1(ACCES_VITESSE_COURANTE(corps),dy) ,ASD1(ACCES_VITESSE_COURANTE(corps),dz) ) ); INITIALISATION_ACCROISSEMENT_3D(ACCES_VITESSE_COURANTE(corps) ,FZERO ,FZERO ,FZERO ); /* Lorsque le module de la vitesse est trop petit, cela signifie qu'en general il y a eu */ /* trop de refraction (avec un indice trop grand). La vitesse a donc tendance a diminuer */ /* tres vite. Pour eviter des problemes ulterieurs avec les nombres flottants ("underflow"s) */ /* on annule la vitesse... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock /* Cas ou l'axe 'OY2' n'a pu etre defini ; cela signifie que le gradient 'G' et la vitesse */ /* 'V' sont colineaires. On ne peut donc pas definir de referentiel ; on fait donc comme */ /* si le milieu etait parfaitement reflechissant par rapport a un plan orthogonal a 'G'. */ INITIALISATION_ACCROISSEMENT_3D(ACCES_VITESSE_COURANTE(corps) ,NEGA(ASD1(ACCES_VITESSE_COURANTE(corps),dx)) ,NEGA(ASD1(ACCES_VITESSE_COURANTE(corps),dy)) ,NEGA(ASD1(ACCES_VITESSE_COURANTE(corps),dz)) ); /* On repart donc dans la direction inverse de la direction incidente... */ EDITION_E(BLOC(CAL2(Prin0(" REFLEXION_ABSOLUE")); ) ); Eblock ETes Eblock ATes Bblock Test(IFET(IFGT(temps_courant,instant_initial) ,IFNE(niveau_central_du_pave_du_Mgradient_local_tri_dimensionnel ,ACCES_NIVEAUX_LOCAUX_COURANTS(corps) ) ) ) Bblock Test(IL_FAUT(editer_les_messages_d_erreur_du_calcul_du_gradient)) /* Test introduit le 20150208081016... */ Bblock PRINT_ERREUR("le Gradient est nul"); CAL1(Prer3("au point........ = {%d,%d,%d}\n",Xg,Yg,Zg)); CAL1(Prer1("alors que le niveau du milieu pour le corps %d a change\n",corps)); CAL1(Prer1("niveau anterieur = %f\n",ACCES_NIVEAUX_LOCAUX_COURANTS(corps))); CAL1(Prer1("niveau courant.. = %f\n" ,niveau_central_du_pave_du_Mgradient_local_tri_dimensionnel ) ); CAL1(Prer3("vitesse......... = {%+f,%+f,%+f}\n" ,ASD1(ACCES_VITESSE_COURANTE(corps),dx) ,ASD1(ACCES_VITESSE_COURANTE(corps),dy) ,ASD1(ACCES_VITESSE_COURANTE(corps),dz) ) ); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes EGAL(ACCES_REFLEXIONS_COURANTS(corps),FAUX); EGAL(ACCES_REFRACTIONS_COURANTS(corps),FAUX); /* Et ce afin d'eviter que, par exemple, juste apres une reflexion, on considere lors du */ /* calcul du gradient qu'il y a refraction ; ceci est tout a fait possible puisqu'apres */ /* une reflexion la situation est inversee et que l'on risque donc de trouver un gradient */ /* inverse de celui qui a cause la reflexion et qui donc implique une refraction... */ EDITION_E(BLOC(CAL2(Prin0(" RIEN")); ) ); Eblock ETes EGAL(ACCES_NIVEAUX_LOCAUX_COURANTS(corps) ,niveau_central_du_pave_du_Mgradient_local_tri_dimensionnel ); /* Pour tester a l'instant suivant s'il y a variation du niveau central de calcul du */ /* gradient. Lorsqu'il ne change pas, on decide arbitrairement qu'il ne peut y avoir de */ /* refraction... */ Eblock ATes Bblock Eblock ETes Test(IZEQ(ACCES_STABILITES_COURANTES(corps))) Bblock DEFV(Int,INIT(decompteur_de_recherche_d_une_bonne_perturbation ,COND(IL_FAUT(limiter_automatiquement_tentatives_recherche_bonne_perturbation) ,EXP2(MUL3(NBRE(ACCES_LISTE(liste_initiale_des_MINIMUM_DELTA_RHO,corps) ,ACCES_LISTE(liste_initiale_des_MAXIMUM_DELTA_RHO,corps) ) ,NBRE(ACCES_LISTE(liste_initiale_des_MINIMUM_N_PHI,corps) ,ACCES_LISTE(liste_initiale_des_MAXIMUM_N_PHI,corps) ) ,NBRE(ACCES_LISTE(liste_initiale_des_MINIMUM_N_THETA,corps) ,ACCES_LISTE(liste_initiale_des_MAXIMUM_N_THETA,corps) ) ) ) ,nombre_maximal_de_tentatives_de_recherche_d_une_bonne_perturbation ) ) ); DEFV(Logical,INIT(chercher_une_bonne_perturbation,VRAI)); /* Afin de boucler tant que l'on n'a pas trouve une perturbation qui ne nous eloigne */ /* pas trop du centre de l'espace. La valeur du decompteur est relativement arbitraire */ /* et est destinee a eviter des bouclages sans fin... */ DEFV(Float,INIT(rho ,Rho_3D(ASD1(ACCES_VITESSE_COURANTE(corps),dx) ,ASD1(ACCES_VITESSE_COURANTE(corps),dy) ,ASD1(ACCES_VITESSE_COURANTE(corps),dz) ) ) ); DEFV(Float,INIT(phi ,Phi_3D(ASD1(ACCES_VITESSE_COURANTE(corps),dx) ,ASD1(ACCES_VITESSE_COURANTE(corps),dy) ,ASD1(ACCES_VITESSE_COURANTE(corps),dz) ) ) ); DEFV(Float,INIT(theta ,Theta_3D(ASD1(ACCES_VITESSE_COURANTE(corps),dx) ,ASD1(ACCES_VITESSE_COURANTE(corps),dy) ,ASD1(ACCES_VITESSE_COURANTE(corps),dz) ) ) ); /* Passage des coordonnees cartesiennes aux coordonnees spheriques pour le vecteur vitesse */ /* du corps courant. */ DEFV(deltaF_3D,vitesse_perturbee); /* Vitesse perturbee (et eventuellement provisoire) du corps courant en coordonnees */ /* cartesiennes. */ Test(IZLE(decompteur_de_recherche_d_une_bonne_perturbation)) Bblock EGAL(decompteur_de_recherche_d_une_bonne_perturbation ,COND(IZGT(nombre_maximal_de_tentatives_de_recherche_d_une_bonne_perturbation) ,nombre_maximal_de_tentatives_de_recherche_d_une_bonne_perturbation ,NOMBRE_MAXIMAL_DE_TENTATIVES_DE_RECHERCHE_D_UNE_BONNE_PERTURBATION ) ); Eblock ATes Bblock Eblock ETes Tant(IL_FAUT(chercher_une_bonne_perturbation)) Bblock DEFV(Float,INIT(distance_courante_a_l_origine,FLOT__UNDEF)); DEFV(Float,INIT(distance_precedente_a_l_origine,FLOT__UNDEF)); /* Afin de savoir si l'on s'eloigne de l'origine... */ DEFV(Float,INIT(rho_perturbe,FLOT__UNDEF)); DEFV(Float,INIT(phi_perturbe,FLOT__UNDEF)); DEFV(Float,INIT(theta_perturbe,FLOT__UNDEF)); /* Vitesse perturbee (et eventuellement provisoire) du corps courant en coordonnees */ /* spheriques. */ DEFV(Float,INIT(variation_de_rho,FLOT__UNDEF)); DEFV(Float,INIT(variation_de_phi,FLOT__UNDEF)); DEFV(Float,INIT(variation_de_theta,FLOT__UNDEF)); GENERATION_D_UNE_VALEUR(variation_de_rho ,ACCES_LISTE(liste_initiale_des_MINIMUM_DELTA_RHO,corps) ,ACCES_LISTE(liste_initiale_des_MAXIMUM_DELTA_RHO,corps) ); GENERATION_D_UNE_VALEUR(variation_de_phi ,ACCES_LISTE(liste_initiale_des_MINIMUM_N_PHI,corps) ,ACCES_LISTE(liste_initiale_des_MAXIMUM_N_PHI,corps) ); GENERATION_D_UNE_VALEUR(variation_de_theta ,ACCES_LISTE(liste_initiale_des_MINIMUM_N_THETA,corps) ,ACCES_LISTE(liste_initiale_des_MAXIMUM_N_THETA,corps) ); EGAL(variation_de_phi ,MUL2(ARRO(variation_de_phi),ACCES_LISTE(liste_initiale_des_DELTA_PHI,corps)) ); EGAL(variation_de_theta ,MUL2(ARRO(variation_de_theta),ACCES_LISTE(liste_initiale_des_DELTA_THETA,corps)) ); /* Variations aleatoires des coordonnees spheriques du vecteur vitesse du corps courant. */ EGAL(rho_perturbe,ADD2(rho,variation_de_rho)); EGAL(phi_perturbe,ADD2(phi,variation_de_phi)); EGAL(theta_perturbe,ADD2(theta,variation_de_theta)); /* Vitesse perturbee (et eventuellement provisoire) du corps courant (en coordonnees */ /* spheriques). */ INITIALISATION_ACCROISSEMENT_3D(vitesse_perturbee ,Xcartesienne_3D(rho_perturbe,phi_perturbe,theta_perturbe) ,Ycartesienne_3D(rho_perturbe,phi_perturbe,theta_perturbe) ,Zcartesienne_3D(rho_perturbe,phi_perturbe,theta_perturbe) ); /* Vitesse perturbee (et eventuellement provisoire) du corps courant (en coordonnees */ /* cartesiennes). */ INITIALISATION_POINT_3D(ACCES_COORDONNEES_COURANTES(corps) ,AXPB(ASD1(vitesse_perturbee,dx) ,dct ,ASD1(ACCES_COORDONNEES_PRECEDENTES(corps),x) ) ,AXPB(ASD1(vitesse_perturbee,dy) ,dct ,ASD1(ACCES_COORDONNEES_PRECEDENTES(corps),y) ) ,AXPB(ASD1(vitesse_perturbee,dz) ,dct ,ASD1(ACCES_COORDONNEES_PRECEDENTES(corps),z) ) ); /* Nouvelle position provisoire et perturbee du corps courant... */ Test(IL_FAUT(utiliser_un_champ_de_force)) Bblock /* Cas ou l'on utilise un champ de force : on va examiner son gradient, puis on utilisera */ /* ensuite la distance a l'origine via 'liste_initiale_des_DISTANCE_MAXIMALE'. */ DEFV(deltaF_3D,Fgradient_local_tri_dimensionnel); /* Gradient local (Gx,Gy,Gz). */ DEFV(Float,INIT(module_du_Fgradient_local_tri_dimensionnel,FLOT__UNDEF)); /* Module |G| du gradient local (Gx,Gy,Gz). */ DEFV(Float,INIT(module_de_la_vitesse_perturbee,FLOT__UNDEF)); /* Module |V| de la vitesse perturbee. */ DEFV(Float,INIT(cosinus_vitesse_gradient,FLOT__UNDEF)); DEFV(Float,INIT(angle_vitesse_gradient,FLOT__UNDEF)); DEFV(Float,INIT(borne_inferieure_de_l_ouverture,FLOT__UNDEF)); DEFV(Float,INIT(borne_superieure_de_l_ouverture,FLOT__UNDEF)); /* Angle entre la vitesse perturbee et le gradient local et ses bornes inferieure et */ /* superieure courantes. */ #define champ_F \ champ_de_force #define eF_NpasX \ MUL2(COND(IL_FAUT(adapter_les_F_nPAS),DIVI(MAX2(pasX,SOUA(X_anticipe,X)),pasX),UN),F_NpasX) #define PreX(x) \ nPREX(x,eF_NpasX) #define SucX(x) \ nSUCX(x,eF_NpasX) #define eF_NpasY \ MUL2(COND(IL_FAUT(adapter_les_F_nPAS),DIVI(MAX2(pasY,SOUA(Y_anticipe,Y)),pasY),UN),F_NpasY) #define PreY(y) \ nPREY(y,eF_NpasY) #define SucY(y) \ nSUCY(y,eF_NpasY) #define eF_NpasZ \ MUL2(COND(IL_FAUT(adapter_les_F_nPAS),DIVI(MAX2(pasZ,SOUA(Z_anticipe,Z)),pasZ),UN),F_NpasZ) #define PreZ(z) \ nPREZ(z,eF_NpasZ) #define SucZ(z) \ nSUCZ(z,eF_NpasZ) #define FALOAD_POINT(champ,x,y,z) \ ______NORMALISE_NIVEAU(FAload_point(champ \ ,x,y,z \ ,F_periodiser_X,F_periodiser_Y,F_periodiser_Z \ ,F_symetriser_X,F_symetriser_Y,F_symetriser_Z \ ,F_prolonger_X,F_prolonger_Y,F_prolonger_Z \ ,F_niveau_hors_du_champ_de_force \ ) \ ) /* Pour reduire la longueur des lignes qui suivent... */ INITIALISATION_ACCROISSEMENT_3D(Fgradient_local_tri_dimensionnel ,DIVI(SOUS(FALOAD_POINT(champ_F,SucX(X),NEUT(Y),NEUT(Z)) ,FALOAD_POINT(champ_F,PreX(X),NEUT(Y),NEUT(Z)) ) ,_____lNORMALISE_OX(DOUB(nPAS(F_NpasX,pasX))) ) ,DIVI(SOUS(FALOAD_POINT(champ_F,NEUT(X),SucY(Y),NEUT(Z)) ,FALOAD_POINT(champ_F,NEUT(X),PreY(Y),NEUT(Z)) ) ,_____lNORMALISE_OY(DOUB(nPAS(F_NpasY,pasY))) ) ,DIVI(SOUS(FALOAD_POINT(champ_F,NEUT(X),NEUT(Y),SucZ(Z)) ,FALOAD_POINT(champ_F,NEUT(X),NEUT(Y),PreZ(Z)) ) ,_____lNORMALISE_OZ(DOUB(nPAS(F_NpasZ,pasZ))) ) ); /* Calcul des trois composantes du gradient local au point {X,Y,Z}. ATTENTION, on notera */ /* que le gradient est recalcule systematiquement pour toutes les tentatives relatives au */ /* point courant ; cela n'est pas tres optimise, mais cela est fait expres afin que les */ /* variables necessaires soient locales au test sur 'utiliser_un_champ_de_force'. */ #undef FALOAD_POINT #undef SucZ #undef PreZ #undef eF_NpasZ #undef SucY #undef PreY #undef eF_NpasY #undef SucX #undef PreX #undef eF_NpasX #undef champ_F EDITION_E(BLOC(CAL2(Prin3(" POTENTIEL gradient={%+f,%+f,%+f}" ,ASD1(Fgradient_local_tri_dimensionnel,dx) ,ASD1(Fgradient_local_tri_dimensionnel,dy) ,ASD1(Fgradient_local_tri_dimensionnel,dz) ) ); ) ); EGAL(module_du_Fgradient_local_tri_dimensionnel ,longF3D(Fgradient_local_tri_dimensionnel) ); /* Calcul du module |G| du gradient local au point {X,Y,Z}. */ EGAL(module_de_la_vitesse_perturbee ,longF3D(vitesse_perturbee) ); /* Calcul du module |V| de la vitesse perturbee. */ EGAL(borne_inferieure_de_l_ouverture ,ACCES_LISTE(liste_initiale_des_BORNE_INFERIEURE_DE_L_OUVERTURE,corps) ); EGAL(borne_superieure_de_l_ouverture ,ACCES_LISTE(liste_initiale_des_BORNE_SUPERIEURE_DE_L_OUVERTURE,corps) ); /* Definition des bornes inferieure et superieure de l'angle entre la vitesse perturbee et */ /* le gradient local. */ Test(IFGT(borne_inferieure_de_l_ouverture,borne_superieure_de_l_ouverture)) Bblock PRINT_ERREUR("le segment d'une ouverture est mal defini"); CAL1(Prer1("corps........... = %d\n",corps)); CAL1(Prer1("borne inferieure = %+f\n",borne_inferieure_de_l_ouverture)); CAL1(Prer1("borne superieure = %+f\n",borne_superieure_de_l_ouverture)); Eblock ATes Bblock Eblock ETes Test(IFET(IZNE(module_de_la_vitesse_perturbee) ,IZNE(module_du_Fgradient_local_tri_dimensionnel) ) ) Bblock EGAL(cosinus_vitesse_gradient ,DIVI(prdF3D(vitesse_perturbee,Fgradient_local_tri_dimensionnel) ,MUL2(module_de_la_vitesse_perturbee ,module_du_Fgradient_local_tri_dimensionnel ) ) ); /* Calcul du cosinus de l'angle entre la vitesse perturbee et le gradient local, */ EGAL(angle_vitesse_gradient,ACOX(cosinus_vitesse_gradient)); /* Puis de cet angle... */ Eblock ATes Bblock EGAL(angle_vitesse_gradient ,MOYE(borne_inferieure_de_l_ouverture,borne_superieure_de_l_ouverture) ); /* Dans le cas ou l'un des deux modules au moins est nul, on force une valeur appartenant */ /* au segment de validite. */ Eblock ETes Test(IFINff(angle_vitesse_gradient ,borne_inferieure_de_l_ouverture ,borne_superieure_de_l_ouverture ) ) Bblock Test(IL_FAUT(prendre_la_premiere_direction_trouvee)) Bblock EGAL(chercher_une_bonne_perturbation,FAUX); /* Et cela n'est plus necessaire d'iterer lorsque le cosinus de l'angle est dans le bon */ /* segment... */ Eblock ATes Bblock DEFV(Float,INIT(plus_petit_selecteur_de_l_angle_vitesse_gradient,F_INFINI)); Repe(nombre_d_iterations_si_on_ne_prend_pas_la_premiere_direction_trouvee) Bblock DEFV(Float,INIT(selecteur_de_l_angle_vitesse_gradient,FLOT__UNDEF)); GENERATION_D_UNE_VALEUR(selecteur_de_l_angle_vitesse_gradient ,borne_inferieure_de_l_ouverture ,borne_superieure_de_l_ouverture ); EGAL(plus_petit_selecteur_de_l_angle_vitesse_gradient ,MIN2(selecteur_de_l_angle_vitesse_gradient ,plus_petit_selecteur_de_l_angle_vitesse_gradient ) ); /* "Selecteur" de l'angle entre le vecteur vitesse perturbee et le gradient qui est le plus */ /* petit de tout ceux que l'on genere ici. */ Eblock ERep Test(IFLT(angle_vitesse_gradient ,plus_petit_selecteur_de_l_angle_vitesse_gradient ) ) Bblock EGAL(chercher_une_bonne_perturbation,FAUX); /* Et cela n'est plus necessaire d'iterer lorsque l'angle entre le vecteur vitesse perturbee */ /* et le gradient est inferieur au "selecteur". Il est ainsi evident que si l'angle entre */ /* la vitesse et le gradient est petit (c'est-a-dire proche de la borne inferieure de */ /* l'ouverture), il y a de forte chance pour que le "selecteur" lui soit plus grand. Ainsi */ /* cette methode privilegie les petites valeurs de l'angle, c'est-a-dire finalement les */ /* directions qui collent le mieux avec le gradient, sans pour cela exclure les autres */ /* (lorsque l'on prend une ouverture proche de pi...). Ce dispositif a ete introduit le */ /* 1995112200 afin de lutter contre un phenomene visible dans la sequence : */ /* */ /* xivPdf 9 1 / 002725_003236 */ /* */ /* En effet, dans cette sequence on voit nettement se dessiner une croix orientee a pi/4. */ /* Celle-ci vient de l'ouverture [0,pi/2] qui a ete choisie pour la generer ; alors on peut */ /* verifier facilement que les axes {0,pi/2,pi,3.pi/2} sont repulsifs (puisque dessus on a */ /* 2 chances sur 3 de tourner (a droite ou a gauche) et seulement 1 chance sur 3 d'aller */ /* tout droit et donc de rester dessus. En ce qui concerne les bissectrices du referentiel */ /* (directions a pi/4), elles sont attractives, puisque sur elles 1 fois sur 2 on tourne a */ /* gauche et une fois sur 2 on tourne a droite ; ainsi, on reste sur elles en oscillant. */ /* Tout vient donc de l'ouverture [0,pi/2] qui interdit tout retour en arriere. C'est donc */ /* ce que permet 'prendre_la_premiere_direction_trouvee' a 'FAUX' associe a une grande */ /* ouverture de [0,pi]. C'est ainsi que la sequence : */ /* */ /* xivPdf 9 1 / 004788_005299 */ /* */ /* a ete generee... */ Eblock ATes Bblock Eblock ETes Eblock ETes Eblock ATes Bblock Eblock ETes Eblock ATes Bblock /* Cas ou l'on n'utilise pas de champ de force : on va utiliser uniquement la distance */ /* a l'origine via 'liste_initiale_des_DISTANCE_MAXIMALE'. */ Eblock ETes EGAL(distance_precedente_a_l_origine ,RdisF3D(ASD1(ACCES_COORDONNEES_PRECEDENTES(corps),x) ,ASD1(ACCES_COORDONNEES_PRECEDENTES(corps),y) ,ASD1(ACCES_COORDONNEES_PRECEDENTES(corps),z) ,Xcentre_ESPACE ,Ycentre_ESPACE ,Zcentre_ESPACE ) ); EGAL(distance_courante_a_l_origine ,RdisF3D(ASD1(ACCES_COORDONNEES_COURANTES(corps),x) ,ASD1(ACCES_COORDONNEES_COURANTES(corps),y) ,ASD1(ACCES_COORDONNEES_COURANTES(corps),z) ,Xcentre_ESPACE ,Ycentre_ESPACE ,Zcentre_ESPACE ) ); /* Afin de savoir si l'on s'eloigne de l'origine... */ Test(IL_FAUT(utiliser_un_champ_de_force)) Bblock Test(IFET(IFGT(distance_courante_a_l_origine ,ACCES_LISTE(liste_initiale_des_DISTANCE_MAXIMALE,corps) ) ,IL_NE_FAUT_PAS(chercher_une_bonne_perturbation) ) ) Bblock EGAL(chercher_une_bonne_perturbation,VRAI); /* Lorsque l'on s'eloigne trop de l'origine, alors qu'il avait ete decide de s'arreter de */ /* chercher une bonne perturbation, on reprend la recherche... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Test(I3OU(IFLE(distance_courante_a_l_origine ,ACCES_LISTE(liste_initiale_des_DISTANCE_MAXIMALE,corps) ) ,IFLE(distance_courante_a_l_origine ,distance_precedente_a_l_origine ) ,IL_FAUT(chercher_une_bonne_perturbation) ) ) Bblock EGAL(chercher_une_bonne_perturbation,FAUX); /* Et cela n'est plus necessaire d'iterer lorsque, soit on n'est pas sorti du "volume" */ /* dans lequel on peut se deplacer, soit on se rapproche de l'origine... */ Eblock ATes Bblock Eblock ETes Eblock ETes Test(IZLE(decompteur_de_recherche_d_une_bonne_perturbation)) Bblock Test(IL_NE_FAUT_PAS(utiliser_un_champ_de_force)) Bblock PRINT_ATTENTION("apparemment, nous sommes en train de boucler"); CAL1(Prer3("position precedente = (%+f,%+f,%+f)\n" ,ASD1(ACCES_COORDONNEES_PRECEDENTES(corps),x) ,ASD1(ACCES_COORDONNEES_PRECEDENTES(corps),y) ,ASD1(ACCES_COORDONNEES_PRECEDENTES(corps),z) ) ); CAL1(Prer1("distance precedente = %+f\n",distance_precedente_a_l_origine)); CAL1(Prer3("position courante = (%+f,%+f,%+f)\n" ,ASD1(ACCES_COORDONNEES_COURANTES(corps),x) ,ASD1(ACCES_COORDONNEES_COURANTES(corps),y) ,ASD1(ACCES_COORDONNEES_COURANTES(corps),z) ) ); CAL1(Prer1("distance courante = %+f\n",distance_courante_a_l_origine)); Eblock ATes Bblock /* Dans le cas ou l'on utilise un champ de force, le bouclage peut arriver "volontairement", */ /* car en effet, si l'on a trouve une vitesse perturbee "compatible" avec le gradient local, */ /* mais qui par malheur nous eloigne, on reprend la recherche. Or malheureusement, suivant */ /* le champ utilise, on peut etre dans des circonstances ou seul l'eloignement de l'origine */ /* est compatible avec ce gradient... */ Eblock ETes EGAL(chercher_une_bonne_perturbation,FAUX); /* Pour eviter de boucler... */ Eblock ATes Bblock DECR(decompteur_de_recherche_d_une_bonne_perturbation,I); /* Pour eviter de boucler... */ Eblock ETes Eblock ETan TRANSFERT_ACCROISSEMENT_3D(ACCES_VITESSE_COURANTE(corps) ,vitesse_perturbee ); EGAL(ACCES_STABILITES_COURANTES(corps),INTE(ACCES_LISTE(liste_initiale_des_STABILITE,corps))); /* Et reinitialisation de la stabilite... */ Eblock ATes Bblock /* Ici, la 'ACCES_VITESSE_COURANTE(...)' ne change pas... */ INITIALISATION_POINT_3D(ACCES_COORDONNEES_COURANTES(corps) ,AXPB(ASD1(ACCES_VITESSE_COURANTE(corps),dx) ,dct ,ASD1(ACCES_COORDONNEES_PRECEDENTES(corps),x) ) ,AXPB(ASD1(ACCES_VITESSE_COURANTE(corps),dy) ,dct ,ASD1(ACCES_COORDONNEES_PRECEDENTES(corps),y) ) ,AXPB(ASD1(ACCES_VITESSE_COURANTE(corps),dz) ,dct ,ASD1(ACCES_COORDONNEES_PRECEDENTES(corps),z) ) ); /* Nouvelle position non perturbee du corps courant... */ DECR(ACCES_STABILITES_COURANTES(corps),I); /* Et decrementation de la stabilite... */ Eblock ETes Eblock ATes Bblock /* Il ne faut pas perturber un corps bloque ou qui n'est pas encore vivant... */ Eblock ETes Test(IFLT(numero_de_la_periode_courante_de_la_simulation,nombre_de_periodes_de_la_simulation)) Bblock TRANSFERT_POINT_3D(ACCES_COORDONNEES_CUMULEES(corps ,SUCC(numero_de_la_periode_courante_de_la_simulation) ) ,ACCES_COORDONNEES_PRECEDENTES(corps) ); Eblock ATes Bblock Eblock ETes Eblock EKom INCREMENTATION_DE_L_HORLOGE(dct); /* Simulation du temps de la simulation... */ Eblock ERep #include xrk/attractor.1A.I" VISUALISATION_DES_AXES_DE_COORDONNEES; /* Visualisation si necessaire des trois axes de coordonnees. */ GENERATION_D_UNE_IMAGE_ET_PASSAGE_A_LA_SUIVANTE(BLOC(VIDE;)); /* Generation de l'image courante... */ Eblock EKom EDEFV(album,champ_de_probabilite); /* Definition de l'album d'images dans lequel ranger le champ de probabilite... */ EDEFV(album,milieu_de_propagation); /* Definition de l'album d'images dans lequel ranger le milieu de propagation... */ EDEFV(album,champ_de_force); /* Definition de l'album d'images dans lequel ranger le champ de force... */ Eblock end_nouveau_block FdTb2(liste_des_coordonnees_cumule_sur_toute_la_duree ,nombre_de_corps ,nombre_de_periodes_de_la_simulation ,pointF_3D ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_compteurs_de_refractions_a_l_instant_courant ,nombre_de_corps ,Positive ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_compteurs_de_reflexions_a_l_instant_courant ,nombre_de_corps ,Positive ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_compteurs_de_collisions_a_l_instant_courant ,nombre_de_corps ,Positive ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_niveaux_locaux_a_l_instant_courant ,nombre_de_corps ,genere_Float ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_refractions_a_l_instant_courant ,nombre_de_corps ,Logical ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_reflexions_a_l_instant_courant ,nombre_de_corps ,Logical ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_blocages_a_l_instant_courant ,nombre_de_corps ,Logical ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_stabilites_a_l_instant_courant ,nombre_de_corps ,Int ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_vitesses_a_l_instant_courant ,nombre_de_corps ,deltaF_3D ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_coordonnees_a_l_instant_courant ,nombre_de_corps ,pointF_3D ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_coordonnees_a_l_instant_precedent ,nombre_de_corps ,pointF_3D ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_vitesses_a_l_instant_initial ,nombre_de_corps ,deltaF_3D ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_coordonnees_a_l_instant_initial ,nombre_de_corps ,pointF_3D ,ADRESSE_NON_ENCORE_DEFINIE ); FdTb1(liste_des_dates_de_naissance ,nombre_de_corps ,Float ,ADRESSE_NON_ENCORE_DEFINIE ); /* Liberation des espaces alloues... */ /* */ /* Les 'ADRESSE_NON_ENCORE_DEFINIE's ont ete introduits le 20050221172036... */ EDITION_DES_EXTREMA_DES_COORDONNEES_ET_DES_DERIVEES; /* Edition facultative des extrema des coordonnees et des derivees. */ RETU_Commande; Eblock ECommande