/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D E F I N I T I O N S   R E L A T I V E S   A U   M I L I E U   D E   P R O P A G A T I O N  :                             */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xrk/rdn_walk.52$I' :                                                                                           */
/*                                                                                                                                   */
/*                    Jean-Francois COLONNA (LACTAMME, 1998??????????).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        G E S T I O N   D E   L A   P R O P A G A T I O N  :                                                                       */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
                    Bblock
                    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,FLOT__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));
                         DEFV(Float,INIT(Rho_du_Mgradient_local_tri_dimensionnel,FZERO));
                                        /* Module |G| du gradient local (Gx,Gy,Gz) du milieu de propagation. On notera que ce        */
                                        /* module est calcule par 'longF3D(...)' ou par 'Rho_3D(...)', suivant les cas, d'ou les     */
                                        /* deux noms differents...                                                                   */
                         DEFV(Float,INIT(Phi_du_Mgradient_local_tri_dimensionnel,FZERO));
                         DEFV(Float,INIT(Theta_du_Mgradient_local_tri_dimensionnel,FZERO));
                                        /* Angles {Phi,Theta} 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

                                        /* ATTENTION, les trois :                                                                    */
                                        /*                                                                                           */
                                        /*        TRON(DIVI(delta_?_anticipe,pas?),MINIMUM_ANTICIPATION_?,MAXIMUM_ANTICIPATION_?)    */
                                        /*                                                                                           */
                                        /* qui suivent sont absents de 'v $xrk/rdn_walk.41$K eM_Npas' et ont du etre ajoutes le      */
                                        /* 19981023095100 dans 'v $xrk/rdn_walk.51$K eM_Npas' car, en effet, a cause de la           */
                                        /* gravitation generalisee, les vitesses peuvent augmenter dans des proportions importantes  */
                                        /* et augmenter ainsi de facon inconsideree le volume des parallelepipedes dans lesquels     */
                                        /* le gradient est calcule.                                                                  */

                                        /* ATTENTION, le 19991224132633, 'delta_?_anticipe' a ete remplace dans 'eM_Npas?' par       */
                                        /* le maximum entre 'delta_?_anticipe' et le rayon (mis dans l'espace de visualisation)      */
                                        /* du 'sorps' courant. L'avantage de cette methode est que le gradient va etre calcule       */
                                        /* si 'IL_FAUT(adapter_les_M_nPAS)' dans une boite qui contient la particule (consideree     */
                                        /* comme non ponctuelle donc) ce qui va permettre de la "confronter" au milieu avec son      */
                                        /* encombrement reel. Ainsi, des "grosses" particules ne risquent plus de donner             */
                                        /* l'impression de penetrer dans le milieu comme cela peut se voir dans la sequence :        */
                                        /*                                                                                           */
                                        /*                  xivPdf 9 2 / 025247_025758                                               */
                                        /*                                                                                           */
                                        /* en particulier sur la derniere image ('025758')...                                        */

                                        /* ATTENTION, le 20000328135804, les valeurs 'MAXIMUM_ANTICIPATION_?' ont ete remplacees     */
                                        /* par 'INFINI' si 'IL_FAUT(prendre_en_compte_M_l_encombrement_des_particules)'...           */

#define   MINIMUM_ANTICIPATION_X                                                                                                        \
                    UN
#define   MAXIMUM_ANTICIPATION_X                                                                                                        \
                    QUATRE
#define   M_NpasX                                                                                                                       \
                    INTE(fM_NpasX)
#define   eM_NpasX                                                                                                                      \
                    INTE(MUL2(COND(IL_FAUT(adapter_les_M_nPAS)                                                                          \
                                  ,TRON(DIVI(COND(IL_FAUT(prendre_en_compte_M_l_encombrement_des_particules)                            \
                                                 ,MAX2(delta_X_anticipe                                                                 \
                                                      ,lX_PHYSIQUE_A_VISUALISATION                                                      \
                                                           (ACCES_LISTE(liste_initiale_des_RAYON_D_INTERACTION,corps))                  \
                                                       )                                                                                \
                                                 ,delta_X_anticipe                                                                      \
                                                  )                                                                                     \
                                            ,pasX                                                                                       \
                                             )                                                                                          \
                                       ,MINIMUM_ANTICIPATION_X                                                                          \
                                       ,COND(IL_FAUT(prendre_en_compte_M_l_encombrement_des_particules),INFINI,MAXIMUM_ANTICIPATION_X)  \
                                        )                                                                                               \
                                  ,MINIMUM_ANTICIPATION_X                                                                               \
                                   )                                                                                                    \
                             ,fM_NpasX                                                                                                  \
                              )                                                                                                         \
                         )                                                                                                              \
                                        /* ATTENTION, jusqu'au 20011015093459, par erreur, c'etait 'liste_initiale_des_RAYON' qui    */ \
                                        /* etait utilise ici a la place de 'liste_initiale_des_RAYON_D_INTERACTION'. Cela a eu des   */ \
                                        /* consequences sur pratiquement toutes les sequences generees avant cette date (voir a ce   */ \
                                        /* propos 'v _____xivPdf_14_1/$Fnota 011777_012288'), puisqu'en regle generale ces deux      */ \
                                        /* parametres different (legerement...).                                                     */
