Edição das 19h56min de 8 de junho de 2016 (ver código-fonte)
Fthewes (Discussão | contribs)
(→‎Método)
Edição das 20h14min de 8 de junho de 2016 (ver código-fonte)
(→‎Simulação - Resultados)
Analisando a função g(r) a medida em que se diminui o tamanho linear da célula (''Figura ao lado''), percebe-se que, para ''R<sub>c</sub><2<math>\sigma </math>'' a medida deixa de corresponder ao sistema físico real. Tal fato se dá pelo alcance do potencial de Lennard-Jones. Se ''R<sub>c</sub><2<math>\sigma</math>'' interações relevantes não estão sendo levadas em conta. Portanto, para o potencial de Lennard-Jones, um bom valor de ''R<sub>c</sub>'' é 2<math>\sigma </math>.
Abaixo, o tempo de simulação em função de ''R<sub>c</sub>'' para dois valores de N.
[[File:tCellRc.png|thumb|center|450px|Tempo computacional em função de ''R<sub>c</sub>''. Quanto menor ''R<sub>c</sub>'', menor o tempo gasto. Deve-se, porém, levar em conta o limite físico como visto acima.]]
Mantendo constante ''R<sub>c</sub>=2<math>\sigma</math>'' e a densidade <math>\rho=1.0</math>, pode-se calcular o tempo computacional a medida em que aumenta o número de partículas no sistema. O resultado pode ser visto na figura ao lado.
Edição das 20h14min de 8 de junho de 2016
Cerca de 95% do tempo de uma simulação é gasto com o cálculo das forças e a respectiva integração. Baseado nisso, criam-se métodos de otimização dos programas de simulação que podem acelerar de forma gigantesca (dependendo do número de partículas em interação) este processo. Claro que estes métodos por sua vez não são perfeitos, eles dependem de algumas características do sistema, no caso em questão, as otimizações chamadas Lista de Verlet e Células baseiam-se na simetria do potencial utilizado (Lennard-Jones) e no fato de ele provocar uma interação de curto alcance (em relação ao tamanho total do sistema), e são restritas a estas simetrias.
2 Otimização por células
2.3 Simulação - Resultados
Para a otimização da Lista de Verlet, por mais que ainda se tenham alguns cálculos de ordem N2, espera-se que sejam muito menos frequentes que no cálculo não otimizado.
Na Figura 5 pode-se analisar então o comportamento do tempo de simulação em relação à quantidade de partículas no sistema, onde os círculos aberto representam as simulações para o programa sem otimização, o programa otimizado com parâmetros ruins e o programa otimizado com parâmetros ótimos; já os traços contínuos representam os ajustes lineares das Equações 1 e 2 para os respectivos programas. O fator flagrante que se marca no gráfico é o fato de que as simulações otimizadas, mesmo para parâmetros ruins, são bem mais rápidas que as efetuadas sem qualquer otimização. Além disso, a partir dos ajustes, obtém-se os coeficientes, já discutidos, das equações de tempo de simulação onde pode-se notar que quando tomam-se parâmetros ruins para a otimização de Verlet (no caso Rv), o programa acaba tendo uma dependência muito maior no parâmetro quadrático (aproximadamente 40x maior) e consequentemente isso afeta de forma drástica o tempo de simulação. No caso particular abordado, em que o sistema tem densidade 1, a difusão das partículas é quase inexistente, isso permite que o fit com parâmetros ótimos quase não possua dependência quadrática, não sendo esta uma regra geral de bons parâmetros. Marcam-se então as diferenças para 2500 partículas, em que os tempos sem otimização, com otimização ruim e com otimização ótima são, respectivamente, τSem-Otim = 2115.340s, τVerl-ruim = 1025.992s e τVerl-bom = 62.564s.
Otimização por células
Otimização por células. Divisão do espaço em células, fazendo com que a partícula interaja somente com suas vizinhas.
Neste método divide-se o espaço em células (normalmente, mas não necessariamente quadradas) e calcula-se, para cada partícula, somente a interação com aquelas que se encontram em uma célula vizinha à sua. Desta forma, ao invés de o tempo computacional escalar com N2, escala segundo a lei:
onde a e b são constantes, n é o número de partículas nas células vizinhas e N é o número total de partículas. Assim como na Lista de Verlet, o método possui muitas operações com matrizes e, por isso, torna-se mais eficiente somente para valores de N grandes.
Em geral, para uma célula Ci,j, considera-se vizinhas as células: Ci,j, Ci+/-1,j, Ci,j+/-1, Ci+/-1,j+/-1, Ci+1,j-1 e Ci-1,j+1, totalizando nove. É importante ressaltar que o tamanho linear de uma célula deve, pelo menos, conter o intervalo em que a interação entre duas partículas é relevante.
Deve-se inicialmente construir uma matriz indicando as células vizinhas de cada célula.
//NC=numero linear de celulas - celulas totais=NC*NC
//cviz[i][j] = j-esima celula vizinha da i-esima celula
void init_viz(int **cviz)
int i, j, ind, ip, im, jp, jm;
for(i=0; i<NC; i++)
for(j=0; j<NC; j++)
ip=(i+1)%NC; im=(i+NC-1)%NC;   //condicoes de contorno periodicas em i
jp=(j+1)%NC; jm=(j+NC-1)%NC;   //condicoes de contorno periodicas em j
ind=i*NC+j;
cviz[ind][0]=i*NC+jm;
cviz[ind][1]  =i*NC+jp;
cviz[ind][2]=im*NC+jm;
cviz[ind][3]=im*NC+jp;
cviz[ind][4]=im*NC+j;          //define vizinhos
cviz[ind][5]=ip*NC+jm;
cviz[ind][6]=ip*NC+jp;
cviz[ind][7]=ip*NC+j;
cviz[ind][8]=ind;
Então, para cada passo de tempo, deve-se determinar quais partículas estão em quais células.
//ncell[i]=numero de particulas na celula i
//cell[i][j]=indice da j-esima particula na i-esima celula
void celula(double *xx, double *yy, int *ncell, int **cell)
int i, cx, cy, ind=0;
for(i=0; i<NC*NC; i++)
ncell[i]=0;
xtmp=fmod(xx[i], L); ytmp=fmod(yy[i], L);    //PBC
if(xtmp<0) xtmp+=L;
if(ytmp<0) ytmp+=L;
cx=(int)(xtmp/(1.*L/NC));                   //determina a celula da particula
cy=(int)(ytmp/(1.*L/NC));
ind=cx*NC + cy;
cell[ind][ncell[ind]]=i;
ncell[ind]++;
Calcula-se então as forças entre cada partícula e suas vizinhas.
void comp_forces(double *ffx, double *ffy, double *xx, double *yy, int **cell, int *ncell, int **cviz)
int i, j, k, cx, cy;
double x1, y1, x2, y2, dxx, dyy, r2, r2i, r6, ff;
int numPart=0, celulaVizinha;
ffx[i]=0.;           //zera as forcas
ffy[i]=0.;
int ind, p2;
for(i=0; i<N; i++)   //para cada particula
x1=xx[i]; y1=yy[i];
xtmp=fmod(x1, L); ytmp=fmod(y1, L);    //PBC
cx=(int)(xtmp/(1.*L/NC));
ind=cx*NC+cy;               //determina indice da celula
for(j=0; j<9; j++)          //para cada celula vizinha
celulaVizinha=cviz[ind][j];
numPart=ncell[celulaVizinha];
for(k=0; k<numPart; k++)     //para cada particula na celula vizinha
p2=cell[celulaVizinha][k];
if(p2!=i)
\\calculos usuais das forcas
Em geral, o algoritmo fica:
init_viz(...)
loopTemporal
celula(...)
comp_forces(...)
integra(...)
endLoopTemporal
Otimização por células. Medida g(r) para diferentes valores de Rc
Analisando a função g(r) a medida em que se diminui o tamanho linear da célula (Figura ao lado), percebe-se que, para Rc<2 a medida deixa de corresponder ao sistema físico real. Tal fato se dá pelo alcance do potencial de Lennard-Jones. Se Rc<2 interações relevantes não estão sendo levadas em conta. Portanto, para o potencial de Lennard-Jones, um bom valor de Rc é 2 .
Abaixo, o tempo de simulação em função de Rc para dois valores de N.
Tempo computacional em função de Rc. Quanto menor Rc, menor o tempo gasto. Deve-se, porém, levar em conta o limite físico como visto acima.
Mantendo constante Rc=2 e a densidade , pode-se calcular o tempo computacional a medida em que aumenta o número de partículas no sistema. O resultado pode ser visto na figura ao lado.
Otimização por células. O tempo computacional escalona com N, ao contrário de N2.
Para fins de comparação, pode-se ver na figura a seguir o tempo computacional gasto em uma simulação com a otimização por células e uma sem nenhuma otimização.