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