#define   PreX(x)                                                                                                                       \
                    nPREX(x,eM_NpasX)
#define   SucX(x)                                                                                                                       \
                    nSUCX(x,eM_NpasX)

#define   MINIMUM_ANTICIPATION_Y                                                                                                        \
                    UN
#define   MAXIMUM_ANTICIPATION_Y                                                                                                        \
                    QUATRE
#define   M_NpasY                                                                                                                       \
                    INTE(fM_NpasY)
#define   eM_NpasY                                                                                                                      \
                    INTE(MUL2(COND(IL_FAUT(adapter_les_M_nPAS)                                                                          \
                                  ,TRON(DIVI(COND(IL_FAUT(prendre_en_compte_M_l_encombrement_des_particules)                            \
                                                 ,MAX2(delta_Y_anticipe                                                                 \
                                                      ,lY_PHYSIQUE_A_VISUALISATION                                                      \
                                                           (ACCES_LISTE(liste_initiale_des_RAYON_D_INTERACTION,corps))                  \
                                                       )                                                                                \
                                                 ,delta_Y_anticipe                                                                      \
                                                  )                                                                                     \
                                            ,pasY                                                                                       \
                                             )                                                                                          \
                                       ,MINIMUM_ANTICIPATION_Y                                                                          \
                                       ,COND(IL_FAUT(prendre_en_compte_M_l_encombrement_des_particules),INFINI,MAXIMUM_ANTICIPATION_Y)  \
                                        )                                                                                               \
                                  ,MINIMUM_ANTICIPATION_Y                                                                               \
                                   )                                                                                                    \
                             ,fM_NpasY                                                                                                  \
                              )                                                                                                         \
                         )                                                                                                              \
                                        /* ATTENTION, jusqu'au 20011015093459, par erreur, c'etait 'liste_initiale_des_RAYON' qui    */ \
                                        /* etait utilise ici a la place de 'liste_initiale_des_RAYON_D_INTERACTION'. Cela a eu des   */ \
                                        /* consequences sur pratiquement toutes les sequences generees avant cette date (voir a ce   */ \
                                        /* propos 'v _____xivPdf_14_1/$Fnota 011777_012288'), puisqu'en regle generale ces deux      */ \
                                        /* parametres different (legerement...).                                                     */
#define   PreY(y)                                                                                                                       \
                    nPREY(y,eM_NpasY)
#define   SucY(y)                                                                                                                       \
                    nSUCY(y,eM_NpasY)

#define   MINIMUM_ANTICIPATION_Z                                                                                                        \
                    UN
#define   MAXIMUM_ANTICIPATION_Z                                                                                                        \
                    QUATRE
#define   M_NpasZ                                                                                                                       \
                    INTE(fM_NpasZ)
#define   eM_NpasZ                                                                                                                      \
                    INTE(MUL2(COND(IL_FAUT(adapter_les_M_nPAS)                                                                          \
                                  ,TRON(DIVI(COND(IL_FAUT(prendre_en_compte_M_l_encombrement_des_particules)                            \
                                                 ,MAX2(delta_Z_anticipe                                                                 \
                                                      ,lZ_PHYSIQUE_A_VISUALISATION                                                      \
                                                           (ACCES_LISTE(liste_initiale_des_RAYON_D_INTERACTION,corps))                  \
                                                       )                                                                                \
                                                 ,delta_Z_anticipe                                                                      \
                                                  )                                                                                     \
                                            ,pasZ                                                                                       \
                                             )                                                                                          \
                                       ,MINIMUM_ANTICIPATION_Z                                                                          \
                                       ,COND(IL_FAUT(prendre_en_compte_M_l_encombrement_des_particules),INFINI,MAXIMUM_ANTICIPATION_Z)  \
                                        )                                                                                               \
                                  ,MINIMUM_ANTICIPATION_Z                                                                               \
                                   )                                                                                                    \
                             ,fM_NpasZ                                                                                                  \
                              )                                                                                                         \
                         )                                                                                                              \
                                        /* ATTENTION, jusqu'au 20011015093459, par erreur, c'etait 'liste_initiale_des_RAYON' qui    */ \
                                        /* etait utilise ici a la place de 'liste_initiale_des_RAYON_D_INTERACTION'. Cela a eu des   */ \
                                        /* consequences sur pratiquement toutes les sequences generees avant cette date (voir a ce   */ \
                                        /* propos 'v _____xivPdf_14_1/$Fnota 011777_012288'), puisqu'en regle generale ces deux      */ \
                                        /* parametres different (legerement...).                                                     */
