Etude des Phénomènes Critiques par les Méthodes de Monte Carlo : Cas du modèle d'Ising à 2 D pour la transition de phase Ferro<->Para( Télécharger le fichier original )par Rostand Choisy TCHUENTE Université de Douala - Cameroun - Maîtrise / Master en Physique (Physique de la matière condensée) 2006 |
REFERENCES BIBLIOGRAPHIQUES[1] K. Binder, D.W. Heermann: Monte Carlo Simulation in Statiscal Physics, and introduction, 3rt edition, (springer serie in Solid-State Sciences) [2] M.E.J. NEWMAN & G.T.BARKERMAN, « Monte Carlo Methods in Statical Physics », Oxford University press, 2002 [3] Oumarou BOUBA, Notes de cours «Thermodynamique statistique» de licence, Université de Ngaoundéré, 2nd semestre 2004 [4] L. Onsager. Phys. Rev. 65, 117 (1944) [5] David FOUEJIO, Thèse de Doctorat (NR) de l'Université du Maine (France), ½Etude par RPE et Diffraction de rayon X des transitions de phase de KGaF4½, 1995 [6] Philippe NDONFACK, Mémoire de maîtrise de Physique « Simulation des phénomènes physiques par les méthodes de Monte Carlo : Cas du modèle d'Ising pour l'étude des transitions de phase» ; 2006 [7] Dominique BAKRY, Notes de cours DEA. [8] Eric GAUME, INRS-EAU, Programme Doctoral, TD application de l'algorithme METROPOLIS pour analyse de sensibilité d'un modèle stochastique de pluie, 29 Avril 1999. [9] Pascal VIOT, Notes de Cours de Master [10] Vincent POUTHIER, INTRODUCTION AUX PHENOMENES CRITIQUES, Notes de cours DEA [11] David FOUEJIO, TP3 de maîtrise de Physique, Etude du comportement en température d'un système de spins à deux orientations possibles : Modèle d'Ising à 2 D ; Université du Maine (France) ; 1995 - 1996 [12] K.G. WILSON, Pour la SCIENCE, Vol 10, N° 24, p16 (1979) ANNEXESORGANIGRAMME DU PROCESSUS DE MARKOV. P est une variable uniforme aléatoire Figure A1 : Organigramme du processus de Markov ORGANIGRAMME DE L'ALGORITHME DE MÉTROPOLIS. Les différents états sont générés par le processus Markovien P est une variable uniforme aléatoire Figure A2 : Organigramme du processus de Métropolis PROGRAMME EN C++ DE L'ALGORITHME DE MÉTROPOLIS Version simplifiée /*beta = température inverse *prob[] = tableau des probabilités d'acceptation * s[] = matrice de spins avec les conditions de bord * l = constante de longueur de la matrice */ # define N (l*l) # define XNN 1 # define YNN l int s[n]; double prob[5]; double beta; void initialisation () { int i; for (i=2; i<5; i+=2) prob[i]=exp(-2*beta*i); } void balayage () { int i,k; int nn,sum,delta; for (k=0; k<N; k++) {i=n*drandom(); /* choix aléatoire du site i*/ if ((nn=i+XNN)>=N) /* calcul de la somme sur les voisins */ nn -= N ; sum = s[nn]; if ((nn=i-XNN)< 0) nn += N ; sum += s[nn]; if ((nn=i+YNN)>=N) nn -= N ; sum = s[nn]; if ((nn=i-YNN)< 0) nn -= n ; sum += s[nn]; delta = sum*s[i]; /* calcul de l'énergie lors du retournement de spin*/ if (delta<=0) /* vérification de la nécessité de retournement de spin*/ { s[i]=-s[i] ; } else if (drandom()<prob[delta]) { S[i]=-s[i]; } } } ORGANIGRAMME DE L'ALGORITHME DE WOLFF Les différents états sont générés par le processus Markovien Si = [Sn+ ou Sn-] et tous les voisins Parcours des 1ers voisins n+ et n- Figure A4 : Organigramme du processus de Wolff PROGRAMME EN C++ DE L'ALGORITHME DE WOLFF /*padd = 1-exp(-2*beta*J) *s[] = matrice de spin avec les conditions de bord considérées *s[] = matrice de spins avec les conditions de bord *l = constante de longueur de la matrice */ # define N (l*l) # define XNN 1 # define YNN l int s[N]; double padd; void etape () { int i; int sp ; int oldspin, newspin ; int current, nn; int stack[N]; /* choix du spin central pour le cluster, */ i=n*drandom() ; /* Le mettre dans le tas et le retourner */ stack[0]=i ; sp = 1; oldspin = s[i]; newspin = -s[i]; s[i] = newspin; while (sp) { /*pousser le spin du tas par la méthode LIFO*/ current = stack[--sp]; if ((nn =current+XNN)>=N) /* recherché des voisins*/ nn -= N; if (s[nn]==oldspin) if (drandom()<padd) { Stack[sp++]=nn; S[nn]=newspin; } if ((nn =current-XNN)<0) /* recherché des voisins*/ nn += N; if (s[nn]==oldspin) if (drandom()<padd) { stack[sp++]=nn; s[nn]=newspin; } if ((nn =current+YNN)>=N) /* recherché des voisins*/ nn -= N; if (s[nn]==oldspin) if (drandom()<padd) { Stack[sp++]=nn; S[nn]=newspin; } if ((nn =current-YNN)<0) /* recherché des voisins*/ nn += N; if (s[nn]==oldspin) if (drandom()<padd) { Stack[sp++]=nn; S[nn]=newspin; } } } ALGORITHME DE GÉNÉRATION DES NOMBRES ALÉATOIRES PAR CONGRUENCE LINEAIRE AVEC `SHUFFLING'. Version simplifiée # include <math.h> # define a 1680 # define m 2147483647 # define q 127773 # define r 2836 # define conv (1.0/(m-1)) # define N 64 long i ; long y ; long j[N]; double drandom() { long L; long k; L = i/q; i = a*(i-q*L)-r*L; if (i<0) I += m; /* début du shuffling (mélange)*/ k = floor ((double) y*N/m); y = j[k]; j[k] = i; /* fin du mélange*/ return conv*(y-1); }L'algorithme de génération des nombres aléatoires par congruence linéaire proposé par lewis et al. en 1969 [2] propose des nombres aléatoires « non corrélés » compris entre 0 et 1. En 1976 Bays et Durham introduisirent dans cet algorithme un reclassement désordonné des nombres aléatoires proposés, rendant plus libres deux nombres consécutivement générés : c'est le shuffling. Il se défini ici par le vecteur j[k] introduit à la dernière boucle de l'algorithme initial de Lewis. Version complète, extraite de ISampling /* RandomNumber.cpp: implementation of the CRandomNumber class.*/ /////// #include "stdafx.h" #include "ISampling.h" #define _MAX_SUFFLING_NUMBER_ 64//97 #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////// CRandomNumber CRandomNumber::CRandomNumber() { m_psn = NULL; /* Seed the random-number generator with current time so that the numbers will be different every time we run. */ srand((unsigned)time(NULL)); } CRandomNumber::~CRandomNumber() { if (m_psn != NULL) delete[] m_psn; m_psn = NULL; } /* Standard random support returns a pseudorandom integer in the range 0 to n - 1 */ unsigned int CRandomNumber::GetNumber(unsigned int n) { return (rand() % n); } /*returns a floating point pseudorandom number in the range 0 to 1 */ double CRandomNumber::GetNumber() { double dblRet = rand(); dblRet = dblRet / RAND_MAX; return dblRet; } /* Initialise le générateur de nombre aléatoires permettant d'effectuer le "shuffling" (mélange) des nombres générés par le système.*/ void CRandomNumber::InitShuffling() { if (m_psn == NULL) m_psn = new double[_MAX_SUFFLING_NUMBER_]; for (int nIndex = 0; nIndex < _MAX_SUFFLING_NUMBER_; nIndex++) m_psn[nIndex] = GetNumber(); } /* Renvoie un nombre aléatoire par congruence linéaire tout en utilisant le "shuffling". Le nombre aléatoire renvoyé est situé dans l'intervalle [0, 1[.La graine ou germe et générée par le système.*/ double CRandomNumber::GetSysShuffledNumber() { VERIFY(m_psn != NULL); double dblSeed = GetNumber(); int nIndex = int(dblSeed*_MAX_SUFFLING_NUMBER_); if (nIndex >= _MAX_SUFFLING_NUMBER_) nIndex = _MAX_SUFFLING_NUMBER_ - 1;
double dblRet = m_psn[nIndex]; m_psn[nIndex] = dblSeed; return dblRet; } /* Renvoie un nombre aléatoire par congruence linéaire tout en utilisant le "shuffling". Le nombre aléatoire renvoyé est situé dans l'intervalle [0, n-1]. La graine ou germe et générée par le système.*/ unsigned int CRandomNumber::GetSysShuffledNumber(unsigned int n) { unsigned int nRet = unsigned int(GetSysShuffledNumber() * RAND_MAX); return (nRet % n); } #define _a_ 16807 #define _m_ INT_MAX #define _q_ 127773 #define _r_ 2836 #define _conv_ 1.0/_m_ // static function CRandomNumber::IsValidSeed(int nSeed) { switch (nSeed) { case Default_Seed : case Default_Seed_Ex : case Default_Seed1 : return true; } return false; } /* Renvoie un nombre aléatoire par congruence linéaire. Le nombre aléatoire renvoyé est situé dans l'intervalle [0, n-1].nSeed est la graine.*/ unsigned int CRandomNumber::GetLinearNumber(unsigned int& nSeed, unsigned int n) { unsigned int nRet = unsigned int(GetLinearNumber(nSeed) * _m_); return (nRet % n); } /* Renvoie un nombre aléatoire par congruence linéaire. Le nombre aléatoire renvoyé est situé dans l'intervalle [0, 1[. nSeed est la graine.*/ double CRandomNumber::GetLinearNumber(unsigned int& nSeed) { unsigned int nValue = nSeed / _q_; nSeed = _a_*(nSeed - _q_*nValue) - _r_*nValue; if (nSeed < 0) nSeed += _m_; else if (nSeed >= _m_) nSeed -= _m_; return nSeed*_conv_; } /* Initialise le générateur de nombre aléatoires permettant d'effectuer le "shuffling" (mélange) : nSeed est la graine.*/ void CRandomNumber::InitShuffling(unsigned int& nSeed) { if (m_psn == NULL) m_psn = new double[_MAX_SUFFLING_NUMBER_];
nSeed = 2*nSeed + 1; for (int nIndex = 0; nIndex < _MAX_SUFFLING_NUMBER_; nIndex++) m_psn[nIndex] = GetLinearNumber(nSeed); } /* Renvoie un nombre aléatoire par congruence linéaire tout en utilisant le "shuffling". Le nombre aléatoire renvoyé est situé dans l'intervalle [0, 1[. nSeed est la graine.*/ double CRandomNumber::GetShuffledNumber(unsigned int& nSeed) { VERIFY(m_psn != NULL); int nSize = _MAX_SUFFLING_NUMBER_ - 1; double dblSeed = GetLinearNumber(nSeed); int nIndex = int(dblSeed*nSize + 1); if (nIndex < 0) nIndex = 0; else if (nIndex > nSize) nIndex = nSize;
double dblRet = m_psn[nIndex]; m_psn[nIndex] = _conv_*(nSeed - 1); //dblSeed
return dblRet; } /* Renvoie un nombre aléatoire par congruence linéaire tout en utilisant le "shuffling". Le nombre aléatoire renvoyé est situé dans l'intervalle [0, n-1]. nSeed est la graine.*/ unsigned int CRandomNumber::GetShuffledNumber(unsigned int& nSeed, unsigned int n) { unsigned int nRet = unsigned int(GetShuffledNumber(nSeed) * _m_); return (nRet % n); } const unsigned int _m1_ = 259200, _m2_ = 134456, _m3_ = 243000; const unsigned int _ia1_ = 7141, _ia2_ = 8121, _ia3_ = 4561; const double _rm1_ = 1.0/_m1_, _rm2_ = 1.0/_m2_; const unsigned int _ic1_ = 54773, _ic2_ = 28411, _ic3_ = 51349; /* Initialise le générateur de nombre aléatoires permettant d'effectuer le "shuffling" (mélange): nSeed1, nSeed2, nSeed3 sont les graines.*/ void CRandomNumber::InitShuffling(unsigned int& nSeed1, unsigned int& nSeed2, unsigned int& nSeed3) { if (m_psn == NULL) m_psn = new double[_MAX_SUFFLING_NUMBER_]; nSeed1 = -abs(1 + 2*nSeed1); nSeed1 = (_ic1_ - nSeed1) % _m1_; nSeed1 = (_ia1_*nSeed1 + _ic1_) % _m1_; nSeed2 = nSeed1 % _m2_; nSeed1 = (_ia1_*nSeed1 + _ic1_) % _m1_; nSeed3 = nSeed1 % _m3_;
for (int nIndex = 0; nIndex < _MAX_SUFFLING_NUMBER_; nIndex++) { nSeed1 = (_ia1_*nSeed1 + _ic1_) % _m1_; nSeed2 = (_ia1_*nSeed2 + _ic2_) % _m2_; m_psn[nIndex] = (nSeed1 + nSeed2)*_rm1_*_rm2_; } } /* Renvoie un nombre aléatoire par congruence linéaire tout en utilisant le "shuffling". Le nombre aléatoire renvoyé est situé dans l'intervalle [0, 1[. nSeed1, nSeed2, nSeed3 sont les graines.*/ double CRandomNumber::GetShuffledNumber(unsigned int& nSeed1, unsigned int& nSeed2, unsigned int& nSeed3) { VERIFY(m_psn != NULL);
nSeed1 = (_ia1_*nSeed1 + _ic1_) % _m1_; nSeed2 = (_ia1_*nSeed2 + _ic2_) % _m2_; nSeed3 = (_ia1_*nSeed3 + _ic3_) % _m3_; int nSize = _MAX_SUFFLING_NUMBER_ - 1; int nIndex = nSize*nSeed3 / _m3_; if (nIndex < 0) nIndex = 0; else if (nIndex > nSize) nIndex = nSize;
double dblRet = m_psn[nIndex]; m_psn[nIndex] = (nSeed1 + nSeed2)*_rm1_*_rm2_; return dblRet; } Vu la longueur d'un tel programme, nous nous réservons de présenter ici les programmes complets issus de ISampling pour les autres algorithmes. Leurs écritures simplifiées sont largement suffisantes pour guider le lecteur. CLASSIFICATION DES TRANSITIONS DE PHASE Tableau A7 : Classification des transitions
... et si seulement vous avez retenu l'infiniment petit qui peut être tiré de ce document ; ... et si seulement ce travail pouvait permettre de mieux cerner, par un plus large public les mystères de la science ; ... et si seulement vous pensez qu'il faut encore en dire plus, après avoir parcouru ces textes ; ... et si seulement ... Alors là, nous aurions la fierté d'avoir été un temps soit peu utile ; Tchueroschoy, Recueils , 1996, page 77 |
|