#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));
#define   SURVEILLANCE_DE_L_AFFINAGE_DU_MAILLAGE_DE_CALCUL_DU_M_GRADIENT                                                                \
                    MILLE
                              DEFV(Int,INIT(surveillance_de_l_affinage_du_maillage_de_calcul_du_M_gradient
                                           ,SURVEILLANCE_DE_L_AFFINAGE_DU_MAILLAGE_DE_CALCUL_DU_M_GRADIENT
                                            )
                                   );
#undef    SURVEILLANCE_DE_L_AFFINAGE_DU_MAILLAGE_DE_CALCUL_DU_M_GRADIENT
                                        /* 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 parcourir 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_EFFECTIF
                                                                                  ,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_EFFECTIF
                                                                                  ,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_EFFECTIF
                                                                                  ,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...         */
                                        /* ATTENTION, jusqu'au 20011022133229, il y avait ici 'dct' et non pas 'DCT_EFFECTIF'        */
                                        /* par erreur...                                                                             */

                              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(I3OU(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
                                                  )
                                            ,IZLE(surveillance_de_l_affinage_du_maillage_de_calcul_du_M_gradient)
                                             )
                                        )
                                        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.                                                   */

                                        DECR(surveillance_de_l_affinage_du_maillage_de_calcul_du_M_gradient,I);
                                        /* Pour eviter de boucler...                                                                 */
                                        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(MAX3(ASD1(pave_du_Mgradient_local_tri_dimensionnel,dx)
                                                 ,ASD1(pave_du_Mgradient_local_tri_dimensionnel,dy)
                                                 ,ASD1(pave_du_Mgradient_local_tri_dimensionnel,dz)
                                                  )
                                             )
                                        );
                                        /* ATTENTION, jusqu'au 20000328135804 il y avait ici 'MIN3(...)', mais c'est evidemment      */
                                        /* 'MAX3(...)' qu'il faut utiliser...                                                        */

                                   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). Ceci doit etre fait quel que soit   */
                                        /* le mode 'calculer_la_moyenne_des_Mgradient_3x3x3_tri_dimensionnel' car, en effet, lorsque */
                                        /* le milieu ne change pas il faut que le gradient soit {0,0,0}, alors que l'on ne cumulera  */
                                        /* aucun point si 'IL_NE_FAUT_PAS(calculer_la_moyenne_des_Mgradient_3x3x3_tri_dimensionnel'. */

                                   begin_albumQ(DoIn,PreZ(Zg),SucZ(Zg),pasZ
                                               ,DoIn,PreY(Yg),SucY(Yg),pasY
                                               ,DoIn,PreX(Xg),SucX(Xg),pasX
                                                )
                                        /* Balayage d'un volume dont le point (Xg,Yg,Zg) est le centre.                              */
                                        /*                                                                                           */
                                        /* 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
                                        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

                                                  Test(IL_FAUT(calculer_la_moyenne_des_Mgradient_3x3x3_tri_dimensionnel))
                                                       Bblock
                                                       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 de tous les points utilises.                                                     */
                                                       Eblock
                                                  ATes
                                                       Bblock
                                                       DEFV(Float,INIT(Rho_du_Mgradient_3x3x3_tri_dimensionnel,FLOT__UNDEF));
                                                       DEFV(Float,INIT(Phi_du_Mgradient_3x3x3_tri_dimensionnel,FLOT__UNDEF));
                                                       DEFV(Float,INIT(Theta_du_Mgradient_3x3x3_tri_dimensionnel,FLOT__UNDEF));
                                        /* Coordonnees spheriques {Rho,Phi,Theta} du gradient "ponctuel" au point courant.           */

                                                       EGAL(Rho_du_Mgradient_3x3x3_tri_dimensionnel
                                                           ,Rho_3D(ASD1(Mgradient_3x3x3_tri_dimensionnel,dx)
                                                                  ,ASD1(Mgradient_3x3x3_tri_dimensionnel,dy)
                                                                  ,ASD1(Mgradient_3x3x3_tri_dimensionnel,dz)
                                                                   )
                                                            );

                                                       Test(IZNE(Rho_du_Mgradient_3x3x3_tri_dimensionnel))
                                                            Bblock
                                                            EGAL(Phi_du_Mgradient_3x3x3_tri_dimensionnel
                                                                ,Phi_3D(ASD1(Mgradient_3x3x3_tri_dimensionnel,dx)
                                                                       ,ASD1(Mgradient_3x3x3_tri_dimensionnel,dy)
                                                                       ,ASD1(Mgradient_3x3x3_tri_dimensionnel,dz)
                                                                        )
                                                                 );
                                                            EGAL(Theta_du_Mgradient_3x3x3_tri_dimensionnel
                                                                ,Theta_3D(ASD1(Mgradient_3x3x3_tri_dimensionnel,dx)
                                                                         ,ASD1(Mgradient_3x3x3_tri_dimensionnel,dy)
                                                                         ,ASD1(Mgradient_3x3x3_tri_dimensionnel,dz)
                                                                          )
                                                                 );
                                        /* Coordonnees spheriques {Rho,Phi,Theta} du gradient "ponctuel" au point courant.           */

                                                            INCR(Rho_du_Mgradient_local_tri_dimensionnel
                                                                ,MUL2(ponderation_du_Mgradient_3x3x3
                                                                     ,Rho_du_Mgradient_3x3x3_tri_dimensionnel
                                                                      )
                                                                 );
                                                            INCR(Phi_du_Mgradient_local_tri_dimensionnel
                                                                ,MUL2(ponderation_du_Mgradient_3x3x3
                                                                     ,Phi_du_Mgradient_3x3x3_tri_dimensionnel
                                                                      )
                                                                 );
                                                            INCR(Theta_du_Mgradient_local_tri_dimensionnel
                                                                ,MUL2(ponderation_du_Mgradient_3x3x3
                                                                     ,Theta_du_Mgradient_3x3x3_tri_dimensionnel
                                                                      )
                                                                 );
                                        /* Cumul d'obtention des coordonnees spheriques {Rho,Phi,Theta} du gradient local (Gx,Gy,Gz) */
                                        /* du milieu de propagation.                                                                 */

                                                            INCR(nombre_de_points_du_Mgradient_local,I);
                                        /* Comptage des points utilises et "non vides" (c'est-a-dire dont le 'Rho' n'est pas nul.    */
                                        /* Cette technique permet, par exemple, de garantir que les mouvements confines dans des     */
                                        /* plans paralleles a {OX,OY} (a 'Z' constant) le restent...                                 */
                                                            Eblock
                                                       ATes
                                                            Bblock
                                                            Eblock
                                                       ETes
                                                       Eblock
                                                  ETes
                                                  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
                                        Test(IL_FAUT(calculer_la_moyenne_des_Mgradient_3x3x3_tri_dimensionnel))
                                             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
                                             EGAL(Rho_du_Mgradient_local_tri_dimensionnel
                                                 ,NEUT(DIVI(Rho_du_Mgradient_local_tri_dimensionnel
                                                           ,FLOT(nombre_de_points_du_Mgradient_local)
                                                            )
                                                       )
                                                  );
                                             EGAL(Phi_du_Mgradient_local_tri_dimensionnel
                                                 ,CERC(DIVI(Phi_du_Mgradient_local_tri_dimensionnel
                                                           ,FLOT(nombre_de_points_du_Mgradient_local)
                                                            )
                                                       )
                                                  );
                                             EGAL(Theta_du_Mgradient_local_tri_dimensionnel
                                                 ,CERC(DIVI(Theta_du_Mgradient_local_tri_dimensionnel
                                                           ,FLOT(nombre_de_points_du_Mgradient_local)
                                                            )
                                                       )
                                                  );
                                        /* Coordonnees spheriques {Rho,Phi,Theta} du gradient local (Gx,Gy,Gz) du milieu de          */
                                        /* propagation.                                                                              */

                                             INITIALISATION_ACCROISSEMENT_3D(Mgradient_local_tri_dimensionnel
                                                                            ,Xcartesienne_3D(Rho_du_Mgradient_local_tri_dimensionnel
                                                                                            ,Phi_du_Mgradient_local_tri_dimensionnel
                                                                                            ,Theta_du_Mgradient_local_tri_dimensionnel
                                                                                             )
                                                                            ,Ycartesienne_3D(Rho_du_Mgradient_local_tri_dimensionnel
                                                                                            ,Phi_du_Mgradient_local_tri_dimensionnel
                                                                                            ,Theta_du_Mgradient_local_tri_dimensionnel
                                                                                             )
                                                                            ,Zcartesienne_3D(Rho_du_Mgradient_local_tri_dimensionnel
                                                                                            ,Phi_du_Mgradient_local_tri_dimensionnel
                                                                                            ,Theta_du_Mgradient_local_tri_dimensionnel
                                                                                             )
                                                                             );
                                        /* Calcul du gradient local au point (Xg,Yg,Zg). 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.    */

                                             INITIALISATION_ACCROISSEMENT_3D(Mgradient_local_tri_dimensionnel
                                                                            ,TROP_PETIT(ASD1(Mgradient_local_tri_dimensionnel,dx)
                                                                                       ,seuil_de_Mgradient_local_tri_dimensionnel_X
                                                                                        )
                                                                            ,TROP_PETIT(ASD1(Mgradient_local_tri_dimensionnel,dy)
                                                                                       ,seuil_de_Mgradient_local_tri_dimensionnel_Y
                                                                                        )
                                                                            ,TROP_PETIT(ASD1(Mgradient_local_tri_dimensionnel,dz)
                                                                                       ,seuil_de_Mgradient_local_tri_dimensionnel_Z
                                                                                        )
                                                                             );
                                        /* Afin de corriger le probleme evoque ci-dessus au-sujet des aller-retours entre les        */
                                        /* coordonnees cartesiennes et spheriques, dont le produit n'est pas la transformation       */
                                        /* unite a cause des erreurs d'arrondi. Lorsque l'une des composantes est trop petite,       */
                                        /* on considere qu'en fait elle doit etre nulle et donc on l'annule...                       */
                                             Eblock
                                        ETes
                                        Eblock
                                   ATes
                                        Bblock
                                        Test(IL_FAUT(calculer_la_moyenne_des_Mgradient_3x3x3_tri_dimensionnel))
                                             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
                                        ATes
                                             Bblock
                                             Eblock
                                        ETes
                                        Eblock
                                   ETes
                                   Eblock
                              ETes
                              Eblock
                         ETes

#undef    FALOAD_POINT

#undef    SucZ
#undef    PreZ
#undef    eM_NpasZ
#undef    M_NpasZ
#undef    MAXIMUM_ANTICIPATION_Z
#undef    MINIMUM_ANTICIPATION_Z

#undef    SucY
#undef    PreY
#undef    eM_NpasY
#undef    M_NpasY
#undef    MAXIMUM_ANTICIPATION_Y
#undef    MINIMUM_ANTICIPATION_Y

#undef    SucX
#undef    PreX
#undef    eM_NpasX
#undef    M_NpasX
#undef    MAXIMUM_ANTICIPATION_X
#undef    MINIMUM_ANTICIPATION_X

#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.52$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...                         */

                         EDITION_E(BLOC(CAL2(Prin1(" niveau central du milieu=%+f"
                                                  ,niveau_central_du_pave_du_Mgradient_local_tri_dimensionnel
                                                   )
                                             );
                                        )
                                   );

                         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...               */

                              DEFV(Logical,INIT(immobiliser_le_corps_courant_suite_a_un_test_probabiliste,FAUX));
                                        /* A priori, le corps courant ne doit pas etre immobilise de facon probabiliste...           */
                                        /* Le 20020219142536 a ete introduit la possibilite d'immobiliser un corps apres une         */
                                        /* reflexion, non plus uniquement avec un decompteur ('ACCES_IMMOBILISABLES(corps)>=0'),     */
                                        /* mais, de plus, avec une probabilite donnee par '|ACCES_IMMOBILISABLES(corps)|'...         */

                              Test(IZLT(ACCES_IMMOBILISABLES(corps)))
                                        /* Cas ou un test d'immobilisation probabiliste est demande, mais evidemment uniquement      */
                                        /* dans le cas ou une reflexion est rencontree ci-apres...                                   */
                                   Bblock
                                   DEFV(Float,INIT(tirage_aleatoire_d_immobilisation,FLOT__UNDEF));
                                   GENERATION_D_UNE_VALEUR(tirage_aleatoire_d_immobilisation
                                                          ,PROBABILITE_NULLE
                                                          ,PROBABILITE_UNITE
                                                           );
                                        /* On notera que 'tirage_aleatoire_d_immobilisation', de meme que l'indicateur               */
                                        /* 'immobiliser_le_corps_courant_suite_a_un_test_probabiliste' qui est evalue ci-apres,      */
                                        /* n'ont d'utilite que s'il y a reflexion du corps courant par la suite. Ce calcul est       */
                                        /* fait malgre tout dans tous les cas afin de simplifier les deux tests differents et        */
                                        /* exclusifs l'un de l'autre qui seront eventuellement effectues par la suite...             */

                                   Test(IFLT(tirage_aleatoire_d_immobilisation,ABSO(ACCES_IMMOBILISABLES(corps))))
                                        Bblock
                                        Test(IFOU(IL_NE_FAUT_PAS(tenter_de_synchroniser_les_immobilisations_sur_les_naissances)
                                                 ,IFET(IL_FAUT(tenter_de_synchroniser_les_immobilisations_sur_les_naissances)
                                                      ,IFLT(compteur_des_particules_immobilisees_lors_d_une_collision_avec_le_milieu
                                                           ,INTE(MUL2(facteur_synchronisation_des_immobilisations_sur_les_naissances
                                                                     ,FLOT(compteur_des_particules_nees_apres_l_instant_initial)
                                                                      )
                                                                 )
                                                            )
                                                       )
                                                  )
                                             )
                                             Bblock
                                        /* Une tentative de synchronisation des morts sur les naissances a ete introduite le         */
                                        /* 20020227092012. D'une part, celle-ci ne s'applique que si le test d'immobilisation        */
                                        /* est probabiliste ('IZLT(ACCES_IMMOBILISABLES(corps))'). D'autre part, elle consiste       */
                                        /* uniquement a refuser une immobilisation s'il n'y a pas au moins une naissance (au cours   */
                                        /* de l'intervalle de temps courant) qui la compense ; ainsi, il ne peut pas y avoir plus    */
                                        /* d'immobilisations (des morts suivant les options) que de naissances, mais il peut y       */
                                        /* avoir plus de naissances que d'immobilisations puisque les naissances sont controlees     */
                                        /* de facon inflexible par 'fichier_LISTE_DATE_DE_NAISSANCE'. Il conviendra donc, si cette   */
                                        /* option est activee, d'avoir des probabilites d'immobilisation suffisamment elevees        */
                                        /* de facon a ce qu'en l'absence de cette synchronisation, il y ait plus d'immobilisations   */
                                        /* que de naissances ; ainsi lorsque la synchronisation sera activee, on sera sur que les    */
                                        /* immobilisations seront "seuillees" par rapport aux naissances...                          */
                                             EGAL(immobiliser_le_corps_courant_suite_a_un_test_probabiliste,VRAI);
                                        /* Si le corps courant est reflechi ci-apres, il doit etre immobilise...                     */
                                             Eblock
                                        ATes
                                             Bblock
                                             Eblock
                                        ETes
                                        Eblock
                                   ATes
                                        Bblock
                                        Eblock
                                   ETes
                                   Eblock
                              ATes
                                   Bblock
                                        /* Cas ou l'immobilisation eventuelle a lieu sur decomptage...                               */
                                   Eblock
                              ETes

                              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'.                                                     */

                                             INCR(compteur_des_collisions_particules_milieu,I);
                                        /* Comptage des collisions de type 'particules-milieu'.                                      */

                                             Test(IFOU(IZEQ(ACCES_IMMOBILISABLES(corps))
                                                      ,IFET(IZLT(ACCES_IMMOBILISABLES(corps))
                                                           ,IL_FAUT(immobiliser_le_corps_courant_suite_a_un_test_probabiliste)
                                                            )
                                                       )
                                                  )
                                        /* Ce dispositif a ete introduit le 20010906164754 et passe de 'EST_VRAI(...)' a 'IZLE(...)' */
                                        /* le 20010910092922 puisqu'a cette date il a ete transforme d'un indicateur logique en un   */
                                        /* decompteur. Le 20020219142536 a ete introduit la possibilite supplementaire de faire un   */
                                        /* test probabiliste, d'ou le passage a 'IFOU(IZEQ(...),...)'.                               */
                                                  Bblock
                                                  Test(EST_VRAI(faire_mourir_les_particules_immobilisables))
                                                       Bblock
                                                       EGAL(ACCES_DATES_DE_MORT(corps),temps_courant);
                                        /* Ce dispositif a ete introduit le 20011008091649 ; il permet de choisir entre la mort      */
                                        /* ('VRAI') auquel cas la particule disparait, et l'immobilisation "inertielle" ('FAUX')     */
                                        /* auquel cas la particule est toujours visible mais ne peut plus bouger...                  */
                                                       Eblock
                                                  ATes
                                                       Bblock
                                                       INITIALISATION_ACCROISSEMENT_3D(vecteur_vitesse_incident
                                                                                      ,FZERO
                                                                                      ,FZERO
                                                                                      ,FZERO
                                                                                       );
                                        /* On immobilise le corps en lui donnant une vitesse nulle...                                */
                                                       EGAL(ACCES_MASSES(corps),MASSE_D_UN_CORPS_APRES_IMMOBILISATION);
                                        /* Mais il faut de plus lui donner une masse infinie afin que lors de chocs ulterieurs       */
                                        /* avec d'autres particules (non immobilisees), celle-ci ne soit pas remise en mouvement     */
                                        /* (via la conservation de la quantite de mouvement...).                                     */
                                                       Eblock
                                                  ETes

                                                  INCR(compteur_des_particules_immobilisees_lors_d_une_collision_avec_le_milieu,I);
                                        /* Comptage...                                                                               */

                                                  EDITION_E(BLOC(CAL2(Prin0("   IMMOBILISATION"));
                                                                 )
                                                            );
                                                  Eblock
                                             ATes
                                                  Bblock
                                                  Test(IZGT(ACCES_IMMOBILISABLES(corps)))
                                                       Bblock
                                                       DECR(ACCES_IMMOBILISABLES(corps),I);
                                        /* Decomptage des reflexions pour 'corps' avant une eventuelle immobilisation.               */
                                                       Eblock
                                                  ATes
                                                       Bblock
                                                       Eblock
                                                  ETes

                                                  EDITION_E(BLOC(CAL2(Prin2("   REFLEXION thetaI=%+f thetaR=%+f"
                                                                           ,theta_incident_VG
                                                                           ,theta_apres_reflexion_ou_refraction
                                                                            )
                                                                      );
                                                                 )
                                                            );
                                                  Eblock
                                             ETes
                                             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 il 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_REFRACTION_REFLEXION(corps)
                                                                             )
                                                                       ,ASD1(vecteur_vitesse_reflechi_ou_refracte,dx)
                                                                       ,ADD2(translation_vitesse_OX2_refraction_reflexion
                                                                            ,ACCES_TRANSLATION_VITESSE_OX2_REFRACTION_REFLEXION(corps)
                                                                             )
                                                                        )
                                                                  ,NEUT(ASD1(vecteur_vitesse_reflechi_ou_refracte,dy))
                                                                  ,AXPB(MUL2(facteur_vitesse_OZ2_refraction_reflexion
                                                                            ,ACCES_FACTEUR_VITESSE_OZ2_REFRACTION_REFLEXION(corps)
                                                                             )
                                                                       ,ASD1(vecteur_vitesse_reflechi_ou_refracte,dz)
                                                                       ,ADD2(translation_vitesse_OZ2_refraction_reflexion
                                                                            ,ACCES_TRANSLATION_VITESSE_OZ2_REFRACTION_REFLEXION(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");
                                        /* Cela peut se produire en particulier depuis l'introduction de l'immobilisation des        */
                                        /* particules lors de leurs collisions avec le milieu lorsque la condition                   */
                                        /* 'IL_NE_FAUT_PAS(faire_mourir_les_particules_immobilisables)' ; en effet, leur masse       */
                                        /* devient quasiment infinie, ce qui donne des vitesses infinitesimales lors des chocs       */
                                        /* (voir donc 'fichier_LISTE_IMMOBILISABLE' introduit le 20010906164754).                    */
                                        CAL1(Prer1("il s'agit du corps %d\n"
                                                  ,corps
                                                   )
                                             );
                                        CAL1(Prer3("vitesse = {%+g,%+g,%+g}\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'.     */

                                   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'.                                                     */

                                   INCR(compteur_des_collisions_particules_milieu,I);
                                        /* Comptage des collisions de type 'particules-milieu'.                                      */

                                   Test(IFOU(IZEQ(ACCES_IMMOBILISABLES(corps))
                                            ,IFET(IZLT(ACCES_IMMOBILISABLES(corps))
                                                 ,IL_FAUT(immobiliser_le_corps_courant_suite_a_un_test_probabiliste)
                                                  )
                                             )
                                        )
                                        /* Ce dispositif a ete introduit le 20010906164754 et passe de 'EST_VRAI(...)' a 'IZLE(...)' */
                                        /* le 20010910092922 puisqu'a cette date il a ete transforme d'un indicateur logique en un   */
                                        /* decompteur. Le 20020219142536 a ete introduit la possibilite supplementaire de faire un   */
                                        /* test probabiliste, d'ou le passage a 'IFOU(IZEQ(...),...)'.                               */
                                        Bblock
                                        Test(EST_VRAI(faire_mourir_les_particules_immobilisables))
                                             Bblock
                                             EGAL(ACCES_DATES_DE_MORT(corps),temps_courant);
                                        /* Ce dispositif a ete introduit le 20011008091649 ; il permet de choisir entre la mort      */
                                        /* ('VRAI') auquel cas la particule disparait, et l'immobilisation "inertielle" ('FAUX')     */
                                        /* auquel cas la particule est toujours visible mais ne peut plus bouger...                  */
                                             Eblock
                                        ATes
                                             Bblock
                                             INITIALISATION_ACCROISSEMENT_3D(ACCES_VITESSE_COURANTE(corps)
                                                                            ,FZERO
                                                                            ,FZERO
                                                                            ,FZERO
                                                                             );
                                        /* On immobilise le corps en lui donnant une vitesse nulle...                                */
                                             EGAL(ACCES_MASSES(corps),MASSE_D_UN_CORPS_APRES_IMMOBILISATION);
                                        /* Mais il faut de plus lui donner une masse infinie afin que lors de chocs ulterieurs       */
                                        /* avec d'autres particules (non immobilisees), celle-ci ne soit pas remise en mouvement     */
                                        /* (via la conservation de la quantite de mouvement...).                                     */
                                             Eblock
                                        ETes

                                        INCR(compteur_des_particules_immobilisees_lors_d_une_collision_avec_le_milieu,I);
                                        /* Comptage...                                                                               */

                                        EDITION_E(BLOC(CAL2(Prin0("   IMMOBILISATION"));
                                                       )
                                                  );
                                        Eblock
                                   ATes
                                        Bblock
                                        Test(IZGT(ACCES_IMMOBILISABLES(corps)))
                                             Bblock
                                             DECR(ACCES_IMMOBILISABLES(corps),I);
                                        /* Decomptage des reflexions pour 'corps' avant une eventuelle immobilisation.               */
                                             Eblock
                                        ATes
                                             Bblock
                                             Eblock
                                        ETes

                                        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
                              ETes
                              Eblock
                         ATes
                              Bblock
                              Test(IFINff(NIVEAU_LOCAL_COURANT_INITIAL
                                         ,______________NOIR_NORMALISE
                                         ,______________BLANC_NORMALISE
                                          )
                                   )
                                   Bblock
                                   PRINT_ERREUR("la valeur de 'NIVEAU_LOCAL_COURANT_INITIAL' est incompatible avec les tests");
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes

                              Test(I3ET(IFGT(temps_courant,instant_initial)
                                       ,IFNE(ACCES_NIVEAUX_LOCAUX_COURANTS(corps)
                                            ,NIVEAU_LOCAL_COURANT_INITIAL
                                             )
                                       ,IFNE(niveau_central_du_pave_du_Mgradient_local_tri_dimensionnel
                                            ,ACCES_NIVEAUX_LOCAUX_COURANTS(corps)
                                             )
                                        )
                                   )
                                        /* Le test sur 'NIVEAU_LOCAL_COURANT_INITIAL' a ete introduit le 19990927173502 parce que    */
                                        /* le test sur 'instant_initial' ne suffit pas ; en effet, lorsque des particules sont       */
                                        /* initialement au repos et qu'elles ne sont mises que plus tard en mouvement, la valeur     */
                                        /* de 'ACCES_NIVEAUX_LOCAUX_COURANTS(corps)' n'est donc pas correcte dans les instants       */
                                        /* suivants. Cela s'est vu en generant la sequence :                                         */
                                        /*                                                                                           */
                                        /*                  xivPdf 9 2 / 015644_016155                                               */
                                        /*                                                                                           */
                                        /* On notera que dans ces conditions, le test :                                              */
                                        /*                                                                                           */
                                        /*                  IFGT(temps_courant,instant_initial)                                      */
                                        /*                                                                                           */
                                        /* n'est plus utile ; je le garde malgre tout, car on ne sait jamais...                      */
                                   Bblock
                                   Test(IL_FAUT(editer_les_messages_d_erreur_du_calcul_du_gradient))
                                        /* Test introduit le 20150208081059...                                                       */
                                        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(Prer0("(cela peut se produire si le milieu est dynamique et si son 'volume' diminue)\n"));
                                        /* Effectivement, lors d'une reduction du "volume" du milieu, une particule peut voir        */
                                        /* changer brutalement son milieu local, sans qu'elle se soit elle-meme deplacee...          */
                                        CAL1(Prer0("(ou encore en presence d'un champ de gravitation trop fort)\n"));
                                        CAL1(Prer0("(auquel cas des accelerations violentes peuvent provoquer)\n"));
                                        CAL1(Prer0("(des deplacements trop importants par rapport au pas de temps)\n"));
                                        /* Effectivement, en presence d'un champ de gravitation trop fort, les accelerations sont    */
                                        /* alors tres violentes et les vitesses peuvent donc devenir tres importantes ; certaines    */
                                        /* particules peuvent donc changer de "zones" dans le milieu sans que cela se voit (a cause  */
                                        /* d'un pas de temps trop grand et qui le sera toujours puisqu'alors les vitesses augmentent */
                                        /* sans arret sauf collision...).                                                            */

                                        CAL1(Prer1("niveau anterieur.......... = %g\n",ACCES_NIVEAUX_LOCAUX_COURANTS(corps)));
                                        CAL1(Prer1("niveau courant............ = %g\n"
                                                  ,niveau_central_du_pave_du_Mgradient_local_tri_dimensionnel
                                                   )
                                             );
                                        CAL1(Prer1("periode................... = %d\n"
                                                  ,numero_de_la_periode_courante_de_la_simulation
                                                   )
                                             );
                                        CAL1(Prer1("temps..................... = %f\n"
                                                  ,temps_courant
                                                   )
                                             );
                                        CAL1(Prer3("coordonnees gradient...... = {%+d,%+d,%+d}\n"
                                                  ,Xg
                                                  ,Yg
                                                  ,Zg
                                                   )
                                             );
                                        CAL1(Prer6("coordonnees particule..... = {%+f,%+f,%+f} --> {%+d,%+d,%+d}\n"
                                                  ,ASD1(ACCES_COORDONNEES_COURANTES(corps),x)
                                                  ,ASD1(ACCES_COORDONNEES_COURANTES(corps),y)
                                                  ,ASD1(ACCES_COORDONNEES_COURANTES(corps),z)
                                                  ,INTE(gX_PHYSIQUE_A_VISUALISATION(ASD1(ACCES_COORDONNEES_COURANTES(corps),x),FZERO))
                                                  ,INTE(gY_PHYSIQUE_A_VISUALISATION(ASD1(ACCES_COORDONNEES_COURANTES(corps),y),FZERO))
                                                  ,INTE(gZ_PHYSIQUE_A_VISUALISATION(ASD1(ACCES_COORDONNEES_COURANTES(corps),z),FZERO))
                                                   )
                                             );
                                        CAL1(Prer3("vitesse particule......... = {%+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
                    Eblock



Copyright © Jean-François COLONNA, 2019-2024.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / École polytechnique, Institut Polytechnique de Paris, 2019-2024.